Skip to content

Commit 27ba8b1

Browse files
stephentoubeiriktsarpalis
andauthoredMar 20, 2025··
Upgrade to xunit.v3 (#8)
* Upgrade to xunit.v3 * Use Assert.Skip where applicable. --------- Co-authored-by: Eirik Tsarpalis <[email protected]>
1 parent 6b8c288 commit 27ba8b1

11 files changed

+128
-110
lines changed
 

‎Directory.Packages.props

+2-2
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@
3535
<PackageVersion Include="Serilog.Sinks.Debug" Version="3.0.0" />
3636
<PackageVersion Include="Serilog.Sinks.File" Version="6.0.0" />
3737
<PackageVersion Include="System.Linq.AsyncEnumerable" Version="$(System10Version)" />
38-
<PackageVersion Include="xunit" Version="2.9.2" />
39-
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.0" />
38+
<PackageVersion Include="xunit.v3" Version="1.1.0" />
39+
<PackageVersion Include="xunit.runner.visualstudio" Version="3.0.2" />
4040
</ItemGroup>
4141
</Project>

‎ModelContextProtocol.sln

+2
Original file line numberDiff line numberDiff line change
@@ -31,9 +31,11 @@ EndProject
3131
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "Solution Items", "Solution Items", "{B6FB2B28-D5DE-4654-BE9A-45E305DE4852}"
3232
ProjectSection(SolutionItems) = preProject
3333
Directory.Build.props = Directory.Build.props
34+
Directory.Packages.props = Directory.Packages.props
3435
global.json = global.json
3536
LICENSE = LICENSE
3637
logo.png = logo.png
38+
nuget.config = nuget.config
3739
README.MD = README.MD
3840
version.json = version.json
3941
EndProjectSection

‎tests/ModelContextProtocol.TestServer/Program.cs

-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
using System.Text;
2-
using System.Text.Json;
32
using ModelContextProtocol.Protocol.Messages;
43
using ModelContextProtocol.Protocol.Transport;
54
using ModelContextProtocol.Protocol.Types;

‎tests/ModelContextProtocol.Tests/Client/McpClientFactoryTests.cs

+17-19
Original file line numberDiff line numberDiff line change
@@ -17,34 +17,28 @@ public class McpClientFactoryTests
1717
[Fact]
1818
public async Task CreateAsync_WithInvalidArgs_Throws()
1919
{
20-
await Assert.ThrowsAsync<ArgumentNullException>("serverConfig", () => McpClientFactory.CreateAsync((McpServerConfig)null!, _defaultOptions));
20+
await Assert.ThrowsAsync<ArgumentNullException>("serverConfig", () => McpClientFactory.CreateAsync((McpServerConfig)null!, _defaultOptions, cancellationToken: TestContext.Current.CancellationToken));
2121

22-
await Assert.ThrowsAsync<ArgumentNullException>("clientOptions", () => McpClientFactory.CreateAsync(
23-
new McpServerConfig()
22+
await Assert.ThrowsAsync<ArgumentNullException>("clientOptions", () => McpClientFactory.CreateAsync(new McpServerConfig()
2423
{
2524
Name = "name",
2625
Id = "id",
2726
TransportType = TransportTypes.StdIo,
28-
}, (McpClientOptions)null!));
27+
}, (McpClientOptions)null!, cancellationToken: TestContext.Current.CancellationToken));
2928

30-
await Assert.ThrowsAsync<ArgumentException>("serverConfig", () => McpClientFactory.CreateAsync(
31-
new McpServerConfig()
29+
await Assert.ThrowsAsync<ArgumentException>("serverConfig", () => McpClientFactory.CreateAsync(new McpServerConfig()
3230
{
3331
Name = "name",
3432
Id = "id",
3533
TransportType = "somethingunsupported",
36-
},
37-
_defaultOptions));
34+
}, _defaultOptions, cancellationToken: TestContext.Current.CancellationToken));
3835

39-
await Assert.ThrowsAsync<InvalidOperationException>(() => McpClientFactory.CreateAsync(
40-
new McpServerConfig()
36+
await Assert.ThrowsAsync<InvalidOperationException>(() => McpClientFactory.CreateAsync(new McpServerConfig()
4137
{
4238
Name = "name",
4339
Id = "id",
4440
TransportType = TransportTypes.StdIo,
45-
},
46-
_defaultOptions,
47-
(_, __) => null!));
41+
}, _defaultOptions, (_, __) => null!, cancellationToken: TestContext.Current.CancellationToken));
4842
}
4943

5044
[Fact]
@@ -68,7 +62,8 @@ public async Task CreateAsync_WithValidStdioConfig_CreatesNewClient()
6862
await using var client = await McpClientFactory.CreateAsync(
6963
serverConfig,
7064
_defaultOptions,
71-
(_, __) => new NopTransport());
65+
(_, __) => new NopTransport(),
66+
cancellationToken: TestContext.Current.CancellationToken);
7267

7368
// Assert
7469
Assert.NotNull(client);
@@ -91,7 +86,8 @@ public async Task CreateAsync_WithNoTransportOptions_CreatesNewClient()
9186
await using var client = await McpClientFactory.CreateAsync(
9287
serverConfig,
9388
_defaultOptions,
94-
(_, __) => new NopTransport());
89+
(_, __) => new NopTransport(),
90+
cancellationToken: TestContext.Current.CancellationToken);
9591

9692
// Assert
9793
Assert.NotNull(client);
@@ -114,7 +110,8 @@ public async Task CreateAsync_WithValidSseConfig_CreatesNewClient()
114110
await using var client = await McpClientFactory.CreateAsync(
115111
serverConfig,
116112
_defaultOptions,
117-
(_, __) => new NopTransport());
113+
(_, __) => new NopTransport(),
114+
cancellationToken: TestContext.Current.CancellationToken);
118115

119116
// Assert
120117
Assert.NotNull(client);
@@ -144,7 +141,8 @@ public async Task CreateAsync_WithSse_CreatesCorrectTransportOptions()
144141
await using var client = await McpClientFactory.CreateAsync(
145142
serverConfig,
146143
_defaultOptions,
147-
(_, __) => new NopTransport());
144+
(_, __) => new NopTransport(),
145+
cancellationToken: TestContext.Current.CancellationToken);
148146

149147
// Assert
150148
Assert.NotNull(client);
@@ -171,7 +169,7 @@ public async Task McpFactory_WithInvalidTransportOptions_ThrowsFormatException(s
171169
};
172170

173171
// act & assert
174-
await Assert.ThrowsAsync<ArgumentException>(() => McpClientFactory.CreateAsync(config, _defaultOptions));
172+
await Assert.ThrowsAsync<ArgumentException>(() => McpClientFactory.CreateAsync(config, _defaultOptions, cancellationToken: TestContext.Current.CancellationToken));
175173
}
176174

177175
private sealed class NopTransport : IClientTransport
@@ -191,7 +189,7 @@ public Task SendMessageAsync(IJsonRpcMessage message, CancellationToken cancella
191189
{
192190
switch (message)
193191
{
194-
case JsonRpcRequest request:
192+
case JsonRpcRequest:
195193
_channel.Writer.TryWrite(new JsonRpcResponse
196194
{
197195
Id = ((JsonRpcRequest)message).Id,

‎tests/ModelContextProtocol.Tests/ClientIntegrationTests.cs

+41-34
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,12 @@
11
using ModelContextProtocol.Client;
2-
using ModelContextProtocol.Configuration;
3-
using ModelContextProtocol.Protocol.Messages;
4-
using ModelContextProtocol.Protocol.Transport;
5-
using ModelContextProtocol.Protocol.Types;
62
using Microsoft.Extensions.AI;
73
using OpenAI;
4+
using ModelContextProtocol.Protocol.Types;
5+
using ModelContextProtocol.Protocol.Messages;
86
using System.Text.Json;
7+
using ModelContextProtocol.Configuration;
8+
using ModelContextProtocol.Protocol.Transport;
9+
using Xunit.Sdk;
910

1011
namespace ModelContextProtocol.Tests;
1112

@@ -61,8 +62,8 @@ public async Task ListTools_Stdio(string clientId)
6162

6263
// act
6364
await using var client = await _fixture.CreateClientAsync(clientId);
64-
var tools = await client.ListToolsAsync().ToListAsync();
65-
var aiFunctions = await client.GetAIFunctionsAsync();
65+
var tools = await client.ListToolsAsync(TestContext.Current.CancellationToken).ToListAsync(TestContext.Current.CancellationToken);
66+
var aiFunctions = await client.GetAIFunctionsAsync(TestContext.Current.CancellationToken);
6667

6768
// assert
6869
Assert.NotEmpty(tools);
@@ -102,9 +103,9 @@ public async Task CallTool_Stdio_ViaAIFunction_EchoServer(string clientId)
102103

103104
// act
104105
await using var client = await _fixture.CreateClientAsync(clientId);
105-
var aiFunctions = await client.GetAIFunctionsAsync();
106+
var aiFunctions = await client.GetAIFunctionsAsync(TestContext.Current.CancellationToken);
106107
var echo = aiFunctions.Single(t => t.Name == "echo");
107-
var result = await echo.InvokeAsync([new KeyValuePair<string, object?>("message", "Hello MCP!")]);
108+
var result = await echo.InvokeAsync([new KeyValuePair<string, object?>("message", "Hello MCP!")], TestContext.Current.CancellationToken);
108109

109110
// assert
110111
Assert.NotNull(result);
@@ -119,7 +120,7 @@ public async Task ListPrompts_Stdio(string clientId)
119120

120121
// act
121122
await using var client = await _fixture.CreateClientAsync(clientId);
122-
var prompts = await client.ListPromptsAsync().ToListAsync();
123+
var prompts = await client.ListPromptsAsync(TestContext.Current.CancellationToken).ToListAsync(TestContext.Current.CancellationToken);
123124

124125
// assert
125126
Assert.NotEmpty(prompts);
@@ -251,7 +252,7 @@ public async Task SubscribeResource_Stdio()
251252
await client.SubscribeToResourceAsync("test://static/resource/1", CancellationToken.None);
252253

253254
// notifications happen every 5 seconds, so we wait for 10 seconds to ensure we get at least one notification
254-
await Task.Delay(10000);
255+
await Task.Delay(10000, TestContext.Current.CancellationToken);
255256

256257
// assert
257258
Assert.True(counter > 0);
@@ -276,17 +277,17 @@ public async Task UnsubscribeResource_Stdio()
276277
await client.SubscribeToResourceAsync("test://static/resource/1", CancellationToken.None);
277278

278279
// notifications happen every 5 seconds, so we wait for 10 seconds to ensure we get at least one notification
279-
await Task.Delay(10000);
280+
await Task.Delay(10000, TestContext.Current.CancellationToken);
280281

281282
// reset counter
282283
int counterAfterSubscribe = counter;
283-
284+
284285
// unsubscribe
285286
await client.UnsubscribeFromResourceAsync("test://static/resource/1", CancellationToken.None);
286287
counter = 0;
287288

288289
// notifications happen every 5 seconds, so we wait for 10 seconds to ensure we would've gotten at least one notification
289-
await Task.Delay(10000);
290+
await Task.Delay(10000, TestContext.Current.CancellationToken);
290291

291292
// assert
292293
Assert.True(counterAfterSubscribe > 0);
@@ -340,7 +341,7 @@ public async Task GetCompletion_Stdio_PromptReference(string clientId)
340341
[Theory]
341342
[MemberData(nameof(GetClients))]
342343
public async Task Sampling_Stdio(string clientId)
343-
{
344+
{
344345
// Set up the sampling handler
345346
int samplingHandlerCalls = 0;
346347
await using var client = await _fixture.CreateClientAsync(clientId, new()
@@ -375,8 +376,8 @@ public async Task Sampling_Stdio(string clientId)
375376
{
376377
["prompt"] = "Test prompt",
377378
["maxTokens"] = 100
378-
}
379-
);
379+
},
380+
TestContext.Current.CancellationToken);
380381

381382
// assert
382383
Assert.NotNull(result);
@@ -423,8 +424,8 @@ public async Task Notifications_Stdio(string clientId)
423424
await using var client = await _fixture.CreateClientAsync(clientId);
424425

425426
// Verify we can send notifications without errors
426-
await client.SendNotificationAsync(NotificationMethods.RootsUpdatedNotification);
427-
await client.SendNotificationAsync("test/notification", new { test = true });
427+
await client.SendNotificationAsync(NotificationMethods.RootsUpdatedNotification, cancellationToken: TestContext.Current.CancellationToken);
428+
await client.SendNotificationAsync("test/notification", new { test = true }, TestContext.Current.CancellationToken);
428429

429430
// assert
430431
// no response to check, if no exception is thrown, it's a success
@@ -452,13 +453,17 @@ public async Task CallTool_Stdio_MemoryServer()
452453
ClientInfo = new() { Name = "IntegrationTestClient", Version = "1.0.0" }
453454
};
454455

455-
await using var client = await McpClientFactory.CreateAsync(serverConfig, clientOptions, loggerFactory: _fixture.LoggerFactory);
456+
await using var client = await McpClientFactory.CreateAsync(
457+
serverConfig,
458+
clientOptions,
459+
loggerFactory: _fixture.LoggerFactory,
460+
cancellationToken: TestContext.Current.CancellationToken);
456461

457462
// act
458463
var result = await client.CallToolAsync(
459464
"read_graph",
460-
[]
461-
);
465+
[],
466+
TestContext.Current.CancellationToken);
462467

463468
// assert
464469
Assert.NotNull(result);
@@ -471,14 +476,14 @@ public async Task CallTool_Stdio_MemoryServer()
471476
[Fact]
472477
public async Task GetAIFunctionsAsync_UsingEverythingServer_ToolsAreProperlyCalled()
473478
{
474-
if (s_openAIKey is null)
475-
{
476-
return; // Skip the test if the OpenAI key is not provided
477-
}
479+
SkipTestIfNoOpenAIKey();
478480

479481
// Get the MCP client and tools from it.
480-
await using var client = await McpClientFactory.CreateAsync(_fixture.EverythingServerConfig, _fixture.DefaultOptions); ;
481-
var mappedTools = await client.GetAIFunctionsAsync();
482+
await using var client = await McpClientFactory.CreateAsync(
483+
_fixture.EverythingServerConfig,
484+
_fixture.DefaultOptions,
485+
cancellationToken: TestContext.Current.CancellationToken);
486+
var mappedTools = await client.GetAIFunctionsAsync(TestContext.Current.CancellationToken);
482487

483488
// Create the chat client.
484489
using IChatClient chatClient = new OpenAIClient(s_openAIKey).AsChatClient("gpt-4o-mini")
@@ -495,7 +500,7 @@ public async Task GetAIFunctionsAsync_UsingEverythingServer_ToolsAreProperlyCall
495500
messages.Add(new(ChatRole.User, "Please call the echo tool with the string 'Hello MCP!' and output the response ad verbatim."));
496501

497502
// Call the chat client
498-
var response = await chatClient.GetResponseAsync(messages, new() { Tools = [.. mappedTools], Temperature = 0 });
503+
var response = await chatClient.GetResponseAsync(messages, new() { Tools = [.. mappedTools], Temperature = 0 }, TestContext.Current.CancellationToken);
499504

500505
// Assert
501506
Assert.Contains("Echo: Hello MCP!", response.Text);
@@ -504,10 +509,7 @@ public async Task GetAIFunctionsAsync_UsingEverythingServer_ToolsAreProperlyCall
504509
[Fact]
505510
public async Task SamplingViaChatClient_RequestResponseProperlyPropagated()
506511
{
507-
if (s_openAIKey is null)
508-
{
509-
return; // Skip the test if the OpenAI key is not provided
510-
}
512+
SkipTestIfNoOpenAIKey();
511513

512514
await using var client = await McpClientFactory.CreateAsync(_fixture.EverythingServerConfig, new()
513515
{
@@ -519,17 +521,22 @@ public async Task SamplingViaChatClient_RequestResponseProperlyPropagated()
519521
SamplingHandler = new OpenAIClient(s_openAIKey).AsChatClient("gpt-4o-mini").CreateSamplingHandler(),
520522
},
521523
},
522-
});
524+
}, cancellationToken: TestContext.Current.CancellationToken);
523525

524526
var result = await client.CallToolAsync("sampleLLM", new()
525527
{
526528
["prompt"] = "In just a few words, what is the most famous tower in Paris?",
527-
});
529+
}, TestContext.Current.CancellationToken);
528530

529531
Assert.NotNull(result);
530532
Assert.NotEmpty(result.Content);
531533
Assert.Equal("text", result.Content[0].Type);
532534
Assert.Contains("LLM sampling result:", result.Content[0].Text);
533535
Assert.Contains("Eiffel", result.Content[0].Text);
534536
}
537+
538+
private static void SkipTestIfNoOpenAIKey()
539+
{
540+
Assert.SkipWhen(s_openAIKey is null, "No OpenAI key provided. Skipping test.");
541+
}
535542
}

‎tests/ModelContextProtocol.Tests/ModelContextProtocol.Tests.csproj

+1-1
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818
<PackageReference Include="Microsoft.NET.Test.Sdk" />
1919
<PackageReference Include="Moq" />
2020
<PackageReference Include="System.Linq.AsyncEnumerable" />
21-
<PackageReference Include="xunit" />
21+
<PackageReference Include="xunit.v3" />
2222
<PackageReference Include="xunit.runner.visualstudio">
2323
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
2424
<PrivateAssets>all</PrivateAssets>

‎tests/ModelContextProtocol.Tests/Server/McpServerTests.cs

+10-12
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
using Microsoft.Extensions.AI;
88
using Microsoft.Extensions.Logging;
99
using Moq;
10-
using System.Diagnostics;
1110

1211
namespace ModelContextProtocol.Tests.Server;
1312

@@ -100,7 +99,7 @@ public async Task StartAsync_Should_Throw_InvalidOperationException_If_Already_I
10099
server.GetType().GetField("_isInitializing", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance)?.SetValue(server, true);
101100

102101
// Act & Assert
103-
await Assert.ThrowsAsync<InvalidOperationException>(() => server.StartAsync());
102+
await Assert.ThrowsAsync<InvalidOperationException>(() => server.StartAsync(TestContext.Current.CancellationToken));
104103
}
105104

106105
[Fact]
@@ -110,7 +109,7 @@ public async Task StartAsync_Should_Do_Nothing_If_Already_Initialized()
110109
await using var server = new McpServer(_serverTransport.Object, _options, _loggerFactory.Object, _serviceProvider);
111110
server.IsInitialized = true;
112111

113-
await server.StartAsync();
112+
await server.StartAsync(TestContext.Current.CancellationToken);
114113

115114
// Assert
116115
_serverTransport.Verify(t => t.StartListeningAsync(It.IsAny<CancellationToken>()), Times.Never);
@@ -123,7 +122,7 @@ public async Task StartAsync_ShouldStartListening()
123122
await using var server = new McpServer(_serverTransport.Object, _options, _loggerFactory.Object, _serviceProvider);
124123

125124
// Act
126-
await server.StartAsync();
125+
await server.StartAsync(TestContext.Current.CancellationToken);
127126

128127
// Assert
129128
_serverTransport.Verify(t => t.StartListeningAsync(It.IsAny<CancellationToken>()), Times.Once);
@@ -135,17 +134,16 @@ public async Task StartAsync_Sets_Initialized_After_Transport_Responses_Initiali
135134
await using var transport = new TestServerTransport();
136135
await using var server = new McpServer(transport, _options, _loggerFactory.Object, _serviceProvider);
137136

138-
await server.StartAsync();
137+
await server.StartAsync(TestContext.Current.CancellationToken);
139138

140139
// Send initialized notification
141-
await transport.SendMessageAsync(
142-
new JsonRpcNotification
140+
await transport.SendMessageAsync(new JsonRpcNotification
143141
{
144142
Method = "notifications/initialized"
145143
}
146-
);
144+
, TestContext.Current.CancellationToken);
147145

148-
await Task.Delay(50);
146+
await Task.Delay(50, TestContext.Current.CancellationToken);
149147

150148
Assert.True(server.IsInitialized);
151149
}
@@ -171,7 +169,7 @@ public async Task RequestSamplingAsync_Should_SendRequest()
171169
await using var server = new McpServer(transport, _options, _loggerFactory.Object, _serviceProvider);
172170
server.ClientCapabilities = new ClientCapabilities { Sampling = new SamplingCapability() };
173171

174-
await server.StartAsync();
172+
await server.StartAsync(TestContext.Current.CancellationToken);
175173

176174
// Act
177175
var result = await server.RequestSamplingAsync(new CreateMessageRequestParams { Messages = [] }, CancellationToken.None);
@@ -200,7 +198,7 @@ public async Task RequestRootsAsync_Should_SendRequest()
200198
await using var transport = new TestServerTransport();
201199
await using var server = new McpServer(transport, _options, _loggerFactory.Object, _serviceProvider);
202200
server.ClientCapabilities = new ClientCapabilities { Roots = new RootsCapability() };
203-
await server.StartAsync();
201+
await server.StartAsync(TestContext.Current.CancellationToken);
204202

205203
// Act
206204
var result = await server.RequestRootsAsync(new ListRootsRequestParams(), CancellationToken.None);
@@ -588,7 +586,7 @@ public async Task AsSamplingChatClient_HandlesRequestResponse()
588586
Temperature = 0.75f,
589587
MaxOutputTokens = 42,
590588
StopSequences = ["."],
591-
});
589+
}, TestContext.Current.CancellationToken);
592590

593591
Assert.Equal("amazingmodel", response.ModelId);
594592
Assert.Equal(ChatFinishReason.Stop, response.FinishReason);

‎tests/ModelContextProtocol.Tests/SseIntegrationTests.cs

+39-23
Original file line numberDiff line numberDiff line change
@@ -37,13 +37,17 @@ public async Task ConnectAndReceiveMessage_InMemoryServer()
3737
};
3838

3939
// Act
40-
await using var client = await McpClientFactory.CreateAsync(defaultConfig, defaultOptions, loggerFactory: loggerFactory);
40+
await using var client = await McpClientFactory.CreateAsync(
41+
defaultConfig,
42+
defaultOptions,
43+
loggerFactory: loggerFactory,
44+
cancellationToken: TestContext.Current.CancellationToken);
4145

4246
// Wait for SSE connection to be established
4347
await server.WaitForConnectionAsync(TimeSpan.FromSeconds(10));
4448

4549
// Send a test message through POST endpoint
46-
await client.SendNotificationAsync("test/message", new { message = "Hello, SSE!" });
50+
await client.SendNotificationAsync("test/message", new { message = "Hello, SSE!" }, TestContext.Current.CancellationToken);
4751

4852
// Assert
4953
Assert.True(true);
@@ -53,10 +57,7 @@ public async Task ConnectAndReceiveMessage_InMemoryServer()
5357
[Trait("Execution", "Manual")]
5458
public async Task ConnectAndReceiveMessage_EverythingServerWithSse()
5559
{
56-
if (!EverythingSseServerFixture.IsDockerAvailable)
57-
{
58-
return;
59-
}
60+
Assert.SkipWhen(!EverythingSseServerFixture.IsDockerAvailable, "docker is not available");
6061

6162
using var loggerFactory = LoggerFactory.Create(builder =>
6263
builder.AddConsole()
@@ -82,8 +83,12 @@ public async Task ConnectAndReceiveMessage_EverythingServerWithSse()
8283
};
8384

8485
// Create client and run tests
85-
await using var client = await McpClientFactory.CreateAsync(defaultConfig, defaultOptions, loggerFactory: loggerFactory);
86-
var tools = await client.ListToolsAsync().ToListAsync();
86+
await using var client = await McpClientFactory.CreateAsync(
87+
defaultConfig,
88+
defaultOptions,
89+
loggerFactory: loggerFactory,
90+
cancellationToken: TestContext.Current.CancellationToken);
91+
var tools = await client.ListToolsAsync(TestContext.Current.CancellationToken).ToListAsync(TestContext.Current.CancellationToken);
8792

8893
// assert
8994
Assert.NotEmpty(tools);
@@ -93,10 +98,7 @@ public async Task ConnectAndReceiveMessage_EverythingServerWithSse()
9398
[Trait("Execution", "Manual")]
9499
public async Task Sampling_Sse_EverythingServer()
95100
{
96-
if (!EverythingSseServerFixture.IsDockerAvailable)
97-
{
98-
return;
99-
}
101+
Assert.SkipWhen(!EverythingSseServerFixture.IsDockerAvailable, "docker is not available");
100102

101103
// arrange
102104
using var loggerFactory = Microsoft.Extensions.Logging.LoggerFactory.Create(builder =>
@@ -147,17 +149,19 @@ public async Task Sampling_Sse_EverythingServer()
147149
},
148150
};
149151

150-
await using var client = await McpClientFactory.CreateAsync(defaultConfig, defaultOptions, loggerFactory: loggerFactory);
152+
await using var client = await McpClientFactory.CreateAsync(
153+
defaultConfig,
154+
defaultOptions,
155+
loggerFactory: loggerFactory,
156+
cancellationToken: TestContext.Current.CancellationToken);
151157

152158
// Call the server's sampleLLM tool which should trigger our sampling handler
153-
var result = await client.CallToolAsync(
154-
"sampleLLM",
155-
new Dictionary<string, object>
159+
var result = await client.CallToolAsync("sampleLLM", new Dictionary<string, object>
156160
{
157161
["prompt"] = "Test prompt",
158162
["maxTokens"] = 100
159163
}
160-
);
164+
, TestContext.Current.CancellationToken);
161165

162166
// assert
163167
Assert.NotNull(result);
@@ -194,13 +198,17 @@ public async Task ConnectAndReceiveMessage_InMemoryServer_WithFullEndpointEventU
194198
};
195199

196200
// Act
197-
await using var client = await McpClientFactory.CreateAsync(defaultConfig, defaultOptions, loggerFactory: loggerFactory);
201+
await using var client = await McpClientFactory.CreateAsync(
202+
defaultConfig,
203+
defaultOptions,
204+
loggerFactory: loggerFactory,
205+
cancellationToken: TestContext.Current.CancellationToken);
198206

199207
// Wait for SSE connection to be established
200208
await server.WaitForConnectionAsync(TimeSpan.FromSeconds(10));
201209

202210
// Send a test message through POST endpoint
203-
await client.SendNotificationAsync("test/message", new { message = "Hello, SSE!" });
211+
await client.SendNotificationAsync("test/message", new { message = "Hello, SSE!" }, TestContext.Current.CancellationToken);
204212

205213
// Assert
206214
Assert.True(true);
@@ -233,7 +241,11 @@ public async Task ConnectAndReceiveNotification_InMemoryServer()
233241
};
234242

235243
// Act
236-
await using var client = await McpClientFactory.CreateAsync(defaultConfig, defaultOptions, loggerFactory: loggerFactory);
244+
await using var client = await McpClientFactory.CreateAsync(
245+
defaultConfig,
246+
defaultOptions,
247+
loggerFactory: loggerFactory,
248+
cancellationToken: TestContext.Current.CancellationToken);
237249

238250
// Wait for SSE connection to be established
239251
await server.WaitForConnectionAsync(TimeSpan.FromSeconds(10));
@@ -251,7 +263,7 @@ public async Task ConnectAndReceiveNotification_InMemoryServer()
251263
await server.SendTestNotificationAsync("Hello from server!");
252264

253265
// Assert
254-
var message = await receivedNotification.Task.WaitAsync(TimeSpan.FromSeconds(10));
266+
var message = await receivedNotification.Task.WaitAsync(TimeSpan.FromSeconds(10), TestContext.Current.CancellationToken);
255267
Assert.Equal("Hello from server!", message);
256268
}
257269

@@ -282,14 +294,18 @@ public async Task ConnectTwice_Throws()
282294
};
283295

284296
// Act
285-
await using var client = await McpClientFactory.CreateAsync(defaultConfig, defaultOptions, loggerFactory: loggerFactory);
297+
await using var client = await McpClientFactory.CreateAsync(
298+
defaultConfig,
299+
defaultOptions,
300+
loggerFactory: loggerFactory,
301+
cancellationToken: TestContext.Current.CancellationToken);
286302
var mcpClient = (McpClient)client;
287303
var transport = (SseClientTransport)mcpClient.Transport;
288304

289305
// Wait for SSE connection to be established
290306
await server.WaitForConnectionAsync(TimeSpan.FromSeconds(10));
291307

292308
// Assert
293-
await Assert.ThrowsAsync<McpTransportException>(async () => await transport.ConnectAsync());
309+
await Assert.ThrowsAsync<McpTransportException>(async () => await transport.ConnectAsync(TestContext.Current.CancellationToken));
294310
}
295311
}

‎tests/ModelContextProtocol.Tests/SseServerIntegrationTests.cs

+5-7
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,7 @@ public async Task ListTools_Sse_TestServer()
5353

5454
// act
5555
var client = await GetClientAsync();
56-
var tools = await client.ListToolsAsync().ToListAsync();
56+
var tools = await client.ListToolsAsync(TestContext.Current.CancellationToken).ToListAsync(TestContext.Current.CancellationToken);
5757

5858
// assert
5959
Assert.NotNull(tools);
@@ -145,7 +145,7 @@ public async Task ListPrompts_Sse_TestServer()
145145

146146
// act
147147
var client = await GetClientAsync();
148-
var prompts = await client.ListPromptsAsync().ToListAsync();
148+
var prompts = await client.ListPromptsAsync(TestContext.Current.CancellationToken).ToListAsync(TestContext.Current.CancellationToken);
149149

150150
// assert
151151
Assert.NotNull(prompts);
@@ -233,14 +233,12 @@ public async Task Sampling_Sse_TestServer()
233233
#pragma warning restore CS1998 // Async method lacks 'await' operators and will run synchronously
234234

235235
// Call the server's sampleLLM tool which should trigger our sampling handler
236-
var result = await client.CallToolAsync(
237-
"sampleLLM",
238-
new Dictionary<string, object>
236+
var result = await client.CallToolAsync("sampleLLM", new Dictionary<string, object>
239237
{
240238
["prompt"] = "Test prompt",
241239
["maxTokens"] = 100
242-
}
243-
);
240+
},
241+
TestContext.Current.CancellationToken);
244242

245243
// assert
246244
Assert.NotNull(result);

‎tests/ModelContextProtocol.Tests/Transport/SseClientTransportTests.cs

+4-4
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ public async Task ConnectAsync_Should_Connect_Successfully()
9595
};
9696
};
9797

98-
await transport.ConnectAsync();
98+
await transport.ConnectAsync(TestContext.Current.CancellationToken);
9999
}
100100

101101
[Fact]
@@ -174,7 +174,7 @@ public async Task SendMessageAsync_Handles_Accepted_Response()
174174
}
175175
};
176176

177-
await transport.ConnectAsync();
177+
await transport.ConnectAsync(TestContext.Current.CancellationToken);
178178

179179
await transport.SendMessageAsync(new JsonRpcRequest() { Method = "initialize", Id = RequestId.FromNumber(44) }, CancellationToken.None);
180180
Assert.True(true);
@@ -213,7 +213,7 @@ public async Task SendMessageAsync_Handles_Accepted_Json_RPC_Response()
213213
}
214214
};
215215

216-
await transport.ConnectAsync();
216+
await transport.ConnectAsync(TestContext.Current.CancellationToken);
217217

218218
await transport.SendMessageAsync(new JsonRpcRequest() { Method = "initialize", Id = RequestId.FromNumber(44) }, CancellationToken.None);
219219
Assert.True(true);
@@ -251,7 +251,7 @@ public async Task ReceiveMessagesAsync_Handles_Messages()
251251
throw new IOException("Abort");
252252
};
253253

254-
await transport.ConnectAsync();
254+
await transport.ConnectAsync(TestContext.Current.CancellationToken);
255255
Assert.True(transport.MessageReader.TryRead(out var message));
256256
Assert.NotNull(message);
257257
Assert.IsType<JsonRpcRequest>(message);

‎tests/ModelContextProtocol.Tests/Transport/StdioServerTransportTests.cs

+7-7
Original file line numberDiff line numberDiff line change
@@ -52,7 +52,7 @@ public async Task StartListeningAsync_Should_Set_Connected_State()
5252
{
5353
await using var transport = new StdioServerTransport(_serverOptions);
5454

55-
await transport.StartListeningAsync();
55+
await transport.StartListeningAsync(TestContext.Current.CancellationToken);
5656

5757
Assert.True(transport.IsConnected);
5858
}
@@ -70,12 +70,12 @@ public async Task SendMessageAsync_Should_Send_Message()
7070
Console.SetOut(output);
7171

7272
await using var transport = new StdioServerTransport(_serverOptions, NullLoggerFactory.Instance);
73-
await transport.StartListeningAsync();
73+
await transport.StartListeningAsync(TestContext.Current.CancellationToken);
7474

7575
var message = new JsonRpcRequest { Method = "test", Id = RequestId.FromNumber(44) };
7676

7777

78-
await transport.SendMessageAsync(message);
78+
await transport.SendMessageAsync(message, TestContext.Current.CancellationToken);
7979

8080
var result = output.ToString()?.Trim();
8181
var expected = JsonSerializer.Serialize(message, McpJsonUtilities.DefaultOptions);
@@ -96,7 +96,7 @@ public async Task SendMessageAsync_Throws_Exception_If_Not_Connected()
9696

9797
var message = new JsonRpcRequest { Method = "test" };
9898

99-
await Assert.ThrowsAsync<McpTransportException>(() => transport.SendMessageAsync(message));
99+
await Assert.ThrowsAsync<McpTransportException>(() => transport.SendMessageAsync(message, TestContext.Current.CancellationToken));
100100
}
101101

102102
[Fact]
@@ -123,9 +123,9 @@ public async Task ReadMessagesAsync_Should_Read_Messages()
123123
Console.SetOut(new StringWriter());
124124

125125
await using var transport = new StdioServerTransport(_serverOptions);
126-
await transport.StartListeningAsync();
126+
await transport.StartListeningAsync(TestContext.Current.CancellationToken);
127127

128-
var canRead = await transport.MessageReader.WaitToReadAsync();
128+
var canRead = await transport.MessageReader.WaitToReadAsync(TestContext.Current.CancellationToken);
129129

130130
Assert.True(canRead, "Nothing to read here from transport message reader");
131131
Assert.True(transport.MessageReader.TryPeek(out var readMessage));
@@ -144,7 +144,7 @@ public async Task ReadMessagesAsync_Should_Read_Messages()
144144
public async Task CleanupAsync_Should_Cleanup_Resources()
145145
{
146146
var transport = new StdioServerTransport(_serverOptions);
147-
await transport.StartListeningAsync();
147+
await transport.StartListeningAsync(TestContext.Current.CancellationToken);
148148

149149
await transport.DisposeAsync();
150150

0 commit comments

Comments
 (0)
Please sign in to comment.