Skip to content
This repository was archived by the owner on Nov 1, 2018. It is now read-only.

Commit 375d037

Browse files
authored
Add applicationInitialization tests (#1402)
1 parent b41f1f0 commit 375d037

File tree

8 files changed

+141
-11
lines changed

8 files changed

+141
-11
lines changed

src/Microsoft.AspNetCore.Server.IntegrationTesting.IIS/IISDeployer.cs

Lines changed: 20 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -357,10 +357,27 @@ private void Stop()
357357
throw new InvalidOperationException("Site not stopped yet");
358358
}
359359

360-
if (appPool.WorkerProcesses != null && appPool.WorkerProcesses.Any(wp => wp.State == WorkerProcessState.Running ||
361-
wp.State == WorkerProcessState.Stopping))
360+
try
362361
{
363-
throw new InvalidOperationException("WorkerProcess not stopped yet");
362+
if (appPool.WorkerProcesses != null &&
363+
appPool.WorkerProcesses.Any(wp =>
364+
wp.State == WorkerProcessState.Running ||
365+
wp.State == WorkerProcessState.Stopping))
366+
{
367+
throw new InvalidOperationException("WorkerProcess not stopped yet");
368+
}
369+
370+
}
371+
// If WAS was stopped for some reason appPool.WorkerProcesses
372+
// would throw UnauthorizedAccessException.
373+
// check if it's the case and continue shutting down deployer
374+
catch (UnauthorizedAccessException)
375+
{
376+
var serviceController = new ServiceController("was");
377+
if (serviceController.Status != ServiceControllerStatus.Stopped)
378+
{
379+
throw;
380+
}
364381
}
365382

366383
if (!HostProcess.HasExited)

test/Common.FunctionalTests/ClientCertificateFixture.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88

99
namespace Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests
1010
{
11-
public class ClientCertificateFixture : IDisposable
11+
public class ClientCertificateFixture : IDisposable
1212
{
1313
private X509Certificate2 _certificate;
1414

test/Common.FunctionalTests/Utilities/EventLogHelpers.cs

Lines changed: 20 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ public static void VerifyEventLogEvent(IISDeploymentResult deploymentResult, str
2020
var entries = GetEntries(deploymentResult);
2121
AssertSingleEntry(expectedRegexMatchString, entries);
2222
}
23-
23+
2424
public static void VerifyEventLogEvents(IISDeploymentResult deploymentResult, params string[] expectedRegexMatchString)
2525
{
2626
Assert.True(deploymentResult.HostProcess.HasExited);
@@ -35,7 +35,7 @@ public static void VerifyEventLogEvents(IISDeploymentResult deploymentResult, pa
3535
entries.Remove(matchedEntry);
3636
}
3737
}
38-
38+
3939
Assert.True(0 == entries.Count, $"Some entries were not matched by any regex {FormatEntries(entries)}");
4040
}
4141

@@ -77,7 +77,7 @@ private static IEnumerable<EventLogEntry> GetEntries(IISDeploymentResult deploym
7777
{
7878
continue;
7979
}
80-
80+
8181
// ReplacementStings == EventData collection in EventLog
8282
// This is unaffected if event providers are not registered correctly
8383
if (eventLogEntry.Source == AncmVersionToMatch(deploymentResult) &&
@@ -96,12 +96,28 @@ private static string AncmVersionToMatch(IISDeploymentResult deploymentResult)
9696
(deploymentResult.DeploymentParameters.AncmVersion == AncmVersion.AspNetCoreModuleV2 ? " V2" : "");
9797
}
9898

99-
99+
public static string Started(IISDeploymentResult deploymentResult)
100+
{
101+
if (deploymentResult.DeploymentParameters.HostingModel == HostingModel.InProcess)
102+
{
103+
return InProcessStarted(deploymentResult);
104+
}
105+
else
106+
{
107+
return OutOfProcessStarted(deploymentResult);
108+
}
109+
}
110+
100111
public static string InProcessStarted(IISDeploymentResult deploymentResult)
101112
{
102113
return $"Application '{EscapedContentRoot(deploymentResult)}' started the coreclr in-process successfully";
103114
}
104115

116+
public static string OutOfProcessStarted(IISDeploymentResult deploymentResult)
117+
{
118+
return $"Application '/LM/W3SVC/1/ROOT' started process '\\d+' successfully and process '\\d+' is listening on port '\\d+'.";
119+
}
120+
105121
public static string InProcessFailedToStart(IISDeploymentResult deploymentResult, string reason)
106122
{
107123
return $"Application '/LM/W3SVC/1/ROOT' with physical root '{EscapedContentRoot(deploymentResult)}' failed to load clr and managed application. {reason}";

test/Common.FunctionalTests/Utilities/Helpers.cs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,10 +111,10 @@ public static async Task<HttpResponseMessage> RetryRequestAsync(this HttpClient
111111
return response;
112112
}
113113

114-
public static void AssertWorkerProcessStop(this IISDeploymentResult deploymentResult)
114+
public static void AssertWorkerProcessStop(this IISDeploymentResult deploymentResult, int? timeout = null)
115115
{
116116
var hostProcess = deploymentResult.HostProcess;
117-
Assert.True(hostProcess.WaitForExit((int)TimeoutExtensions.DefaultTimeoutValue.TotalMilliseconds));
117+
Assert.True(hostProcess.WaitForExit(timeout ?? (int)TimeoutExtensions.DefaultTimeoutValue.TotalMilliseconds));
118118

119119
if (deploymentResult.DeploymentParameters.ServerType == ServerType.IISExpress)
120120
{

test/Common.FunctionalTests/Utilities/IISCapability.cs

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ public enum IISCapability
1313
WindowsAuthentication = 2,
1414
PoolEnvironmentVariables = 4,
1515
ShutdownToken = 8,
16-
DynamicCompression = 16
16+
DynamicCompression = 16,
17+
ApplicationInitialization = 32
1718
}
1819
}

test/IIS.FunctionalTests/RequiresIISAttribute.cs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ public sealed class RequiresIISAttribute : Attribute, ITestCondition
2222
private static readonly bool _windowsAuthAvailable;
2323
private static readonly bool _poolEnvironmentVariablesAvailable;
2424
private static readonly bool _dynamicCompressionAvailable;
25+
private static readonly bool _applicationInitializationModule;
2526

2627
static RequiresIISAttribute()
2728
{
@@ -84,6 +85,8 @@ static RequiresIISAttribute()
8485

8586
_dynamicCompressionAvailable = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "compdyn.dll"));
8687

88+
_applicationInitializationModule = File.Exists(Path.Combine(Environment.SystemDirectory, "inetsrv", "warmup.dll"));
89+
8790
var iisRegistryKey = Registry.LocalMachine.OpenSubKey(@"Software\Microsoft\InetStp", writable: false);
8891
if (iisRegistryKey == null)
8992
{
@@ -145,6 +148,15 @@ public RequiresIISAttribute(IISCapability capabilities)
145148
SkipReason += "The machine does not have IIS dynamic compression installed.";
146149
}
147150
}
151+
152+
if (capabilities.HasFlag(IISCapability.ApplicationInitialization))
153+
{
154+
IsMet &= _dynamicCompressionAvailable;
155+
if (!_dynamicCompressionAvailable)
156+
{
157+
SkipReason += "The machine does not have IIS ApplicationInitialization installed.";
158+
}
159+
}
148160
}
149161

150162
public bool IsMet { get; }
Lines changed: 73 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,73 @@
1+
// Copyright (c) .NET Foundation. All rights reserved.
2+
// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
3+
4+
using System.ServiceProcess;
5+
using System.Threading.Tasks;
6+
using Microsoft.AspNetCore.Server.IIS.FunctionalTests.Utilities;
7+
using Microsoft.AspNetCore.Server.IISIntegration.FunctionalTests;
8+
using Microsoft.AspNetCore.Server.IntegrationTesting;
9+
using Microsoft.AspNetCore.Server.IntegrationTesting.IIS;
10+
using Microsoft.AspNetCore.Testing;
11+
using Microsoft.AspNetCore.Testing.xunit;
12+
using Xunit;
13+
14+
namespace IIS.FunctionalTests
15+
{
16+
[Collection(PublishedSitesCollection.Name)]
17+
public class ApplicationInitializationTests : IISFunctionalTestBase
18+
{
19+
private readonly PublishedSitesFixture _fixture;
20+
21+
public ApplicationInitializationTests(PublishedSitesFixture fixture)
22+
{
23+
_fixture = fixture;
24+
}
25+
26+
[ConditionalTheory]
27+
[RequiresIIS(IISCapability.ApplicationInitialization)]
28+
[InlineData(HostingModel.InProcess)]
29+
[InlineData(HostingModel.OutOfProcess)]
30+
public async Task ApplicationInitializationInitializedInProc(HostingModel hostingModel)
31+
{
32+
var baseDeploymentParameters = _fixture.GetBaseDeploymentParameters(hostingModel);
33+
EnableAppInitialization(baseDeploymentParameters);
34+
35+
var result = await DeployAsync(baseDeploymentParameters);
36+
37+
// Allow IIS a bit of time to complete starting before we start checking
38+
await Task.Delay(100);
39+
// There is always a race between which Init request arrives first
40+
// retry couple times to see if we ever get the one comming from ApplicationInitialization module
41+
await result.HttpClient.RetryRequestAsync("/ApplicationInitialization", async message => await message.Content.ReadAsStringAsync() == "True");
42+
43+
StopServer();
44+
EventLogHelpers.VerifyEventLogEvent(result, EventLogHelpers.Started(result));
45+
}
46+
47+
private static void EnableAppInitialization(IISDeploymentParameters baseDeploymentParameters)
48+
{
49+
baseDeploymentParameters.ServerConfigActionList.Add(
50+
(config, _) => {
51+
config
52+
.RequiredElement("configSections")
53+
.GetOrAdd("sectionGroup", "name", "system.webServer")
54+
.GetOrAdd("section", "name", "applicationInitialization")
55+
.SetAttributeValue("overrideModeDefault", "Allow");
56+
57+
config
58+
.RequiredElement("system.applicationHost")
59+
.RequiredElement("sites")
60+
.RequiredElement("site")
61+
.RequiredElement("application")
62+
.SetAttributeValue("preloadEnabled", true);
63+
64+
config
65+
.RequiredElement("system.webServer")
66+
.GetOrAdd("applicationInitialization")
67+
.GetOrAdd("add", "initializationPage", "/ApplicationInitialization?IISInit=true");
68+
});
69+
70+
baseDeploymentParameters.EnableModule("ApplicationInitializationModule", "%IIS_BIN%\\warmup.dll");
71+
}
72+
}
73+
}

test/WebSites/shared/SharedStartup/Startup.shared.cs

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,5 +71,16 @@ public async Task WaitingRequestCount(HttpContext context)
7171
{
7272
await context.Response.WriteAsync(_waitingRequestCount.ToString());
7373
}
74+
75+
private static bool _applicationInitializationCalled;
76+
77+
public async Task ApplicationInitialization(HttpContext context)
78+
{
79+
if (context.Request.Query["IISInit"] == "true")
80+
{
81+
_applicationInitializationCalled = true;
82+
}
83+
await context.Response.WriteAsync(_applicationInitializationCalled.ToString());
84+
}
7485
}
7586
}

0 commit comments

Comments
 (0)