WebHostFunctionalTests.cs 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. // Licensed to the .NET Foundation under one or more agreements.
  2. // The .NET Foundation licenses this file to you under the MIT license.
  3. using System;
  4. using System.Collections.Generic;
  5. using System.IO;
  6. using System.Net.Http;
  7. using System.Threading.Tasks;
  8. using Microsoft.AspNetCore.Http;
  9. using Microsoft.AspNetCore.Server.IntegrationTesting;
  10. using Microsoft.AspNetCore.Testing;
  11. using Microsoft.Extensions.Logging;
  12. using Microsoft.Extensions.Logging.Testing;
  13. using Xunit;
  14. using Xunit.Sdk;
  15. namespace Microsoft.AspNetCore.Tests;
  16. public class WebHostFunctionalTests : LoggedTest
  17. {
  18. [Fact]
  19. public async Task Start_RequestDelegate_Url()
  20. {
  21. await ExecuteStartOrStartWithTest(deploymentResult => deploymentResult.HttpClient.GetAsync(string.Empty), "StartRequestDelegateUrlApp");
  22. }
  23. [Fact]
  24. public async Task Start_RouteBuilder_Url()
  25. {
  26. await ExecuteStartOrStartWithTest(deploymentResult => deploymentResult.HttpClient.GetAsync("/route"), "StartRouteBuilderUrlApp");
  27. }
  28. [Fact]
  29. public async Task StartWith_IApplicationBuilder_Url()
  30. {
  31. await ExecuteStartOrStartWithTest(deploymentResult => deploymentResult.HttpClient.GetAsync(string.Empty), "StartWithIApplicationBuilderUrlApp");
  32. }
  33. [Fact]
  34. public async Task CreateDefaultBuilder_InitializeWithDefaults()
  35. {
  36. var applicationName = "CreateDefaultBuilderApp";
  37. await ExecuteTestApp(applicationName, async (deploymentResult, logger) =>
  38. {
  39. var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), logger, deploymentResult.HostShutdownToken, retryCount: 5);
  40. var responseText = await response.Content.ReadAsStringAsync();
  41. try
  42. {
  43. // Assert server is Kestrel
  44. Assert.Equal("Kestrel", response.Headers.Server.ToString());
  45. // The application name will be sent in response when all asserts succeed in the test app.
  46. Assert.Equal(applicationName, responseText);
  47. }
  48. catch (XunitException)
  49. {
  50. logger.LogWarning(response.ToString());
  51. logger.LogWarning(responseText);
  52. throw;
  53. }
  54. }, setTestEnvVars: true);
  55. }
  56. [Fact]
  57. public async Task CreateDefaultBuilderOfT_InitializeWithDefaults()
  58. {
  59. var applicationName = "CreateDefaultBuilderOfTApp";
  60. await ExecuteTestApp(applicationName, async (deploymentResult, logger) =>
  61. {
  62. var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), logger, deploymentResult.HostShutdownToken, retryCount: 5);
  63. var responseText = await response.Content.ReadAsStringAsync();
  64. try
  65. {
  66. // Assert server is Kestrel
  67. Assert.Equal("Kestrel", response.Headers.Server.ToString());
  68. // The application name will be sent in response when all asserts succeed in the test app.
  69. Assert.Equal(applicationName, responseText);
  70. }
  71. catch (XunitException)
  72. {
  73. logger.LogWarning(response.ToString());
  74. logger.LogWarning(responseText);
  75. throw;
  76. }
  77. }, setTestEnvVars: true);
  78. }
  79. [Theory]
  80. [InlineData("Development", "InvalidOperationException: Cannot consume scoped service")]
  81. [InlineData("Production", "Success")]
  82. public async Task CreateDefaultBuilder_InitializesDependencyInjectionSettingsBasedOnEnv(string environment, string expected)
  83. {
  84. var applicationName = "DependencyInjectionApp";
  85. await ExecuteTestApp(applicationName, async (deploymentResult, logger) =>
  86. {
  87. var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), logger, deploymentResult.HostShutdownToken);
  88. var responseText = await response.Content.ReadAsStringAsync();
  89. try
  90. {
  91. // Assert UseDeveloperExceptionPage is called in WebHostStartupFilter.
  92. Assert.Contains(expected, responseText);
  93. }
  94. catch (XunitException)
  95. {
  96. logger.LogWarning(response.ToString());
  97. logger.LogWarning(responseText);
  98. throw;
  99. }
  100. }, setTestEnvVars: true, environment: environment);
  101. }
  102. [Fact]
  103. [QuarantinedTest("https://github.com/dotnet/aspnetcore/issues/36079")]
  104. public void LoggingConfigurationSectionPassedToLoggerByDefault()
  105. {
  106. try
  107. {
  108. File.WriteAllText("appsettings.json", @"
  109. {
  110. ""Logging"": {
  111. ""LogLevel"": {
  112. ""Default"": ""Warning""
  113. }
  114. }
  115. }
  116. ");
  117. using (var webHost = WebHost.Start("http://127.0.0.1:0", context => context.Response.WriteAsync("Hello, World!")))
  118. {
  119. var factory = (ILoggerFactory)webHost.Services.GetService(typeof(ILoggerFactory));
  120. var logger = factory.CreateLogger("Test");
  121. logger.Log(LogLevel.Information, 0, "Message", null, (s, e) =>
  122. {
  123. Assert.True(false);
  124. return string.Empty;
  125. });
  126. var logWritten = false;
  127. logger.Log(LogLevel.Warning, 0, "Message", null, (s, e) =>
  128. {
  129. logWritten = true;
  130. return string.Empty;
  131. });
  132. Assert.True(logWritten);
  133. }
  134. }
  135. finally
  136. {
  137. File.Delete("appsettings.json");
  138. }
  139. }
  140. [ConditionalFact]
  141. [OSSkipCondition(OperatingSystems.Linux | OperatingSystems.MacOSX)]
  142. public async Task RunsInIISExpressInProcess()
  143. {
  144. var applicationName = "CreateDefaultBuilderApp";
  145. var deploymentParameters = new DeploymentParameters(Path.Combine(GetTestSitesPath(), applicationName), ServerType.IISExpress, RuntimeFlavor.CoreClr, RuntimeArchitecture.x64)
  146. {
  147. TargetFramework = "net7.0",
  148. HostingModel = HostingModel.InProcess
  149. };
  150. SetEnvironmentVariables(deploymentParameters, "Development");
  151. using (var deployer = IISApplicationDeployerFactory.Create(deploymentParameters, LoggerFactory))
  152. {
  153. var deploymentResult = await deployer.DeployAsync();
  154. var response = await RetryHelper.RetryRequest(() => deploymentResult.HttpClient.GetAsync(string.Empty), Logger, deploymentResult.HostShutdownToken, retryCount: 5);
  155. var responseText = await response.Content.ReadAsStringAsync();
  156. try
  157. {
  158. // Assert server is IISExpress
  159. Assert.Equal("Microsoft-IIS/10.0", response.Headers.Server.ToString());
  160. // The application name will be sent in response when all asserts succeed in the test app.
  161. Assert.Equal(applicationName, responseText);
  162. }
  163. catch (XunitException)
  164. {
  165. Logger.LogWarning(response.ToString());
  166. Logger.LogWarning(responseText);
  167. throw;
  168. }
  169. }
  170. }
  171. private async Task ExecuteStartOrStartWithTest(Func<DeploymentResult, Task<HttpResponseMessage>> getResponse, string applicationName)
  172. {
  173. await ExecuteTestApp(applicationName, async (deploymentResult, logger) =>
  174. {
  175. var response = await RetryHelper.RetryRequest(() => getResponse(deploymentResult), logger, deploymentResult.HostShutdownToken);
  176. var responseText = await response.Content.ReadAsStringAsync();
  177. try
  178. {
  179. Assert.Equal(applicationName, responseText);
  180. }
  181. catch (XunitException)
  182. {
  183. logger.LogWarning(response.ToString());
  184. logger.LogWarning(responseText);
  185. throw;
  186. }
  187. });
  188. }
  189. private async Task ExecuteTestApp(string applicationName,
  190. Func<DeploymentResult, ILogger, Task> assertAction,
  191. bool setTestEnvVars = false,
  192. string environment = "Development")
  193. {
  194. var deploymentParameters = new DeploymentParameters(Path.Combine(GetTestSitesPath(), applicationName), ServerType.Kestrel, RuntimeFlavor.CoreClr, RuntimeArchitectures.Current)
  195. {
  196. TargetFramework = "net7.0",
  197. };
  198. if (setTestEnvVars)
  199. {
  200. SetEnvironmentVariables(deploymentParameters, environment);
  201. }
  202. using (var deployer = IISApplicationDeployerFactory.Create(deploymentParameters, LoggerFactory))
  203. {
  204. var deploymentResult = await deployer.DeployAsync();
  205. await assertAction(deploymentResult, Logger);
  206. }
  207. }
  208. private static void SetEnvironmentVariables(DeploymentParameters deploymentParameters, string environment)
  209. {
  210. deploymentParameters.EnvironmentVariables.Add(new KeyValuePair<string, string>("aspnetcore_environment", environment));
  211. deploymentParameters.EnvironmentVariables.Add(new KeyValuePair<string, string>("envKey", "envValue"));
  212. }
  213. private static string GetTestSitesPath()
  214. {
  215. var applicationBasePath = AppContext.BaseDirectory;
  216. var directoryInfo = new DirectoryInfo(applicationBasePath);
  217. do
  218. {
  219. var solutionFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, "DefaultBuilder.slnf"));
  220. if (solutionFileInfo.Exists)
  221. {
  222. return Path.GetFullPath(Path.Combine(directoryInfo.FullName, "testassets"));
  223. }
  224. directoryInfo = directoryInfo.Parent;
  225. }
  226. while (directoryInfo.Parent != null);
  227. throw new Exception($"Solution root could not be found using {applicationBasePath}");
  228. }
  229. }