From ba2536b6d3826ae465bb40aa897a223adfa138e8 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 12 Apr 2024 13:06:22 +0200 Subject: [PATCH 01/46] Add logging to HTTP/3 test --- .../Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 0fe06a4670ef99..b99c5b49337969 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -73,6 +73,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { + TestUtilities.TestEventListener? listener = null; + + if (UseVersion == HttpVersion.Version30) + { + listener = new TestUtilities.TestEventListener(_output, TestUtilities.TestEventListener.NetworkingEvents); + } + using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; From 272121a592fc599df92759c0c138808a554fc5f1 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 12 Apr 2024 22:04:59 +0200 Subject: [PATCH 02/46] Dispose EventListener and fix version --- .../Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index b99c5b49337969..4c971bc7bd5fbf 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -75,7 +75,7 @@ public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength { TestUtilities.TestEventListener? listener = null; - if (UseVersion == HttpVersion.Version30) + if (UseVersion == HttpVersion30) { listener = new TestUtilities.TestEventListener(_output, TestUtilities.TestEventListener.NetworkingEvents); } @@ -105,6 +105,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} #endif }); + + listener?.Dispose(); } [Theory] From 4396379a87f655da16d51fbde61227968a420c57 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Mon, 15 Apr 2024 11:10:12 +0200 Subject: [PATCH 03/46] Add logging to SetAfterUse test --- .../HttpClientHandlerTest.MaxResponseHeadersLength.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 4c971bc7bd5fbf..c8aea1f5b1e3d6 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -56,6 +56,13 @@ public void ValidValue_SetGet_Roundtrips(int validValue) [Fact] public async Task SetAfterUse_Throws() { + TestUtilities.TestEventListener? listener = null; + + if (UseVersion == HttpVersion30) + { + listener = new TestUtilities.TestEventListener(_output, TestUtilities.TestEventListener.NetworkingEvents); + } + await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using HttpClientHandler handler = CreateHttpClientHandler(); @@ -105,8 +112,6 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} #endif }); - - listener?.Dispose(); } [Theory] From ca2f4fa160c74825b5a86023cf02b20100191d1d Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Mon, 15 Apr 2024 18:39:46 +0200 Subject: [PATCH 04/46] Call Dispose for listeners --- .../Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index c8aea1f5b1e3d6..bff41f17464d04 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -73,6 +73,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Throws(() => handler.MaxResponseHeadersLength = 1); }, server => server.AcceptConnectionSendResponseAndCloseAsync()); + + listener?.Dispose(); } [Theory] @@ -112,6 +114,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} #endif }); + + listener?.Dispose(); } [Theory] From 34160a14e6bf4f02f53704289c542f3761bc0db6 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 16 Apr 2024 08:11:51 +0200 Subject: [PATCH 05/46] Remove unnecessary logs for investigation --- .../Common/tests/TestUtilities/TestEventListener.cs | 13 ------------- 1 file changed, 13 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs index bd7b633ba6f822..1dac77a7316b95 100644 --- a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs +++ b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs @@ -22,21 +22,8 @@ public sealed class TestEventListener : EventListener public static string[] NetworkingEvents => new[] { "System.Net.Http", - "System.Net.NameResolution", - "System.Net.Sockets", - "System.Net.Security", - "System.Net.TestLogging", "Private.InternalDiagnostics.System.Net.Http", - "Private.InternalDiagnostics.System.Net.NameResolution", - "Private.InternalDiagnostics.System.Net.Sockets", - "Private.InternalDiagnostics.System.Net.Security", "Private.InternalDiagnostics.System.Net.Quic", - "Private.InternalDiagnostics.System.Net.Http.WinHttpHandler", - "Private.InternalDiagnostics.System.Net.HttpListener", - "Private.InternalDiagnostics.System.Net.Mail", - "Private.InternalDiagnostics.System.Net.NetworkInformation", - "Private.InternalDiagnostics.System.Net.Primitives", - "Private.InternalDiagnostics.System.Net.Requests", }; private readonly Action _writeFunc; From 3697c87a6dd35d88b363a8c6ab2e8045cda35bc5 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 16 Apr 2024 08:48:53 +0200 Subject: [PATCH 06/46] Add more log to understand which connection is ours --- .../HttpClientHandlerTest.MaxResponseHeadersLength.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index bff41f17464d04..33a7caab940dd5 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -95,6 +95,10 @@ public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using HttpClient client = CreateHttpClient(handler); + if (UseVersion == HttpVersion30) + { + _output.WriteLine("H/3 LargeSingleHeader_Throws HttpClient created."); + } Exception e = await Assert.ThrowsAsync(() => client.GetAsync(uri)); if (!IsWinHttpHandler) @@ -104,6 +108,10 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }, async server => { + if (UseVersion == HttpVersion30) + { + _output.WriteLine($"H/3 LargeSingleHeader_Throws: Listening on: {server.Address}"); + } try { await server.HandleRequestAsync(headers: new[] { new HttpHeaderData("Foo", new string('a', handler.MaxResponseHeadersLength * 1024)) }); From 134fd3d48a95c7dd3282ad096c840a9f86a158c6 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 16 Apr 2024 19:50:16 +0200 Subject: [PATCH 07/46] Add output to loopback connection --- .../Net/Http/Http3LoopbackConnection.cs | 1 + ...entHandlerTest.MaxResponseHeadersLength.cs | 26 ------------------- 2 files changed, 1 insertion(+), 26 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index 9d6fef5fb3a720..0dbe083fd0a5fb 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -127,6 +127,7 @@ async Task EnsureControlStreamAcceptedInternalAsync() while (true) { + Console.WriteLine("Ensuring Control Stream Accepted"); QuicStream quicStream = await _connection.AcceptInboundStreamAsync().ConfigureAwait(false); if (!quicStream.CanWrite) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 33a7caab940dd5..0fe06a4670ef99 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -56,13 +56,6 @@ public void ValidValue_SetGet_Roundtrips(int validValue) [Fact] public async Task SetAfterUse_Throws() { - TestUtilities.TestEventListener? listener = null; - - if (UseVersion == HttpVersion30) - { - listener = new TestUtilities.TestEventListener(_output, TestUtilities.TestEventListener.NetworkingEvents); - } - await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using HttpClientHandler handler = CreateHttpClientHandler(); @@ -73,8 +66,6 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Throws(() => handler.MaxResponseHeadersLength = 1); }, server => server.AcceptConnectionSendResponseAndCloseAsync()); - - listener?.Dispose(); } [Theory] @@ -82,23 +73,12 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { - TestUtilities.TestEventListener? listener = null; - - if (UseVersion == HttpVersion30) - { - listener = new TestUtilities.TestEventListener(_output, TestUtilities.TestEventListener.NetworkingEvents); - } - using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using HttpClient client = CreateHttpClient(handler); - if (UseVersion == HttpVersion30) - { - _output.WriteLine("H/3 LargeSingleHeader_Throws HttpClient created."); - } Exception e = await Assert.ThrowsAsync(() => client.GetAsync(uri)); if (!IsWinHttpHandler) @@ -108,10 +88,6 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }, async server => { - if (UseVersion == HttpVersion30) - { - _output.WriteLine($"H/3 LargeSingleHeader_Throws: Listening on: {server.Address}"); - } try { await server.HandleRequestAsync(headers: new[] { new HttpHeaderData("Foo", new string('a', handler.MaxResponseHeadersLength * 1024)) }); @@ -122,8 +98,6 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} #endif }); - - listener?.Dispose(); } [Theory] From 393d283cffb1b606c1f36c3a0e22a733d5128271 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 16 Apr 2024 21:35:07 +0200 Subject: [PATCH 08/46] Remove ActiveIssues --- .../tests/FunctionalTests/SocketsHttpHandlerTest.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index c0eda6ab1a57ed..96a45d49fe5b5f 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -1634,8 +1634,6 @@ public SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http2(ITest } [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] - [ActiveIssue("https://github.com/dotnet/runtime/issues/91757")] - [ActiveIssue("https://github.com/dotnet/runtime/issues/101015")] public sealed class SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http3 : SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength { public SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http3(ITestOutputHelper output) : base(output) { } From f1b6cc7e672ecd2a435328aa0e1ed58b7631fb68 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 17 Apr 2024 06:56:29 +0200 Subject: [PATCH 09/46] Add more logging and WaitAsync --- .../tests/System/Net/Http/Http3LoopbackConnection.cs | 2 +- ...HttpClientHandlerTest.MaxResponseHeadersLength.cs | 5 ++++- .../src/System/Net/Quic/QuicConnection.cs | 12 +++++++++++- 3 files changed, 16 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index 0dbe083fd0a5fb..fcae20ca12ce34 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -124,7 +124,7 @@ private Task EnsureControlStreamAcceptedAsync() async Task EnsureControlStreamAcceptedInternalAsync() { Http3LoopbackStream controlStream; - + Console.WriteLine("New call to EnsureControlStreamAcceptedInternalAsync"); while (true) { Console.WriteLine("Ensuring Control Stream Accepted"); diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 0fe06a4670ef99..70e23947e5b652 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -14,6 +14,7 @@ using Microsoft.DotNet.XUnitExtensions; using Xunit; using Xunit.Abstractions; +using TestUtilities; namespace System.Net.Http.Functional.Tests { @@ -73,6 +74,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { + Console.WriteLine("Test start"); + using TestEventListener listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; @@ -97,7 +100,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => #if !WINHTTPHANDLER_TEST catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} #endif - }); + }).WaitAsync(TimeSpan.FromSeconds(7)); } [Theory] diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 315352d2797bb4..2b6f3ec001c52b 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -446,10 +446,20 @@ public async ValueTask AcceptInboundStreamAsync(CancellationToken ca throw new InvalidOperationException(SR.net_quic_accept_not_allowed); } + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Waiting for incoming stream"); + } + GCHandle keepObject = GCHandle.Alloc(this); try { - return await _acceptQueue.Reader.ReadAsync(cancellationToken).ConfigureAwait(false); + QuicStream stream = await _acceptQueue.Reader.ReadAsync(cancellationToken).ConfigureAwait(false); + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Accepted incoming stream {stream}"); + } + return stream; } catch (ChannelClosedException ex) when (ex.InnerException is not null) { From ad9cf2b9f437794973168f8c5c20fa3d77e2c14e Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 17 Apr 2024 08:39:39 +0200 Subject: [PATCH 10/46] Delete http from logging as well --- src/libraries/Common/tests/TestUtilities/TestEventListener.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs index 1dac77a7316b95..3dcc635663deda 100644 --- a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs +++ b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs @@ -21,8 +21,6 @@ public sealed class TestEventListener : EventListener { public static string[] NetworkingEvents => new[] { - "System.Net.Http", - "Private.InternalDiagnostics.System.Net.Http", "Private.InternalDiagnostics.System.Net.Quic", }; From 03e38e36027565d66f3cf586e60a6f0c6299d04e Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 17 Apr 2024 10:09:36 +0200 Subject: [PATCH 11/46] Delete WaitAsync --- .../Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 70e23947e5b652..f0265c5840b91f 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -100,7 +100,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => #if !WINHTTPHANDLER_TEST catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} #endif - }).WaitAsync(TimeSpan.FromSeconds(7)); + }); } [Theory] From efbc1e94505605a3dca72cbdeb297ae70ecac8ae Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Thu, 18 Apr 2024 13:12:16 +0200 Subject: [PATCH 12/46] Add more logging around stream accepting --- .../src/System/Net/Quic/QuicConnection.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 2b6f3ec001c52b..7e7b359b8286d7 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -452,6 +452,10 @@ public async ValueTask AcceptInboundStreamAsync(CancellationToken ca } GCHandle keepObject = GCHandle.Alloc(this); + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} GC Handle allocated, will read from acceptQueue"); + } try { QuicStream stream = await _acceptQueue.Reader.ReadAsync(cancellationToken).ConfigureAwait(false); @@ -561,6 +565,10 @@ private unsafe int HandleEventPeerAddressChanged(ref PEER_ADDRESS_CHANGED_DATA d private unsafe int HandleEventPeerStreamStarted(ref PEER_STREAM_STARTED_DATA data) { QuicStream stream = new QuicStream(_handle, data.Stream, data.Flags, _defaultStreamErrorCode); + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Stream object has been created {stream}"); + } if (!_acceptQueue.Writer.TryWrite(stream)) { if (NetEventSource.Log.IsEnabled()) @@ -571,6 +579,10 @@ private unsafe int HandleEventPeerStreamStarted(ref PEER_STREAM_STARTED_DATA dat stream.Dispose(); return QUIC_STATUS_SUCCESS; } + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{this} Stream has been enqueued to the _acceptQueue {stream}"); + } data.Flags |= QUIC_STREAM_OPEN_FLAGS.DELAY_ID_FC_UPDATES; return QUIC_STATUS_SUCCESS; From dddf05edc432fdea915673b9474d62b83264b112 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 19 Apr 2024 18:38:15 +0200 Subject: [PATCH 13/46] Revert "Run MsQuic tests in parallel again. (#100947)" This reverts commit c30ea3439c8894e51be32f713e46968870c9c49c. --- .../FunctionalTests/SocketsHttpHandlerTest.cs | 11 ++++++++-- .../tests/StressTests/HttpStress/Program.cs | 22 +++++++++++++++++-- .../src/System/Net/Quic/Internal/MsQuicApi.cs | 2 +- .../tests/FunctionalTests/MsQuicTests.cs | 4 +++- .../FunctionalTests/QuicTestCollection.cs | 2 +- 5 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 96a45d49fe5b5f..d2e1b54dcafa84 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -4024,6 +4024,7 @@ public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http2(ITestOutputH protected override Version UseVersion => HttpVersion.Version20; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Http3 : HttpClientHandlerTest { @@ -4031,6 +4032,7 @@ public SocketsHttpHandlerTest_HttpClientHandlerTest_Http3(ITestOutputHelper outp protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_Cookies_Http3 : HttpClientHandlerTest_Cookies { @@ -4038,6 +4040,7 @@ public SocketsHttpHandlerTest_Cookies_Http3(ITestOutputHelper output) : base(out protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3 : HttpClientHandlerTest_Headers { @@ -4045,6 +4048,7 @@ public SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3(ITestOutputHel protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3 : SocketsHttpHandler_Cancellation_Test { @@ -4052,6 +4056,7 @@ public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3(ITestOutputH protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3 : HttpClientHandler_AltSvc_Test { @@ -4059,6 +4064,7 @@ public SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3(ITestOutputHelper protected override Version UseVersion => HttpVersion.Version30; } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_Finalization_Http3 : HttpClientHandler_Finalization_Test { @@ -4322,7 +4328,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync( }; policy.ExtraStore.AddRange(caCerts); - policy.CustomTrustStore.Add(caCerts[caCerts.Count - 1]); + policy.CustomTrustStore.Add(caCerts[caCerts.Count -1]); socketsHandler.SslOptions = new SslClientAuthenticationOptions() { CertificateChainPolicy = policy }; using HttpClient client = CreateHttpClient(handler); @@ -4484,7 +4490,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => options: new GenericLoopbackOptions() { UseSsl = true }); } - + } public sealed class SocketsHttpHandler_HttpRequestErrorTest_Http11 : SocketsHttpHandler_HttpRequestErrorTest @@ -4527,6 +4533,7 @@ await Http11LoopbackServerFactory.Singleton.CreateClientAndServerAsync(async uri } } + [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpRequestErrorTest_Http30 : SocketsHttpHandler_HttpRequestErrorTest { diff --git a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs index d5962dfba4d096..e97e4baaf8208a 100644 --- a/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs +++ b/src/libraries/System.Net.Http/tests/StressTests/HttpStress/Program.cs @@ -16,8 +16,8 @@ using System.Net.Quic; using Microsoft.Quic; -[assembly: SupportedOSPlatform("windows")] -[assembly: SupportedOSPlatform("linux")] +[assembly:SupportedOSPlatform("windows")] +[assembly:SupportedOSPlatform("linux")] namespace HttpStress { @@ -186,6 +186,24 @@ private static async Task Run(Configuration config) Console.WriteLine("Query Parameters: " + config.MaxParameters); Console.WriteLine(); + if (config.HttpVersion == HttpVersion.Version30 && IsQuicSupported) + { + unsafe + { + // If the system gets overloaded, MsQuic has a tendency to drop incoming connections, see https://github.com/dotnet/runtime/issues/55979. + // So in case we're running H/3 stress test, we're using the same hack as for System.Net.Quic tests, which increases the time limit for pending operations in MsQuic thread pool. + object msQuicApiInstance = msQuicApiType.GetProperty("Api", BindingFlags.NonPublic | BindingFlags.Static)!.GetGetMethod(true)!.Invoke(null, Array.Empty())!; + QUIC_API_TABLE* apiTable = (QUIC_API_TABLE*)(Pointer.Unbox(msQuicApiType.GetProperty("ApiTable")!.GetGetMethod()!.Invoke(msQuicApiInstance, Array.Empty())!)); + QUIC_SETTINGS settings = default(QUIC_SETTINGS); + settings.IsSet.MaxWorkerQueueDelayUs = 1; + settings.MaxWorkerQueueDelayUs = 2_500_000u; // 2.5s, 10x the default + if (MsQuic.StatusFailed(apiTable->SetParam(null, MsQuic.QUIC_PARAM_GLOBAL_SETTINGS, (uint)sizeof(QUIC_SETTINGS), (byte*)&settings))) + { + Console.WriteLine($"Unable to set MsQuic MaxWorkerQueueDelayUs."); + } + } + } + StressServer? server = null; if (config.RunMode.HasFlag(RunMode.server)) { diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs index 28c326b7b65fb0..829c279969c2ea 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/Internal/MsQuicApi.cs @@ -62,7 +62,7 @@ private MsQuicApi(QUIC_API_TABLE* apiTable) internal static string? NotSupportedReason { get; } // workaround for https://github.com/microsoft/msquic/issues/4132 - internal static bool SupportsAsyncCertValidation => Version >= new Version(2, 3, 5); + internal static bool SupportsAsyncCertValidation => Version >= new Version(2, 4, 0); internal static bool UsesSChannelBackend { get; } diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs index 41ac5e41da24de..b2042adffe33b4 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/MsQuicTests.cs @@ -357,8 +357,10 @@ public async Task UntrustedClientCertificateFails() } } + static bool SupportsAsyncCertValidation => QuicTestCollection.MsQuicVersion >= new Version(2, 4); + [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/99074")] + [ActiveIssue("https://github.com/dotnet/runtime/issues/99074", typeof(MsQuicTests), nameof(SupportsAsyncCertValidation))] public async Task CertificateCallbackThrowPropagates() { using CancellationTokenSource cts = new CancellationTokenSource(PassingTestTimeout); diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs index 5125c72e0ca8d1..f8dd160acb00b7 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs @@ -15,7 +15,7 @@ namespace System.Net.Quic.Tests; -[CollectionDefinition(nameof(QuicTestCollection))] +[CollectionDefinition(nameof(QuicTestCollection), DisableParallelization = true)] public unsafe class QuicTestCollection : ICollectionFixture, IDisposable { public static bool IsSupported => QuicListener.IsSupported && QuicConnection.IsSupported; From 3d9e8686c3a627e532c82128a439e1dbc99256d6 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 19 Apr 2024 18:57:08 +0200 Subject: [PATCH 14/46] Add more logging even in Http3Loopback --- .../System/Net/Http/GenericLoopbackServer.cs | 1 + .../Net/Http/Http3LoopbackConnection.cs | 24 ++++++++++++------- .../System/Net/Http/Http3LoopbackServer.cs | 7 +++++- .../System/Net/Http/Http3LoopbackStream.cs | 7 +++++- ...entHandlerTest.MaxResponseHeadersLength.cs | 2 +- .../src/System/Net/Quic/QuicListener.cs | 16 +++++++++++++ 6 files changed, 45 insertions(+), 12 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs index 66c64e3e8a578f..065d2ae9bfab02 100644 --- a/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/GenericLoopbackServer.cs @@ -188,6 +188,7 @@ public class GenericLoopbackOptions #if !NETSTANDARD2_0 && !NETFRAMEWORK public SslStreamCertificateContext? CertificateContext { get; set; } #endif + public Xunit.Abstractions.ITestOutputHelper? TestOutputHelper { get; set; } } public struct HttpHeaderData diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index fcae20ca12ce34..15429d188cb685 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -52,9 +52,12 @@ public sealed class Http3LoopbackConnection : GenericLoopbackConnection public Http3LoopbackStream OutboundControlStream => _outboundControlStream ?? throw new Exception("Control stream has not been opened yet"); public Http3LoopbackStream InboundControlStream => _inboundControlStream ?? throw new Exception("Inbound control stream has not been accepted yet"); - public Http3LoopbackConnection(QuicConnection connection) + private Xunit.Abstractions.ITestOutputHelper? _output; + + public Http3LoopbackConnection(QuicConnection connection, Xunit.Abstractions.ITestOutputHelper? output) { _connection = connection; + _output = output; } public long MaxHeaderListSize { get; private set; } = -1; @@ -92,12 +95,12 @@ public override async ValueTask DisposeAsync() public async ValueTask OpenUnidirectionalStreamAsync() { - return new Http3LoopbackStream(await _connection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional)); + return new Http3LoopbackStream(await _connection.OpenOutboundStreamAsync(QuicStreamType.Unidirectional), _output); } public async ValueTask OpenBidirectionalStreamAsync() { - return new Http3LoopbackStream(await _connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional)); + return new Http3LoopbackStream(await _connection.OpenOutboundStreamAsync(QuicStreamType.Bidirectional), _output); } public static int GetRequestId(QuicStream stream) @@ -124,16 +127,15 @@ private Task EnsureControlStreamAcceptedAsync() async Task EnsureControlStreamAcceptedInternalAsync() { Http3LoopbackStream controlStream; - Console.WriteLine("New call to EnsureControlStreamAcceptedInternalAsync"); while (true) { - Console.WriteLine("Ensuring Control Stream Accepted"); + _output?.WriteLine($"{this} {_connection} Accepting a new stream"); QuicStream quicStream = await _connection.AcceptInboundStreamAsync().ConfigureAwait(false); - + _output?.WriteLine($"{this} {quicStream} Accepted a stream, CanWrite = {quicStream.CanWrite}"); if (!quicStream.CanWrite) { // control stream accepted - controlStream = new Http3LoopbackStream(quicStream); + controlStream = new Http3LoopbackStream(quicStream, _output); break; } @@ -141,7 +143,7 @@ async Task EnsureControlStreamAcceptedInternalAsync() // keep it for later and wait for another stream _delayedStreams.Enqueue(quicStream); } - + _output?.WriteLine($"{this} {_connection} All streams has been caught, delayed streams count = {_delayedStreams.Count}"); long? streamType = await controlStream.ReadIntegerAsync(); Assert.Equal(Http3LoopbackStream.ControlStream, streamType); @@ -158,6 +160,7 @@ async Task EnsureControlStreamAcceptedInternalAsync() // This will automatically handle the control stream, including validating its contents public async Task AcceptRequestStreamAsync() { + _output?.WriteLine($"{this} {_connection} Accepting control stream."); await EnsureControlStreamAcceptedAsync().ConfigureAwait(false); if (!_delayedStreams.TryDequeue(out QuicStream quicStream)) @@ -165,7 +168,7 @@ public async Task AcceptRequestStreamAsync() quicStream = await _connection.AcceptInboundStreamAsync().ConfigureAwait(false); } - var stream = new Http3LoopbackStream(quicStream); + var stream = new Http3LoopbackStream(quicStream, _output); Assert.True(quicStream.CanWrite, "Expected writeable stream."); @@ -186,7 +189,9 @@ public async Task AcceptRequestStreamAsync() public async Task EstablishControlStreamAsync(SettingsEntry[] settingsEntries) { + _output?.WriteLine($"{this} Establishing control stream"); _outboundControlStream = await OpenUnidirectionalStreamAsync(); + _output?.WriteLine($"{this} {_outboundControlStream.Stream} Stream opened."); await _outboundControlStream.SendUnidirectionalStreamTypeAsync(Http3LoopbackStream.ControlStream); await _outboundControlStream.SendSettingsFrameAsync(settingsEntries); } @@ -243,6 +248,7 @@ public override Task SendPartialResponseHeadersAsync(HttpStatusCode statusCode = public override async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { + _output?.WriteLine($"{this} {_connection} HandleRequestAsync triggered."); Http3LoopbackStream stream = await AcceptRequestStreamAsync().ConfigureAwait(false); HttpRequestData request = await stream.ReadRequestDataAsync().ConfigureAwait(false); diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index 63368b49c129fd..160a93baff2f85 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -16,6 +16,7 @@ public sealed class Http3LoopbackServer : GenericLoopbackServer { private X509Certificate2 _cert; private QuicListener _listener; + private Xunit.Abstractions.ITestOutputHelper? _output; public override Uri Address => new Uri($"https://{_listener.LocalEndPoint}/"); @@ -58,6 +59,8 @@ public Http3LoopbackServer(Http3Options options = null) ValueTask valueTask = QuicListener.ListenAsync(listenerOptions); Debug.Assert(valueTask.IsCompleted); _listener = valueTask.Result; + _output = options.TestOutputHelper; + _output?.WriteLine($"{this} Http3LoopbackServer created."); } public override void Dispose() @@ -68,8 +71,10 @@ public override void Dispose() private async Task EstablishHttp3ConnectionAsync(params SettingsEntry[] settingsEntries) { + _output?.WriteLine($"{this} Accepting connection"); QuicConnection con = await _listener.AcceptConnectionAsync().ConfigureAwait(false); - Http3LoopbackConnection connection = new Http3LoopbackConnection(con); + _output?.WriteLine($"{this} Connection accepted: {con}"); + Http3LoopbackConnection connection = new Http3LoopbackConnection(con, _output); await connection.EstablishControlStreamAsync(settingsEntries); return connection; diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs index d8d0f9a7a7caf3..2d3d5ef1f3327e 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs @@ -34,13 +34,18 @@ public sealed class Http3LoopbackStream : IAsyncDisposable public bool CanRead => _stream.CanRead; public bool CanWrite => _stream.CanWrite; - public Http3LoopbackStream(QuicStream stream) + private Xunit.Abstractions.ITestOutputHelper? _output; + + public Http3LoopbackStream(QuicStream stream, Xunit.Abstractions.ITestOutputHelper? output) { _stream = stream; + _output = output; } public ValueTask DisposeAsync() => _stream.DisposeAsync(); + public QuicStream Stream => _stream; + public long StreamId => _stream.Id; public async Task HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index f0265c5840b91f..67e78527c521b6 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -74,7 +74,6 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { - Console.WriteLine("Test start"); using TestEventListener listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; @@ -91,6 +90,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }, async server => { + _output.WriteLine($"Listening on {server.Address}"); try { await server.HandleRequestAsync(headers: new[] { new HttpHeaderData("Foo", new string('a', handler.MaxResponseHeadersLength * 1024)) }); diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicListener.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicListener.cs index 88ea309054a7db..53446d6811d5fd 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicListener.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicListener.cs @@ -238,12 +238,24 @@ private async void StartConnectionHandshake(QuicConnection connection, SslClient handshakeTimeout = options.HandshakeTimeout; linkedCts.CancelAfter(handshakeTimeout); + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{connection} Finishing handshake with options: {options}"); + } await connection.FinishHandshakeAsync(options, clientHello.ServerName, cancellationToken).ConfigureAwait(false); + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{connection} Finished handshake with options: {options}"); + } if (!_acceptQueue.Writer.TryWrite(connection)) { // Channel has been closed, dispose the connection as it'll never be handed out. await connection.DisposeAsync().ConfigureAwait(false); } + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{connection} has been enqueued to the _acceptQueue"); + } } catch (OperationCanceledException) when (connection.ConnectionShutdownToken.IsCancellationRequested) { @@ -337,6 +349,10 @@ private unsafe int HandleEventNewConnection(ref NEW_CONNECTION_DATA data) QuicConnection connection = new QuicConnection(data.Connection, data.Info); SslClientHelloInfo clientHello = new SslClientHelloInfo(data.Info->ServerNameLength > 0 ? Marshal.PtrToStringUTF8((IntPtr)data.Info->ServerName, data.Info->ServerNameLength) : "", SslProtocols.Tls13); + if (NetEventSource.Log.IsEnabled()) + { + NetEventSource.Info(this, $"{connection} Starting the handshake process for connection."); + } // Kicks off the rest of the handshake in the background, the process itself will enqueue the result in the accept queue. StartConnectionHandshake(connection, clientHello); From 7a0476c150126905792363ee406273ac9f125dad Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 20 Apr 2024 05:58:46 +0200 Subject: [PATCH 15/46] Enable logging in H3Loopback --- .../Common/tests/System/Net/Http/Http3LoopbackServer.cs | 1 + .../Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index 160a93baff2f85..f199408df729e1 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -143,6 +143,7 @@ private static Http3Options CreateOptions(GenericLoopbackOptions options) http3Options.Certificate = options.Certificate; http3Options.SslProtocols = options.SslProtocols; http3Options.ListenBacklog = options.ListenBacklog; + http3Options.TestOutputHelper = options.TestOutputHelper; } return http3Options; } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 67e78527c521b6..892e3c57bcdcdb 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -100,7 +100,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => #if !WINHTTPHANDLER_TEST catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} #endif - }); + }, options: new() { TestOutputHelper = _output }); } [Theory] From 39cc76f7ea0b0b3a79004793ad909fff24745b87 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 20 Apr 2024 07:31:28 +0200 Subject: [PATCH 16/46] Fail on idle connection --- .../System.Net.Quic/src/System/Net/Quic/QuicConnection.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 7e7b359b8286d7..4d103f4824b10b 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -530,6 +530,10 @@ private unsafe int HandleEventConnected(ref CONNECTED_DATA data) } private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATED_BY_TRANSPORT_DATA data) { + if (data.Status == QUIC_STATUS_CONNECTION_IDLE) + { + Debug.Fail("Connection was idle for too long and was closed by MsQuic"); + } Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetExceptionForMsQuicStatus(data.Status, (long)data.ErrorCode)); _connectedTcs.TrySetException(exception); _acceptQueue.Writer.TryComplete(exception); From d3b662091584f3269637b3c7a64d6796dc4f4f57 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 20 Apr 2024 10:59:07 +0200 Subject: [PATCH 17/46] Crash on failure only if logging is enabled --- .../System.Net.Quic/src/System/Net/Quic/QuicConnection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 4d103f4824b10b..8777dcc7d9f5e4 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -530,7 +530,7 @@ private unsafe int HandleEventConnected(ref CONNECTED_DATA data) } private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATED_BY_TRANSPORT_DATA data) { - if (data.Status == QUIC_STATUS_CONNECTION_IDLE) + if (data.Status == QUIC_STATUS_CONNECTION_IDLE && NetEventSource.Log.IsEnabled()) { Debug.Fail("Connection was idle for too long and was closed by MsQuic"); } From d36b894b585b270b5bcc10413d14d66a155afdde Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 20 Apr 2024 21:10:08 +0200 Subject: [PATCH 18/46] Add more logging and delete debug fail --- .../Common/tests/System/Net/Http/Http3LoopbackServer.cs | 2 ++ .../Common/tests/System/Net/Http/Http3LoopbackStream.cs | 2 ++ .../System.Net.Quic/src/System/Net/Quic/QuicConnection.cs | 4 ---- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index f199408df729e1..995c8de5792b3f 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -77,6 +77,7 @@ private async Task EstablishHttp3ConnectionAsync(params Http3LoopbackConnection connection = new Http3LoopbackConnection(con, _output); await connection.EstablishControlStreamAsync(settingsEntries); + _output?.WriteLine($"{this} {con} Control stream established"); return connection; } @@ -100,6 +101,7 @@ public override async Task AcceptConnectionAsync(Func HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { await using Http3LoopbackConnection con = (Http3LoopbackConnection)await EstablishGenericConnectionAsync().ConfigureAwait(false); + _output?.WriteLine($"{con} Connection established successfully!"); return await con.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); } } diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs index 2d3d5ef1f3327e..8f89046c0bae57 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs @@ -167,7 +167,9 @@ private async Task SendFrameHeaderAsync(long frameType, int payloadLength) public async Task SendFrameAsync(long frameType, ReadOnlyMemory framePayload) { await SendFrameHeaderAsync(frameType, framePayload.Length).ConfigureAwait(false); + _output?.WriteLine($"Sent {frameType} header"); await _stream.WriteAsync(framePayload).ConfigureAwait(false); + _output?.WriteLine($"Sent {framePayload} - Length: {framePayload.Length} frame"); } static int EncodeHttpInteger(long longToEncode, Span buffer) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 8777dcc7d9f5e4..7e7b359b8286d7 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -530,10 +530,6 @@ private unsafe int HandleEventConnected(ref CONNECTED_DATA data) } private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATED_BY_TRANSPORT_DATA data) { - if (data.Status == QUIC_STATUS_CONNECTION_IDLE && NetEventSource.Log.IsEnabled()) - { - Debug.Fail("Connection was idle for too long and was closed by MsQuic"); - } Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetExceptionForMsQuicStatus(data.Status, (long)data.ErrorCode)); _connectedTcs.TrySetException(exception); _acceptQueue.Writer.TryComplete(exception); From 594d3a58a05c462fba2bdddaa8b2a78f7d55a7d7 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 23 Apr 2024 15:55:03 +0200 Subject: [PATCH 19/46] Change GenericConnectionEstablishment to Direct Http3Establishment Method --- .../Common/tests/System/Net/Http/Http3LoopbackServer.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index 995c8de5792b3f..2077eec589f006 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -83,7 +83,7 @@ private async Task EstablishHttp3ConnectionAsync(params public override async Task EstablishGenericConnectionAsync() { - return await EstablishHttp3ConnectionAsync(); + return await EstablishHttp3ConnectionAsync().ConfigureAwait(false); } public Task EstablishConnectionAsync(params SettingsEntry[] settingsEntries) @@ -100,7 +100,7 @@ public override async Task AcceptConnectionAsync(Func HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { - await using Http3LoopbackConnection con = (Http3LoopbackConnection)await EstablishGenericConnectionAsync().ConfigureAwait(false); + await using Http3LoopbackConnection con = await EstablishHttp3ConnectionAsync().ConfigureAwait(false); _output?.WriteLine($"{con} Connection established successfully!"); return await con.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); } From 5e260c08c734fc526052e3f5746201817308c5d8 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 26 Apr 2024 17:36:32 +0200 Subject: [PATCH 20/46] Revert "Disable parallel test execution for QUIC and HTTP/3 (#101569)" This reverts commit 009d74eb199b07aa2e07111b9f64216395f9d86d. --- .../Net/Http/HttpClientHandlerTest.Cookies.cs | 2 +- .../HttpClientHandlerTest.AltSvc.cs | 7 +------ .../FunctionalTests/SocketsHttpHandlerTest.cs | 14 -------------- .../tests/FunctionalTests/QuicTestCollection.cs | 2 +- 4 files changed, 3 insertions(+), 22 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs index 6ecd7261ca2d97..714cec7bae3d56 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs @@ -44,7 +44,7 @@ private static CookieContainer CreateSingleCookieContainer(Uri uri, string cooki private static string GetCookieHeaderValue(string cookieName, string cookieValue) => $"{cookieName}={cookieValue}"; [Fact] - public virtual async Task GetAsync_DefaultCoookieContainer_NoCookieSent() + public async Task GetAsync_DefaultCoookieContainer_NoCookieSent() { await LoopbackServerFactory.CreateClientAndServerAsync( async uri => diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index d6a53a33e2342e..d20b0f2635dcab 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -29,15 +29,10 @@ private HttpClient CreateHttpClient(Version version) return client; } - [ConditionalTheory] + [Theory] [MemberData(nameof(AltSvcHeaderUpgradeVersions))] public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overrideHost) { - if (UseVersion == HttpVersion30 && fromVersion == HttpVersion.Version11 && overrideHost) - { - throw new SkipTestException("https://github.com/dotnet/runtime/issues/91757"); - } - // The test makes a request to a HTTP/1 or HTTP/2 server first, which supplies an Alt-Svc header pointing to the second server. using GenericLoopbackServer firstServer = fromVersion.Major switch diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index f2c56bf37d23cc..66029ecd1c0e82 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs @@ -1633,7 +1633,6 @@ public SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http2(ITest protected override Version UseVersion => HttpVersion.Version20; } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength_Http3 : SocketsHttpHandler_HttpClientHandler_MaxResponseHeadersLength { @@ -4026,7 +4025,6 @@ public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http2(ITestOutputH protected override Version UseVersion => HttpVersion.Version20; } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Http3 : HttpClientHandlerTest { @@ -4034,19 +4032,13 @@ public SocketsHttpHandlerTest_HttpClientHandlerTest_Http3(ITestOutputHelper outp protected override Version UseVersion => HttpVersion.Version30; } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_Cookies_Http3 : HttpClientHandlerTest_Cookies { public SocketsHttpHandlerTest_Cookies_Http3(ITestOutputHelper output) : base(output) { } protected override Version UseVersion => HttpVersion.Version30; - - [Fact] - [ActiveIssue("https://github.com/dotnet/runtime/issues/91757")] - public override Task GetAsync_DefaultCoookieContainer_NoCookieSent() { return null!; } } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3 : HttpClientHandlerTest_Headers { @@ -4054,7 +4046,6 @@ public SocketsHttpHandlerTest_HttpClientHandlerTest_Headers_Http3(ITestOutputHel protected override Version UseVersion => HttpVersion.Version30; } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3 : SocketsHttpHandler_Cancellation_Test { @@ -4062,7 +4053,6 @@ public SocketsHttpHandler_HttpClientHandler_Cancellation_Test_Http3(ITestOutputH protected override Version UseVersion => HttpVersion.Version30; } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3 : HttpClientHandler_AltSvc_Test { @@ -4070,7 +4060,6 @@ public SocketsHttpHandler_HttpClientHandler_AltSvc_Test_Http3(ITestOutputHelper protected override Version UseVersion => HttpVersion.Version30; } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpClientHandler_Finalization_Http3 : HttpClientHandler_Finalization_Test { @@ -4235,7 +4224,6 @@ public SocketsHttpHandler_RequestContentLengthMismatchTest_Http2(ITestOutputHelp protected override Version UseVersion => HttpVersion.Version20; } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_RequestContentLengthMismatchTest_Http3 : SocketsHttpHandler_RequestContentLengthMismatchTest { @@ -4412,7 +4400,6 @@ public SocketsHttpHandler_SocketsHttpHandler_SecurityTest_Http2(ITestOutputHelpe protected override Version UseVersion => HttpVersion.Version20; } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_SocketsHttpHandler_SecurityTest_Http3 : SocketsHttpHandler_SecurityTest { @@ -4541,7 +4528,6 @@ await Http11LoopbackServerFactory.Singleton.CreateClientAndServerAsync(async uri } } - [Collection(nameof(DisableParallelization))] [ConditionalClass(typeof(HttpClientHandlerTestBase), nameof(IsQuicSupported))] public sealed class SocketsHttpHandler_HttpRequestErrorTest_Http30 : SocketsHttpHandler_HttpRequestErrorTest { diff --git a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs index f8dd160acb00b7..5125c72e0ca8d1 100644 --- a/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs +++ b/src/libraries/System.Net.Quic/tests/FunctionalTests/QuicTestCollection.cs @@ -15,7 +15,7 @@ namespace System.Net.Quic.Tests; -[CollectionDefinition(nameof(QuicTestCollection), DisableParallelization = true)] +[CollectionDefinition(nameof(QuicTestCollection))] public unsafe class QuicTestCollection : ICollectionFixture, IDisposable { public static bool IsSupported => QuicListener.IsSupported && QuicConnection.IsSupported; From c31cdb11d31e7d791062e3eed802dd5b7ec816f7 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 26 Apr 2024 19:08:23 +0200 Subject: [PATCH 21/46] Revert "Disable frequently failing tests (#101439)" This reverts commit e01db175827165aa9b056d3127ce2bcc40a311f9. --- .../Net/Http/HttpClientHandlerTest.Cookies.cs | 9 +--- .../System/Net/Http/HttpClientHandlerTest.cs | 49 +++++++++---------- .../HttpClientHandlerTest.AltSvc.cs | 9 +--- .../HttpClientHandlerTest.Headers.cs | 9 +--- 4 files changed, 26 insertions(+), 50 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs index 714cec7bae3d56..b2f03bfbc930e5 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.Cookies.cs @@ -216,15 +216,10 @@ private string GetCookieValue(HttpRequestData request) return cookieHeaderValue; } - [ConditionalFact] + [Fact] [SkipOnPlatform(TestPlatforms.Browser, "CookieContainer is not supported on Browser")] public async Task GetAsync_SetCookieContainerAndCookieHeader_BothCookiesSent() { - if (UseVersion == HttpVersion30) - { - throw new SkipTestException("https://github.com/dotnet/runtime/issues/101377"); - } - await LoopbackServerFactory.CreateServerAsync(async (server, url) => { HttpClientHandler handler = CreateHttpClientHandler(); @@ -318,7 +313,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async url => using (HttpClient client = CreateHttpClient(handler)) { client.DefaultRequestHeaders.ConnectionClose = true; // to avoid issues with connection pooling - await client.GetAsync(url1); + await client.GetAsync(url1); } }, async server => diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 31d8d9f154fc4f..96cc4858477a99 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -270,7 +270,7 @@ await LoopbackServer.CreateClientAndServerAsync(async proxyUri => public static IEnumerable SecureAndNonSecure_IPBasedUri_MemberData() => from address in new[] { IPAddress.Loopback, IPAddress.IPv6Loopback } from useSsl in BoolValues - // we could not create SslStream in browser, [ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)] + // we could not create SslStream in browser, [ActiveIssue("https://github.com/dotnet/runtime/issues/37669", TestPlatforms.Browser)] where PlatformDetection.IsNotBrowser || !useSsl select new object[] { address, useSsl }; @@ -883,8 +883,8 @@ await LoopbackServer.CreateClientAndServerAsync(async url => "\r\n" + "5\r\n" + "hello" + // missing \r\n terminator - //"5\r\n" + - //"world" + // missing \r\n terminator + //"5\r\n" + + //"world" + // missing \r\n terminator "0\r\n" + "\r\n")); } @@ -989,7 +989,7 @@ await connection.WriteStringAsync( }); } - [ConditionalTheory] + [Theory] [InlineData(true, true, true)] [InlineData(true, true, false)] [InlineData(true, false, false)] @@ -999,11 +999,6 @@ await connection.WriteStringAsync( [ActiveIssue("https://github.com/dotnet/runtime/issues/65429", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(bool? chunked, bool enableWasmStreaming, bool slowChunks) { - if (UseVersion == HttpVersion30) - { - throw new SkipTestException("https://github.com/dotnet/runtime/issues/91757"); - } - if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) { return; @@ -1103,7 +1098,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => if (PlatformDetection.IsBrowser) { #if !NETFRAMEWORK - if (slowChunks) + if(slowChunks) { Assert.Equal(1, await responseStream.ReadAsync(new Memory(buffer2))); Assert.Equal((byte)'h', buffer2[0]); @@ -1213,7 +1208,7 @@ await server.AcceptConnectionAsync(async connection => { case true: await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Transfer-Encoding", "chunked") }, isFinal: false); - if (PlatformDetection.IsBrowser && slowChunks) + if(PlatformDetection.IsBrowser && slowChunks) { await connection.SendResponseBodyAsync("1\r\nh\r\n", false); await tcs.Task; @@ -1228,12 +1223,12 @@ await server.AcceptConnectionAsync(async connection => break; case false: - await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", "11") }, content: "hello world"); + await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", "11")}, content: "hello world"); break; case null: // This inject Content-Length header with null value to hint Loopback code to not include one automatically. - await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", null) }, isFinal: false); + await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", null)}, isFinal: false); await connection.SendResponseBodyAsync("hello world"); break; } @@ -1469,10 +1464,10 @@ await LoopbackServerFactory.CreateServerAsync(async (server3, url3) => Task serverTask3 = server3.AcceptConnectionAsync(async connection3 => { await connection3.ReadRequestDataAsync(); - await connection3.SendResponseAsync(HttpStatusCode.OK, new HttpHeaderData[] { new HttpHeaderData("Content-Length", "20") }, isFinal: false); - await connection3.SendResponseBodyAsync("1234567890", isFinal: false); + await connection3.SendResponseAsync(HttpStatusCode.OK, new HttpHeaderData[] { new HttpHeaderData("Content-Length", "20") }, isFinal : false); + await connection3.SendResponseBodyAsync("1234567890", isFinal : false); await unblockServers.Task; - await connection3.SendResponseBodyAsync("1234567890", isFinal: true); + await connection3.SendResponseBodyAsync("1234567890", isFinal : true); }); // Make three requests @@ -1546,7 +1541,7 @@ public async Task GetAsync_UnicodeHostName_SuccessStatusCodeInResponse() } } - #region Post Methods Tests +#region Post Methods Tests [Fact] [SkipOnPlatform(TestPlatforms.Browser, "ExpectContinue not supported on Browser")] @@ -1590,13 +1585,13 @@ await server.AcceptConnectionAsync(async connection => public static IEnumerable Interim1xxStatusCode() { - yield return new object[] { (HttpStatusCode)100 }; // 100 Continue. + yield return new object[] { (HttpStatusCode) 100 }; // 100 Continue. // 101 SwitchingProtocols will be treated as a final status code. - yield return new object[] { (HttpStatusCode)102 }; // 102 Processing. - yield return new object[] { (HttpStatusCode)103 }; // 103 EarlyHints. - yield return new object[] { (HttpStatusCode)150 }; - yield return new object[] { (HttpStatusCode)180 }; - yield return new object[] { (HttpStatusCode)199 }; + yield return new object[] { (HttpStatusCode) 102 }; // 102 Processing. + yield return new object[] { (HttpStatusCode) 103 }; // 103 EarlyHints. + yield return new object[] { (HttpStatusCode) 150 }; + yield return new object[] { (HttpStatusCode) 180 }; + yield return new object[] { (HttpStatusCode) 199 }; } [Theory] @@ -1657,7 +1652,7 @@ await server.AcceptConnectionAsync(async connection => new HttpHeaderData("Content-type", "text/xml"), new HttpHeaderData("Set-Cookie", SetCookieIgnored1)}, isFinal: false); - await connection.SendResponseAsync(responseStatusCode, headers: new HttpHeaderData[] { + await connection.SendResponseAsync(responseStatusCode, headers: new HttpHeaderData[] { new HttpHeaderData("Cookie", "ignore_cookie=choco2"), new HttpHeaderData("Content-type", "text/plain"), new HttpHeaderData("Set-Cookie", SetCookieIgnored2)}, isFinal: false); @@ -1761,7 +1756,7 @@ await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestDataAsync(readBody: false); // Send multiple 100-Continue responses. - for (int count = 0; count < 4; count++) + for (int count = 0 ; count < 4; count++) { await connection.SendResponseAsync(HttpStatusCode.Continue, isFinal: false); } @@ -1865,7 +1860,7 @@ await server.AcceptConnectionAsync(async connection => { await connection.ReadRequestDataAsync(readBody: false); - await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] { new HttpHeaderData("Content-Length", $"{ResponseString.Length}") }, isFinal: false); + await connection.SendResponseAsync(HttpStatusCode.OK, headers: new HttpHeaderData[] {new HttpHeaderData("Content-Length", $"{ResponseString.Length}")}, isFinal : false); byte[] body = await connection.ReadRequestBodyAsync(); Assert.Equal(RequestString, Encoding.ASCII.GetString(body)); @@ -2146,7 +2141,7 @@ await LoopbackServerFactory.CreateServerAsync(async (server, rootUrl) => } }); } - #endregion +#endregion [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowserDomSupported))] public async Task GetAsync_InvalidUrl_ExpectedExceptionThrown() diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index d20b0f2635dcab..f71efde6631058 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -8,8 +8,6 @@ using System.Net.Test.Common; using System.Net.Quic; -using Microsoft.DotNet.XUnitExtensions; - namespace System.Net.Http.Functional.Tests { public abstract class HttpClientHandler_AltSvc_Test : HttpClientHandlerTestBase @@ -73,14 +71,9 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri { HttpVersion.Version20, false } }; - [ConditionalFact] + [Fact] public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { - if (UseVersion == HttpVersion30) - { - throw new SkipTestException("https://github.com/dotnet/runtime/issues/101376"); - } - using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(); using HttpClient client = CreateHttpClient(HttpVersion.Version20); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs index cbd74f8188a20f..48d72d48880133 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Headers.cs @@ -13,8 +13,6 @@ using Xunit; using Xunit.Abstractions; -using Microsoft.DotNet.XUnitExtensions; - namespace System.Net.Http.Functional.Tests { using Configuration = System.Net.Test.Common.Configuration; @@ -289,17 +287,12 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => }); } - [ConditionalTheory] + [Theory] [InlineData("Thu, 01 Dec 1994 16:00:00 GMT", true)] [InlineData("-1", false)] [InlineData("0", false)] public async Task SendAsync_Expires_Success(string value, bool isValid) { - if (UseVersion == HttpVersion30) - { - throw new SkipTestException("https://github.com/dotnet/runtime/issues/91757"); - } - await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using (HttpClient client = CreateHttpClient()) From c466dfe7e292c59dfb8e38aba491dfadb5bd574e Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 27 Apr 2024 13:15:09 +0200 Subject: [PATCH 22/46] Add WaitAsync on ConnectionEstablishment for H/3 on Loopback Server --- .../Common/tests/System/Net/Http/Http3LoopbackConnection.cs | 6 +++--- .../Common/tests/System/Net/Http/Http3LoopbackServer.cs | 5 +++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs index 5453c346646bd5..a85e06974fcbeb 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackConnection.cs @@ -190,10 +190,10 @@ public async Task AcceptRequestStreamAsync() public async Task EstablishControlStreamAsync(SettingsEntry[] settingsEntries) { _output?.WriteLine($"{this} Establishing control stream"); - _outboundControlStream = await OpenUnidirectionalStreamAsync(); + _outboundControlStream = await OpenUnidirectionalStreamAsync().ConfigureAwait(false); _output?.WriteLine($"{this} {_outboundControlStream.Stream} Stream opened."); - await _outboundControlStream.SendUnidirectionalStreamTypeAsync(Http3LoopbackStream.ControlStream); - await _outboundControlStream.SendSettingsFrameAsync(settingsEntries); + await _outboundControlStream.SendUnidirectionalStreamTypeAsync(Http3LoopbackStream.ControlStream).ConfigureAwait(false); + await _outboundControlStream.SendSettingsFrameAsync(settingsEntries).ConfigureAwait(false); } public async Task DisposeCurrentStream() diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index 2077eec589f006..dc823dd1c4a227 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -76,7 +76,7 @@ private async Task EstablishHttp3ConnectionAsync(params _output?.WriteLine($"{this} Connection accepted: {con}"); Http3LoopbackConnection connection = new Http3LoopbackConnection(con, _output); - await connection.EstablishControlStreamAsync(settingsEntries); + await connection.EstablishControlStreamAsync(settingsEntries).ConfigureAwait(false); _output?.WriteLine($"{this} {con} Control stream established"); return connection; } @@ -100,7 +100,8 @@ public override async Task AcceptConnectionAsync(Func HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { - await using Http3LoopbackConnection con = await EstablishHttp3ConnectionAsync().ConfigureAwait(false); + await using Http3LoopbackConnection con = await EstablishHttp3ConnectionAsync() + .WaitAsync(TimeSpan.FromSeconds(10)).ConfigureAwait(false); _output?.WriteLine($"{con} Connection established successfully!"); return await con.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); } From 07f88714306acec35484a7e1431bf298a7479ed3 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Thu, 2 May 2024 12:33:12 +0200 Subject: [PATCH 23/46] Add logging to another test --- .../Common/tests/System/Net/Http/Http3LoopbackServer.cs | 3 +-- .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index dc823dd1c4a227..5b5199fc7aae21 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -100,8 +100,7 @@ public override async Task AcceptConnectionAsync(Func HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { - await using Http3LoopbackConnection con = await EstablishHttp3ConnectionAsync() - .WaitAsync(TimeSpan.FromSeconds(10)).ConfigureAwait(false); + await using Http3LoopbackConnection con = await EstablishHttp3ConnectionAsync().ConfigureAwait(false); _output?.WriteLine($"{con} Connection established successfully!"); return await con.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 96cc4858477a99..ae600c7dafe1fa 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -18,6 +18,7 @@ using Microsoft.DotNet.XUnitExtensions; using Xunit; using Xunit.Abstractions; +using TestUtilities; namespace System.Net.Http.Functional.Tests { @@ -1016,6 +1017,8 @@ public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(boo return; } + using TestEventListener listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + var tcs = new TaskCompletionSource(); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { From 1b54ef00c0ecda69ec7e7ebe5960ebd94bab45a1 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Thu, 2 May 2024 14:08:24 +0200 Subject: [PATCH 24/46] Add another log and increase timeout --- .../tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index f71efde6631058..d8b7fc65a23a37 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -7,6 +7,7 @@ using Xunit.Abstractions; using System.Net.Test.Common; using System.Net.Quic; +using TestUtilities; namespace System.Net.Http.Functional.Tests { @@ -74,6 +75,7 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri [Fact] public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { + using TestEventListener listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(); using HttpClient client = CreateHttpClient(HttpVersion.Version20); @@ -88,7 +90,7 @@ public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() await connection.SendDefaultResponseAsync(streamId); }); - await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000); + await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(60_000); // Allow to fail due to hang and QuicException HttpResponseMessage firstResponse = firstResponseTask.Result; Assert.True(firstResponse.IsSuccessStatusCode); From c98aca62d9c970ef52d6d1fdc773ff664ce234f5 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Thu, 2 May 2024 17:11:29 +0200 Subject: [PATCH 25/46] Add debug fail to idle case --- .../System.Net.Quic/src/System/Net/Quic/QuicConnection.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 75bdafccf4cec2..517554ce2a4211 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -557,6 +557,11 @@ private unsafe int HandleEventConnected(ref CONNECTED_DATA data) } private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATED_BY_TRANSPORT_DATA data) { + if (NetEventSource.Log.IsEnabled() && data.Status == QUIC_STATUS_CONNECTION_IDLE && data.ErrorCode == 1) // Idle + { + Debug.Fail("Failing this"); + } + Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetExceptionForMsQuicStatus(data.Status, (long)data.ErrorCode)); _connectedTcs.TrySetException(exception); _connectionCloseTcs.TrySetException(exception); From 4fc225310579c1a90c781f5edb335631f2504f8a Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Thu, 2 May 2024 17:14:17 +0200 Subject: [PATCH 26/46] Convert assertion to noop --- .../Common/src/System/Net/Logging/NetEventSource.Common.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs b/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs index 8dadcacb9be91f..b08fddb86fc04b 100644 --- a/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs +++ b/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs @@ -77,7 +77,8 @@ public static void Info(object? thisOrContextObject, object? message, [CallerMem [Event(InfoEventId, Level = EventLevel.Informational, Keywords = Keywords.Default)] private void Info(string thisOrContextObject, string? memberName, string? message) { - Debug.Assert(IsEnabled()); + //Debug.Assert(IsEnabled()); + if (!IsEnabled()) return; WriteEvent(InfoEventId, thisOrContextObject, memberName ?? MissingMember, message); } #endregion From e1d4940fbfb15ffcf0cc94486278c44d7fefa410 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Thu, 2 May 2024 19:41:15 +0200 Subject: [PATCH 27/46] Delete extra logs and enable logging only for H3 --- .../HttpClientHandlerTest.MaxResponseHeadersLength.cs | 9 ++++++++- .../tests/System/Net/Http/HttpClientHandlerTest.cs | 2 -- .../FunctionalTests/HttpClientHandlerTest.AltSvc.cs | 1 - 3 files changed, 8 insertions(+), 4 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 892e3c57bcdcdb..9848666214072a 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -74,7 +74,12 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { - using TestEventListener listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + } + using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; @@ -101,6 +106,8 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => catch (QuicException ex) when (ex.QuicError == QuicError.StreamAborted && ex.ApplicationErrorCode == Http3ExcessiveLoad) {} #endif }, options: new() { TestOutputHelper = _output }); + + listener?.Dispose(); } [Theory] diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index ae600c7dafe1fa..602b7609c397c9 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1017,8 +1017,6 @@ public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(boo return; } - using TestEventListener listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); - var tcs = new TaskCompletionSource(); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index d8b7fc65a23a37..5263d06e79bdae 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -75,7 +75,6 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri [Fact] public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { - using TestEventListener listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(); using HttpClient client = CreateHttpClient(HttpVersion.Version20); From 8c7b78a60997a37dec909c9c62051f20ae5ff806 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Mon, 13 May 2024 12:47:28 +0200 Subject: [PATCH 28/46] Convert crash to log --- .../Common/tests/System/Net/Http/Http3LoopbackServer.cs | 3 ++- src/libraries/Common/tests/TestUtilities/TestEventListener.cs | 2 ++ .../System.Net.Quic/src/System/Net/Quic/QuicConnection.cs | 2 +- 3 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs index 5b5199fc7aae21..0f7e0160b32274 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackServer.cs @@ -100,8 +100,9 @@ public override async Task AcceptConnectionAsync(Func HandleRequestAsync(HttpStatusCode statusCode = HttpStatusCode.OK, IList headers = null, string content = "") { + _output?.WriteLine("Establishing HTTP/3 connection."); await using Http3LoopbackConnection con = await EstablishHttp3ConnectionAsync().ConfigureAwait(false); - _output?.WriteLine($"{con} Connection established successfully!"); + _output?.WriteLine($"{con} HTTP/3 Connection established successfully!"); return await con.HandleRequestAsync(statusCode, headers, content).ConfigureAwait(false); } } diff --git a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs index 09f2c897ef4eb0..ff67c66d2c110e 100644 --- a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs +++ b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs @@ -22,6 +22,8 @@ public sealed class TestEventListener : EventListener public static string[] NetworkingEvents => new[] { "Private.InternalDiagnostics.System.Net.Quic", + "Private.InternalDiagnostics.System.Net.Http", + "System.Net.Http", }; private readonly Action _writeFunc; diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 517554ce2a4211..b143290cdad91d 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -559,7 +559,7 @@ private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATE { if (NetEventSource.Log.IsEnabled() && data.Status == QUIC_STATUS_CONNECTION_IDLE && data.ErrorCode == 1) // Idle { - Debug.Fail("Failing this"); + NetEventSource.Info(this, $"{this} Connection idle."); } Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetExceptionForMsQuicStatus(data.Status, (long)data.ErrorCode)); From 9826432d84a93d52524ae0e0be9c7bec8ac05e70 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 14 May 2024 09:49:46 +0200 Subject: [PATCH 29/46] Add logging to other tests --- .../HttpClientHandlerTest.MaxResponseHeadersLength.cs | 8 ++++++++ .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 8 ++++++++ .../tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs | 7 +++++++ 3 files changed, 23 insertions(+) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 9848666214072a..3906b6840f8e9b 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -57,6 +57,13 @@ public void ValidValue_SetGet_Roundtrips(int validValue) [Fact] public async Task SetAfterUse_Throws() { + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + } + _output.WriteLine("Starting SetAfterUse_Throws test"); + await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { using HttpClientHandler handler = CreateHttpClientHandler(); @@ -67,6 +74,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Throws(() => handler.MaxResponseHeadersLength = 1); }, server => server.AcceptConnectionSendResponseAndCloseAsync()); + listener?.Dispose(); } [Theory] diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 602b7609c397c9..ccfc142266e902 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1017,6 +1017,13 @@ public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(boo return; } + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + } + _output.WriteLine("Starting ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream test"); + var tcs = new TaskCompletionSource(); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { @@ -1235,6 +1242,7 @@ await server.AcceptConnectionAsync(async connection => } }); }); + listener?.Dispose(); } [Fact] diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index 5263d06e79bdae..48de857b6c77cd 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -75,6 +75,12 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri [Fact] public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + } + _output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(); using HttpClient client = CreateHttpClient(HttpVersion.Version20); @@ -95,6 +101,7 @@ public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() Assert.True(firstResponse.IsSuccessStatusCode); await AltSvc_Upgrade_Success(firstServer, secondServer, client); + listener?.Dispose(); } [Fact] From 164e2527135fb3c5e915e9a0e5bd907fb43fba7c Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 14 May 2024 13:21:21 +0200 Subject: [PATCH 30/46] Pass testoutputhelper to other functions as well --- .../Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs | 2 +- .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 2 +- .../tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 3906b6840f8e9b..1e5ccd96502d5e 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -73,7 +73,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => (await client.GetStreamAsync(uri)).Dispose(); Assert.Throws(() => handler.MaxResponseHeadersLength = 1); }, - server => server.AcceptConnectionSendResponseAndCloseAsync()); + server => server.AcceptConnectionSendResponseAndCloseAsync(), options: new() { TestOutputHelper = _output }); listener?.Dispose(); } diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index ccfc142266e902..75880a5de759a9 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1241,7 +1241,7 @@ await server.AcceptConnectionAsync(async connection => break; } }); - }); + }, options: new() { TestOutputHelper = _output }); listener?.Dispose(); } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index 48de857b6c77cd..e7066134510e42 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -82,7 +82,7 @@ public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() } _output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); - using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(); + using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(options: new() { TestOutputHelper = _output }); using HttpClient client = CreateHttpClient(HttpVersion.Version20); Task firstResponseTask = client.GetAsync(firstServer.Address); From e337a40a936c55d91be5aaa6b02a55cf4ed6c172 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Mon, 20 May 2024 11:30:09 +0200 Subject: [PATCH 31/46] Disable Svc Upgrade to H/3 test --- .../HttpClientHandlerTest.AltSvc.cs | 58 ++++++++++--------- 1 file changed, 30 insertions(+), 28 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index e7066134510e42..f28b0ae794ad89 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -8,6 +8,7 @@ using System.Net.Test.Common; using System.Net.Quic; using TestUtilities; +using Microsoft.DotNet.XUnitExtensions; namespace System.Net.Http.Functional.Tests { @@ -73,35 +74,36 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri }; [Fact] - public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() + public Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { - TestEventListener? listener = null; - if (UseVersion == HttpVersion30) - { - listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); - } - _output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); - using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); - using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(options: new() { TestOutputHelper = _output }); - using HttpClient client = CreateHttpClient(HttpVersion.Version20); - - Task firstResponseTask = client.GetAsync(firstServer.Address); - Task serverTask = Task.Run(async () => - { - await using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync(); - - int streamId = await connection.ReadRequestHeaderAsync(); - await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId: 0)); - await connection.SendDefaultResponseAsync(streamId); - }); - - await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(60_000); // Allow to fail due to hang and QuicException - - HttpResponseMessage firstResponse = firstResponseTask.Result; - Assert.True(firstResponse.IsSuccessStatusCode); - - await AltSvc_Upgrade_Success(firstServer, secondServer, client); - listener?.Dispose(); + throw new SkipTestException("Can't get any useful info from this"); + //TestEventListener? listener = null; + //if (UseVersion == HttpVersion30) + //{ + // listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + //} + //_output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); + //using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); + //using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(options: new() { TestOutputHelper = _output }); + //using HttpClient client = CreateHttpClient(HttpVersion.Version20); + + //Task firstResponseTask = client.GetAsync(firstServer.Address); + //Task serverTask = Task.Run(async () => + //{ + // await using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync(); + + // int streamId = await connection.ReadRequestHeaderAsync(); + // await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId: 0)); + // await connection.SendDefaultResponseAsync(streamId); + //}); + + //await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(60_000); // Allow to fail due to hang and QuicException + + //HttpResponseMessage firstResponse = firstResponseTask.Result; + //Assert.True(firstResponse.IsSuccessStatusCode); + + //await AltSvc_Upgrade_Success(firstServer, secondServer, client); + //listener?.Dispose(); } [Fact] From 9f5021314641f98d60e7bb35195264df486c89d7 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Mon, 20 May 2024 16:43:30 +0200 Subject: [PATCH 32/46] Add more log --- .../Common/src/System/Net/Logging/NetEventSource.Common.cs | 3 ++- .../Common/tests/System/Net/Http/Http3LoopbackStream.cs | 5 +++++ .../tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs | 2 +- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs b/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs index b08fddb86fc04b..ca60b6b0ad52e7 100644 --- a/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs +++ b/src/libraries/Common/src/System/Net/Logging/NetEventSource.Common.cs @@ -103,7 +103,8 @@ public static void Error(object? thisOrContextObject, object message, [CallerMem [Event(ErrorEventId, Level = EventLevel.Error, Keywords = Keywords.Default)] private void ErrorMessage(string thisOrContextObject, string? memberName, string? message) { - Debug.Assert(IsEnabled()); + //Debug.Assert(IsEnabled()); + if (!IsEnabled()) return; WriteEvent(ErrorEventId, thisOrContextObject, memberName ?? MissingMember, message); } #endregion diff --git a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs index 8f89046c0bae57..829d41dae7907a 100644 --- a/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs +++ b/src/libraries/Common/tests/System/Net/Http/Http3LoopbackStream.cs @@ -40,6 +40,7 @@ public Http3LoopbackStream(QuicStream stream, Xunit.Abstractions.ITestOutputHelp { _stream = stream; _output = output; + _output?.WriteLine($"Created stream {stream}, Readable: {stream.CanRead}, Writable: {stream.CanWrite}"); } public ValueTask DisposeAsync() => _stream.DisposeAsync(); @@ -438,9 +439,11 @@ public void Abort(long errorCode) public async Task<(long? frameType, byte[] payload)> ReadFrameAsync() { long? frameType = await ReadIntegerAsync().ConfigureAwait(false); + _output?.WriteLine($"Read frame type: {frameType}"); if (frameType == null) return (null, null); long? payloadLength = await ReadIntegerAsync().ConfigureAwait(false); + _output?.WriteLine($"Read payload length: {payloadLength}"); if (payloadLength == null) throw new Exception("Unable to read frame; unexpected end of stream."); byte[] payload = new byte[checked((int)payloadLength)]; @@ -449,11 +452,13 @@ public void Abort(long errorCode) while (totalBytesRead != payloadLength) { int bytesRead = await _stream.ReadAsync(payload.AsMemory(totalBytesRead)).ConfigureAwait(false); + _output?.WriteLine($"Read {bytesRead} bytes of payload"); if (bytesRead == 0) throw new Exception("Unable to read frame; unexpected end of stream."); totalBytesRead += bytesRead; } + _output?.WriteLine($"Read frame payload: {payload}"); return (frameType, payload); } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index f28b0ae794ad89..875084d95774ce 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -76,7 +76,7 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri [Fact] public Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { - throw new SkipTestException("Can't get any useful info from this"); + return Task.CompletedTask; //TestEventListener? listener = null; //if (UseVersion == HttpVersion30) //{ From 62f65db9a9fb24384db434aa3e76e23487938203 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Tue, 21 May 2024 11:38:57 +0200 Subject: [PATCH 33/46] Http3Connection add trace --- .../SocketsHttpHandler/Http3Connection.cs | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) diff --git a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs index 75b9d9b1f8a964..7fb59c417e279d 100644 --- a/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs +++ b/src/libraries/System.Net.Http/src/System/Net/Http/SocketsHttpHandler/Http3Connection.cs @@ -308,10 +308,20 @@ private void OnServerGoAway(long firstRejectedStreamId) // Stop sending requests to this connection. _pool.InvalidateHttp3Connection(this); + if (NetEventSource.Log.IsEnabled()) + { + Trace($"OnServerGoAway - Just before entering lock zone."); + } + var streamsToGoAway = new List(); lock (SyncObj) { + if (NetEventSource.Log.IsEnabled()) + { + Trace($"OnServerGoAway - After entering lock zone."); + } + if (_firstRejectedStreamId != -1 && firstRejectedStreamId > _firstRejectedStreamId) { // Server can send multiple GOAWAY frames. @@ -334,7 +344,17 @@ private void OnServerGoAway(long firstRejectedStreamId) } } + if (NetEventSource.Log.IsEnabled()) + { + Trace($"OnServerGoAway - Before CheckForShutdown"); + } + CheckForShutdown(); + + if (NetEventSource.Log.IsEnabled()) + { + Trace($"OnServerGoAway - After CheckForShutdown"); + } } // GOAWAY each stream outside of the lock, so they can acquire the lock to remove themselves from _activeRequests. From 7436ee86c98ef81cfd748663ca75d37f0ef2e071 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 22 May 2024 11:23:51 +0200 Subject: [PATCH 34/46] Disable some test so I can repro another --- .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 75880a5de759a9..687b14bf1ef087 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1000,6 +1000,9 @@ await connection.WriteStringAsync( [ActiveIssue("https://github.com/dotnet/runtime/issues/65429", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(bool? chunked, bool enableWasmStreaming, bool slowChunks) { + if (UseVersion == HttpVersion30) + return; + if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) { return; From bda7314857688bd52099241d515754f000d83cc3 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 22 May 2024 14:35:07 +0200 Subject: [PATCH 35/46] Disable AltSvc Tests --- .../HttpClientHandlerTest.AltSvc.cs | 68 +++++++++++-------- 1 file changed, 38 insertions(+), 30 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index 875084d95774ce..f41acb0a920612 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -33,6 +33,10 @@ private HttpClient CreateHttpClient(Version version) [MemberData(nameof(AltSvcHeaderUpgradeVersions))] public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overrideHost) { + if (UseVersion == HttpVersion30) + { + return; + } // The test makes a request to a HTTP/1 or HTTP/2 server first, which supplies an Alt-Svc header pointing to the second server. using GenericLoopbackServer firstServer = fromVersion.Major switch @@ -74,41 +78,45 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri }; [Fact] - public Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() + public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { - return Task.CompletedTask; - //TestEventListener? listener = null; - //if (UseVersion == HttpVersion30) - //{ - // listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); - //} - //_output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); - //using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); - //using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(options: new() { TestOutputHelper = _output }); - //using HttpClient client = CreateHttpClient(HttpVersion.Version20); - - //Task firstResponseTask = client.GetAsync(firstServer.Address); - //Task serverTask = Task.Run(async () => - //{ - // await using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync(); - - // int streamId = await connection.ReadRequestHeaderAsync(); - // await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId: 0)); - // await connection.SendDefaultResponseAsync(streamId); - //}); - - //await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(60_000); // Allow to fail due to hang and QuicException - - //HttpResponseMessage firstResponse = firstResponseTask.Result; - //Assert.True(firstResponse.IsSuccessStatusCode); - - //await AltSvc_Upgrade_Success(firstServer, secondServer, client); - //listener?.Dispose(); + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + } + _output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); + using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); + using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(options: new() { TestOutputHelper = _output }); + using HttpClient client = CreateHttpClient(HttpVersion.Version20); + + Task firstResponseTask = client.GetAsync(firstServer.Address); + Task serverTask = Task.Run(async () => + { + await using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync(); + + int streamId = await connection.ReadRequestHeaderAsync(); + await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId: 0)); + await connection.SendDefaultResponseAsync(streamId); + }); + + await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(60_000); // Allow to fail due to hang and QuicException + + HttpResponseMessage firstResponse = firstResponseTask.Result; + Assert.True(firstResponse.IsSuccessStatusCode); + + await AltSvc_Upgrade_Success(firstServer, secondServer, client); + listener?.Dispose(); } [Fact] public async Task AltSvc_ResponseFrame_UpgradeFrom20_Success() { + if (UseVersion == HttpVersion30) + { + return; + } + using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(); using HttpClient client = CreateHttpClient(HttpVersion.Version20); @@ -137,7 +145,7 @@ private async Task AltSvc_Upgrade_Success(GenericLoopbackServer firstServer, Htt Task secondResponseTask = client.GetAsync(firstServer.Address); Task secondRequestTask = secondServer.AcceptConnectionSendResponseAndCloseAsync(); - await new[] { (Task)secondResponseTask, secondRequestTask }.WhenAllOrAnyFailed(30_000); + await new[] { (Task)secondResponseTask, secondRequestTask }.WhenAllOrAnyFailed(60_000); HttpRequestData secondRequest = secondRequestTask.Result; using HttpResponseMessage secondResponse = secondResponseTask.Result; From a468fb57944c3fca3ce0da21ffd76ab836d84185 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 22 May 2024 16:50:33 +0200 Subject: [PATCH 36/46] Add Miha's trick --- ...entHandlerTest.MaxResponseHeadersLength.cs | 42 +++++++++++++------ .../System/Net/Http/HttpClientHandlerTest.cs | 15 +++++-- .../HttpClientHandlerTest.AltSvc.cs | 13 ++++-- 3 files changed, 49 insertions(+), 21 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 1e5ccd96502d5e..2e40c32b7fb707 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -57,12 +57,20 @@ public void ValidValue_SetGet_Roundtrips(int validValue) [Fact] public async Task SetAfterUse_Throws() { - TestEventListener? listener = null; - if (UseVersion == HttpVersion30) - { - listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); - } - _output.WriteLine("Starting SetAfterUse_Throws test"); + //TestEventListener? listener = null; + //AsyncLocal asyncLocal = new(); + //asyncLocal.Value = new(); + //if (UseVersion == HttpVersion30) + //{ + // listener = new TestEventListener(e => + // { + // if (asyncLocal.Value is not null) + // { + // _output.WriteLine(e); + // } + // }, TestEventListener.NetworkingEvents); + //} + //_output.WriteLine("Starting SetAfterUse_Throws test"); await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { @@ -74,7 +82,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Throws(() => handler.MaxResponseHeadersLength = 1); }, server => server.AcceptConnectionSendResponseAndCloseAsync(), options: new() { TestOutputHelper = _output }); - listener?.Dispose(); + //listener?.Dispose(); } [Theory] @@ -82,11 +90,19 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { - TestEventListener? listener = null; - if (UseVersion == HttpVersion30) - { - listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); - } + //TestEventListener? listener = null; + //AsyncLocal asyncLocal = new(); + //asyncLocal.Value = new(); + //if (UseVersion == HttpVersion30) + //{ + // listener = new TestEventListener(e => + // { + // if (asyncLocal.Value is not null) + // { + // _output.WriteLine(e); + // } + // }, TestEventListener.NetworkingEvents); + //} using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; @@ -115,7 +131,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => #endif }, options: new() { TestOutputHelper = _output }); - listener?.Dispose(); + //listener?.Dispose(); } [Theory] diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 687b14bf1ef087..f5aec2666acef0 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1000,9 +1000,6 @@ await connection.WriteStringAsync( [ActiveIssue("https://github.com/dotnet/runtime/issues/65429", typeof(PlatformDetection), nameof(PlatformDetection.IsNodeJS))] public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(bool? chunked, bool enableWasmStreaming, bool slowChunks) { - if (UseVersion == HttpVersion30) - return; - if (IsWinHttpHandler && UseVersion >= HttpVersion20.Value) { return; @@ -1020,11 +1017,21 @@ public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(boo return; } + AsyncLocal asyncLocal = new(); + asyncLocal.Value = new(); + TestEventListener? listener = null; if (UseVersion == HttpVersion30) { - listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + listener = new TestEventListener(e => + { + if (asyncLocal.Value is not null) + { + _output.WriteLine(e); + } + }, TestEventListener.NetworkingEvents); } + _output.WriteLine("Starting ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream test"); var tcs = new TaskCompletionSource(); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index f41acb0a920612..9d9b014e09983e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -80,12 +80,17 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri [Fact] public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { - TestEventListener? listener = null; if (UseVersion == HttpVersion30) { - listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + return; } - _output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); + + //TestEventListener? listener = null; + //if (UseVersion == HttpVersion30) + //{ + // listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); + //} + //_output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(options: new() { TestOutputHelper = _output }); using HttpClient client = CreateHttpClient(HttpVersion.Version20); @@ -106,7 +111,7 @@ public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() Assert.True(firstResponse.IsSuccessStatusCode); await AltSvc_Upgrade_Success(firstServer, secondServer, client); - listener?.Dispose(); + //listener?.Dispose(); } [Fact] From d7218f3fba575f7cfefb728bf8fe7092f7a3336b Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 22 May 2024 23:02:50 +0200 Subject: [PATCH 37/46] TestEventListener NetworkingEvents revert --- .../tests/TestUtilities/TestEventListener.cs | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs index 1f1d6f79c6cabe..a2b70be5874b54 100644 --- a/src/libraries/Common/tests/TestUtilities/TestEventListener.cs +++ b/src/libraries/Common/tests/TestUtilities/TestEventListener.cs @@ -21,9 +21,22 @@ public sealed class TestEventListener : EventListener { public static string[] NetworkingEvents => new[] { - "Private.InternalDiagnostics.System.Net.Quic", - "Private.InternalDiagnostics.System.Net.Http", "System.Net.Http", + "System.Net.NameResolution", + "System.Net.Sockets", + "System.Net.Security", + "System.Net.TestLogging", + "Private.InternalDiagnostics.System.Net.Http", + "Private.InternalDiagnostics.System.Net.NameResolution", + "Private.InternalDiagnostics.System.Net.Sockets", + "Private.InternalDiagnostics.System.Net.Security", + "Private.InternalDiagnostics.System.Net.Quic", + "Private.InternalDiagnostics.System.Net.Http.WinHttpHandler", + "Private.InternalDiagnostics.System.Net.HttpListener", + "Private.InternalDiagnostics.System.Net.Mail", + "Private.InternalDiagnostics.System.Net.NetworkInformation", + "Private.InternalDiagnostics.System.Net.Primitives", + "Private.InternalDiagnostics.System.Net.Requests" }; private readonly Action _writeFunc; From 4479ccfb9ee2b6337a450f6602f40c74fc08cea1 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 22 May 2024 23:16:49 +0200 Subject: [PATCH 38/46] Add more logging to other tests --- ...entHandlerTest.MaxResponseHeadersLength.cs | 65 ++++++++++--------- .../System/Net/Http/HttpClientHandlerTest.cs | 5 +- .../HttpClientHandlerTest.AltSvc.cs | 46 +++++++++---- 3 files changed, 73 insertions(+), 43 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs index 2e40c32b7fb707..1dec0141427de7 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.MaxResponseHeadersLength.cs @@ -57,20 +57,23 @@ public void ValidValue_SetGet_Roundtrips(int validValue) [Fact] public async Task SetAfterUse_Throws() { - //TestEventListener? listener = null; - //AsyncLocal asyncLocal = new(); - //asyncLocal.Value = new(); - //if (UseVersion == HttpVersion30) - //{ - // listener = new TestEventListener(e => - // { - // if (asyncLocal.Value is not null) - // { - // _output.WriteLine(e); - // } - // }, TestEventListener.NetworkingEvents); - //} - //_output.WriteLine("Starting SetAfterUse_Throws test"); + AsyncLocal asyncLocal = new(); + asyncLocal.Value = new(); + + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(e => + { + if (asyncLocal.Value is not null) + { + lock (_output) + { + _output.WriteLine($"[SetAfterUse]{e}"); + } + } + }, TestEventListener.NetworkingEvents); + } await LoopbackServerFactory.CreateClientAndServerAsync(async uri => { @@ -82,7 +85,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => Assert.Throws(() => handler.MaxResponseHeadersLength = 1); }, server => server.AcceptConnectionSendResponseAndCloseAsync(), options: new() { TestOutputHelper = _output }); - //listener?.Dispose(); + listener?.Dispose(); } [Theory] @@ -90,19 +93,23 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => [InlineData(15)] public async Task LargeSingleHeader_ThrowsException(int maxResponseHeadersLength) { - //TestEventListener? listener = null; - //AsyncLocal asyncLocal = new(); - //asyncLocal.Value = new(); - //if (UseVersion == HttpVersion30) - //{ - // listener = new TestEventListener(e => - // { - // if (asyncLocal.Value is not null) - // { - // _output.WriteLine(e); - // } - // }, TestEventListener.NetworkingEvents); - //} + AsyncLocal asyncLocal = new(); + asyncLocal.Value = new(); + + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(e => + { + if (asyncLocal.Value is not null) + { + lock (_output) + { + _output.WriteLine($"[LargeSingleHeader_ThrowsException]{e}"); + } + } + }, TestEventListener.NetworkingEvents); + } using HttpClientHandler handler = CreateHttpClientHandler(); handler.MaxResponseHeadersLength = maxResponseHeadersLength; @@ -131,7 +138,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => #endif }, options: new() { TestOutputHelper = _output }); - //listener?.Dispose(); + listener?.Dispose(); } [Theory] diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index f5aec2666acef0..4410be3e788187 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1027,7 +1027,10 @@ public async Task ReadAsStreamAsync_HandlerProducesWellBehavedResponseStream(boo { if (asyncLocal.Value is not null) { - _output.WriteLine(e); + lock (_output) + { + _output.WriteLine($"[ReadAsStreamAsync]{e}"); + } } }, TestEventListener.NetworkingEvents); } diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index 9d9b014e09983e..7d0431356acd02 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -9,6 +9,7 @@ using System.Net.Quic; using TestUtilities; using Microsoft.DotNet.XUnitExtensions; +using System.Threading; namespace System.Net.Http.Functional.Tests { @@ -33,9 +34,22 @@ private HttpClient CreateHttpClient(Version version) [MemberData(nameof(AltSvcHeaderUpgradeVersions))] public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overrideHost) { + AsyncLocal asyncLocal = new(); + asyncLocal.Value = new(); + + TestEventListener? listener = null; if (UseVersion == HttpVersion30) { - return; + listener = new TestEventListener(e => + { + if (asyncLocal.Value is not null) + { + lock (_output) + { + _output.WriteLine($"[AltSvc_Header_Upgrade_Success]{e}"); + } + } + }, TestEventListener.NetworkingEvents); } // The test makes a request to a HTTP/1 or HTTP/2 server first, which supplies an Alt-Svc header pointing to the second server. using GenericLoopbackServer firstServer = @@ -85,12 +99,23 @@ public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() return; } - //TestEventListener? listener = null; - //if (UseVersion == HttpVersion30) - //{ - // listener = new TestEventListener(_output, TestEventListener.NetworkingEvents); - //} - //_output.WriteLine("Starting AltSvc_ConnectionFrame_UpgradeFrom20_Success test"); + AsyncLocal asyncLocal = new(); + asyncLocal.Value = new(); + + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(e => + { + if (asyncLocal.Value is not null) + { + lock (_output) + { + _output.WriteLine($"[AltSvc_ConnectionFrame_UpgradeFrom20_Success]{e}"); + } + } + }, TestEventListener.NetworkingEvents); + } using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(options: new() { TestOutputHelper = _output }); using HttpClient client = CreateHttpClient(HttpVersion.Version20); @@ -111,17 +136,12 @@ public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() Assert.True(firstResponse.IsSuccessStatusCode); await AltSvc_Upgrade_Success(firstServer, secondServer, client); - //listener?.Dispose(); + listener?.Dispose(); } [Fact] public async Task AltSvc_ResponseFrame_UpgradeFrom20_Success() { - if (UseVersion == HttpVersion30) - { - return; - } - using Http2LoopbackServer firstServer = Http2LoopbackServer.CreateServer(); using Http3LoopbackServer secondServer = CreateHttp3LoopbackServer(); using HttpClient client = CreateHttpClient(HttpVersion.Version20); From 89f61024285dd85cb3c743780667a6813b6e84e0 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Wed, 22 May 2024 23:18:06 +0200 Subject: [PATCH 39/46] Call Dispose --- .../tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index 7d0431356acd02..6e7407f33bd49e 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -80,6 +80,7 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri Assert.True(firstResponse.IsSuccessStatusCode); await AltSvc_Upgrade_Success(firstServer, secondServer, client); + listener?.Dispose(); } public static TheoryData AltSvcHeaderUpgradeVersions => From 1e54a46fd3a85c9529d6c5d29df3399ea57e4b27 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 24 May 2024 16:25:39 +0200 Subject: [PATCH 40/46] Convert to fail --- .../System.Net.Quic/src/System/Net/Quic/QuicConnection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index b143290cdad91d..ac447ff30845af 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -559,7 +559,7 @@ private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATE { if (NetEventSource.Log.IsEnabled() && data.Status == QUIC_STATUS_CONNECTION_IDLE && data.ErrorCode == 1) // Idle { - NetEventSource.Info(this, $"{this} Connection idle."); + Environment.FailFast($"{LocalEndPoint}"); } Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetExceptionForMsQuicStatus(data.Status, (long)data.ErrorCode)); From 61725c6cd258fbe86926302bae55da6871ffa6f1 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 24 May 2024 16:26:06 +0200 Subject: [PATCH 41/46] Delete errorCode --- .../System.Net.Quic/src/System/Net/Quic/QuicConnection.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index ac447ff30845af..81f16733b93f4b 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -557,7 +557,7 @@ private unsafe int HandleEventConnected(ref CONNECTED_DATA data) } private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATED_BY_TRANSPORT_DATA data) { - if (NetEventSource.Log.IsEnabled() && data.Status == QUIC_STATUS_CONNECTION_IDLE && data.ErrorCode == 1) // Idle + if (NetEventSource.Log.IsEnabled() && data.Status == QUIC_STATUS_CONNECTION_IDLE) // Idle { Environment.FailFast($"{LocalEndPoint}"); } From a31d22488691db35675b7ed58192a1368af827c5 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Fri, 24 May 2024 19:17:47 +0200 Subject: [PATCH 42/46] Add ConfigureAwait(false) and convert fail to log --- .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 2 +- .../System.Net.Quic/src/System/Net/Quic/QuicConnection.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 4410be3e788187..f50644221ae55a 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1052,7 +1052,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => } using (var client = new HttpMessageInvoker(CreateHttpClientHandler())) - using (HttpResponseMessage response = await client.SendAsync(TestAsync, request, CancellationToken.None)) + using (HttpResponseMessage response = await client.SendAsync(TestAsync, request, CancellationToken.None).ConfigureAwait(false)) { using (Stream responseStream = await response.Content.ReadAsStreamAsync(TestAsync)) { diff --git a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs index 81f16733b93f4b..b471f73bcaf747 100644 --- a/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs +++ b/src/libraries/System.Net.Quic/src/System/Net/Quic/QuicConnection.cs @@ -559,7 +559,7 @@ private unsafe int HandleEventShutdownInitiatedByTransport(ref SHUTDOWN_INITIATE { if (NetEventSource.Log.IsEnabled() && data.Status == QUIC_STATUS_CONNECTION_IDLE) // Idle { - Environment.FailFast($"{LocalEndPoint}"); + NetEventSource.Info($"{this} Connection Idle: {LocalEndPoint} - {RemoteEndPoint}"); } Exception exception = ExceptionDispatchInfo.SetCurrentStackTrace(ThrowHelper.GetExceptionForMsQuicStatus(data.Status, (long)data.ErrorCode)); From 2f0cce2d50669c842c10aa8bd72d80f72b2ace40 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 25 May 2024 09:01:33 +0200 Subject: [PATCH 43/46] Add more ConfigureAwait and a bit logs --- .../System/Net/Http/HttpClientHandlerTest.cs | 8 +++++-- .../HttpClientHandlerTest.AltSvc.cs | 23 ++++++++----------- 2 files changed, 15 insertions(+), 16 deletions(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index f50644221ae55a..872324cd939282 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1051,9 +1051,13 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => } } - using (var client = new HttpMessageInvoker(CreateHttpClientHandler())) - using (HttpResponseMessage response = await client.SendAsync(TestAsync, request, CancellationToken.None).ConfigureAwait(false)) + using var client = new HttpMessageInvoker(CreateHttpClientHandler()); + _output.WriteLine("[ReadAsStreamAsync] Before SendAsync on test code"); + Task responseTask = client.SendAsync(TestAsync, request, CancellationToken.None); + _output.WriteLine("[ReadAsStreamAsync] After SendAsync on test code"); + using (HttpResponseMessage response = await responseTask) { + _output.WriteLine("[ReadAsStreamAsync] After await of responseTask on test code"); using (Stream responseStream = await response.Content.ReadAsStreamAsync(TestAsync)) { Assert.Same(responseStream, await response.Content.ReadAsStreamAsync(TestAsync)); diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index 6e7407f33bd49e..7aa18b5f229995 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -74,12 +74,12 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri new HttpHeaderData("Alt-Svc", $"h3=\"{(overrideHost ? secondServer.Address.IdnHost : null)}:{secondServer.Address.Port}\"") }); - await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000); + await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000).ConfigureAwait(false); using HttpResponseMessage firstResponse = firstResponseTask.Result; Assert.True(firstResponse.IsSuccessStatusCode); - await AltSvc_Upgrade_Success(firstServer, secondServer, client); + await AltSvc_Upgrade_Success(firstServer, secondServer, client).ConfigureAwait(false); listener?.Dispose(); } @@ -95,11 +95,6 @@ public async Task AltSvc_Header_Upgrade_Success(Version fromVersion, bool overri [Fact] public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() { - if (UseVersion == HttpVersion30) - { - return; - } - AsyncLocal asyncLocal = new(); asyncLocal.Value = new(); @@ -124,19 +119,19 @@ public async Task AltSvc_ConnectionFrame_UpgradeFrom20_Success() Task firstResponseTask = client.GetAsync(firstServer.Address); Task serverTask = Task.Run(async () => { - await using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync(); + await using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync().ConfigureAwait(false); - int streamId = await connection.ReadRequestHeaderAsync(); - await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId: 0)); - await connection.SendDefaultResponseAsync(streamId); + int streamId = await connection.ReadRequestHeaderAsync().ConfigureAwait(false); + await connection.WriteFrameAsync(new AltSvcFrame($"https://{firstServer.Address.IdnHost}:{firstServer.Address.Port}", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId: 0)).ConfigureAwait(false); + await connection.SendDefaultResponseAsync(streamId).ConfigureAwait(false); }); - await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(60_000); // Allow to fail due to hang and QuicException + await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(60_000).ConfigureAwait(false); // Allow to fail due to hang and QuicException HttpResponseMessage firstResponse = firstResponseTask.Result; Assert.True(firstResponse.IsSuccessStatusCode); - await AltSvc_Upgrade_Success(firstServer, secondServer, client); + await AltSvc_Upgrade_Success(firstServer, secondServer, client).ConfigureAwait(false); listener?.Dispose(); } @@ -171,7 +166,7 @@ private async Task AltSvc_Upgrade_Success(GenericLoopbackServer firstServer, Htt Task secondResponseTask = client.GetAsync(firstServer.Address); Task secondRequestTask = secondServer.AcceptConnectionSendResponseAndCloseAsync(); - await new[] { (Task)secondResponseTask, secondRequestTask }.WhenAllOrAnyFailed(60_000); + await new[] { (Task)secondResponseTask, secondRequestTask }.WhenAllOrAnyFailed(60_000).ConfigureAwait(false); HttpRequestData secondRequest = secondRequestTask.Result; using HttpResponseMessage secondResponse = secondResponseTask.Result; From 2d37bb07633c53e36249b5d2c9e306d1e1cb520f Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 25 May 2024 10:43:19 +0200 Subject: [PATCH 44/46] Add ConfigureAwait(false) again --- .../Common/tests/System/Net/Http/HttpClientHandlerTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs index 872324cd939282..a8c6460c46c520 100644 --- a/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs +++ b/src/libraries/Common/tests/System/Net/Http/HttpClientHandlerTest.cs @@ -1055,7 +1055,7 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async uri => _output.WriteLine("[ReadAsStreamAsync] Before SendAsync on test code"); Task responseTask = client.SendAsync(TestAsync, request, CancellationToken.None); _output.WriteLine("[ReadAsStreamAsync] After SendAsync on test code"); - using (HttpResponseMessage response = await responseTask) + using (HttpResponseMessage response = await responseTask.ConfigureAwait(false)) { _output.WriteLine("[ReadAsStreamAsync] After await of responseTask on test code"); using (Stream responseStream = await response.Content.ReadAsStreamAsync(TestAsync)) From a770b2acc6dd6e4ec10cdb0f15ed279ab88c7b66 Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 25 May 2024 13:44:49 +0200 Subject: [PATCH 45/46] Add more ConfigureAwait(false) to see if it actually fixes --- .../HttpClientHandlerTest.AltSvc.cs | 14 +++++++------- .../HttpClientHandlerTest.Finalization.cs | 12 ++++++------ 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index 7aa18b5f229995..0ac76137626b96 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -145,20 +145,20 @@ public async Task AltSvc_ResponseFrame_UpgradeFrom20_Success() Task firstResponseTask = client.GetAsync(firstServer.Address); Task serverTask = Task.Run(async () => { - await using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync(); + await using Http2LoopbackConnection connection = await firstServer.EstablishConnectionAsync().ConfigureAwait(false); - int streamId = await connection.ReadRequestHeaderAsync(); - await connection.SendDefaultResponseHeadersAsync(streamId); - await connection.WriteFrameAsync(new AltSvcFrame("", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId)); - await connection.SendResponseDataAsync(streamId, Array.Empty(), true); + int streamId = await connection.ReadRequestHeaderAsync().ConfigureAwait(false); + await connection.SendDefaultResponseHeadersAsync(streamId).ConfigureAwait(false); + await connection.WriteFrameAsync(new AltSvcFrame("", $"h3=\"{secondServer.Address.IdnHost}:{secondServer.Address.Port}\"", streamId)).ConfigureAwait(false); + await connection.SendResponseDataAsync(streamId, Array.Empty(), true).ConfigureAwait(false); }); - await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(30_000); + await new[] { firstResponseTask, serverTask }.WhenAllOrAnyFailed(60_000).ConfigureAwait(false); HttpResponseMessage firstResponse = firstResponseTask.Result; Assert.True(firstResponse.IsSuccessStatusCode); - await AltSvc_Upgrade_Success(firstServer, secondServer, client); + await AltSvc_Upgrade_Success(firstServer, secondServer, client).ConfigureAwait(false); } private async Task AltSvc_Upgrade_Success(GenericLoopbackServer firstServer, Http3LoopbackServer secondServer, HttpClient client) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Finalization.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Finalization.cs index 49989acffb36cf..634ca89f327084 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Finalization.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.Finalization.cs @@ -21,7 +21,7 @@ private static Task GetAndDropResponse(HttpClient client, Uri url) return Task.Run(async () => { // Get the response stream, but don't dispose it or return it. Just drop it. - await client.GetStreamAsync(url); + _ = await client.GetStreamAsync(url).ConfigureAwait(false); }); } @@ -33,7 +33,7 @@ public async Task IncompleteResponseStream_ResponseDropped_CancelsRequestToServe bool stopGCs = false; await LoopbackServerFactory.CreateClientAndServerAsync(async url => { - await GetAndDropResponse(client, url); + await GetAndDropResponse(client, url).ConfigureAwait(false); while (!Volatile.Read(ref stopGCs)) { @@ -46,15 +46,15 @@ await LoopbackServerFactory.CreateClientAndServerAsync(async url => { try { - HttpRequestData data = await connection.ReadRequestDataAsync(readBody: false); - await connection.SendResponseHeadersAsync(headers: new HttpHeaderData[] { new HttpHeaderData("SomeHeaderName", "AndValue") }); - await connection.WaitForCancellationAsync(); + HttpRequestData data = await connection.ReadRequestDataAsync(readBody: false).ConfigureAwait(false); + await connection.SendResponseHeadersAsync(headers: new HttpHeaderData[] { new HttpHeaderData("SomeHeaderName", "AndValue") }).ConfigureAwait(false); + await connection.WaitForCancellationAsync().ConfigureAwait(false); } finally { Volatile.Write(ref stopGCs, true); } - })); + })).ConfigureAwait(false); } } } From 3b5a39d1b6304c3b196cc809d4f7274912b564bb Mon Sep 17 00:00:00 2001 From: Ahmet Ibrahim Aksoy Date: Sat, 25 May 2024 15:42:35 +0200 Subject: [PATCH 46/46] Add logging to helper function --- .../HttpClientHandlerTest.AltSvc.cs | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs index 0ac76137626b96..cd0b3461780174 100644 --- a/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs +++ b/src/libraries/System.Net.Http/tests/FunctionalTests/HttpClientHandlerTest.AltSvc.cs @@ -163,6 +163,23 @@ public async Task AltSvc_ResponseFrame_UpgradeFrom20_Success() private async Task AltSvc_Upgrade_Success(GenericLoopbackServer firstServer, Http3LoopbackServer secondServer, HttpClient client) { + AsyncLocal asyncLocal = new(); + asyncLocal.Value = new(); + + TestEventListener? listener = null; + if (UseVersion == HttpVersion30) + { + listener = new TestEventListener(e => + { + if (asyncLocal.Value is not null) + { + lock (_output) + { + _output.WriteLine($"[AltSvc_Upgrade_Success]{e}"); + } + } + }, TestEventListener.NetworkingEvents); + } Task secondResponseTask = client.GetAsync(firstServer.Address); Task secondRequestTask = secondServer.AcceptConnectionSendResponseAndCloseAsync(); @@ -174,6 +191,7 @@ private async Task AltSvc_Upgrade_Success(GenericLoopbackServer firstServer, Htt string altUsed = secondRequest.GetSingleHeaderValue("Alt-Used"); Assert.Equal($"{secondServer.Address.IdnHost}:{secondServer.Address.Port}", altUsed); Assert.True(secondResponse.IsSuccessStatusCode); + listener?.Dispose(); } } }