Fix process crash when testing Stderr (#1449)

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Eric StJohn 2026-04-06 11:29:00 -07:00 • committed by GitHub
commit 2e7209c35a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 254 additions and 148 deletions

View file

@ -59,6 +59,17 @@ public class StdioClientTransportTests(ITestOutputHelper testOutputHelper) : Log
Assert.Contains(id, sb.ToString());
}
[Fact(Skip = "Platform not supported by this test.", SkipUnless = nameof(IsStdErrCallbackSupported))]
public async Task CreateAsync_StdErrCallbackThrows_DoesNotCrashProcess()
{
StdioClientTransport transport = RuntimeInformation.IsOSPlatform(OSPlatform.Windows) ?
new(new() { Command = "cmd", Arguments = ["/c", "echo fail >&2 & exit /b 1"], StandardErrorLines = _ => throw new InvalidOperationException("boom") }, LoggerFactory) :
new(new() { Command = "sh", Arguments = ["-c", "echo fail >&2; exit 1"], StandardErrorLines = _ => throw new InvalidOperationException("boom") }, LoggerFactory);
// Should throw IOException for the failed server, not crash the host process.
await Assert.ThrowsAnyAsync<IOException>(() => McpClient.CreateAsync(transport, loggerFactory: LoggerFactory, cancellationToken: TestContext.Current.CancellationToken));
}
[Theory]
[InlineData(null)]
[InlineData("argument with spaces")]

View file

@ -27,8 +27,11 @@ public class StdioServerTransportTests : LoggedTest
[Fact]
public async Task Constructor_Should_Initialize_With_Valid_Parameters()
{
// Act
await using var transport = new StdioServerTransport(_serverOptions);
// Use StreamServerTransport with Stream.Null rather than StdioServerTransport.
// StdioServerTransport opens Console.OpenStandardInput() which permanently
// blocks a thread pool thread on the test host's stdin. StdioServerTransport
// should only be instantiated in a dedicated child process.
await using var transport = new StreamServerTransport(Stream.Null, Stream.Null, _serverOptions.ServerInfo?.Name);
// Assert
Assert.NotNull(transport);