diff --git a/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs b/src/libraries/System.Net.Http/tests/FunctionalTests/SocketsHttpHandlerTest.cs index 96a45d49fe5b5..d2e1b54dcafa8 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 d5962dfba4d09..e97e4baaf8208 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 28c326b7b65fb..829c279969c2e 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 41ac5e41da24d..b2042adffe33b 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 5125c72e0ca8d..f8dd160acb00b 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;