[HttpClientFactory] Add tests for all simple SocketsHttpHandler properties (#89202)
authorNatalia Kondratyeva <knatalia@microsoft.com>
Thu, 27 Jul 2023 14:51:43 +0000 (15:51 +0100)
committerGitHub <noreply@github.com>
Thu, 27 Jul 2023 14:51:43 +0000 (16:51 +0200)
* Add tests for all simple SocketsHttpHandler properties

* Fix typo

src/libraries/Microsoft.Extensions.Http/src/DependencyInjection/SocketsHttpHandlerBuilderExtensions.cs
src/libraries/Microsoft.Extensions.Http/tests/Microsoft.Extensions.Http.Tests/SocketsHttpHandlerConfigurationTest.cs

index d7635d3..0d56606 100644 (file)
@@ -66,7 +66,7 @@ namespace Microsoft.Extensions.DependencyInjection
         }
 
         [UnsupportedOSPlatform("browser")]
-        private static void FillFromConfig(SocketsHttpHandler handler, SocketsHttpHandlerConfiguration config)
+        private static void FillFromConfig(SocketsHttpHandler handler, in SocketsHttpHandlerConfiguration config)
         {
             if (config.PooledConnectionIdleTimeout is not null)
             {
index acc1810..4473917 100644 (file)
@@ -4,6 +4,7 @@
 #if NET5_0_OR_GREATER
 using System;
 using System.Collections.Generic;
+using System.Net;
 using System.Net.Http;
 using System.Net.Security;
 using System.Threading;
@@ -119,6 +120,78 @@ namespace Microsoft.Extensions.Http
             Assert.Equal(TimeSpan.FromMinutes(1), configuredHandler.PooledConnectionLifetime);
         }
 
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
+        [InlineData(nameof(SocketsHttpHandler.InitialHttp2StreamWindowSize), 16777216, "16777216")] // default value: 65535
+        [InlineData(nameof(SocketsHttpHandler.MaxAutomaticRedirections), 3, "3")] // default value: 50
+        [InlineData(nameof(SocketsHttpHandler.MaxConnectionsPerServer), 1, "1")] // default value: int.MaxValue
+        [InlineData(nameof(SocketsHttpHandler.MaxResponseDrainSize), 10240, "10240")] // default value: 1024 * 1024
+        [InlineData(nameof(SocketsHttpHandler.MaxResponseHeadersLength), 32, "32")] // default value: 64 (K)
+        public void UseSocketsHttpHandler_ConfiguredByIConfiguration_AllIntProperties(string propertyName, int expectedValue, string configValue)
+        {
+            TestPropertyIsConfigured(propertyName, expectedValue, configValue);
+        }
+
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
+        [InlineData(nameof(SocketsHttpHandler.AllowAutoRedirect), false, "false")] // default value: true
+        [InlineData(nameof(SocketsHttpHandler.EnableMultipleHttp2Connections), true, "true")] // default value: false
+        [InlineData(nameof(SocketsHttpHandler.PreAuthenticate), true, "true")] // default value: false
+        [InlineData(nameof(SocketsHttpHandler.UseCookies), false, "false")] // default value: true
+        [InlineData(nameof(SocketsHttpHandler.UseProxy), false, "false")] // default value: true
+        public void UseSocketsHttpHandler_ConfiguredByIConfiguration_AllBoolProperties(string propertyName, bool expectedValue, string configValue)
+        {
+            TestPropertyIsConfigured(propertyName, expectedValue, configValue);
+        }
+
+        [ConditionalTheory(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
+        [InlineData(nameof(SocketsHttpHandler.PooledConnectionIdleTimeout))] // default value: 1m
+        [InlineData(nameof(SocketsHttpHandler.PooledConnectionLifetime))] // default value: -1
+        [InlineData(nameof(SocketsHttpHandler.ResponseDrainTimeout))] // default value: 2s
+        [InlineData(nameof(SocketsHttpHandler.ConnectTimeout))] // default value: -1
+        [InlineData(nameof(SocketsHttpHandler.Expect100ContinueTimeout))] // default value: 1s
+        [InlineData(nameof(SocketsHttpHandler.KeepAlivePingDelay))] // default value: -1
+        [InlineData(nameof(SocketsHttpHandler.KeepAlivePingTimeout))] // default value: 20s
+        public void UseSocketsHttpHandler_ConfiguredByIConfiguration_AllTimeSpanProperties(string propertyName)
+        {
+            TestPropertyIsConfigured(propertyName, TimeSpan.FromSeconds(30), "00:00:30");
+        }
+
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
+        public void UseSocketsHttpHandler_ConfiguredByIConfiguration_AutomaticDecompression() // default value: None
+        {
+            TestPropertyIsConfigured(nameof(SocketsHttpHandler.AutomaticDecompression), DecompressionMethods.GZip, "gzip"); // should be case-insensitive
+        }
+
+        [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
+        public void UseSocketsHttpHandler_ConfiguredByIConfiguration_KeepAlivePingPolicy() // default value: Always
+        {
+            TestPropertyIsConfigured(nameof(SocketsHttpHandler.KeepAlivePingPolicy), HttpKeepAlivePingPolicy.WithActiveRequests, "WithActiveRequests");
+        }
+
+        private static void TestPropertyIsConfigured<T>(string propertyName, T expectedValue, string configValue)
+        {
+            var property = typeof(SocketsHttpHandler).GetProperty(propertyName);
+            Assert.NotNull(property);
+            Func<SocketsHttpHandler, T> propertyGetter = h => (T)property.GetValue(h);
+
+            IConfiguration config = new ConfigurationBuilder()
+                .AddInMemoryCollection(new Dictionary<string, string>{{ $"test:{propertyName}", configValue }})
+                .Build();
+
+            var serviceCollection = new ServiceCollection();
+
+            serviceCollection.AddHttpClient("TestPropertyIsConfigured")
+                .UseSocketsHttpHandler(builder =>
+                    builder.Configure(config.GetSection("test")));
+
+            var services = serviceCollection.BuildServiceProvider();
+            var messageHandlerFactory = services.GetRequiredService<IHttpMessageHandlerFactory>();
+
+            var configuredHandlerChain = messageHandlerFactory.CreateHandler("TestPropertyIsConfigured");
+            var configuredHandler = (SocketsHttpHandler)GetPrimaryHandler(configuredHandlerChain);
+
+            Assert.Equal(expectedValue, propertyGetter(configuredHandler));
+        }
+
         [ConditionalFact(typeof(PlatformDetection), nameof(PlatformDetection.IsNotBrowser))]
         public void UseSocketsHttpHandler_ChainingActionAfterIConfiguration_Updates()
         {
@@ -234,7 +307,7 @@ namespace Microsoft.Extensions.Http
             Assert.Equal(allowAllCertsSslOptions, configuredHandler.SslOptions); // from second config
         }
 
-        private HttpMessageHandler GetPrimaryHandler(HttpMessageHandler handlerChain)
+        private static HttpMessageHandler GetPrimaryHandler(HttpMessageHandler handlerChain)
         {
             var handler = handlerChain;
             while (handler is DelegatingHandler delegatingHandler)