Speed up CLI argument escaping tests (#1773)

Copilot-Session: 323a2062-9493-4be4-a710-f6c2b9e15a49
This commit is contained in:
Pranav Senthilnathan 2026-07-29 14:46:35 -07:00 • committed by GitHub
commit 155f619441
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 34 additions and 16 deletions

View file

@ -34,6 +34,13 @@ internal static class Program
private static async Task Main(string[] args) private static async Task Main(string[] args)
{ {
if (args.Contains("--echo-cli-arg-and-exit"))
{
Console.Error.WriteLine($"CLI_ARG:{JsonSerializer.Serialize(ParseCliArgument(args))}");
Console.Error.Flush();
return;
}
Log.Logger.Information("Starting server..."); Log.Logger.Information("Starting server...");
string? cliArg = ParseCliArgument(args); string? cliArg = ParseCliArgument(args);

View file

@ -153,6 +153,8 @@ public class StdioClientTransportTests(ITestOutputHelper testOutputHelper) : Log
Assert.Skip("mono runtime does not handle arguments ending with backslash correctly."); Assert.Skip("mono runtime does not handle arguments ending with backslash correctly.");
} }
const string OutputPrefix = "CLI_ARG:";
var capturedArgument = new TaskCompletionSource<string>(TaskCreationOptions.RunContinuationsAsynchronously);
string cliArgument = $"--cli-arg={cliArgumentValue}"; string cliArgument = $"--cli-arg={cliArgumentValue}";
string testServerExecutable = Path.Combine(AppContext.BaseDirectory, "TestServer.exe"); string testServerExecutable = Path.Combine(AppContext.BaseDirectory, "TestServer.exe");
string testServerDll = Path.Combine(AppContext.BaseDirectory, "TestServer.dll"); string testServerDll = Path.Combine(AppContext.BaseDirectory, "TestServer.dll");
@ -168,25 +170,34 @@ public class StdioClientTransportTests(ITestOutputHelper testOutputHelper) : Log
}, },
Arguments = (PlatformDetection.IsMonoRuntime, PlatformDetection.IsWindows) switch Arguments = (PlatformDetection.IsMonoRuntime, PlatformDetection.IsWindows) switch
{ {
(true, _) => [testServerExecutable, cliArgument], (true, _) => [testServerExecutable, "--echo-cli-arg-and-exit", cliArgument],
(_, true) => [cliArgument], (_, true) => ["--echo-cli-arg-and-exit", cliArgument],
_ => [testServerDll, cliArgument], _ => [testServerDll, "--echo-cli-arg-and-exit", cliArgument],
},
StandardErrorLines = line =>
{
if (line.StartsWith(OutputPrefix, StringComparison.Ordinal))
{
capturedArgument.TrySetResult(line[OutputPrefix.Length..]);
}
}, },
}; };
var transport = new StdioClientTransport(options, LoggerFactory); var transport = new StdioClientTransport(options, LoggerFactory);
await using var session = await transport.ConnectAsync(TestContext.Current.CancellationToken);
// Act: Create client (handshake) and list tools to ensure full round trip works with the argument present. string serializedArgument = await capturedArgument.Task.WaitAsync(
await using var client = await McpClient.CreateAsync(transport, loggerFactory: LoggerFactory, cancellationToken: TestContext.Current.CancellationToken); TestConstants.DefaultTimeout,
var tools = await client.ListToolsAsync(cancellationToken: TestContext.Current.CancellationToken); TestContext.Current.CancellationToken);
JsonElement parsedArgument = JsonElement.Parse(serializedArgument);
Assert.Equal(cliArgumentValue ?? "", parsedArgument.GetString());
// Assert var exception = await Assert.ThrowsAsync<ClientTransportClosedException>(
Assert.NotNull(tools); async () => await session.MessageReader.Completion.WaitAsync(
Assert.NotEmpty(tools); TestConstants.DefaultTimeout,
TestContext.Current.CancellationToken));
var result = await client.CallToolAsync("echoCliArg", cancellationToken: TestContext.Current.CancellationToken); var completionDetails = Assert.IsType<StdioClientCompletionDetails>(exception.Details);
var content = Assert.IsType<TextContentBlock>(Assert.Single(result.Content)); Assert.Equal(0, completionDetails.ExitCode);
Assert.Equal(cliArgumentValue ?? "", content.Text);
} }
[Fact(Skip = "Platform not supported by this test.", SkipUnless = nameof(IsStdErrCallbackSupported))] [Fact(Skip = "Platform not supported by this test.", SkipUnless = nameof(IsStdErrCallbackSupported))]