Reduce flakiness in long-running stateless HTTP tool timeout test (#1300)
Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: halter73 <54385+halter73@users.noreply.github.com>
This commit is contained in:
parent
b967835144
commit
231e013160
1 changed files with 39 additions and 24 deletions
|
|
@ -245,34 +245,49 @@ public abstract class MapMcpTests(ITestOutputHelper testOutputHelper) : KestrelI
|
||||||
app.MapMcp();
|
app.MapMcp();
|
||||||
await app.StartAsync(TestContext.Current.CancellationToken);
|
await app.StartAsync(TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
// Create a custom HttpClient with a very short timeout (1 second)
|
// Retry a couple of times to reduce occasional flakiness on low-resource machines.
|
||||||
// The tool will take 2 seconds to complete
|
// If the server regresses to flushing only after tool completion, each attempt should still fail
|
||||||
using var shortTimeoutClient = new HttpClient(SocketsHttpHandler)
|
// because HttpClient timeout (1 second) is below the tool duration (2 seconds).
|
||||||
|
for (var attempt = 0; attempt < 3; attempt++)
|
||||||
{
|
{
|
||||||
BaseAddress = new Uri("http://localhost:5000/"),
|
try
|
||||||
Timeout = TimeSpan.FromSeconds(1)
|
{
|
||||||
};
|
// Create a custom HttpClient with a very short timeout (1 second)
|
||||||
|
// The tool will take 2 seconds to complete
|
||||||
|
using var shortTimeoutClient = new HttpClient(SocketsHttpHandler, disposeHandler: false)
|
||||||
|
{
|
||||||
|
BaseAddress = new Uri("http://localhost:5000/"),
|
||||||
|
Timeout = TimeSpan.FromSeconds(1)
|
||||||
|
};
|
||||||
|
|
||||||
var path = UseStreamableHttp ? "/" : "/sse";
|
var path = UseStreamableHttp ? "/" : "/sse";
|
||||||
var transportMode = UseStreamableHttp ? HttpTransportMode.StreamableHttp : HttpTransportMode.Sse;
|
var transportMode = UseStreamableHttp ? HttpTransportMode.StreamableHttp : HttpTransportMode.Sse;
|
||||||
|
|
||||||
await using var transport = new HttpClientTransport(new()
|
await using var transport = new HttpClientTransport(new()
|
||||||
{
|
{
|
||||||
Endpoint = new($"http://localhost:5000{path}"),
|
Endpoint = new($"http://localhost:5000{path}"),
|
||||||
TransportMode = transportMode,
|
TransportMode = transportMode,
|
||||||
}, shortTimeoutClient, LoggerFactory);
|
}, shortTimeoutClient, LoggerFactory);
|
||||||
|
|
||||||
await using var mcpClient = await McpClient.CreateAsync(transport, loggerFactory: LoggerFactory, cancellationToken: TestContext.Current.CancellationToken);
|
await using var mcpClient = await McpClient.CreateAsync(transport, loggerFactory: LoggerFactory, cancellationToken: TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
// Call a tool that takes 2 seconds - this should succeed despite the 1 second HttpClient timeout
|
// Call a tool that takes 2 seconds - this should succeed despite the 1 second HttpClient timeout
|
||||||
// because the response stream is flushed immediately after receiving the request
|
// because the response stream is flushed immediately after receiving the request
|
||||||
var response = await mcpClient.CallToolAsync(
|
var response = await mcpClient.CallToolAsync(
|
||||||
"long_running_operation",
|
"long_running_operation",
|
||||||
new Dictionary<string, object?>() { ["durationMs"] = 2000 },
|
new Dictionary<string, object?>() { ["durationMs"] = 2000 },
|
||||||
cancellationToken: TestContext.Current.CancellationToken);
|
cancellationToken: TestContext.Current.CancellationToken);
|
||||||
|
|
||||||
|
var content = Assert.Single(response.Content.OfType<TextContentBlock>());
|
||||||
|
Assert.Equal("Operation completed after 2000ms", content.Text);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
catch (OperationCanceledException) when (attempt < 2)
|
||||||
|
{
|
||||||
|
// Retry intermittent timeout-related failures on slow CI machines.
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
var content = Assert.Single(response.Content.OfType<TextContentBlock>());
|
|
||||||
Assert.Equal("Operation completed after 2000ms", content.Text);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private ClaimsPrincipal CreateUser(string name)
|
private ClaimsPrincipal CreateUser(string name)
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue