Streamable HTTP resumability + redelivery + SSE polling via server-side disconnect (#1077)
Co-authored-by: Stephen Halter <halter73@gmail.com>
This commit is contained in:
parent
4cb2fd4655
commit
b8311756b4
1 changed files with 2675 additions and 246 deletions
|
|
@ -283,4 +283,75 @@ public class MapMcpStreamableHttpTests(ITestOutputHelper outputHelper) : MapMcpT
|
|||
|
||||
Assert.Equal(1, runSessionCount);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnablePollingAsync_ThrowsInvalidOperationException_InStatelessMode()
|
||||
{
|
||||
Assert.SkipUnless(Stateless, "This test only applies to stateless mode.");
|
||||
|
||||
InvalidOperationException? capturedException = null;
|
||||
var pollingTool = McpServerTool.Create(async (RequestContext<CallToolRequestParams> context) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await context.EnablePollingAsync(retryInterval: TimeSpan.FromSeconds(1));
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
capturedException = ex;
|
||||
}
|
||||
|
||||
return "Complete";
|
||||
}, options: new() { Name = "polling_tool" });
|
||||
|
||||
Builder.Services.AddMcpServer().WithHttpTransport(ConfigureStateless).WithTools([pollingTool]);
|
||||
|
||||
await using var app = Builder.Build();
|
||||
app.MapMcp();
|
||||
|
||||
await app.StartAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
await using var mcpClient = await ConnectAsync();
|
||||
|
||||
await mcpClient.CallToolAsync("polling_tool", cancellationToken: TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.NotNull(capturedException);
|
||||
Assert.Contains("stateless", capturedException.Message, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
|
||||
[Fact]
|
||||
public async Task EnablePollingAsync_ThrowsInvalidOperationException_WhenNoEventStreamStoreConfigured()
|
||||
{
|
||||
Assert.SkipWhen(Stateless, "This test only applies to stateful mode without an event stream store.");
|
||||
|
||||
InvalidOperationException? capturedException = null;
|
||||
var pollingTool = McpServerTool.Create(async (RequestContext<CallToolRequestParams> context) =>
|
||||
{
|
||||
try
|
||||
{
|
||||
await context.EnablePollingAsync(retryInterval: TimeSpan.FromSeconds(1));
|
||||
}
|
||||
catch (InvalidOperationException ex)
|
||||
{
|
||||
capturedException = ex;
|
||||
}
|
||||
|
||||
return "Complete";
|
||||
}, options: new() { Name = "polling_tool" });
|
||||
|
||||
// Configure without EventStreamStore
|
||||
Builder.Services.AddMcpServer().WithHttpTransport(ConfigureStateless).WithTools([pollingTool]);
|
||||
|
||||
await using var app = Builder.Build();
|
||||
app.MapMcp();
|
||||
|
||||
await app.StartAsync(TestContext.Current.CancellationToken);
|
||||
|
||||
await using var mcpClient = await ConnectAsync();
|
||||
|
||||
await mcpClient.CallToolAsync("polling_tool", cancellationToken: TestContext.Current.CancellationToken);
|
||||
|
||||
Assert.NotNull(capturedException);
|
||||
Assert.Contains("event stream store", capturedException.Message, StringComparison.OrdinalIgnoreCase);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in a new issue