|
|
@@ -41,14 +41,15 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
deploymentParameters.WebConfigActionList.Add(
|
|
|
WebConfigHelpers.AddOrModifyAspNetCoreSection("shutdownTimeLimit", "1"));
|
|
|
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- Assert.Equal("Hello World", await deploymentResult.HttpClient.GetStringAsync("/HelloWorld"));
|
|
|
- StopServer();
|
|
|
- EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
|
|
- EventLogHelpers.InProcessStarted(deploymentResult),
|
|
|
- EventLogHelpers.InProcessFailedToStop(deploymentResult, ""));
|
|
|
- });
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
+
|
|
|
+ Assert.Equal("Hello World", await deploymentResult.HttpClient.GetStringAsync("/HelloWorld"));
|
|
|
+
|
|
|
+ StopServer();
|
|
|
+
|
|
|
+ EventLogHelpers.VerifyEventLogEvents(deploymentResult,
|
|
|
+ EventLogHelpers.InProcessStarted(deploymentResult),
|
|
|
+ EventLogHelpers.InProcessFailedToStop(deploymentResult, ""));
|
|
|
}
|
|
|
|
|
|
[ConditionalTheory]
|
|
|
@@ -59,18 +60,17 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
// Canceled token doesn't affect shutdown, in-proc doesn't handle ungraceful shutdown
|
|
|
// IIS's ShutdownTimeLimit will handle that.
|
|
|
var parameters = Fixture.GetBaseDeploymentParameters();
|
|
|
- await RunTest(parameters, async deploymentResult =>
|
|
|
+ var deploymentResult = await DeployAsync(parameters);
|
|
|
+ try
|
|
|
{
|
|
|
- try
|
|
|
- {
|
|
|
- await deploymentResult.HttpClient.GetAsync(path);
|
|
|
- }
|
|
|
- catch (HttpRequestException ex) when (ex.InnerException is IOException)
|
|
|
- {
|
|
|
- // Server might close a connection before request completes
|
|
|
- }
|
|
|
- deploymentResult.AssertWorkerProcessStop();
|
|
|
- });
|
|
|
+ await deploymentResult.HttpClient.GetAsync(path);
|
|
|
+ }
|
|
|
+ catch (HttpRequestException ex) when (ex.InnerException is IOException)
|
|
|
+ {
|
|
|
+ // Server might close a connection before request completes
|
|
|
+ }
|
|
|
+
|
|
|
+ deploymentResult.AssertWorkerProcessStop();
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -88,49 +88,47 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
[RequiresNewShim]
|
|
|
public async Task AppOfflineDroppedWhileSiteIsDown_SiteReturns503_OutOfProcess()
|
|
|
{
|
|
|
- await RunTest(HostingModel.OutOfProcess, async deploymentResult =>
|
|
|
- {
|
|
|
- AddAppOffline(deploymentResult.ContentRoot);
|
|
|
- await AssertAppOffline(deploymentResult);
|
|
|
- DeletePublishOutput(deploymentResult);
|
|
|
- });
|
|
|
+ var deploymentResult = await DeployApp(HostingModel.OutOfProcess);
|
|
|
+
|
|
|
+ AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+
|
|
|
+ await AssertAppOffline(deploymentResult);
|
|
|
+ DeletePublishOutput(deploymentResult);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
public async Task LockedAppOfflineDroppedWhileSiteIsDown_SiteReturns503_InProcess()
|
|
|
{
|
|
|
- await RunTest(HostingModel.InProcess, async deploymentResult =>
|
|
|
+ var deploymentResult = await DeployApp(HostingModel.InProcess);
|
|
|
+
|
|
|
+ // Add app_offline without shared access
|
|
|
+ using (var stream = File.Open(Path.Combine(deploymentResult.ContentRoot, "app_offline.htm"), FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
|
|
|
+ using (var writer = new StreamWriter(stream))
|
|
|
{
|
|
|
- // Add app_offline without shared access
|
|
|
- using (var stream = File.Open(Path.Combine(deploymentResult.ContentRoot, "app_offline.htm"), FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
|
|
|
- using (var writer = new StreamWriter(stream))
|
|
|
- {
|
|
|
- await writer.WriteLineAsync("App if offline but you wouldn't see this message");
|
|
|
- await writer.FlushAsync();
|
|
|
- await AssertAppOffline(deploymentResult, "");
|
|
|
- }
|
|
|
+ await writer.WriteLineAsync("App if offline but you wouldn't see this message");
|
|
|
+ await writer.FlushAsync();
|
|
|
+ await AssertAppOffline(deploymentResult, "");
|
|
|
+ }
|
|
|
|
|
|
- DeletePublishOutput(deploymentResult);
|
|
|
- });
|
|
|
+ DeletePublishOutput(deploymentResult);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
[RequiresNewShim]
|
|
|
public async Task LockedAppOfflineDroppedWhileSiteIsDown_SiteReturns503_OutOfProcess()
|
|
|
{
|
|
|
- await RunTest(HostingModel.OutOfProcess, async deploymentResult =>
|
|
|
+ var deploymentResult = await DeployApp(HostingModel.OutOfProcess);
|
|
|
+
|
|
|
+ // Add app_offline without shared access
|
|
|
+ using (var stream = File.Open(Path.Combine(deploymentResult.ContentRoot, "app_offline.htm"), FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
|
|
|
+ using (var writer = new StreamWriter(stream))
|
|
|
{
|
|
|
- // Add app_offline without shared access
|
|
|
- using (var stream = File.Open(Path.Combine(deploymentResult.ContentRoot, "app_offline.htm"), FileMode.CreateNew, FileAccess.ReadWrite, FileShare.None))
|
|
|
- using (var writer = new StreamWriter(stream))
|
|
|
- {
|
|
|
- await writer.WriteLineAsync("App if offline but you wouldn't see this message");
|
|
|
- await writer.FlushAsync();
|
|
|
- await AssertAppOffline(deploymentResult, "");
|
|
|
- }
|
|
|
+ await writer.WriteLineAsync("App if offline but you wouldn't see this message");
|
|
|
+ await writer.FlushAsync();
|
|
|
+ await AssertAppOffline(deploymentResult, "");
|
|
|
+ }
|
|
|
|
|
|
- DeletePublishOutput(deploymentResult);
|
|
|
- });
|
|
|
+ DeletePublishOutput(deploymentResult);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -138,17 +136,17 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(hostingModel: HostingModel.InProcess);
|
|
|
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "nonexistent"));
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var result = await deploymentResult.HttpClient.GetAsync("/");
|
|
|
- Assert.Equal(500, (int)result.StatusCode);
|
|
|
- Assert.Contains("500.0", await result.Content.ReadAsStringAsync());
|
|
|
|
|
|
- AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
|
|
|
- await AssertAppOffline(deploymentResult);
|
|
|
- DeletePublishOutput(deploymentResult);
|
|
|
- });
|
|
|
+ var result = await deploymentResult.HttpClient.GetAsync("/");
|
|
|
+ Assert.Equal(500, (int)result.StatusCode);
|
|
|
+ Assert.Contains("500.0", await result.Content.ReadAsStringAsync());
|
|
|
+
|
|
|
+ AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+
|
|
|
+ await AssertAppOffline(deploymentResult);
|
|
|
+ DeletePublishOutput(deploymentResult);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -157,35 +155,34 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(hostingModel: HostingModel.OutOfProcess);
|
|
|
deploymentParameters.WebConfigActionList.Add(WebConfigHelpers.AddOrModifyAspNetCoreSection("processPath", "nonexistent"));
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var result = await deploymentResult.HttpClient.GetAsync("/");
|
|
|
- Assert.Equal(502, (int)result.StatusCode);
|
|
|
- Assert.Contains("502.5", await result.Content.ReadAsStringAsync());
|
|
|
|
|
|
- AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
|
|
|
- await AssertAppOffline(deploymentResult);
|
|
|
- DeletePublishOutput(deploymentResult);
|
|
|
- });
|
|
|
+ var result = await deploymentResult.HttpClient.GetAsync("/");
|
|
|
+ Assert.Equal(502, (int)result.StatusCode);
|
|
|
+ Assert.Contains("502.5", await result.Content.ReadAsStringAsync());
|
|
|
+
|
|
|
+ AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+
|
|
|
+ await AssertAppOffline(deploymentResult);
|
|
|
+ DeletePublishOutput(deploymentResult);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
public async Task AppOfflineDroppedWhileSiteFailedToStartInRequestHandler_SiteStops_InProcess()
|
|
|
{
|
|
|
- await RunTest(HostingModel.InProcess, async deploymentResult =>
|
|
|
- {
|
|
|
- // Set file content to empty so it fails at runtime
|
|
|
- File.WriteAllText(Path.Combine(deploymentResult.ContentRoot, "Microsoft.AspNetCore.Server.IIS.dll"), "");
|
|
|
+ var deploymentResult = await DeployApp(HostingModel.InProcess);
|
|
|
|
|
|
- var result = await deploymentResult.HttpClient.GetAsync("/");
|
|
|
- Assert.Equal(500, (int)result.StatusCode);
|
|
|
- Assert.Contains("500.30", await result.Content.ReadAsStringAsync());
|
|
|
+ // Set file content to empty so it fails at runtime
|
|
|
+ File.WriteAllText(Path.Combine(deploymentResult.ContentRoot, "Microsoft.AspNetCore.Server.IIS.dll"), "");
|
|
|
|
|
|
- AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+ var result = await deploymentResult.HttpClient.GetAsync("/");
|
|
|
+ Assert.Equal(500, (int)result.StatusCode);
|
|
|
+ Assert.Contains("500.30", await result.Content.ReadAsStringAsync());
|
|
|
|
|
|
- await deploymentResult.AssertRecycledAsync(() => AssertAppOffline(deploymentResult));
|
|
|
- });
|
|
|
+ AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+
|
|
|
+ await deploymentResult.AssertRecycledAsync(() => AssertAppOffline(deploymentResult));
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -196,69 +193,69 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
// and graceful shutdown occurs.
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(Fixture.InProcessTestSite);
|
|
|
deploymentParameters.TransformArguments((a, _) => $"{a} IncreaseShutdownLimit");
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var result = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
|
|
|
|
|
- // Send two requests that will hang until data is sent from the client.
|
|
|
- var connectionList = new List<TestConnection>();
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
|
|
|
- for (var i = 0; i < 2; i++)
|
|
|
- {
|
|
|
- var connection = new TestConnection(deploymentResult.HttpClient.BaseAddress.Port);
|
|
|
- await connection.Send(
|
|
|
- "POST /ReadAndCountRequestBody HTTP/1.1",
|
|
|
- "Content-Length: 1",
|
|
|
- "Host: localhost",
|
|
|
- "Connection: close",
|
|
|
- "",
|
|
|
- "");
|
|
|
-
|
|
|
- await connection.Receive(
|
|
|
- "HTTP/1.1 200 OK", "");
|
|
|
- await connection.ReceiveHeaders();
|
|
|
- await connection.Receive("1", $"{i + 1}");
|
|
|
- connectionList.Add(connection);
|
|
|
- }
|
|
|
+ var result = await deploymentResult.HttpClient.GetAsync("/HelloWorld");
|
|
|
|
|
|
- // Send a request that will end once app lifetime is triggered (ApplicationStopping cts).
|
|
|
- var statusConnection = new TestConnection(deploymentResult.HttpClient.BaseAddress.Port);
|
|
|
+ // Send two requests that will hang until data is sent from the client.
|
|
|
+ var connectionList = new List<TestConnection>();
|
|
|
|
|
|
- await statusConnection.Send(
|
|
|
- "GET /WaitForAppToStartShuttingDown HTTP/1.1",
|
|
|
+ for (var i = 0; i < 2; i++)
|
|
|
+ {
|
|
|
+ var connection = new TestConnection(deploymentResult.HttpClient.BaseAddress.Port);
|
|
|
+ await connection.Send(
|
|
|
+ "POST /ReadAndCountRequestBody HTTP/1.1",
|
|
|
+ "Content-Length: 1",
|
|
|
"Host: localhost",
|
|
|
"Connection: close",
|
|
|
"",
|
|
|
"");
|
|
|
|
|
|
- await statusConnection.Receive("HTTP/1.1 200 OK",
|
|
|
- "");
|
|
|
+ await connection.Receive(
|
|
|
+ "HTTP/1.1 200 OK", "");
|
|
|
+ await connection.ReceiveHeaders();
|
|
|
+ await connection.Receive("1", $"{i + 1}");
|
|
|
+ connectionList.Add(connection);
|
|
|
+ }
|
|
|
|
|
|
- await statusConnection.ReceiveHeaders();
|
|
|
+ // Send a request that will end once app lifetime is triggered (ApplicationStopping cts).
|
|
|
+ var statusConnection = new TestConnection(deploymentResult.HttpClient.BaseAddress.Port);
|
|
|
|
|
|
- // Receiving some data means we are currently waiting for IHostApplicationLifetime.
|
|
|
- await statusConnection.Receive("5",
|
|
|
- "test1",
|
|
|
- "");
|
|
|
+ await statusConnection.Send(
|
|
|
+ "GET /WaitForAppToStartShuttingDown HTTP/1.1",
|
|
|
+ "Host: localhost",
|
|
|
+ "Connection: close",
|
|
|
+ "",
|
|
|
+ "");
|
|
|
|
|
|
- AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+ await statusConnection.Receive("HTTP/1.1 200 OK",
|
|
|
+ "");
|
|
|
|
|
|
- // Receive the rest of all open connections.
|
|
|
- await statusConnection.Receive("5", "test2", "");
|
|
|
+ await statusConnection.ReceiveHeaders();
|
|
|
|
|
|
- for (var i = 0; i < 2; i++)
|
|
|
- {
|
|
|
- await connectionList[i].Send("a", "");
|
|
|
- await connectionList[i].Receive("", "4", "done");
|
|
|
- connectionList[i].Dispose();
|
|
|
- }
|
|
|
+ // Receiving some data means we are currently waiting for IHostApplicationLifetime.
|
|
|
+ await statusConnection.Receive("5",
|
|
|
+ "test1",
|
|
|
+ "");
|
|
|
|
|
|
- deploymentResult.AssertWorkerProcessStop();
|
|
|
+ AddAppOffline(deploymentResult.ContentRoot);
|
|
|
|
|
|
- // Shutdown should be graceful here!
|
|
|
- EventLogHelpers.VerifyEventLogEvent(deploymentResult,
|
|
|
- EventLogHelpers.InProcessShutdown(), Logger);
|
|
|
- });
|
|
|
+ // Receive the rest of all open connections.
|
|
|
+ await statusConnection.Receive("5", "test2", "");
|
|
|
+
|
|
|
+ for (var i = 0; i < 2; i++)
|
|
|
+ {
|
|
|
+ await connectionList[i].Send("a", "");
|
|
|
+ await connectionList[i].Receive("", "4", "done");
|
|
|
+ connectionList[i].Dispose();
|
|
|
+ }
|
|
|
+
|
|
|
+ deploymentResult.AssertWorkerProcessStop();
|
|
|
+
|
|
|
+ // Shutdown should be graceful here!
|
|
|
+ EventLogHelpers.VerifyEventLogEvent(deploymentResult,
|
|
|
+ EventLogHelpers.InProcessShutdown(), Logger);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -290,26 +287,30 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
[ConditionalFact]
|
|
|
public async Task AppOfflineDropped_CanRemoveAppOfflineAfterAddingAndSiteWorks_InProcess()
|
|
|
{
|
|
|
- await RunTest(HostingModel.InProcess, async deploymentResult =>
|
|
|
- {
|
|
|
- AddAppOffline(deploymentResult.ContentRoot);
|
|
|
- await AssertAppOffline(deploymentResult);
|
|
|
- RemoveAppOffline(deploymentResult.ContentRoot);
|
|
|
- await AssertRunning(deploymentResult);
|
|
|
- });
|
|
|
+ var deploymentResult = await DeployApp(HostingModel.InProcess);
|
|
|
+
|
|
|
+ AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+
|
|
|
+ await AssertAppOffline(deploymentResult);
|
|
|
+
|
|
|
+ RemoveAppOffline(deploymentResult.ContentRoot);
|
|
|
+
|
|
|
+ await AssertRunning(deploymentResult);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
[RequiresNewShim]
|
|
|
public async Task AppOfflineDropped_CanRemoveAppOfflineAfterAddingAndSiteWorks_OutOfProcess()
|
|
|
{
|
|
|
- await RunTest(HostingModel.OutOfProcess, async deploymentResult =>
|
|
|
- {
|
|
|
- AddAppOffline(deploymentResult.ContentRoot);
|
|
|
- await AssertAppOffline(deploymentResult);
|
|
|
- RemoveAppOffline(deploymentResult.ContentRoot);
|
|
|
- await AssertRunning(deploymentResult);
|
|
|
- });
|
|
|
+ var deploymentResult = await DeployApp(HostingModel.OutOfProcess);
|
|
|
+
|
|
|
+ AddAppOffline(deploymentResult.ContentRoot);
|
|
|
+
|
|
|
+ await AssertAppOffline(deploymentResult);
|
|
|
+
|
|
|
+ RemoveAppOffline(deploymentResult.ContentRoot);
|
|
|
+
|
|
|
+ await AssertRunning(deploymentResult);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -371,15 +372,15 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
public async Task ConfigurationChangeStopsInProcess()
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.InProcess);
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- await deploymentResult.AssertStarts();
|
|
|
|
|
|
- // Just "touching" web.config should be enough
|
|
|
- deploymentResult.ModifyWebConfig(element => { });
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
|
|
|
- await deploymentResult.AssertRecycledAsync();
|
|
|
- });
|
|
|
+ await deploymentResult.AssertStarts();
|
|
|
+
|
|
|
+ // Just "touching" web.config should be enough
|
|
|
+ deploymentResult.ModifyWebConfig(element => { });
|
|
|
+
|
|
|
+ await deploymentResult.AssertRecycledAsync();
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -388,17 +389,16 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess);
|
|
|
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
|
|
|
- // Just "touching" web.config should be enough
|
|
|
- deploymentResult.ModifyWebConfig(element => { });
|
|
|
+ var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
|
|
|
|
|
- // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
- // Verify that worker process gets restarted with new process id
|
|
|
- await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() != processBefore);
|
|
|
- });
|
|
|
+ // Just "touching" web.config should be enough
|
|
|
+ deploymentResult.ModifyWebConfig(element => { });
|
|
|
+
|
|
|
+ // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
+ // Verify that worker process gets restarted with new process id
|
|
|
+ await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() != processBefore);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -406,19 +406,19 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.InProcess);
|
|
|
deploymentParameters.HandlerSettings["disallowRotationOnConfigChange"] = "true";
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
|
|
|
|
|
- await deploymentResult.AssertStarts();
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
|
|
|
- // Just "touching" web.config should be enough
|
|
|
- deploymentResult.ModifyWebConfig(element => { });
|
|
|
+ var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
|
|
|
|
|
- // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
- // Verify that worker process does not get restarted with new process id
|
|
|
- await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() == processBefore);
|
|
|
- });
|
|
|
+ await deploymentResult.AssertStarts();
|
|
|
+
|
|
|
+ // Just "touching" web.config should be enough
|
|
|
+ deploymentResult.ModifyWebConfig(element => { });
|
|
|
+
|
|
|
+ // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
+ // Verify that worker process does not get restarted with new process id
|
|
|
+ await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() == processBefore);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -426,19 +426,19 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.InProcess);
|
|
|
deploymentParameters.HandlerSettings["disallowRotationOnConfigChange"] = "true";
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
|
|
|
|
|
- await deploymentResult.AssertStarts();
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
|
|
|
- // Just "touching" applicationHost.config should be enough
|
|
|
- _deployer.ModifyApplicationHostConfig(element => { });
|
|
|
+ var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
|
|
|
|
|
- // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
- // Verify that worker process does not get restarted with new process id
|
|
|
- await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() == processBefore);
|
|
|
- });
|
|
|
+ await deploymentResult.AssertStarts();
|
|
|
+
|
|
|
+ // Just "touching" applicationHost.config should be enough
|
|
|
+ _deployer.ModifyApplicationHostConfig(element => { });
|
|
|
+
|
|
|
+ // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
+ // Verify that worker process does not get restarted with new process id
|
|
|
+ await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() == processBefore);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -447,38 +447,38 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess);
|
|
|
deploymentParameters.HandlerSettings["disallowRotationOnConfigChange"] = "true";
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
|
|
|
|
|
- // Just "touching" web.config should be enough
|
|
|
- deploymentResult.ModifyWebConfig(element => { });
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
|
|
|
- // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
- // Verify that worker process does not get restarted with new process id
|
|
|
- await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() == processBefore);
|
|
|
- });
|
|
|
+ var processBefore = await deploymentResult.HttpClient.GetStringAsync("/ProcessId");
|
|
|
+
|
|
|
+ // Just "touching" web.config should be enough
|
|
|
+ deploymentResult.ModifyWebConfig(element => { });
|
|
|
+
|
|
|
+ // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
+ // Verify that worker process does not get restarted with new process id
|
|
|
+ await deploymentResult.HttpClient.RetryRequestAsync("/ProcessId", async r => await r.Content.ReadAsStringAsync() == processBefore);
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
public async Task OutOfProcessToInProcessHostingModelSwitchWorks()
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess);
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- await deploymentResult.AssertStarts();
|
|
|
-
|
|
|
- deploymentResult.ModifyWebConfig(element => element
|
|
|
- .Descendants("system.webServer")
|
|
|
- .Single()
|
|
|
- .GetOrAdd("aspNetCore")
|
|
|
- .SetAttributeValue("hostingModel", "inprocess"));
|
|
|
-
|
|
|
- // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
- // Verify that inprocess application was created and started, checking the server
|
|
|
- // header to see that it is running inprocess
|
|
|
- await deploymentResult.HttpClient.RetryRequestAsync("/HelloWorld", r => r.Headers.Server.ToString().StartsWith("Microsoft", StringComparison.Ordinal));
|
|
|
- });
|
|
|
+
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
+
|
|
|
+ await deploymentResult.AssertStarts();
|
|
|
+
|
|
|
+ deploymentResult.ModifyWebConfig(element => element
|
|
|
+ .Descendants("system.webServer")
|
|
|
+ .Single()
|
|
|
+ .GetOrAdd("aspNetCore")
|
|
|
+ .SetAttributeValue("hostingModel", "inprocess"));
|
|
|
+
|
|
|
+ // Have to retry here to allow ANCM to receive notification and react to it
|
|
|
+ // Verify that inprocess application was created and started, checking the server
|
|
|
+ // header to see that it is running inprocess
|
|
|
+ await deploymentResult.HttpClient.RetryRequestAsync("/HelloWorld", r => r.Headers.Server.ToString().StartsWith("Microsoft", StringComparison.Ordinal));
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -489,38 +489,37 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
|
|
|
private async Task ConfigurationTouchedStress(HostingModel hostingModel)
|
|
|
{
|
|
|
- await RunTest(Fixture.GetBaseDeploymentParameters(hostingModel), async deploymentResult =>
|
|
|
+ var deploymentResult = await DeployAsync(Fixture.GetBaseDeploymentParameters(hostingModel));
|
|
|
+
|
|
|
+ await deploymentResult.AssertStarts();
|
|
|
+ var load = Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response =>
|
|
|
{
|
|
|
- await deploymentResult.AssertStarts();
|
|
|
- var load = Helpers.StressLoad(deploymentResult.HttpClient, "/HelloWorld", response =>
|
|
|
- {
|
|
|
- var statusCode = (int)response.StatusCode;
|
|
|
- Assert.True(statusCode == 200 || statusCode == 503, "Status code was " + statusCode);
|
|
|
- });
|
|
|
+ var statusCode = (int)response.StatusCode;
|
|
|
+ Assert.True(statusCode == 200 || statusCode == 503, "Status code was " + statusCode);
|
|
|
+ });
|
|
|
|
|
|
- for (var i = 0; i < 100; i++)
|
|
|
- {
|
|
|
- // ModifyWebConfig might fail if web.config is being read by IIS
|
|
|
- RetryHelper.RetryOperation(
|
|
|
- () => deploymentResult.ModifyWebConfig(element => { }),
|
|
|
- e => Logger.LogError($"Failed to touch web.config : {e.Message}"),
|
|
|
- retryCount: 3,
|
|
|
- retryDelayMilliseconds: RetryDelay.Milliseconds);
|
|
|
- }
|
|
|
+ for (var i = 0; i < 100; i++)
|
|
|
+ {
|
|
|
+ // ModifyWebConfig might fail if web.config is being read by IIS
|
|
|
+ RetryHelper.RetryOperation(
|
|
|
+ () => deploymentResult.ModifyWebConfig(element => { }),
|
|
|
+ e => Logger.LogError($"Failed to touch web.config : {e.Message}"),
|
|
|
+ retryCount: 3,
|
|
|
+ retryDelayMilliseconds: RetryDelay.Milliseconds);
|
|
|
+ }
|
|
|
|
|
|
- try
|
|
|
- {
|
|
|
- await load;
|
|
|
- }
|
|
|
- catch (HttpRequestException ex) when (ex.InnerException is IOException | ex.InnerException is SocketException)
|
|
|
+ try
|
|
|
+ {
|
|
|
+ await load;
|
|
|
+ }
|
|
|
+ catch (HttpRequestException ex) when (ex.InnerException is IOException | ex.InnerException is SocketException)
|
|
|
+ {
|
|
|
+ // IOException in InProcess is fine, just means process stopped
|
|
|
+ if (hostingModel != HostingModel.InProcess)
|
|
|
{
|
|
|
- // IOException in InProcess is fine, just means process stopped
|
|
|
- if (hostingModel != HostingModel.InProcess)
|
|
|
- {
|
|
|
- throw;
|
|
|
- }
|
|
|
+ throw;
|
|
|
}
|
|
|
- });
|
|
|
+ }
|
|
|
}
|
|
|
|
|
|
[ConditionalFact]
|
|
|
@@ -530,14 +529,14 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
try
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.OutOfProcess);
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var response = await deploymentResult.HttpClient.GetAsync("/Abort").TimeoutAfter(TimeoutExtensions.DefaultTimeoutValue);
|
|
|
|
|
|
- Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode);
|
|
|
- // 0x80072f78 ERROR_HTTP_INVALID_SERVER_RESPONSE The server returned an invalid or unrecognized response
|
|
|
- Assert.Contains("0x80072f78", await response.Content.ReadAsStringAsync());
|
|
|
- });
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
+
|
|
|
+ var response = await deploymentResult.HttpClient.GetAsync("/Abort").TimeoutAfter(TimeoutExtensions.DefaultTimeoutValue);
|
|
|
+
|
|
|
+ Assert.Equal(HttpStatusCode.BadGateway, response.StatusCode);
|
|
|
+ // 0x80072f78 ERROR_HTTP_INVALID_SERVER_RESPONSE The server returned an invalid or unrecognized response
|
|
|
+ Assert.Contains("0x80072f78", await response.Content.ReadAsStringAsync());
|
|
|
}
|
|
|
catch (HttpRequestException)
|
|
|
{
|
|
|
@@ -551,11 +550,11 @@ public class ShutdownTests : IISFunctionalTestBase
|
|
|
try
|
|
|
{
|
|
|
var deploymentParameters = Fixture.GetBaseDeploymentParameters(HostingModel.InProcess);
|
|
|
- await RunTest(deploymentParameters, async deploymentResult =>
|
|
|
- {
|
|
|
- var response = await deploymentResult.HttpClient.GetAsync("/Abort").TimeoutAfter(TimeoutExtensions.DefaultTimeoutValue);
|
|
|
- Assert.True(false, "Should not reach here");
|
|
|
- });
|
|
|
+
|
|
|
+ var deploymentResult = await DeployAsync(deploymentParameters);
|
|
|
+ var response = await deploymentResult.HttpClient.GetAsync("/Abort").TimeoutAfter(TimeoutExtensions.DefaultTimeoutValue);
|
|
|
+
|
|
|
+ Assert.True(false, "Should not reach here");
|
|
|
}
|
|
|
catch (HttpRequestException)
|
|
|
{
|