diff --git a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs index 45145aadc5..2b0fd8b039 100644 --- a/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs +++ b/src/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv/Internal/ListenerPrimary.cs @@ -33,6 +33,11 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Internal { } + /// + /// For testing purposes. + /// + public int UvPipeCount => _dispatchPipes.Count; + private UvPipeHandle ListenPipe { get; set; } public async Task StartAsync( diff --git a/test/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests/ListenerPrimaryTests.cs b/test/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests/ListenerPrimaryTests.cs index 0c9d5b52be..0edcfd37f5 100644 --- a/test/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests/ListenerPrimaryTests.cs +++ b/test/Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests/ListenerPrimaryTests.cs @@ -53,12 +53,24 @@ namespace Microsoft.AspNetCore.Server.Kestrel.Transport.Libuv.Tests Assert.Equal("Primary", await HttpClientSlim.GetStringAsync(address)); Assert.Equal("Primary", await HttpClientSlim.GetStringAsync(address)); + var listenerCount = listenerPrimary.UvPipeCount; // Add secondary listener var libuvThreadSecondary = new LibuvThread(libuvTransport); await libuvThreadSecondary.StartAsync(); var listenerSecondary = new ListenerSecondary(transportContextSecondary); await listenerSecondary.StartAsync(pipeName, pipeMessage, listenOptions, libuvThreadSecondary); + var maxWait = Task.Delay(TimeSpan.FromSeconds(30)); + // wait for ListenerPrimary.ReadCallback to add the secondary pipe + while (listenerPrimary.UvPipeCount == listenerCount) + { + var completed = await Task.WhenAny(maxWait, Task.Delay(100)); + if (ReferenceEquals(completed, maxWait)) + { + throw new TimeoutException("Timed out waiting for secondary listener to become available"); + } + } + // Once a secondary listener is added, TCP connections start getting dispatched to it await AssertResponseEventually(address, "Secondary", allowed: new[] { "Primary" });