Fix tests in Dev Container (#965)

This commit is contained in:
Stephen Halter 2025-11-17 08:48:18 -08:00 • committed by GitHub
commit b9c9f44e06
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 18 additions and 18 deletions

View file

@ -1,7 +1,7 @@
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Connections;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.Extensions.DependencyInjection.Extensions;
using ModelContextProtocol.Tests.Utils;
namespace ModelContextProtocol.AspNetCore.Tests.Utils;
@ -11,11 +11,11 @@ public class KestrelInMemoryTest : LoggedTest
public KestrelInMemoryTest(ITestOutputHelper testOutputHelper)
: base(testOutputHelper)
{
// Use SlimBuilder instead of EmptyBuilder to avoid having to call UseRouting() and UseEndpoints(_ => { })
// or a helper that does the same every test. But clear out the existing socket transport to avoid potential port conflicts.
Builder = WebApplication.CreateSlimBuilder();
Builder.Services.RemoveAll<IConnectionListenerFactory>();
Builder = WebApplication.CreateEmptyBuilder(new());
Builder.Services.AddSingleton<IConnectionListenerFactory>(KestrelInMemoryTransport);
Builder.WebHost.UseKestrelCore();
Builder.Services.AddRoutingCore();
Builder.Services.AddLogging();
Builder.Services.AddSingleton(XunitLoggerProvider);
SocketsHttpHandler.ConnectCallback = (context, token) =>

View file

@ -7,13 +7,18 @@ namespace ModelContextProtocol.AspNetCore.Tests.Utils;
public sealed class KestrelInMemoryTransport : IConnectionListenerFactory
{
// socket accept queues keyed by listen port.
// Socket accept queues keyed by listen port.
private readonly ConcurrentDictionary<int, Channel<ConnectionContext>> _acceptQueues = [];
public KestrelInMemoryConnection CreateConnection(EndPoint endpoint)
{
if (!_acceptQueues.TryGetValue(GetEndpointPort(endpoint), out var acceptQueue))
{
throw new IOException($"No listener is bound to endpoint '{endpoint}'.");
}
var connection = new KestrelInMemoryConnection();
if (!GetAcceptQueue(endpoint).Writer.TryWrite(connection))
if (!acceptQueue.Writer.TryWrite(connection))
{
throw new IOException("The KestrelInMemoryTransport has been shut down.");
};
@ -21,11 +26,11 @@ public sealed class KestrelInMemoryTransport : IConnectionListenerFactory
return connection;
}
public ValueTask<IConnectionListener> BindAsync(EndPoint endpoint, CancellationToken cancellationToken = default) =>
new(new KestrelInMemoryListener(endpoint, GetAcceptQueue(endpoint)));
private Channel<ConnectionContext> GetAcceptQueue(EndPoint endpoint) =>
_acceptQueues.GetOrAdd(GetEndpointPort(endpoint), _ => Channel.CreateUnbounded<ConnectionContext>());
public ValueTask<IConnectionListener> BindAsync(EndPoint endpoint, CancellationToken cancellationToken = default)
{
var acceptQueue = _acceptQueues.GetOrAdd(GetEndpointPort(endpoint), _ => Channel.CreateUnbounded<ConnectionContext>());
return new(new KestrelInMemoryListener(endpoint, acceptQueue));
}
private static int GetEndpointPort(EndPoint endpoint) =>
endpoint switch