diff --git a/test/DeploymentHelpers/Common/DeploymentResult.cs b/test/DeploymentHelpers/Common/DeploymentResult.cs
index 25c2729905..b0ea83de2f 100644
--- a/test/DeploymentHelpers/Common/DeploymentResult.cs
+++ b/test/DeploymentHelpers/Common/DeploymentResult.cs
@@ -1,4 +1,6 @@
-namespace DeploymentHelpers
+using System.Threading;
+
+namespace DeploymentHelpers
{
///
/// Result of a deployment.
@@ -20,5 +22,10 @@
/// Original deployment parameters used for this deployment.
///
public DeploymentParameters DeploymentParameters { get; set; }
+
+ ///
+ /// Triggered when the host process dies or pulled down.
+ ///
+ public CancellationToken HostShutdownToken { get; set; }
}
}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Common/RetryHelper.cs b/test/DeploymentHelpers/Common/RetryHelper.cs
index 0e98960189..106b97282c 100644
--- a/test/DeploymentHelpers/Common/RetryHelper.cs
+++ b/test/DeploymentHelpers/Common/RetryHelper.cs
@@ -8,12 +8,28 @@ namespace DeploymentHelpers
{
public class RetryHelper
{
- public static void RetryRequest(Func retryBlock, ILogger logger, int retryCount = 12)
+ ///
+ /// Retries every 1 sec for 60 times by default.
+ ///
+ ///
+ ///
+ ///
+ ///
+ public static void RetryRequest(
+ Func retryBlock,
+ ILogger logger,
+ CancellationToken cancellationToken = default(CancellationToken),
+ int retryCount = 60)
{
for (int retry = 0; retry < retryCount; retry++)
{
try
{
+ if (cancellationToken.IsCancellationRequested)
+ {
+ break;
+ }
+
logger.LogWarning("Retry count {retryCount}..", retry + 1);
var response = retryBlock();
@@ -41,7 +57,7 @@ namespace DeploymentHelpers
)
{
logger.LogWarning("Failed to complete the request : {0}.", exception.InnerException.Message);
- Thread.Sleep(7 * 1000); //Wait for a while before retry.
+ Thread.Sleep(1 * 1000); //Wait for a while before retry.
}
}
}
diff --git a/test/DeploymentHelpers/Deployers/ApplicationDeployer.cs b/test/DeploymentHelpers/Deployers/ApplicationDeployer.cs
index 9c25a351d2..a04e3f6124 100644
--- a/test/DeploymentHelpers/Deployers/ApplicationDeployer.cs
+++ b/test/DeploymentHelpers/Deployers/ApplicationDeployer.cs
@@ -3,6 +3,7 @@ using System.Diagnostics;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;
+using System.Threading;
using Microsoft.Framework.Logging;
namespace DeploymentHelpers
@@ -171,6 +172,18 @@ namespace DeploymentHelpers
}
}
+ protected void TriggerHostShutdown(CancellationTokenSource hostShutdownSource)
+ {
+ try
+ {
+ hostShutdownSource.Cancel();
+ }
+ catch (Exception)
+ {
+ // Suppress errors.
+ }
+ }
+
public abstract void Dispose();
}
}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Deployers/IISDeployer.cs b/test/DeploymentHelpers/Deployers/IISDeployer.cs
index 2e1c85f3a1..fc0e5d1bae 100644
--- a/test/DeploymentHelpers/Deployers/IISDeployer.cs
+++ b/test/DeploymentHelpers/Deployers/IISDeployer.cs
@@ -2,6 +2,7 @@
using System;
using System.IO;
using System.Linq;
+using System.Threading;
using System.Xml;
using Microsoft.Framework.Logging;
using Microsoft.Web.Administration;
@@ -14,6 +15,7 @@ namespace DeploymentHelpers
public class IISDeployer : ApplicationDeployer
{
private IISApplication _application;
+ private CancellationTokenSource _hostShutdownToken = new CancellationTokenSource();
public IISDeployer(DeploymentParameters startParameters, ILogger logger)
: base(startParameters, logger)
@@ -49,7 +51,8 @@ namespace DeploymentHelpers
WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters,
// Accomodate the vdir name.
- ApplicationBaseUri = new UriBuilder(Uri.UriSchemeHttp, "localhost", _application.Port, _application.VirtualDirectoryName).Uri.AbsoluteUri + "/"
+ ApplicationBaseUri = new UriBuilder(Uri.UriSchemeHttp, "localhost", _application.Port, _application.VirtualDirectoryName).Uri.AbsoluteUri + "/",
+ HostShutdownToken = _hostShutdownToken.Token
};
}
@@ -84,6 +87,8 @@ namespace DeploymentHelpers
if (_application != null)
{
_application.StopAndDeleteAppPool();
+ Logger.LogError("Application pool was shutdown successfully.");
+ TriggerHostShutdown(_hostShutdownToken);
}
CleanPublishedOutput();
diff --git a/test/DeploymentHelpers/Deployers/IISExpressDeployer.cs b/test/DeploymentHelpers/Deployers/IISExpressDeployer.cs
index 1378f9c17b..f686cda17a 100644
--- a/test/DeploymentHelpers/Deployers/IISExpressDeployer.cs
+++ b/test/DeploymentHelpers/Deployers/IISExpressDeployer.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
+using System.Threading;
using Microsoft.Framework.Logging;
using Microsoft.Framework.Runtime;
using Microsoft.Framework.Runtime.Infrastructure;
@@ -29,18 +30,19 @@ namespace DeploymentHelpers
}
// Launch the host process.
- _hostProcess = StartHeliosHost();
+ var hostExitToken = StartHeliosHost();
return new DeploymentResult
{
WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters,
// Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath.
- ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint
+ ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint,
+ HostShutdownToken = hostExitToken
};
}
- private Process StartHeliosHost()
+ private CancellationToken StartHeliosHost()
{
if (!string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigTemplateContent))
{
@@ -96,16 +98,21 @@ namespace DeploymentHelpers
startInfo.Environment["DNX_APPBASE"] = DeploymentParameters.ApplicationPath;
#endif
- var hostProcess = Process.Start(startInfo);
- if (hostProcess.HasExited)
+ _hostProcess = Process.Start(startInfo);
+ var hostExitTokenSource = new CancellationTokenSource();
+ _hostProcess.Exited += (sender, e) =>
{
- Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode);
+ TriggerHostShutdown(hostExitTokenSource);
+ };
+
+ if (_hostProcess.HasExited)
+ {
+ Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, _hostProcess.ExitCode);
throw new Exception("Failed to start host");
}
- Logger.LogInformation("Started iisexpress. Process Id : {processId}", hostProcess.Id);
-
- return hostProcess;
+ Logger.LogInformation("Started iisexpress. Process Id : {processId}", _hostProcess.Id);
+ return hostExitTokenSource.Token;
}
private void CopyAspNetLoader()
diff --git a/test/DeploymentHelpers/Deployers/MonoDeployer.cs b/test/DeploymentHelpers/Deployers/MonoDeployer.cs
index 67bfbb65fa..e98fe5c849 100644
--- a/test/DeploymentHelpers/Deployers/MonoDeployer.cs
+++ b/test/DeploymentHelpers/Deployers/MonoDeployer.cs
@@ -2,6 +2,7 @@
using System.Diagnostics;
using System.IO;
using System.Linq;
+using System.Threading;
using Microsoft.Framework.Logging;
namespace DeploymentHelpers
@@ -37,17 +38,18 @@ namespace DeploymentHelpers
}
// Launch the host process.
- _hostProcess = StartMonoHost();
+ var hostExitToken = StartMonoHost();
return new DeploymentResult
{
WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters,
- ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint
+ ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint,
+ HostShutdownToken = hostExitToken
};
}
- private Process StartMonoHost()
+ private CancellationToken StartMonoHost()
{
if (DeploymentParameters.ServerType != ServerType.Kestrel)
{
@@ -66,16 +68,23 @@ namespace DeploymentHelpers
RedirectStandardInput = true
};
- var hostProcess = Process.Start(startInfo);
- Logger.LogInformation("Started {0}. Process Id : {1}", hostProcess.MainModule.FileName, hostProcess.Id);
-
- if (hostProcess.HasExited)
+ _hostProcess = Process.Start(startInfo);
+ var hostExitTokenSource = new CancellationTokenSource();
+ _hostProcess.Exited += (sender, e) =>
{
- Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode);
+ Logger.LogError("Host process {processName} exited with code {exitCode}.", startInfo.FileName, _hostProcess.ExitCode);
+ TriggerHostShutdown(hostExitTokenSource);
+ };
+
+ Logger.LogInformation("Started {0}. Process Id : {1}", _hostProcess.MainModule.FileName, _hostProcess.Id);
+
+ if (_hostProcess.HasExited)
+ {
+ Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, _hostProcess.ExitCode);
throw new Exception("Failed to start host");
}
- return hostProcess;
+ return hostExitTokenSource.Token;
}
public override void Dispose()
diff --git a/test/DeploymentHelpers/Deployers/SelfHostDeployer.cs b/test/DeploymentHelpers/Deployers/SelfHostDeployer.cs
index 2142189633..6ddc9a1569 100644
--- a/test/DeploymentHelpers/Deployers/SelfHostDeployer.cs
+++ b/test/DeploymentHelpers/Deployers/SelfHostDeployer.cs
@@ -1,6 +1,7 @@
using System;
using System.Diagnostics;
using System.IO;
+using System.Threading;
using Microsoft.Framework.Logging;
namespace DeploymentHelpers
@@ -27,17 +28,18 @@ namespace DeploymentHelpers
}
// Launch the host process.
- _hostProcess = StartSelfHost();
+ var hostExitToken = StartSelfHost();
return new DeploymentResult
{
WebRootLocation = DeploymentParameters.ApplicationPath,
DeploymentParameters = DeploymentParameters,
- ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint
+ ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint,
+ HostShutdownToken = hostExitToken
};
}
- private Process StartSelfHost()
+ private CancellationToken StartSelfHost()
{
var commandName = DeploymentParameters.ServerType == ServerType.WebListener ? "web" : "kestrel";
Logger.LogInformation("Executing dnx.exe {appPath} {command} --server.urls {url}", DeploymentParameters.ApplicationPath, commandName, DeploymentParameters.ApplicationBaseUriHint);
@@ -52,15 +54,21 @@ namespace DeploymentHelpers
AddEnvironmentVariablesToProcess(startInfo);
- var hostProcess = Process.Start(startInfo);
- if (hostProcess.HasExited)
+ _hostProcess = Process.Start(startInfo);
+ var hostExitTokenSource = new CancellationTokenSource();
+ _hostProcess.Exited += (sender, e) =>
{
- Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, hostProcess.ExitCode);
+ TriggerHostShutdown(hostExitTokenSource);
+ };
+
+ if (_hostProcess.HasExited)
+ {
+ Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, _hostProcess.ExitCode);
throw new Exception("Failed to start host");
}
- Logger.LogInformation("Started {fileName}. Process Id : {processId}", startInfo.FileName, hostProcess.Id);
- return hostProcess;
+ Logger.LogInformation("Started {fileName}. Process Id : {processId}", startInfo.FileName, _hostProcess.Id);
+ return hostExitTokenSource.Token;
}
public override void Dispose()
diff --git a/test/E2ETests/NtlmAuthentationTest.cs b/test/E2ETests/NtlmAuthentationTest.cs
index 4555637c74..4bce69f22d 100644
--- a/test/E2ETests/NtlmAuthentationTest.cs
+++ b/test/E2ETests/NtlmAuthentationTest.cs
@@ -70,7 +70,7 @@ namespace E2ETests
{
response = httpClient.GetAsync(string.Empty).Result;
return response;
- }, logger: logger);
+ }, logger: logger, cancellationToken: deploymentResult.HostShutdownToken);
logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds);
diff --git a/test/E2ETests/OpenIdConnectTests.cs b/test/E2ETests/OpenIdConnectTests.cs
index e88f52de7c..debc2f9fde 100644
--- a/test/E2ETests/OpenIdConnectTests.cs
+++ b/test/E2ETests/OpenIdConnectTests.cs
@@ -79,7 +79,7 @@ namespace E2ETests
{
response = httpClient.GetAsync(string.Empty).Result;
return response;
- }, logger: logger);
+ }, logger: logger, cancellationToken: deploymentResult.HostShutdownToken);
logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds);
diff --git a/test/E2ETests/PublishAndRunTests.cs b/test/E2ETests/PublishAndRunTests.cs
index c543c522fc..6ddcb23228 100644
--- a/test/E2ETests/PublishAndRunTests.cs
+++ b/test/E2ETests/PublishAndRunTests.cs
@@ -102,7 +102,7 @@ namespace E2ETests
{
response = httpClient.GetAsync(string.Empty).Result;
return response;
- }, logger: logger);
+ }, logger: logger, cancellationToken: deploymentResult.HostShutdownToken);
logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds);
diff --git a/test/E2ETests/SmokeTests.cs b/test/E2ETests/SmokeTests.cs
index f3989390c4..26aef4143a 100644
--- a/test/E2ETests/SmokeTests.cs
+++ b/test/E2ETests/SmokeTests.cs
@@ -171,7 +171,7 @@ namespace E2ETests
{
response = httpClient.GetAsync(string.Empty).Result;
return response;
- }, logger: logger);
+ }, logger: logger, cancellationToken: deploymentResult.HostShutdownToken);
logger.LogInformation("[Time]: Approximate time taken for application initialization : '{t}' seconds", stopwatch.Elapsed.TotalSeconds);