Merge pull request #1417 from dotnet-maestro-bot/merge/release/2.2-to-master
[automated] Merge branch 'release/2.2' => 'master'
This commit is contained in:
commit
ca0b9ee512
|
|
@ -357,10 +357,27 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting.IIS
|
||||||
throw new InvalidOperationException("Site not stopped yet");
|
throw new InvalidOperationException("Site not stopped yet");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (appPool.WorkerProcesses != null && appPool.WorkerProcesses.Any(wp => wp.State == WorkerProcessState.Running ||
|
try
|
||||||
wp.State == WorkerProcessState.Stopping))
|
|
||||||
{
|
{
|
||||||
throw new InvalidOperationException("WorkerProcess not stopped yet");
|
if (appPool.WorkerProcesses != null &&
|
||||||
|
appPool.WorkerProcesses.Any(wp =>
|
||||||
|
wp.State == WorkerProcessState.Running ||
|
||||||
|
wp.State == WorkerProcessState.Stopping))
|
||||||
|
{
|
||||||
|
throw new InvalidOperationException("WorkerProcess not stopped yet");
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
// If WAS was stopped for some reason appPool.WorkerProcesses
|
||||||
|
// would throw UnauthorizedAccessException.
|
||||||
|
// check if it's the case and continue shutting down deployer
|
||||||
|
catch (UnauthorizedAccessException)
|
||||||
|
{
|
||||||
|
var serviceController = new ServiceController("was");
|
||||||
|
if (serviceController.Status != ServiceControllerStatus.Stopped)
|
||||||
|
{
|
||||||
|
throw;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!HostProcess.HasExited)
|
if (!HostProcess.HasExited)
|
||||||
|
|
|
||||||
|
|
@ -8,7 +8,7 @@ using Xunit;
|
||||||
|
|
||||||
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
{
|
{
|
||||||
public class ClientCertificateFixture : IDisposable
|
public class ClientCertificateFixture : IDisposable
|
||||||
{
|
{
|
||||||
private X509Certificate2 _certificate;
|
private X509Certificate2 _certificate;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -20,7 +20,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
var entries = GetEntries(deploymentResult);
|
var entries = GetEntries(deploymentResult);
|
||||||
AssertSingleEntry(expectedRegexMatchString, entries);
|
AssertSingleEntry(expectedRegexMatchString, entries);
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void VerifyEventLogEvents(IISDeploymentResult deploymentResult, params string[] expectedRegexMatchString)
|
public static void VerifyEventLogEvents(IISDeploymentResult deploymentResult, params string[] expectedRegexMatchString)
|
||||||
{
|
{
|
||||||
Assert.True(deploymentResult.HostProcess.HasExited);
|
Assert.True(deploymentResult.HostProcess.HasExited);
|
||||||
|
|
@ -35,7 +35,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
entries.Remove(matchedEntry);
|
entries.Remove(matchedEntry);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.True(0 == entries.Count, $"Some entries were not matched by any regex {FormatEntries(entries)}");
|
Assert.True(0 == entries.Count, $"Some entries were not matched by any regex {FormatEntries(entries)}");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -77,7 +77,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
// ReplacementStings == EventData collection in EventLog
|
// ReplacementStings == EventData collection in EventLog
|
||||||
// This is unaffected if event providers are not registered correctly
|
// This is unaffected if event providers are not registered correctly
|
||||||
if (eventLogEntry.Source == AncmVersionToMatch(deploymentResult) &&
|
if (eventLogEntry.Source == AncmVersionToMatch(deploymentResult) &&
|
||||||
|
|
@ -96,12 +96,28 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
(deploymentResult.DeploymentParameters.AncmVersion == AncmVersion.AspNetCoreModuleV2 ? " V2" : "");
|
(deploymentResult.DeploymentParameters.AncmVersion == AncmVersion.AspNetCoreModuleV2 ? " V2" : "");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string Started(IISDeploymentResult deploymentResult)
|
||||||
|
{
|
||||||
|
if (deploymentResult.DeploymentParameters.HostingModel == HostingModel.InProcess)
|
||||||
|
{
|
||||||
|
return InProcessStarted(deploymentResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
return OutOfProcessStarted(deploymentResult);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
public static string InProcessStarted(IISDeploymentResult deploymentResult)
|
public static string InProcessStarted(IISDeploymentResult deploymentResult)
|
||||||
{
|
{
|
||||||
return $"Application '{EscapedContentRoot(deploymentResult)}' started the coreclr in-process successfully";
|
return $"Application '{EscapedContentRoot(deploymentResult)}' started the coreclr in-process successfully";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static string OutOfProcessStarted(IISDeploymentResult deploymentResult)
|
||||||
|
{
|
||||||
|
return $"Application '/LM/W3SVC/1/ROOT' started process '\\d+' successfully and process '\\d+' is listening on port '\\d+'.";
|
||||||
|
}
|
||||||
|
|
||||||
public static string InProcessFailedToStart(IISDeploymentResult deploymentResult, string reason)
|
public static string InProcessFailedToStart(IISDeploymentResult deploymentResult, string reason)
|
||||||
{
|
{
|
||||||
return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' failed to load clr and managed application. {reason}";
|
return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' failed to load clr and managed application. {reason}";
|
||||||
|
|
|
||||||
|
|
@ -111,10 +111,10 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void AssertWorkerProcessStop(this IISDeploymentResult deploymentResult)
|
public static void AssertWorkerProcessStop(this IISDeploymentResult deploymentResult, int? timeout = null)
|
||||||
{
|
{
|
||||||
var hostProcess = deploymentResult.HostProcess;
|
var hostProcess = deploymentResult.HostProcess;
|
||||||
Assert.True(hostProcess.WaitForExit((int)TimeoutExtensions.DefaultTimeoutValue.TotalMilliseconds));
|
Assert.True(hostProcess.WaitForExit(timeout ?? (int)TimeoutExtensions.DefaultTimeoutValue.TotalMilliseconds));
|
||||||
|
|
||||||
if (deploymentResult.DeploymentParameters.ServerType == ServerType.IISExpress)
|
if (deploymentResult.DeploymentParameters.ServerType == ServerType.IISExpress)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
WindowsAuthentication = 2,
|
WindowsAuthentication = 2,
|
||||||
PoolEnvironmentVariables = 4,
|
PoolEnvironmentVariables = 4,
|
||||||
ShutdownToken = 8,
|
ShutdownToken = 8,
|
||||||
DynamicCompression = 16
|
DynamicCompression = 16,
|
||||||
|
ApplicationInitialization = 32
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
private static readonly bool _windowsAuthAvailable;
|
private static readonly bool _windowsAuthAvailable;
|
||||||
private static readonly bool _poolEnvironmentVariablesAvailable;
|
private static readonly bool _poolEnvironmentVariablesAvailable;
|
||||||
private static readonly bool _dynamicCompressionAvailable;
|
private static readonly bool _dynamicCompressionAvailable;
|
||||||
|
private static readonly bool _applicationInitializationModule;
|
||||||
|
|
||||||
static RequiresIISAttribute()
|
static RequiresIISAttribute()
|
||||||
{
|
{
|
||||||
|
|
@ -84,6 +85,8 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
|
|
||||||
_dynamicCompressionAvailable = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "compdyn.dll"));
|
_dynamicCompressionAvailable = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "compdyn.dll"));
|
||||||
|
|
||||||
|
_applicationInitializationModule = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "warmup.dll"));
|
||||||
|
|
||||||
var iisRegistryKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\InetStp", writable: false);
|
var iisRegistryKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\InetStp", writable: false);
|
||||||
if (iisRegistryKey == null)
|
if (iisRegistryKey == null)
|
||||||
{
|
{
|
||||||
|
|
@ -145,6 +148,15 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
SkipReason += "The machine does not have IIS dynamic compression installed.";
|
SkipReason += "The machine does not have IIS dynamic compression installed.";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (capabilities.HasFlag(IISCapability.ApplicationInitialization))
|
||||||
|
{
|
||||||
|
IsMet &= _dynamicCompressionAvailable;
|
||||||
|
if (!_dynamicCompressionAvailable)
|
||||||
|
{
|
||||||
|
SkipReason += "The machine does not have IIS ApplicationInitialization installed.";
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool IsMet { get; }
|
public bool IsMet { get; }
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,73 @@
|
||||||
|
// Copyright (c) .NET Foundation. All rights reserved.
|
||||||
|
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
|
||||||
|
|
||||||
|
using System.ServiceProcess;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
|
||||||
|
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
|
||||||
|
using Microsoft.AspNetCore.Server.IntegrationTesting;
|
||||||
|
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
|
||||||
|
using Microsoft.AspNetCore.Testing;
|
||||||
|
using Microsoft.AspNetCore.Testing.xunit;
|
||||||
|
using Xunit;
|
||||||
|
|
||||||
|
namespace IIS.FunctionalTests
|
||||||
|
{
|
||||||
|
[Collection(PublishedSitesCollection.Name)]
|
||||||
|
public class ApplicationInitializationTests : IISFunctionalTestBase
|
||||||
|
{
|
||||||
|
private readonly PublishedSitesFixture _fixture;
|
||||||
|
|
||||||
|
public ApplicationInitializationTests(PublishedSitesFixture fixture)
|
||||||
|
{
|
||||||
|
_fixture = fixture;
|
||||||
|
}
|
||||||
|
|
||||||
|
[ConditionalTheory]
|
||||||
|
[RequiresIIS(IISCapability.ApplicationInitialization)]
|
||||||
|
[InlineData(HostingModel.InProcess)]
|
||||||
|
[InlineData(HostingModel.OutOfProcess)]
|
||||||
|
public async Task ApplicationInitializationInitializedInProc(HostingModel hostingModel)
|
||||||
|
{
|
||||||
|
var baseDeploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel);
|
||||||
|
EnableAppInitialization(baseDeploymentParameters);
|
||||||
|
|
||||||
|
var result = await DeployAsync(baseDeploymentParameters);
|
||||||
|
|
||||||
|
// Allow IIS a bit of time to complete starting before we start checking
|
||||||
|
await Task.Delay(100);
|
||||||
|
// There is always a race between which Init request arrives first
|
||||||
|
// retry couple times to see if we ever get the one comming from ApplicationInitialization module
|
||||||
|
await result.HttpClient.RetryRequestAsync("/ApplicationInitialization", async message => await message.Content.ReadAsStringAsync() == "True");
|
||||||
|
|
||||||
|
StopServer();
|
||||||
|
EventLogHelpers.VerifyEventLogEvent(result, EventLogHelpers.Started(result));
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void EnableAppInitialization(IISDeploymentParameters baseDeploymentParameters)
|
||||||
|
{
|
||||||
|
baseDeploymentParameters.ServerConfigActionList.Add(
|
||||||
|
(config, _) => {
|
||||||
|
config
|
||||||
|
.RequiredElement("configSections")
|
||||||
|
.GetOrAdd("sectionGroup", "name", "system.webServer")
|
||||||
|
.GetOrAdd("section", "name", "applicationInitialization")
|
||||||
|
.SetAttributeValue("overrideModeDefault", "Allow");
|
||||||
|
|
||||||
|
config
|
||||||
|
.RequiredElement("system.applicationHost")
|
||||||
|
.RequiredElement("sites")
|
||||||
|
.RequiredElement("site")
|
||||||
|
.RequiredElement("application")
|
||||||
|
.SetAttributeValue("preloadEnabled", true);
|
||||||
|
|
||||||
|
config
|
||||||
|
.RequiredElement("system.webServer")
|
||||||
|
.GetOrAdd("applicationInitialization")
|
||||||
|
.GetOrAdd("add", "initializationPage", "/ApplicationInitialization?IISInit=true");
|
||||||
|
});
|
||||||
|
|
||||||
|
baseDeploymentParameters.EnableModule("ApplicationInitializationModule", "%IIS_BIN%\\warmup.dll");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -97,6 +97,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
await deploymentResult.AssertStarts();
|
await deploymentResult.AssertStarts();
|
||||||
|
|
||||||
|
StopServer();
|
||||||
// Verify that in this scenario where.exe was invoked only once by shim and request handler uses cached value
|
// Verify that in this scenario where.exe was invoked only once by shim and request handler uses cached value
|
||||||
Assert.Equal(1, TestSink.Writes.Count(w => w.Message.Contains("Invoking where.exe to find dotnet.exe")));
|
Assert.Equal(1, TestSink.Writes.Count(w => w.Message.Contains("Invoking where.exe to find dotnet.exe")));
|
||||||
}
|
}
|
||||||
|
|
@ -143,7 +144,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
|
||||||
StopServer();
|
StopServer();
|
||||||
|
|
||||||
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
||||||
EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"),
|
EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"),
|
||||||
EventLogHelpers.InProcessThreadException(deploymentResult, ".*?Application is running inside IIS process but is not configured to use IIS server"));
|
EventLogHelpers.InProcessThreadException(deploymentResult, ".*?Application is running inside IIS process but is not configured to use IIS server"));
|
||||||
|
|
@ -154,7 +155,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
{
|
{
|
||||||
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
var deploymentParameters = _fixture.GetBaseDeploymentParameters(_fixture.InProcessTestSite, publish: true);
|
||||||
deploymentParameters.TransformArguments((a, _) => $"{a} Throw");
|
deploymentParameters.TransformArguments((a, _) => $"{a} Throw");
|
||||||
|
|
||||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
var response = await deploymentResult.HttpClient.GetAsync("/");
|
var response = await deploymentResult.HttpClient.GetAsync("/");
|
||||||
|
|
@ -166,7 +167,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"),
|
EventLogHelpers.InProcessFailedToStart(deploymentResult, "CLR worker thread exited prematurely"),
|
||||||
EventLogHelpers.InProcessThreadException(deploymentResult, ", exception code = '0xe0434352'"));
|
EventLogHelpers.InProcessThreadException(deploymentResult, ", exception code = '0xe0434352'"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[ConditionalFact]
|
[ConditionalFact]
|
||||||
public async Task LogsUnexpectedThreadExitError()
|
public async Task LogsUnexpectedThreadExitError()
|
||||||
{
|
{
|
||||||
|
|
@ -193,7 +194,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
WebConfigHelpers.AddOrModifyAspNetCoreSection("startupTimeLimit", "1"));
|
WebConfigHelpers.AddOrModifyAspNetCoreSection("startupTimeLimit", "1"));
|
||||||
|
|
||||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
var response = await deploymentResult.HttpClient.GetAsync("/");
|
var response = await deploymentResult.HttpClient.GetAsync("/");
|
||||||
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
Assert.Equal(HttpStatusCode.InternalServerError, response.StatusCode);
|
||||||
|
|
||||||
|
|
@ -213,7 +214,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
WebConfigHelpers.AddOrModifyAspNetCoreSection("shutdownTimeLimit", "1"));
|
WebConfigHelpers.AddOrModifyAspNetCoreSection("shutdownTimeLimit", "1"));
|
||||||
|
|
||||||
var deploymentResult = await DeployAsync(deploymentParameters);
|
var deploymentResult = await DeployAsync(deploymentParameters);
|
||||||
|
|
||||||
Assert.Equal("Hello World", await deploymentResult.HttpClient.GetStringAsync("/HelloWorld"));
|
Assert.Equal("Hello World", await deploymentResult.HttpClient.GetStringAsync("/HelloWorld"));
|
||||||
|
|
||||||
StopServer();
|
StopServer();
|
||||||
|
|
|
||||||
|
|
@ -184,6 +184,7 @@ namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
|
||||||
|
|
||||||
private void AssertLoadedVersion(string version)
|
private void AssertLoadedVersion(string version)
|
||||||
{
|
{
|
||||||
|
StopServer();
|
||||||
Assert.Contains(TestSink.Writes, context => context.Message.Contains(version + @"\aspnetcorev2_outofprocess.dll"));
|
Assert.Contains(TestSink.Writes, context => context.Message.Contains(version + @"\aspnetcorev2_outofprocess.dll"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -71,5 +71,16 @@ namespace TestSite
|
||||||
{
|
{
|
||||||
await context.Response.WriteAsync(_waitingRequestCount.ToString());
|
await context.Response.WriteAsync(_waitingRequestCount.ToString());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static bool _applicationInitializationCalled;
|
||||||
|
|
||||||
|
public async Task ApplicationInitialization(HttpContext context)
|
||||||
|
{
|
||||||
|
if (context.Request.Query["IISInit"] == "true")
|
||||||
|
{
|
||||||
|
_applicationInitializationCalled = true;
|
||||||
|
}
|
||||||
|
await context.Response.WriteAsync(_applicationInitializationCalled.ToString());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue