diff --git a/src/Netclaw.Daemon.Tests/Mcp/McpSdkCatalogNotificationIntegrationTests.cs b/src/Netclaw.Daemon.Tests/Mcp/McpSdkCatalogNotificationIntegrationTests.cs index 0bd925ece..6ebe7b4c4 100644 --- a/src/Netclaw.Daemon.Tests/Mcp/McpSdkCatalogNotificationIntegrationTests.cs +++ b/src/Netclaw.Daemon.Tests/Mcp/McpSdkCatalogNotificationIntegrationTests.cs @@ -10,7 +10,7 @@ namespace Netclaw.Daemon.Tests.Mcp; -public sealed class McpSdkCatalogNotificationIntegrationTests +public sealed class McpSdkCatalogNotificationIntegrationTests(ITestOutputHelper output) { private static readonly McpServerName ServerName = new("notifications"); @@ -27,9 +27,11 @@ public async Task RawListenAcknowledgementAndToolEvent_RefreshLiveCatalog() var registry = new ToolRegistry(); await using var harness = McpSmokeHarness.Create( new Dictionary { [ServerName.Value] = entry }, - registry); + registry, + output); await harness.Manager.StartAsync(TestContext.Current.CancellationToken); + harness.AssertConnected(ServerName.Value); var first = Assert.IsType(harness.Manager.GetSnapshot(ServerName)); var lease = Assert.IsType(first.NotificationLease); Assert.Equal(McpCatalogNotificationMode.Modern, lease.Mode); @@ -47,4 +49,30 @@ public async Task RawListenAcknowledgementAndToolEvent_RefreshLiveCatalog() Assert.Equal(first.Generation + 1, second.Generation); Assert.Contains("dynamic-added", second.ToolFunctions.Keys); } + + [Fact] + public async Task FailedStdioStartup_IsReportedBeforeLeaseAssertions() + { + var entry = new McpServerEntry + { + Transport = "stdio", + Command = $"netclaw-missing-mcp-server-{Guid.NewGuid():N}", + Enabled = true, + }; + await using var harness = McpSmokeHarness.Create( + new Dictionary { [ServerName.Value] = entry }, + new ToolRegistry(), + output); + + await harness.Manager.StartAsync(TestContext.Current.CancellationToken); + + var failure = Assert.Throws( + () => harness.AssertConnected(ServerName.Value)); + Assert.Contains("state=Unreachable", failure.Message, StringComparison.Ordinal); + Assert.Contains("Failed to reach MCP server", failure.Message, StringComparison.Ordinal); + Assert.Contains("Failed to connect to MCP server", output.Output, StringComparison.Ordinal); + Assert.Contains("System.IO.IOException", output.Output, StringComparison.Ordinal); + Assert.Contains(entry.Command, output.Output, StringComparison.Ordinal); + Assert.Null(harness.Manager.GetSnapshot(ServerName)?.NotificationLease); + } }