diff --git a/MusicStore.sln b/MusicStore.sln
index c0d448f626..b267f652cc 100644
--- a/MusicStore.sln
+++ b/MusicStore.sln
@@ -1,7 +1,7 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.22617.0
+VisualStudioVersion = 14.0.22803.0
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = ".nuget", ".nuget", "{44621553-AA7D-4893-8834-79582A7D8348}"
EndProject
@@ -28,6 +28,8 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MusicStore.Test", "test\Mus
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MusicStore.Spa.Test", "test\MusicStore.Spa.Test\MusicStore.Spa.Test.xproj", "{9D3326C4-1F12-4526-9F25-712A1463B3FA}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DeploymentHelpers", "test\DeploymentHelpers\DeploymentHelpers.xproj", "{C98E54D3-F4C6-4D16-A5A6-E86A636A7311}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -112,6 +114,18 @@ Global
{9D3326C4-1F12-4526-9F25-712A1463B3FA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{9D3326C4-1F12-4526-9F25-712A1463B3FA}.Release|x86.ActiveCfg = Release|Any CPU
{9D3326C4-1F12-4526-9F25-712A1463B3FA}.Release|x86.Build.0 = Release|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Debug|x86.Build.0 = Debug|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Release|x86.ActiveCfg = Release|Any CPU
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -124,5 +138,6 @@ Global
{93891170-A8D5-46FD-A291-40F90CF258C2} = {B7B176B6-8D4D-4EF1-BBD2-DDA650C78FFF}
{CA663205-77DE-4E55-B300-85594181B5A9} = {363D2681-31A6-48C9-90BB-9ACFF4A41F06}
{9D3326C4-1F12-4526-9F25-712A1463B3FA} = {363D2681-31A6-48C9-90BB-9ACFF4A41F06}
+ {C98E54D3-F4C6-4D16-A5A6-E86A636A7311} = {363D2681-31A6-48C9-90BB-9ACFF4A41F06}
EndGlobalSection
EndGlobal
diff --git a/src/MusicStore/Startup.cs b/src/MusicStore/Startup.cs
index 5aed990a29..2f1215786f 100644
--- a/src/MusicStore/Startup.cs
+++ b/src/MusicStore/Startup.cs
@@ -111,7 +111,7 @@ namespace MusicStore
//The allowed values are Development,Staging and Production
public void ConfigureDevelopment(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
- loggerFactory.AddConsole();
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
// StatusCode pages to gracefully handle status codes 400-599.
app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage");
@@ -134,7 +134,7 @@ namespace MusicStore
//The allowed values are Development,Staging and Production
public void ConfigureStaging(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
- loggerFactory.AddConsole();
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
// StatusCode pages to gracefully handle status codes 400-599.
app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage");
@@ -148,7 +148,7 @@ namespace MusicStore
//The allowed values are Development,Staging and Production
public void ConfigureProduction(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
- loggerFactory.AddConsole();
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
// StatusCode pages to gracefully handle status codes 400-599.
app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage");
diff --git a/src/MusicStore/StartupNtlmAuthentication.cs b/src/MusicStore/StartupNtlmAuthentication.cs
index 94fc6dc3e3..9b0f026784 100644
--- a/src/MusicStore/StartupNtlmAuthentication.cs
+++ b/src/MusicStore/StartupNtlmAuthentication.cs
@@ -82,7 +82,7 @@ namespace MusicStore
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
- loggerFactory.AddConsole();
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage");
diff --git a/src/MusicStore/StartupOpenIdConnect.cs b/src/MusicStore/StartupOpenIdConnect.cs
index fbc05c6542..7e9d5b2cab 100644
--- a/src/MusicStore/StartupOpenIdConnect.cs
+++ b/src/MusicStore/StartupOpenIdConnect.cs
@@ -103,7 +103,7 @@ namespace MusicStore
public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory)
{
- loggerFactory.AddConsole();
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
app.UseStatusCodePagesWithRedirects("~/Home/StatusCodePage");
diff --git a/test/DeploymentHelpers/Common/DeploymentParameters.cs b/test/DeploymentHelpers/Common/DeploymentParameters.cs
new file mode 100644
index 0000000000..849a144e72
--- /dev/null
+++ b/test/DeploymentHelpers/Common/DeploymentParameters.cs
@@ -0,0 +1,89 @@
+using System;
+using System.Collections.Generic;
+using System.IO;
+
+namespace DeploymentHelpers
+{
+ ///
+ /// Parameters to control application deployment.
+ ///
+ public class DeploymentParameters
+ {
+ ///
+ /// Creates an instance of .
+ ///
+ /// Source code location of the target location to be deployed.
+ /// Where to be deployed on.
+ /// Flavor of the clr to run against.
+ /// Architecture of the DNX to be used.
+ public DeploymentParameters(
+ string applicationPath,
+ ServerType serverType,
+ RuntimeFlavor runtimeFlavor,
+ RuntimeArchitecture runtimeArchitecture)
+ {
+ if (string.IsNullOrEmpty(applicationPath))
+ {
+ throw new ArgumentException("Value cannot be null.", "applicationPath");
+ }
+
+ if (!Directory.Exists(applicationPath))
+ {
+ throw new DirectoryNotFoundException(string.Format("Application path {0} does not exist.", applicationPath));
+ }
+
+ ApplicationPath = applicationPath;
+ ServerType = serverType;
+ RuntimeFlavor = runtimeFlavor;
+ RuntimeArchitecture = runtimeArchitecture;
+ }
+
+ public ServerType ServerType { get; private set; }
+
+ public RuntimeFlavor RuntimeFlavor { get; private set; }
+
+ public RuntimeArchitecture RuntimeArchitecture { get; private set; }
+
+ ///
+ /// Suggested base url for the deployed application. The final deployed url could be
+ /// different than this. Use for the
+ /// deployed url.
+ ///
+ public string ApplicationBaseUriHint { get; set; }
+
+ public string EnvironmentName { get; set; }
+
+ public string ApplicationHostConfigTemplateContent { get; set; }
+
+ public string ApplicationHostConfigLocation { get; set; }
+
+ public string SiteName { get; set; }
+
+ public string ApplicationPath { get; set; }
+
+ ///
+ /// To publish the application before deployment.
+ ///
+ public bool PublishApplicationBeforeDeployment { get; set; }
+
+ public string PublishedApplicationRootPath { get; set; }
+
+ ///
+ /// Passes the --no-source option when publishing.
+ ///
+ public bool PublishWithNoSource { get; set; }
+
+ public string DnxRuntime { get; set; }
+
+ ///
+ /// Environment variables to be set before starting the host.
+ /// Not applicable for IIS Scenarios.
+ ///
+ public List> EnvironmentVariables { get; private set; } = new List>();
+
+ ///
+ /// For any application level cleanup to be invoked after performing host cleanup.
+ ///
+ public Action UserAdditionalCleanup { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Common/DeploymentResult.cs b/test/DeploymentHelpers/Common/DeploymentResult.cs
new file mode 100644
index 0000000000..25c2729905
--- /dev/null
+++ b/test/DeploymentHelpers/Common/DeploymentResult.cs
@@ -0,0 +1,24 @@
+namespace DeploymentHelpers
+{
+ ///
+ /// Result of a deployment.
+ ///
+ public class DeploymentResult
+ {
+ ///
+ /// Base Uri of the deployment application.
+ ///
+ public string ApplicationBaseUri { get; set; }
+
+ ///
+ /// The web root folder where the application is hosted. This path can be different from the
+ /// original application source location if published before deployment.
+ ///
+ public string WebRootLocation { get; set; }
+
+ ///
+ /// Original deployment parameters used for this deployment.
+ ///
+ public DeploymentParameters DeploymentParameters { get; set; }
+ }
+}
\ No newline at end of file
diff --git a/test/E2ETests/Common/DotnetArchitecture.cs b/test/DeploymentHelpers/Common/DotnetArchitecture.cs
similarity index 57%
rename from test/E2ETests/Common/DotnetArchitecture.cs
rename to test/DeploymentHelpers/Common/DotnetArchitecture.cs
index 827e01de3a..e358d24783 100644
--- a/test/E2ETests/Common/DotnetArchitecture.cs
+++ b/test/DeploymentHelpers/Common/DotnetArchitecture.cs
@@ -1,8 +1,8 @@
-namespace E2ETests
+namespace DeploymentHelpers
{
public enum RuntimeArchitecture
{
- amd64,
+ x64,
x86
}
}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Common/DotnetFlavor.cs b/test/DeploymentHelpers/Common/DotnetFlavor.cs
new file mode 100644
index 0000000000..32447a57b6
--- /dev/null
+++ b/test/DeploymentHelpers/Common/DotnetFlavor.cs
@@ -0,0 +1,9 @@
+namespace DeploymentHelpers
+{
+ public enum RuntimeFlavor
+ {
+ clr,
+ coreclr,
+ mono
+ }
+}
diff --git a/test/DeploymentHelpers/Common/RetryHelper.cs b/test/DeploymentHelpers/Common/RetryHelper.cs
new file mode 100644
index 0000000000..43aa02c0ed
--- /dev/null
+++ b/test/DeploymentHelpers/Common/RetryHelper.cs
@@ -0,0 +1,51 @@
+using System;
+using System.Net;
+using System.Net.Http;
+using System.Threading;
+using Microsoft.Framework.Logging;
+
+namespace DeploymentHelpers
+{
+ public class RetryHelper
+ {
+ public static void RetryRequest(Func retryBlock, ILogger logger, int retryCount = 12)
+ {
+ for (int retry = 0; retry < retryCount; retry++)
+ {
+ try
+ {
+ logger.LogWarning("Retry count {retryCount}..", retry + 1);
+ var response = retryBlock();
+
+ if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
+ {
+ // Automatically retry on 503. May be application is still booting.
+ logger.LogWarning("Retrying a service unavailable error.");
+ continue;
+ }
+
+ break; //Went through successfully
+ }
+ catch (AggregateException exception)
+ {
+ if (retry == retryCount - 1)
+ {
+ throw;
+ }
+ else
+ {
+ if (exception.InnerException is HttpRequestException
+#if DNX451
+ || exception.InnerException is System.Net.WebException
+#endif
+ )
+ {
+ logger.LogWarning("Failed to complete the request : {0}.", exception.Message);
+ Thread.Sleep(7 * 1000); //Wait for a while before retry.
+ }
+ }
+ }
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/E2ETests/Common/ServerType.cs b/test/DeploymentHelpers/Common/ServerType.cs
similarity index 80%
rename from test/E2ETests/Common/ServerType.cs
rename to test/DeploymentHelpers/Common/ServerType.cs
index ff2fa543b6..0cf6c0131e 100644
--- a/test/E2ETests/Common/ServerType.cs
+++ b/test/DeploymentHelpers/Common/ServerType.cs
@@ -1,4 +1,4 @@
-namespace E2ETests
+namespace DeploymentHelpers
{
public enum ServerType
{
diff --git a/test/DeploymentHelpers/Deployers/ApplicationDeployer.cs b/test/DeploymentHelpers/Deployers/ApplicationDeployer.cs
new file mode 100644
index 0000000000..b07d3b4f1c
--- /dev/null
+++ b/test/DeploymentHelpers/Deployers/ApplicationDeployer.cs
@@ -0,0 +1,173 @@
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.IO;
+using System.Text;
+using System.Text.RegularExpressions;
+using Microsoft.Framework.Logging;
+
+namespace DeploymentHelpers
+{
+ ///
+ /// Abstract base class of all deplolyers with a back bone implementation of some of the common helpers.
+ ///
+ public abstract class ApplicationDeployer : IApplicationDeployer
+ {
+ protected string ChosenRuntimePath { get; set; }
+
+ protected string ChosenRuntimeName { get; set; }
+
+ protected DeploymentParameters DeploymentParameters { get; private set; }
+
+ protected ILogger Logger { get; private set; }
+
+ public abstract DeploymentResult Deploy();
+
+ public ApplicationDeployer(
+ DeploymentParameters deploymentParameters,
+ ILogger logger)
+ {
+ DeploymentParameters = deploymentParameters;
+ Logger = logger;
+ }
+
+ protected string PopulateChosenRuntimeInformation()
+ {
+ var runtimePath = Process.GetCurrentProcess().MainModule.FileName;
+ Logger.LogInformation(string.Empty);
+ Logger.LogInformation("Current runtime path is : {0}", runtimePath);
+
+ var replaceStr = new StringBuilder().
+ Append("dnx").
+ Append((DeploymentParameters.RuntimeFlavor == RuntimeFlavor.coreclr) ? "-coreclr" : "-clr").
+ Append("-win").
+ Append((DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86) ? "-x86" : "-x64").
+ ToString();
+
+ runtimePath = Regex.Replace(runtimePath, "dnx-(clr|coreclr)-win-(x86|x64)", replaceStr, RegexOptions.IgnoreCase);
+ ChosenRuntimePath = Path.GetDirectoryName(runtimePath);
+
+ var runtimeDirectoryInfo = new DirectoryInfo(ChosenRuntimePath);
+ if (!runtimeDirectoryInfo.Exists)
+ {
+ throw new Exception(
+ string.Format("Requested runtime at location '{0}' does not exist. Please make sure it is installed before running test.",
+ runtimeDirectoryInfo.FullName));
+ }
+
+ ChosenRuntimeName = runtimeDirectoryInfo.Parent.Name;
+ Logger.LogInformation(string.Empty);
+ Logger.LogInformation("Changing to use runtime : {runtimeName}", ChosenRuntimeName);
+ return ChosenRuntimeName;
+ }
+
+ protected void DnuPublish(string publishRoot = null)
+ {
+ DeploymentParameters.PublishedApplicationRootPath = Path.Combine(publishRoot ?? Path.GetTempPath(), Guid.NewGuid().ToString());
+
+ var parameters =
+ string.Format(
+ "publish {0} -o {1} --runtime {2} {3}",
+ DeploymentParameters.ApplicationPath,
+ DeploymentParameters.PublishedApplicationRootPath,
+ DeploymentParameters.DnxRuntime,
+ DeploymentParameters.PublishWithNoSource ? "--no-source" : string.Empty);
+
+ Logger.LogInformation("Executing command dnu {args}", parameters);
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = Path.Combine(ChosenRuntimePath, "dnu.cmd"),
+ Arguments = parameters,
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
+ var hostProcess = Process.Start(startInfo);
+ hostProcess.WaitForExit(60 * 1000);
+
+ DeploymentParameters.ApplicationPath =
+ (DeploymentParameters.ServerType == ServerType.IISExpress ||
+ DeploymentParameters.ServerType == ServerType.IISNativeModule ||
+ DeploymentParameters.ServerType == ServerType.IIS) ?
+ Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "wwwroot") :
+ Path.Combine(DeploymentParameters.PublishedApplicationRootPath, "approot", "src", "MusicStore");
+
+ Logger.LogInformation("dnu publish finished with exit code : {exitCode}", hostProcess.ExitCode);
+ }
+
+ protected void CleanPublishedOutput()
+ {
+ try
+ {
+ // We've originally published the application in a temp folder. We need to delete it.
+ Directory.Delete(DeploymentParameters.PublishedApplicationRootPath, true);
+ }
+ catch (Exception exception)
+ {
+ Logger.LogWarning("Failed to delete directory : {error}", exception.Message);
+ }
+ }
+
+ protected void ShutDownIfAnyHostProcess(Process hostProcess)
+ {
+ if (hostProcess != null && !hostProcess.HasExited)
+ {
+ // Shutdown the host process.
+ hostProcess.Kill();
+ hostProcess.WaitForExit(5 * 1000);
+ if (!hostProcess.HasExited)
+ {
+ Logger.LogWarning("Unable to terminate the host process with process Id '{processId}", hostProcess.Id);
+ }
+ else
+ {
+ Logger.LogInformation("Successfully terminated host process with process Id '{processId}'", hostProcess.Id);
+ }
+ }
+ else
+ {
+ Logger.LogWarning("Host process already exited or never started successfully.");
+ }
+ }
+
+ protected void AddEnvironmentVariablesToProcess(ProcessStartInfo startInfo)
+ {
+ var environment =
+#if DNX451
+ startInfo.EnvironmentVariables;
+#elif DNXCORE50
+ startInfo.Environment;
+#endif
+
+ environment.Add("ASPNET_ENV", DeploymentParameters.EnvironmentName);
+
+ // Work around for https://github.com/aspnet/dnx/issues/1515
+ environment.Add("DNX_PACKAGES", string.Empty);
+ environment.Remove("DNX_DEFAULT_LIB");
+
+ foreach (var environmentVariable in DeploymentParameters.EnvironmentVariables)
+ {
+ environment.Add(environmentVariable.Key, environmentVariable.Value);
+ }
+ }
+
+ protected void InvokeUserApplicationCleanup()
+ {
+ if (DeploymentParameters.UserAdditionalCleanup != null)
+ {
+ // User cleanup.
+ try
+ {
+ DeploymentParameters.UserAdditionalCleanup(DeploymentParameters);
+ }
+ catch (Exception exception)
+ {
+ Logger.LogWarning("User cleanup code failed with exception : {exception}", exception.Message);
+ }
+ }
+ }
+
+ public abstract void Dispose();
+ }
+}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Deployers/ApplicationDeployerFactory.cs b/test/DeploymentHelpers/Deployers/ApplicationDeployerFactory.cs
new file mode 100644
index 0000000000..a6d9304382
--- /dev/null
+++ b/test/DeploymentHelpers/Deployers/ApplicationDeployerFactory.cs
@@ -0,0 +1,54 @@
+using System;
+using Microsoft.Framework.Logging;
+
+namespace DeploymentHelpers
+{
+ ///
+ /// Factory to create an appropriate deployer based on .
+ ///
+ public class ApplicationDeployerFactory
+ {
+ ///
+ /// Creates a deployer instance based on settings in .
+ ///
+ ///
+ ///
+ ///
+ public static IApplicationDeployer Create(DeploymentParameters deploymentParameters, ILogger logger)
+ {
+ if (deploymentParameters == null)
+ {
+ throw new ArgumentNullException(nameof(deploymentParameters));
+ }
+
+ if (logger == null)
+ {
+ throw new ArgumentNullException(nameof(logger));
+ }
+
+ if (deploymentParameters.RuntimeFlavor == RuntimeFlavor.mono)
+ {
+ return new MonoDeployer(deploymentParameters, logger);
+ }
+
+ switch (deploymentParameters.ServerType)
+ {
+ case ServerType.IISExpress:
+ return new IISExpressDeployer(deploymentParameters, logger);
+#if DNX451
+ case ServerType.IIS:
+ case ServerType.IISNativeModule:
+ return new IISDeployer(deploymentParameters, logger);
+#endif
+ case ServerType.WebListener:
+ case ServerType.Kestrel:
+ return new SelfHostDeployer(deploymentParameters, logger);
+ default:
+ throw new NotSupportedException(
+ string.Format("Found no deployers suitable for server type '{0}' with the current runtime.",
+ deploymentParameters.ServerType)
+ );
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Deployers/IApplicationDeployer.cs b/test/DeploymentHelpers/Deployers/IApplicationDeployer.cs
new file mode 100644
index 0000000000..bf27c51e65
--- /dev/null
+++ b/test/DeploymentHelpers/Deployers/IApplicationDeployer.cs
@@ -0,0 +1,16 @@
+using System;
+
+namespace DeploymentHelpers
+{
+ ///
+ /// Common operations on an application deployer.
+ ///
+ public interface IApplicationDeployer : IDisposable
+ {
+ ///
+ /// Deploys the application to the target with specified .
+ ///
+ ///
+ DeploymentResult Deploy();
+ }
+}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Deployers/IISDeployer.cs b/test/DeploymentHelpers/Deployers/IISDeployer.cs
new file mode 100644
index 0000000000..c10405be11
--- /dev/null
+++ b/test/DeploymentHelpers/Deployers/IISDeployer.cs
@@ -0,0 +1,195 @@
+#if DNX451
+using System;
+using System.IO;
+using System.Linq;
+using System.Threading;
+using System.Xml;
+using Microsoft.Framework.Logging;
+using Microsoft.Web.Administration;
+
+namespace DeploymentHelpers
+{
+ ///
+ /// Deployer for IIS (Both Helios and NativeModule).
+ ///
+ public class IISDeployer : ApplicationDeployer
+ {
+ private IISApplication _application;
+
+ public IISDeployer(DeploymentParameters startParameters, ILogger logger)
+ : base(startParameters, logger)
+ {
+ }
+
+ public override DeploymentResult Deploy()
+ {
+ // Only supports publish and run on IIS.
+ DeploymentParameters.PublishApplicationBeforeDeployment = true;
+
+ _application = new IISApplication(DeploymentParameters, Logger);
+
+ DeploymentParameters.DnxRuntime = PopulateChosenRuntimeInformation();
+
+ // Publish to IIS root\application folder.
+ DnuPublish(publishRoot: _application.WebSiteRootFolder);
+
+ // Drop an ini file instead of setting environment variable.
+ SetAspEnvironmentWithIni();
+
+ // Setup the IIS Application.
+ if (DeploymentParameters.ServerType == ServerType.IISNativeModule)
+ {
+ TurnRammFarOnNativeModule();
+ }
+
+ _application.Deploy();
+ Logger.LogInformation("Successfully finished IIS application directory setup.");
+
+ Thread.Sleep(1 * 1000);
+
+ return new DeploymentResult
+ {
+ WebRootLocation = DeploymentParameters.ApplicationPath,
+ DeploymentParameters = DeploymentParameters,
+ // Accomodate the vdir name.
+ ApplicationBaseUri = new UriBuilder(Uri.UriSchemeHttp, "localhost", _application.Port, _application.VirtualDirectoryName).Uri.AbsoluteUri + "/"
+ };
+ }
+
+ private void SetAspEnvironmentWithIni()
+ {
+ // Drop a Microsoft.AspNet.Hosting.ini with ASPNET_ENV information.
+ Logger.LogInformation("Creating Microsoft.AspNet.Hosting.ini file with ASPNET_ENV.");
+ var iniFile = Path.Combine(DeploymentParameters.ApplicationPath, "Microsoft.AspNet.Hosting.ini");
+ File.WriteAllText(iniFile, string.Format("ASPNET_ENV={0}", DeploymentParameters.EnvironmentName));
+ }
+
+ private void TurnRammFarOnNativeModule()
+ {
+ Logger.LogInformation("Turning runAllManagedModulesForAllRequests=true in web.config for native module.");
+ var webConfig = Path.Combine(DeploymentParameters.ApplicationPath, "web.config");
+ var configuration = new XmlDocument();
+ configuration.LoadXml(File.ReadAllText(webConfig));
+
+ // https://github.com/aspnet/Helios/issues/77
+ var rammfarAttribute = configuration.CreateAttribute("runAllManagedModulesForAllRequests");
+ rammfarAttribute.Value = "true";
+ var modulesNode = configuration.CreateElement("modules");
+ modulesNode.Attributes.Append(rammfarAttribute);
+ var systemWebServerNode = configuration.CreateElement("system.webServer");
+ systemWebServerNode.AppendChild(modulesNode);
+ configuration.SelectSingleNode("//configuration").AppendChild(systemWebServerNode);
+ configuration.Save(webConfig);
+ }
+
+ public override void Dispose()
+ {
+ if (_application != null)
+ {
+ _application.StopAndDeleteAppPool();
+ }
+
+ CleanPublishedOutput();
+ InvokeUserApplicationCleanup();
+ }
+
+ private class IISApplication
+ {
+ private const string WEBSITE_NAME = "TestWebSite";
+ private const string NATIVE_MODULE_MANAGED_RUNTIME_VERSION = "vCoreFX";
+
+ private readonly ServerManager _serverManager = new ServerManager();
+ private readonly DeploymentParameters _startParameters;
+ private readonly ILogger _logger;
+ private ApplicationPool _applicationPool;
+ private Application _application;
+
+ public string VirtualDirectoryName { get; set; }
+
+ public string WebSiteRootFolder
+ {
+ get
+ {
+ return Path.Combine(
+ Environment.GetEnvironmentVariable("SystemDrive") + @"\",
+ "inetpub",
+ "TestWebSite");
+ }
+ }
+
+ public int Port
+ {
+ get
+ {
+ return new Uri(_startParameters.ApplicationBaseUriHint).Port;
+ }
+ }
+
+ public IISApplication(DeploymentParameters startParameters, ILogger logger)
+ {
+ _startParameters = startParameters;
+ _logger = logger;
+ }
+
+ public void Deploy()
+ {
+ VirtualDirectoryName = new DirectoryInfo(_startParameters.ApplicationPath).Parent.Name;
+ _applicationPool = CreateAppPool(VirtualDirectoryName);
+ _application = Website.Applications.Add("/" + VirtualDirectoryName, _startParameters.ApplicationPath);
+ _application.ApplicationPoolName = _applicationPool.Name;
+ _serverManager.CommitChanges();
+ }
+
+ private Site _website;
+ private Site Website
+ {
+ get
+ {
+ _website = _serverManager.Sites.Where(s => s.Name == WEBSITE_NAME).FirstOrDefault();
+ if (_website == null)
+ {
+ _website = _serverManager.Sites.Add(WEBSITE_NAME, WebSiteRootFolder, Port);
+ }
+
+ return _website;
+ }
+ }
+
+ private ApplicationPool CreateAppPool(string appPoolName)
+ {
+ var applicationPool = _serverManager.ApplicationPools.Add(appPoolName);
+ if (_startParameters.ServerType == ServerType.IISNativeModule)
+ {
+ // Not assigning a runtime version will choose v4.0 default.
+ applicationPool.ManagedRuntimeVersion = NATIVE_MODULE_MANAGED_RUNTIME_VERSION;
+ }
+
+ applicationPool.Enable32BitAppOnWin64 = (_startParameters.RuntimeArchitecture == RuntimeArchitecture.x86);
+ _logger.LogInformation("Created {bit} application pool '{name}' with runtime version '{runtime}'.",
+ _startParameters.RuntimeArchitecture, applicationPool.Name,
+ applicationPool.ManagedRuntimeVersion ?? "default");
+ return applicationPool;
+ }
+
+ public void StopAndDeleteAppPool()
+ {
+ if (_applicationPool != null)
+ {
+ _logger.LogInformation("Stopping application pool '{name}' and deleting application.", _applicationPool.Name);
+ _applicationPool.Stop();
+ }
+
+ // Remove the application from website.
+ if (_application != null)
+ {
+ _application = Website.Applications.Where(a => a.Path == _application.Path).FirstOrDefault();
+ Website.Applications.Remove(_application);
+ _serverManager.ApplicationPools.Remove(_serverManager.ApplicationPools[_applicationPool.Name]);
+ _serverManager.CommitChanges();
+ _logger.LogInformation("Successfully stopped application pool '{name}' and deleted application from IIS.", _applicationPool.Name);
+ }
+ }
+ }
+ }
+}
+#endif
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Deployers/IISExpressDeployer.cs b/test/DeploymentHelpers/Deployers/IISExpressDeployer.cs
new file mode 100644
index 0000000000..2600e792fa
--- /dev/null
+++ b/test/DeploymentHelpers/Deployers/IISExpressDeployer.cs
@@ -0,0 +1,184 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using Microsoft.Framework.Logging;
+using Microsoft.Framework.Runtime;
+using Microsoft.Framework.Runtime.Infrastructure;
+
+namespace DeploymentHelpers
+{
+ ///
+ /// Deployment helper for IISExpress.
+ ///
+ public class IISExpressDeployer : ApplicationDeployer
+ {
+ private Process _hostProcess;
+
+ public IISExpressDeployer(DeploymentParameters deploymentParameters, ILogger logger)
+ : base(deploymentParameters, logger)
+ {
+ }
+
+ public override DeploymentResult Deploy()
+ {
+ DeploymentParameters.DnxRuntime = PopulateChosenRuntimeInformation();
+
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ DnuPublish();
+ }
+
+ // Launch the host process.
+ _hostProcess = 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
+ };
+ }
+
+ private Process StartHeliosHost()
+ {
+ if (!string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigTemplateContent))
+ {
+ // Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config
+ // We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo.
+
+ DeploymentParameters.ApplicationHostConfigTemplateContent =
+ DeploymentParameters.ApplicationHostConfigTemplateContent
+ .Replace("[ApplicationPhysicalPath]", Path.Combine(DeploymentParameters.ApplicationPath, "wwwroot"))
+ .Replace("[PORT]", new Uri(DeploymentParameters.ApplicationBaseUriHint).Port.ToString());
+
+ DeploymentParameters.ApplicationHostConfigLocation = Path.GetTempFileName();
+
+ File.WriteAllText(DeploymentParameters.ApplicationHostConfigLocation,
+ DeploymentParameters.ApplicationHostConfigTemplateContent.Replace("[ApplicationPhysicalPath]", DeploymentParameters.ApplicationPath));
+ }
+
+ if (!DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ CopyAspNetLoader();
+ }
+
+ var webroot = DeploymentParameters.ApplicationPath;
+ if (!webroot.EndsWith("wwwroot"))
+ {
+ webroot = Path.Combine(webroot, "wwwroot");
+ }
+
+ var parameters = string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigLocation) ?
+ string.Format("/port:{0} /path:\"{1}\"", new Uri(DeploymentParameters.ApplicationBaseUriHint).Port, webroot) :
+ string.Format("/site:{0} /config:{1}", DeploymentParameters.SiteName, DeploymentParameters.ApplicationHostConfigLocation);
+
+ var iisExpressPath = GetIISExpressPath();
+
+ Logger.LogInformation("Executing command : {iisExpress} {args}", iisExpressPath, parameters);
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = iisExpressPath,
+ Arguments = parameters,
+ UseShellExecute = false,
+ CreateNoWindow = false
+ };
+
+ AddEnvironmentVariablesToProcess(startInfo);
+
+ // IIS express figures out the DNX from %PATH%.
+#if DNX451
+ startInfo.EnvironmentVariables["PATH"] = ChosenRuntimePath + ";" + startInfo.EnvironmentVariables["PATH"];
+#elif DNXCORE50
+ startInfo.Environment["PATH"] = ChosenRuntimePath + ";" + startInfo.Environment["PATH"];
+#endif
+
+ Process hostProcess = Process.Start(startInfo);
+ Logger.LogInformation("Started iisexpress. Process Id : {processId}", hostProcess.Id);
+
+ return hostProcess;
+ }
+
+ private void CopyAspNetLoader()
+ {
+ var libraryManager = (ILibraryManager)CallContextServiceLocator.Locator.ServiceProvider.GetService(typeof(ILibraryManager));
+ var interopLibrary = libraryManager.GetLibraryInformation("Microsoft.AspNet.Loader.IIS.Interop");
+
+ if (interopLibrary == null)
+ {
+ throw new Exception(
+ string.Format("Include Microsoft.AspNet.Server.IIS package in your project.json to deploy in {0}.",
+ ServerType.IISExpress));
+ }
+
+ var aspNetLoaderSrcPath = Path.Combine(interopLibrary.Path, "tools", "AspNet.Loader.dll");
+ var aspNetLoaderDestPath = Path.Combine(DeploymentParameters.ApplicationPath, "wwwroot", "bin", "AspNet.Loader.dll");
+
+ // Create bin directory if it does not exist.
+ Directory.CreateDirectory(new DirectoryInfo(aspNetLoaderDestPath).Parent.FullName);
+
+ if (!File.Exists(aspNetLoaderDestPath))
+ {
+ try
+ {
+ File.Copy(aspNetLoaderSrcPath, aspNetLoaderDestPath);
+ }
+ catch (IOException)
+ {
+ // Ignore file already exists exception. Sometimes multiple tests might try
+ // doing the same and one of them wins.
+ }
+ }
+ }
+
+ private string GetIISExpressPath()
+ {
+ // Get path to program files
+ var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles(x86)"), "IIS Express", "iisexpress.exe");
+
+ // Get path to 64 bit of IIS Express
+ if (DeploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x64)
+ {
+ iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles"), "IIS Express", "iisexpress.exe");
+
+ // If process is 32 bit, the path points to x86. Replace path to point to x64
+ iisExpressPath = IntPtr.Size == 8 ? iisExpressPath : iisExpressPath.Replace(" (x86)", "");
+ }
+
+ if (!File.Exists(iisExpressPath))
+ {
+ throw new Exception("Unable to find IISExpress on the machine");
+ }
+
+ return iisExpressPath;
+ }
+
+ public override void Dispose()
+ {
+ ShutDownIfAnyHostProcess(_hostProcess);
+
+ if (!string.IsNullOrWhiteSpace(DeploymentParameters.ApplicationHostConfigLocation)
+ && File.Exists(DeploymentParameters.ApplicationHostConfigLocation))
+ {
+ // Delete the temp applicationHostConfig that we created.
+ try
+ {
+ File.Delete(DeploymentParameters.ApplicationHostConfigLocation);
+ }
+ catch (Exception exception)
+ {
+ // Ignore delete failures - just write a log.
+ Logger.LogWarning("Failed to delete '{config}'. Exception : {exception}", DeploymentParameters.ApplicationHostConfigLocation, exception.Message);
+ }
+ }
+
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ CleanPublishedOutput();
+ }
+
+ InvokeUserApplicationCleanup();
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Deployers/MonoDeployer.cs b/test/DeploymentHelpers/Deployers/MonoDeployer.cs
new file mode 100644
index 0000000000..67bfbb65fa
--- /dev/null
+++ b/test/DeploymentHelpers/Deployers/MonoDeployer.cs
@@ -0,0 +1,93 @@
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Linq;
+using Microsoft.Framework.Logging;
+
+namespace DeploymentHelpers
+{
+ ///
+ /// Deployer for Kestrel on Mono.
+ ///
+ public class MonoDeployer : ApplicationDeployer
+ {
+ private Process _hostProcess;
+
+ public MonoDeployer(DeploymentParameters deploymentParameters, ILogger logger)
+ : base(deploymentParameters, logger)
+ {
+ }
+
+ public override DeploymentResult Deploy()
+ {
+ var path = Environment.GetEnvironmentVariable("PATH");
+ var runtimeBin = path.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries).
+ Where(c => c.Contains("dnx-mono")).FirstOrDefault();
+
+ if (string.IsNullOrWhiteSpace(runtimeBin))
+ {
+ throw new Exception("Runtime not detected on the machine.");
+ }
+
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ // We use full path to runtime to pack.
+ DeploymentParameters.DnxRuntime = new DirectoryInfo(runtimeBin).Parent.FullName;
+ DnuPublish();
+ }
+
+ // Launch the host process.
+ _hostProcess = StartMonoHost();
+
+ return new DeploymentResult
+ {
+ WebRootLocation = DeploymentParameters.ApplicationPath,
+ DeploymentParameters = DeploymentParameters,
+ ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint
+ };
+ }
+
+ private Process StartMonoHost()
+ {
+ if (DeploymentParameters.ServerType != ServerType.Kestrel)
+ {
+ throw new InvalidOperationException("kestrel is the only valid ServerType for Mono");
+ }
+
+ Logger.LogInformation("Executing command: dnx \"{appPath}\" kestrel --server.urls {url}",
+ DeploymentParameters.ApplicationPath, DeploymentParameters.ApplicationBaseUriHint);
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = "dnx",
+ Arguments = string.Format("\"{0}\" kestrel --server.urls {1}", DeploymentParameters.ApplicationPath, DeploymentParameters.ApplicationBaseUriHint),
+ UseShellExecute = false,
+ CreateNoWindow = true,
+ RedirectStandardInput = true
+ };
+
+ var hostProcess = Process.Start(startInfo);
+ 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;
+ }
+
+ public override void Dispose()
+ {
+ ShutDownIfAnyHostProcess(_hostProcess);
+
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ CleanPublishedOutput();
+ }
+
+ InvokeUserApplicationCleanup();
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/Deployers/SelfHostDeployer.cs b/test/DeploymentHelpers/Deployers/SelfHostDeployer.cs
new file mode 100644
index 0000000000..ca35162a53
--- /dev/null
+++ b/test/DeploymentHelpers/Deployers/SelfHostDeployer.cs
@@ -0,0 +1,91 @@
+using System;
+using System.ComponentModel;
+using System.Diagnostics;
+using System.IO;
+using System.Threading;
+using Microsoft.Framework.Logging;
+
+namespace DeploymentHelpers
+{
+ ///
+ /// Deployer for WebListener and Kestrel.
+ ///
+ public class SelfHostDeployer : ApplicationDeployer
+ {
+ private Process _hostProcess;
+
+ public SelfHostDeployer(DeploymentParameters deploymentParameters, ILogger logger)
+ : base(deploymentParameters, logger)
+ {
+ }
+
+ public override DeploymentResult Deploy()
+ {
+ DeploymentParameters.DnxRuntime = PopulateChosenRuntimeInformation();
+
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ DnuPublish();
+ }
+
+ // Launch the host process.
+ _hostProcess = StartSelfHost();
+
+ return new DeploymentResult
+ {
+ WebRootLocation = DeploymentParameters.ApplicationPath,
+ DeploymentParameters = DeploymentParameters,
+ ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint
+ };
+ }
+
+ private Process StartSelfHost()
+ {
+ var commandName = DeploymentParameters.ServerType == ServerType.WebListener ? "web" : "kestrel";
+ Logger.LogInformation("Executing dnx.exe {appPath} {command} --server.urls {url}", DeploymentParameters.ApplicationPath, commandName, DeploymentParameters.ApplicationBaseUriHint);
+
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = Path.Combine(ChosenRuntimePath, "dnx.exe"),
+ Arguments = string.Format("\"{0}\" {1} --server.urls {2}", DeploymentParameters.ApplicationPath, commandName, DeploymentParameters.ApplicationBaseUriHint),
+ UseShellExecute = false,
+ CreateNoWindow = true
+ };
+
+ AddEnvironmentVariablesToProcess(startInfo);
+ var hostProcess = Process.Start(startInfo);
+
+ //Sometimes reading MainModule returns null if called immediately after starting process.
+ Thread.Sleep(1 * 1000);
+
+ 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");
+ }
+
+ try
+ {
+ Logger.LogInformation("Started {fileName}. Process Id : {processId}", hostProcess.MainModule.FileName, hostProcess.Id);
+ }
+ catch (Win32Exception)
+ {
+ // Ignore.
+ }
+
+ return hostProcess;
+ }
+
+ public override void Dispose()
+ {
+ ShutDownIfAnyHostProcess(_hostProcess);
+
+ if (DeploymentParameters.PublishApplicationBeforeDeployment)
+ {
+ CleanPublishedOutput();
+ }
+
+ InvokeUserApplicationCleanup();
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/DeploymentHelpers/DeploymentHelpers.xproj b/test/DeploymentHelpers/DeploymentHelpers.xproj
new file mode 100644
index 0000000000..7209772a5b
--- /dev/null
+++ b/test/DeploymentHelpers/DeploymentHelpers.xproj
@@ -0,0 +1,26 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+
+ c98e54d3-f4c6-4d16-a5a6-e86a636a7311
+ DeploymentHelpers
+ ..\..\artifacts\obj\$(MSBuildProjectName)
+ ..\..\artifacts\bin\$(MSBuildProjectName)\
+
+
+
+ 2.0
+
+
+ True
+
+
+ True
+
+
+
diff --git a/test/DeploymentHelpers/project.json b/test/DeploymentHelpers/project.json
new file mode 100644
index 0000000000..3c4612fae9
--- /dev/null
+++ b/test/DeploymentHelpers/project.json
@@ -0,0 +1,32 @@
+{
+ "version": "1.0.0-*",
+ "description": "Helpers to deploy applications to IIS Express, IIS, WebListener and Kestrel.",
+ "dependencies": {
+ "Microsoft.AspNet.Testing": "1.0.0-*",
+ "Microsoft.Framework.Logging.Interfaces": "1.0.0-*",
+ "Microsoft.Framework.Runtime.Interfaces": "1.0.0-*"
+ },
+ "frameworks": {
+ "dnx451": {
+ "dependencies": {
+ "Microsoft.Web.Administration": "7.0.0"
+ },
+ "frameworkAssemblies": {
+ "System.Net.Http": "",
+ "System.Xml": ""
+ }
+ },
+ "dnxcore50": {
+ "dependencies": {
+ "Microsoft.Win32.Primitives": "4.0.0-beta-*",
+ "System.Diagnostics.Process": "4.0.0-beta-*",
+ "System.IO.FileSystem": "4.0.0-*",
+ "System.Net.Http": "4.0.0-beta-*",
+ "System.Runtime.Extensions": "4.0.10-beta-*",
+ "System.Text.RegularExpressions": "4.0.10-beta-*",
+ "System.Threading": "4.0.10-beta-*",
+ "System.Threading.Thread": "4.0.0-*"
+ }
+ }
+ }
+}
\ No newline at end of file
diff --git a/test/E2ETests/xunit/SkipIfCurrentRuntimeIsCoreClr.cs b/test/DeploymentHelpers/xunit/SkipIfCurrentRuntimeIsCoreClr.cs
similarity index 95%
rename from test/E2ETests/xunit/SkipIfCurrentRuntimeIsCoreClr.cs
rename to test/DeploymentHelpers/xunit/SkipIfCurrentRuntimeIsCoreClr.cs
index 82e2533775..0e53655217 100644
--- a/test/E2ETests/xunit/SkipIfCurrentRuntimeIsCoreClr.cs
+++ b/test/DeploymentHelpers/xunit/SkipIfCurrentRuntimeIsCoreClr.cs
@@ -2,7 +2,7 @@
using System.Diagnostics;
using Microsoft.AspNet.Testing.xunit;
-namespace E2ETests
+namespace DeploymentHelpers
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class SkipIfCurrentRuntimeIsCoreClrAttribute : Attribute, ITestCondition
diff --git a/test/E2ETests/xunit/SkipIfNativeModuleNotInstalledAttribute.cs b/test/DeploymentHelpers/xunit/SkipIfNativeModuleNotInstalledAttribute.cs
similarity index 96%
rename from test/E2ETests/xunit/SkipIfNativeModuleNotInstalledAttribute.cs
rename to test/DeploymentHelpers/xunit/SkipIfNativeModuleNotInstalledAttribute.cs
index 1196b613ec..e6e62c2330 100644
--- a/test/E2ETests/xunit/SkipIfNativeModuleNotInstalledAttribute.cs
+++ b/test/DeploymentHelpers/xunit/SkipIfNativeModuleNotInstalledAttribute.cs
@@ -1,7 +1,7 @@
using System;
using Microsoft.AspNet.Testing.xunit;
-namespace E2ETests
+namespace DeploymentHelpers
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class SkipIfNativeModuleNotInstalledAttribute : Attribute, ITestCondition
diff --git a/test/E2ETests/xunit/SkipOn32BitOSAttribute.cs b/test/DeploymentHelpers/xunit/SkipOn32BitOSAttribute.cs
similarity index 95%
rename from test/E2ETests/xunit/SkipOn32BitOSAttribute.cs
rename to test/DeploymentHelpers/xunit/SkipOn32BitOSAttribute.cs
index 1a6cf49b73..f0b0c324f0 100644
--- a/test/E2ETests/xunit/SkipOn32BitOSAttribute.cs
+++ b/test/DeploymentHelpers/xunit/SkipOn32BitOSAttribute.cs
@@ -2,7 +2,7 @@
using System.IO;
using Microsoft.AspNet.Testing.xunit;
-namespace E2ETests
+namespace DeploymentHelpers
{
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
public class SkipOn32BitOSAttribute : Attribute, ITestCondition
diff --git a/test/E2ETests/Common/DeploymentUtility.cs b/test/E2ETests/Common/DeploymentUtility.cs
deleted file mode 100644
index 1aeab11de7..0000000000
--- a/test/E2ETests/Common/DeploymentUtility.cs
+++ /dev/null
@@ -1,427 +0,0 @@
-using System;
-using System.ComponentModel;
-using System.Diagnostics;
-using System.IO;
-using System.Linq;
-using System.Text;
-using System.Text.RegularExpressions;
-using System.Threading;
-using System.Xml;
-using Microsoft.Framework.Logging;
-
-namespace E2ETests
-{
- internal class DeploymentUtility
- {
- private static string APP_RELATIVE_PATH = Path.Combine("..", "..", "src", "MusicStore");
-
- public static Process StartApplication(StartParameters startParameters, ILogger logger)
- {
- startParameters.ApplicationPath = Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), APP_RELATIVE_PATH));
-
- //To avoid the DNX_DEFAULT_LIB of the test process flowing into Helios, set it to empty
- var backupRuntimeDefaultLibPath = Environment.GetEnvironmentVariable("DNX_DEFAULT_LIB");
- Environment.SetEnvironmentVariable("DNX_DEFAULT_LIB", string.Empty);
-
- if (!string.IsNullOrWhiteSpace(startParameters.EnvironmentName))
- {
- if (startParameters.ServerType != ServerType.IISNativeModule &&
- startParameters.ServerType != ServerType.IIS)
- {
- // To choose an environment based Startup.
- Environment.SetEnvironmentVariable("ASPNET_ENV", startParameters.EnvironmentName);
- }
- else
- {
- // Cannot override with environment in case of IIS. Publish and write a Microsoft.AspNet.Hosting.ini file.
- startParameters.PublishApplicationBeforeStart = true;
- }
- }
-
- Process hostProcess = null;
-
- if (startParameters.RuntimeFlavor == RuntimeFlavor.Mono)
- {
- hostProcess = StartMonoHost(startParameters, logger);
- }
- else
- {
- //Tweak the %PATH% to the point to the right RUNTIMEFLAVOR
- startParameters.Runtime = SwitchPathToRuntimeFlavor(startParameters.RuntimeFlavor, startParameters.RuntimeArchitecture, logger);
-
- //Reason to do pack here instead of in a common place is use the right runtime to do the packing. Previous line switches to use the right runtime.
- if (startParameters.PublishApplicationBeforeStart)
- {
-#if DNX451
- if (startParameters.ServerType == ServerType.IISNativeModule ||
- startParameters.ServerType == ServerType.IIS)
- {
- // Publish to IIS root\application folder.
- DnuPublish(startParameters, logger, Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + @"\", @"inetpub\wwwroot"));
-
- // Drop a Microsoft.AspNet.Hosting.ini with ASPNET_ENV information.
- logger.LogInformation("Creating Microsoft.AspNet.Hosting.ini file with ASPNET_ENV.");
- var iniFile = Path.Combine(startParameters.ApplicationPath, "Microsoft.AspNet.Hosting.ini");
- File.WriteAllText(iniFile, string.Format("ASPNET_ENV={0}", startParameters.EnvironmentName));
-
- // Can't use localdb with IIS. Setting an override to use InMemoryStore.
- logger.LogInformation("Creating configoverride.json file to override default config.");
- var overrideConfig = Path.Combine(startParameters.ApplicationPath, "..", "approot", "src", "MusicStore", "configoverride.json");
- overrideConfig = Path.GetFullPath(overrideConfig);
- File.WriteAllText(overrideConfig, "{\"UseInMemoryStore\": \"true\"}");
-
- if (startParameters.ServerType == ServerType.IISNativeModule)
- {
- logger.LogInformation("Turning runAllManagedModulesForAllRequests=true in web.config.");
- // Set runAllManagedModulesForAllRequests=true
- var webConfig = Path.Combine(startParameters.ApplicationPath, "web.config");
- var configuration = new XmlDocument();
- configuration.LoadXml(File.ReadAllText(webConfig));
-
- // https://github.com/aspnet/Helios/issues/77
- var rammfarAttribute = configuration.CreateAttribute("runAllManagedModulesForAllRequests");
- rammfarAttribute.Value = "true";
- var modulesNode = configuration.CreateElement("modules");
- modulesNode.Attributes.Append(rammfarAttribute);
- var systemWebServerNode = configuration.CreateElement("system.webServer");
- systemWebServerNode.AppendChild(modulesNode);
- configuration.SelectSingleNode("//configuration").AppendChild(systemWebServerNode);
- configuration.Save(webConfig);
- }
-
- logger.LogInformation("Successfully finished IIS application directory setup.");
-
- Thread.Sleep(1 * 1000);
- }
- else
-#endif
- {
- DnuPublish(startParameters, logger);
- }
- }
-
-#if DNX451
- if (startParameters.ServerType == ServerType.IISNativeModule ||
- startParameters.ServerType == ServerType.IIS)
- {
- startParameters.IISApplication = new IISApplication(startParameters, logger);
- startParameters.IISApplication.SetupApplication();
- }
- else
-#endif
- if (startParameters.ServerType == ServerType.IISExpress)
- {
- hostProcess = StartHeliosHost(startParameters, logger);
- }
- else
- {
- hostProcess = StartSelfHost(startParameters, logger);
- }
- }
-
- //Restore the DNX_DEFAULT_LIB after starting the host process
- Environment.SetEnvironmentVariable("DNX_DEFAULT_LIB", backupRuntimeDefaultLibPath);
- Environment.SetEnvironmentVariable("ASPNET_ENV", string.Empty);
- return hostProcess;
- }
-
- private static Process StartMonoHost(StartParameters startParameters, ILogger logger)
- {
- var path = Environment.GetEnvironmentVariable("PATH");
- var runtimeBin = path.Split(new char[] { ':' }, StringSplitOptions.RemoveEmptyEntries).
- Where(c => c.Contains("dnx-mono")).FirstOrDefault();
-
- if (string.IsNullOrWhiteSpace(runtimeBin))
- {
- throw new Exception("Runtime not detected on the machine.");
- }
-
- if (startParameters.PublishApplicationBeforeStart)
- {
- // We use full path to runtime to pack.
- startParameters.Runtime = new DirectoryInfo(runtimeBin).Parent.FullName;
- DnuPublish(startParameters, logger);
- }
-
- //Mono now supports --appbase
- logger.LogInformation("Setting the --appbase to {0}", startParameters.ApplicationPath);
-
- var bootstrapper = "dnx";
-
- var commandName = startParameters.ServerType == ServerType.Kestrel ? "kestrel" : string.Empty;
- logger.LogInformation("Executing command: {dnx} \"{appPath}\" {command}", bootstrapper, startParameters.ApplicationPath, commandName);
-
- var startInfo = new ProcessStartInfo
- {
- FileName = bootstrapper,
- Arguments = string.Format("\"{0}\" {1}", startParameters.ApplicationPath, commandName),
- UseShellExecute = false,
- CreateNoWindow = true,
- RedirectStandardInput = true
- };
-
- var hostProcess = Process.Start(startInfo);
- 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;
- }
-
- private static Process StartHeliosHost(StartParameters startParameters, ILogger logger)
- {
- if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigTemplateContent))
- {
- startParameters.ApplicationHostConfigTemplateContent =
- startParameters.ApplicationHostConfigTemplateContent.Replace("[ApplicationPhysicalPath]", Path.Combine(startParameters.ApplicationPath, "wwwroot"));
- }
-
- if (!startParameters.PublishApplicationBeforeStart)
- {
- IISExpressHelper.CopyAspNetLoader(startParameters.ApplicationPath);
- }
-
- if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigTemplateContent))
- {
- //Pass on the applicationhost.config to iis express. With this don't need to pass in the /path /port switches as they are in the applicationHost.config
- //We take a copy of the original specified applicationHost.Config to prevent modifying the one in the repo.
-
- var tempApplicationHostConfig = Path.GetTempFileName();
- File.WriteAllText(tempApplicationHostConfig, startParameters.ApplicationHostConfigTemplateContent.Replace("[ApplicationPhysicalPath]", startParameters.ApplicationPath));
- startParameters.ApplicationHostConfigLocation = tempApplicationHostConfig;
- }
-
- var webroot = startParameters.ApplicationPath;
- if (!webroot.EndsWith("wwwroot"))
- {
- webroot = Path.Combine(webroot, "wwwroot");
- }
-
- var parameters = string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigLocation) ?
- string.Format("/port:5001 /path:\"{0}\"", webroot) :
- string.Format("/site:{0} /config:{1}", startParameters.SiteName, startParameters.ApplicationHostConfigLocation);
-
- var iisExpressPath = IISExpressHelper.GetPath(startParameters.RuntimeArchitecture);
-
- logger.LogInformation("Executing command : {iisExpress} {args}", iisExpressPath, parameters);
-
- var startInfo = new ProcessStartInfo
- {
- FileName = iisExpressPath,
- Arguments = parameters,
- UseShellExecute = true,
- CreateNoWindow = true
- };
-
- // Work around for https://github.com/aspnet/dnx/issues/1515
- string backup_Dnx_Packages = string.Empty;
- if (startParameters.PublishWithNoSource)
- {
- backup_Dnx_Packages = Environment.GetEnvironmentVariable("DNX_PACKAGES");
- Environment.SetEnvironmentVariable("DNX_PACKAGES", string.Empty);
- }
-
- var hostProcess = Process.Start(startInfo);
- logger.LogInformation("Started iisexpress. Process Id : {processId}", hostProcess.Id);
-
- if (startParameters.PublishWithNoSource)
- {
- // Roll back the change.
- Environment.SetEnvironmentVariable("DNX_PACKAGES", backup_Dnx_Packages);
- }
-
- return hostProcess;
- }
-
- private static Process StartSelfHost(StartParameters startParameters, ILogger logger)
- {
- var commandName = startParameters.ServerType == ServerType.WebListener ? "web" : "kestrel";
- logger.LogInformation("Executing dnx.exe --appbase {appPath} \"Microsoft.Framework.ApplicationHost\" {command}", startParameters.ApplicationPath, commandName);
-
- var startInfo = new ProcessStartInfo
- {
- FileName = "dnx.exe",
- Arguments = string.Format("--appbase \"{0}\" \"Microsoft.Framework.ApplicationHost\" {1}", startParameters.ApplicationPath, commandName),
- UseShellExecute = true,
- CreateNoWindow = true
- };
-
- // Work around for https://github.com/aspnet/dnx/issues/1515
- string backup_Dnx_Packages = string.Empty;
- if (startParameters.PublishWithNoSource)
- {
- backup_Dnx_Packages = Environment.GetEnvironmentVariable("DNX_PACKAGES");
- Environment.SetEnvironmentVariable("DNX_PACKAGES", string.Empty);
- }
-
- var hostProcess = Process.Start(startInfo);
-
- if (startParameters.PublishWithNoSource)
- {
- // Roll back the change.
- Environment.SetEnvironmentVariable("DNX_PACKAGES", backup_Dnx_Packages);
- }
-
- //Sometimes reading MainModule returns null if called immediately after starting process.
- Thread.Sleep(1 * 1000);
-
- 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");
- }
-
- try
- {
- logger.LogInformation("Started {fileName}. Process Id : {processId}", hostProcess.MainModule.FileName, hostProcess.Id);
- }
- catch (Win32Exception win32Exception)
- {
- logger.LogWarning("Cannot access 64 bit modules from a 32 bit process. Failed with following message : {error}", win32Exception.Message);
- }
-
- return hostProcess;
- }
-
- private static string SwitchPathToRuntimeFlavor(RuntimeFlavor runtimeFlavor, RuntimeArchitecture runtimeArchitecture, ILogger logger)
- {
- var runtimePath = Process.GetCurrentProcess().MainModule.FileName;
- logger.LogInformation(string.Empty);
- logger.LogInformation("Current runtime path is : {0}", runtimePath);
-
- var replaceStr = new StringBuilder().
- Append("dnx").
- Append((runtimeFlavor == RuntimeFlavor.CoreClr) ? "-coreclr" : "-clr").
- Append("-win").
- Append((runtimeArchitecture == RuntimeArchitecture.x86) ? "-x86" : "-x64").
- ToString();
-
- runtimePath = Regex.Replace(runtimePath, "dnx-(clr|coreclr)-win-(x86|x64)", replaceStr, RegexOptions.IgnoreCase);
- runtimePath = Path.GetDirectoryName(runtimePath);
-
- // Tweak the %PATH% to the point to the right RUNTIMEFLAVOR.
- Environment.SetEnvironmentVariable("PATH", runtimePath + ";" + Environment.GetEnvironmentVariable("PATH"));
-
- var runtimeDirectoryInfo = new DirectoryInfo(runtimePath);
- if (!runtimeDirectoryInfo.Exists)
- {
- throw new Exception(
- string.Format("Requested runtime at location '{0}' does not exist. Please make sure it is installed before running test.",
- runtimeDirectoryInfo.FullName));
- }
-
- var runtimeName = runtimeDirectoryInfo.Parent.Name;
- logger.LogInformation(string.Empty);
- logger.LogInformation("Changing to use runtime : {runtimeName}", runtimeName);
- return runtimeName;
- }
-
- private static void DnuPublish(StartParameters startParameters, ILogger logger, string publishRoot = null)
- {
- startParameters.PublishedApplicationRootPath = Path.Combine(publishRoot ?? Path.GetTempPath(), Guid.NewGuid().ToString());
-
- var parameters =
- string.Format(
- "publish {0} -o {1} --runtime {2} {3}",
- startParameters.ApplicationPath,
- startParameters.PublishedApplicationRootPath,
- startParameters.Runtime,
- startParameters.PublishWithNoSource ? "--no-source" : string.Empty);
-
- logger.LogInformation("Executing command dnu {args}", parameters);
-
- var startInfo = new ProcessStartInfo
- {
- FileName = "dnu",
- Arguments = parameters,
- UseShellExecute = true,
- CreateNoWindow = true
- };
-
- var hostProcess = Process.Start(startInfo);
- hostProcess.WaitForExit(60 * 1000);
-
- startParameters.ApplicationPath =
- (startParameters.ServerType == ServerType.IISExpress ||
- startParameters.ServerType == ServerType.IISNativeModule ||
- startParameters.ServerType == ServerType.IIS) ?
- Path.Combine(startParameters.PublishedApplicationRootPath, "wwwroot") :
- Path.Combine(startParameters.PublishedApplicationRootPath, "approot", "src", "MusicStore");
-
- logger.LogInformation("dnu publish finished with exit code : {exitCode}", hostProcess.ExitCode);
- }
-
- public static void CleanUpApplication(StartParameters startParameters, Process hostProcess, string musicStoreDbName, ILogger logger)
- {
- if (startParameters.ServerType == ServerType.IISNativeModule ||
- startParameters.ServerType == ServerType.IIS)
- {
-#if DNX451
- // Stop & delete the application pool.
- if (startParameters.IISApplication != null)
- {
- startParameters.IISApplication.StopAndDeleteAppPool();
- }
-#endif
- }
- else if (hostProcess != null && !hostProcess.HasExited)
- {
- //Shutdown the host process
- hostProcess.Kill();
- hostProcess.WaitForExit(5 * 1000);
- if (!hostProcess.HasExited)
- {
- logger.LogWarning("Unable to terminate the host process with process Id '{processId}", hostProcess.Id);
- }
- else
- {
- logger.LogInformation("Successfully terminated host process with process Id '{processId}'", hostProcess.Id);
- }
- }
- else
- {
- logger.LogWarning("Host process already exited or never started successfully.");
- }
-
- if (!Helpers.RunningOnMono)
- {
- //Mono uses InMemoryStore
- DbUtils.DropDatabase(musicStoreDbName, logger);
- }
-
- if (!string.IsNullOrWhiteSpace(startParameters.ApplicationHostConfigLocation))
- {
- //Delete the temp applicationHostConfig that we created
- if (File.Exists(startParameters.ApplicationHostConfigLocation))
- {
- try
- {
- File.Delete(startParameters.ApplicationHostConfigLocation);
- }
- catch (Exception exception)
- {
- //Ignore delete failures - just write a log
- logger.LogWarning("Failed to delete '{config}'. Exception : {exception}", startParameters.ApplicationHostConfigLocation, exception.Message);
- }
- }
- }
-
- if (startParameters.PublishApplicationBeforeStart)
- {
- try
- {
- //We've originally published the application in a temp folder. We need to delete it.
- Directory.Delete(startParameters.PublishedApplicationRootPath, true);
- }
- catch (Exception exception)
- {
- logger.LogWarning("Failed to delete directory : {error}", exception.Message);
- }
- }
- }
- }
-}
\ No newline at end of file
diff --git a/test/E2ETests/Common/DotnetFlavor.cs b/test/E2ETests/Common/DotnetFlavor.cs
deleted file mode 100644
index 44e9dffbe2..0000000000
--- a/test/E2ETests/Common/DotnetFlavor.cs
+++ /dev/null
@@ -1,9 +0,0 @@
-namespace E2ETests
-{
- public enum RuntimeFlavor
- {
- DesktopClr,
- CoreClr,
- Mono
- }
-}
diff --git a/test/E2ETests/Common/Helpers.cs b/test/E2ETests/Common/Helpers.cs
index 913289bc81..4ce2ac6c08 100644
--- a/test/E2ETests/Common/Helpers.cs
+++ b/test/E2ETests/Common/Helpers.cs
@@ -1,7 +1,8 @@
using System;
+using System.IO;
using System.Net;
using System.Net.Http;
-using System.Threading;
+using DeploymentHelpers;
using Microsoft.Framework.Logging;
namespace E2ETests
@@ -16,29 +17,44 @@ namespace E2ETests
}
}
- public static void Retry(Action retryBlock, ILogger logger, int retryCount = 7)
+ public static string GetApplicationPath()
{
- for (int retry = 0; retry < retryCount; retry++)
+ return Path.GetFullPath(Path.Combine(Directory.GetCurrentDirectory(), "..", "..", "src", "MusicStore"));
+ }
+
+ public static void SetInMemoryStoreForIIS(DeploymentParameters startParameters, ILogger logger)
+ {
+ if (startParameters.ServerType == ServerType.IIS
+ || startParameters.ServerType == ServerType.IISNativeModule)
{
- try
- {
- logger.LogWarning("Retry count {retryCount}..", retry + 1);
- retryBlock();
- break; //Went through successfully
- }
- catch (AggregateException exception)
- {
- if (exception.InnerException is HttpRequestException
-#if DNX451
- || exception.InnerException is WebException
-#endif
- )
- {
- logger.LogWarning("Failed to complete the request : {0}.", exception.Message);
- Thread.Sleep(7 * 1000); //Wait for a while before retry.
- }
- }
+ // Can't use localdb with IIS. Setting an override to use InMemoryStore.
+ logger.LogInformation("Creating configoverride.json file to override default config.");
+ var overrideConfig = Path.Combine(startParameters.ApplicationPath, "..", "approot", "src", "MusicStore", "configoverride.json");
+ overrideConfig = Path.GetFullPath(overrideConfig);
+ File.WriteAllText(overrideConfig, "{\"UseInMemoryStore\": \"true\"}");
}
}
+
+ public static void ThrowIfResponseStatusNotOk(HttpResponseMessage response, ILogger _logger)
+ {
+ if (response.StatusCode != HttpStatusCode.OK)
+ {
+ _logger.LogError(response.Content.ReadAsStringAsync().Result);
+ throw new Exception(string.Format("Received the above response with status code : {0}", response.StatusCode));
+ }
+ }
+
+ public static string PrefixBaseAddress(string url, ServerType serverType, string vDirName = null)
+ {
+#if DNX451
+ url = (serverType == ServerType.IISNativeModule || serverType == ServerType.IIS) ?
+ string.Format(url, vDirName) :
+ string.Format(url, string.Empty);
+#else
+ url = string.Format(url, string.Empty);
+#endif
+
+ return url.Replace("//", "/").Replace("%2F%2F", "%2F").Replace("%2F/", "%2F");
+ }
}
}
\ No newline at end of file
diff --git a/test/E2ETests/Common/IISApplication.cs b/test/E2ETests/Common/IISApplication.cs
deleted file mode 100644
index d74c15e5d8..0000000000
--- a/test/E2ETests/Common/IISApplication.cs
+++ /dev/null
@@ -1,81 +0,0 @@
-#if DNX451
-using System;
-using System.IO;
-using System.Linq;
-using Microsoft.Framework.Logging;
-using Microsoft.Web.Administration;
-
-namespace E2ETests
-{
- public class IISApplication
- {
- private const string WEBSITE_NAME = "MusicStore";
- private const string NATIVE_MODULE_MANAGED_RUNTIME_VERSION = "vCoreFX";
-
- private readonly ServerManager _serverManager = new ServerManager();
- private readonly StartParameters _startParameters;
- private readonly ILogger _logger;
- private ApplicationPool _applicationPool;
- private Application _application;
-
- public string VirtualDirectoryName { get; set; }
-
- public IISApplication(StartParameters startParameters, ILogger logger)
- {
- _startParameters = startParameters;
- _logger = logger;
- }
-
- public void SetupApplication()
- {
- VirtualDirectoryName = new DirectoryInfo(_startParameters.ApplicationPath).Parent.Name;
- _applicationPool = CreateAppPool(VirtualDirectoryName);
- _application = Website.Applications.Add("/" + VirtualDirectoryName, _startParameters.ApplicationPath);
- _application.ApplicationPoolName = _applicationPool.Name;
- _serverManager.CommitChanges();
- }
-
- private Site _website;
- private Site Website
- {
- get
- {
- _website = _serverManager.Sites.Where(s => s.Name == WEBSITE_NAME).FirstOrDefault();
- if (_website == null)
- {
- _website = _serverManager.Sites.Add(WEBSITE_NAME, Path.Combine(Environment.GetEnvironmentVariable("SystemDrive") + @"\", @"inetpub\wwwroot"), 5005);
- }
-
- return _website;
- }
- }
-
- private ApplicationPool CreateAppPool(string appPoolName)
- {
- var applicationPool = _serverManager.ApplicationPools.Add(appPoolName);
- if (_startParameters.ServerType == ServerType.IISNativeModule)
- {
- // Not assigning a runtime version will choose v4.0 default.
- applicationPool.ManagedRuntimeVersion = NATIVE_MODULE_MANAGED_RUNTIME_VERSION;
- }
- applicationPool.Enable32BitAppOnWin64 = (_startParameters.RuntimeArchitecture == RuntimeArchitecture.x86);
- _logger.LogInformation("Created {bit} application pool '{name}' with runtime version '{runtime}'.",
- _startParameters.RuntimeArchitecture, applicationPool.Name,
- applicationPool.ManagedRuntimeVersion ?? "default");
- return applicationPool;
- }
-
- public void StopAndDeleteAppPool()
- {
- _logger.LogInformation("Stopping application pool '{name}' and deleting application.", _applicationPool.Name);
- _applicationPool.Stop();
- // Remove the application from website.
- _application = Website.Applications.Where(a => a.Path == _application.Path).FirstOrDefault();
- Website.Applications.Remove(_application);
- _serverManager.ApplicationPools.Remove(_serverManager.ApplicationPools[_applicationPool.Name]);
- _serverManager.CommitChanges();
- _logger.LogInformation("Successfully stopped application pool '{name}' and deleted application from IIS.", _applicationPool.Name);
- }
- }
-}
-#endif
diff --git a/test/E2ETests/Common/IISExpressHelper.cs b/test/E2ETests/Common/IISExpressHelper.cs
deleted file mode 100644
index ee9d164bda..0000000000
--- a/test/E2ETests/Common/IISExpressHelper.cs
+++ /dev/null
@@ -1,49 +0,0 @@
-using System;
-using System.IO;
-using Microsoft.Framework.Runtime;
-using Microsoft.Framework.Runtime.Infrastructure;
-
-namespace E2ETests
-{
- public class IISExpressHelper
- {
- public static string GetPath(RuntimeArchitecture architecture)
- {
- // Get path to program files
- var iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles(x86)"), "IIS Express", "iisexpress.exe");
-
- // Get path to 64 bit of IIS Express
- if (architecture == RuntimeArchitecture.amd64)
- {
- iisExpressPath = Path.Combine(Environment.GetEnvironmentVariable("ProgramFiles"), "IIS Express", "iisexpress.exe");
-
- // If process is 32 bit, the path points to x86. Replace path to point to x64
- iisExpressPath = IntPtr.Size == 8 ? iisExpressPath : iisExpressPath.Replace(" (x86)", "");
- }
-
- if (!File.Exists(iisExpressPath))
- {
- throw new Exception("Unable to find IISExpress on the machine");
- }
-
- return iisExpressPath;
- }
-
- public static void CopyAspNetLoader(string applicationPath)
- {
- var libraryManager = (ILibraryManager)CallContextServiceLocator.Locator.ServiceProvider.GetService(typeof(ILibraryManager));
- var interopLibrary = libraryManager.GetLibraryInformation("Microsoft.AspNet.Loader.IIS.Interop");
-
- var aspNetLoaderSrcPath = Path.Combine(interopLibrary.Path, "tools", "AspNet.Loader.dll");
- var aspNetLoaderDestPath = Path.Combine(applicationPath, "wwwroot", "bin", "AspNet.Loader.dll");
-
- // Create bin directory if it does not exist.
- Directory.CreateDirectory(new DirectoryInfo(aspNetLoaderDestPath).Parent.FullName);
-
- if (!File.Exists(aspNetLoaderDestPath))
- {
- File.Copy(aspNetLoaderSrcPath, aspNetLoaderDestPath);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/test/E2ETests/Common/StartParameters.cs b/test/E2ETests/Common/StartParameters.cs
deleted file mode 100644
index 14a85f8143..0000000000
--- a/test/E2ETests/Common/StartParameters.cs
+++ /dev/null
@@ -1,36 +0,0 @@
-namespace E2ETests
-{
- ///
- /// Summary description for StartParameters
- ///
- public class StartParameters
- {
- public ServerType ServerType { get; set; }
-
- public RuntimeFlavor RuntimeFlavor { get; set; }
-
- public RuntimeArchitecture RuntimeArchitecture { get; set; }
-
- public string EnvironmentName { get; set; }
-
- public string ApplicationHostConfigTemplateContent { get; set; }
-
- public string ApplicationHostConfigLocation { get; set; }
-
- public string SiteName { get; set; }
-
- public string ApplicationPath { get; set; }
-
- public bool PublishApplicationBeforeStart { get; set; }
-
- public string PublishedApplicationRootPath { get; set; }
-
- public bool PublishWithNoSource { get; set; }
-
- public string Runtime { get; set; }
-
-#if DNX451
- public IISApplication IISApplication { get; set; }
-#endif
- }
-}
diff --git a/test/E2ETests/Implementation/FacebookLoginScenarios.cs b/test/E2ETests/Implementation/FacebookLoginScenarios.cs
index c44e66e5b9..788ea92add 100644
--- a/test/E2ETests/Implementation/FacebookLoginScenarios.cs
+++ b/test/E2ETests/Implementation/FacebookLoginScenarios.cs
@@ -9,15 +9,15 @@ using Xunit;
namespace E2ETests
{
- public partial class SmokeTests
+ public partial class Validator
{
- private void LoginWithFacebook()
+ public void LoginWithFacebook()
{
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = false };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
var response = _httpClient.GetAsync("Account/Login").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
var responseContent = response.Content.ReadAsStringAsync().Result;
_logger.LogInformation("Signing in with Facebook account");
var formParameters = new List>
@@ -33,16 +33,16 @@ namespace E2ETests
var queryItems = new ReadableStringCollection(QueryHelpers.ParseQuery(response.Headers.Location.Query));
Assert.Equal("code", queryItems["response_type"]);
Assert.Equal("[AppId]", queryItems["client_id"]);
- Assert.Equal(_applicationBaseUrl + "signin-facebook", queryItems["redirect_uri"]);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "signin-facebook", queryItems["redirect_uri"]);
Assert.Equal("email,read_friendlists,user_checkins", queryItems["scope"]);
Assert.Equal("ValidStateData", queryItems["state"]);
Assert.Equal("custom", queryItems["custom_redirect_uri"]);
//Check for the correlation cookie
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Correlation.Facebook"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Correlation.Facebook"));
//This is just to generate a correlation cookie. Previous step would generate this cookie, but we have reset the handler now.
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = true };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
response = _httpClient.GetAsync("Account/Login").Result;
responseContent = response.Content.ReadAsStringAsync().Result;
@@ -58,15 +58,15 @@ namespace E2ETests
//Post a message to the Facebook middleware
response = _httpClient.GetAsync("signin-facebook?code=ValidCode&state=ValidStateData").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
//Correlation cookie not getting cleared after successful signin?
if (!Helpers.RunningOnMono)
{
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Correlation.Facebook"));
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Correlation.Facebook"));
}
- Assert.Equal(_applicationBaseUrl + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
Assert.Contains("AspnetvnextTest@test.com", responseContent, StringComparison.OrdinalIgnoreCase);
formParameters = new List>
@@ -77,14 +77,14 @@ namespace E2ETests
content = new FormUrlEncodedContent(formParameters.ToArray());
response = _httpClient.PostAsync("Account/ExternalLoginConfirmation", content).Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
Assert.Contains(string.Format("Hello {0}!", "AspnetvnextTest@test.com"), responseContent, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
//Verify cookie sent
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
_logger.LogInformation("Successfully signed in with user '{email}'", "AspnetvnextTest@test.com");
_logger.LogInformation("Verifying if the middleware notifications were fired");
diff --git a/test/E2ETests/Implementation/GoogleLoginScenarios.cs b/test/E2ETests/Implementation/GoogleLoginScenarios.cs
index b97d1772c5..17b322ca48 100644
--- a/test/E2ETests/Implementation/GoogleLoginScenarios.cs
+++ b/test/E2ETests/Implementation/GoogleLoginScenarios.cs
@@ -9,15 +9,15 @@ using Xunit;
namespace E2ETests
{
- public partial class SmokeTests
+ public partial class Validator
{
- private void LoginWithGoogle()
+ public void LoginWithGoogle()
{
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = false };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
var response = _httpClient.GetAsync("Account/Login").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
var responseContent = response.Content.ReadAsStringAsync().Result;
_logger.LogInformation("Signing in with Google account");
var formParameters = new List>
@@ -34,16 +34,16 @@ namespace E2ETests
Assert.Equal("code", queryItems["response_type"]);
Assert.Equal("offline", queryItems["access_type"]);
Assert.Equal("[ClientId]", queryItems["client_id"]);
- Assert.Equal(_applicationBaseUrl + "signin-google", queryItems["redirect_uri"]);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "signin-google", queryItems["redirect_uri"]);
Assert.Equal("openid profile email", queryItems["scope"]);
Assert.Equal("ValidStateData", queryItems["state"]);
Assert.Equal("custom", queryItems["custom_redirect_uri"]);
//Check for the correlation cookie
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Correlation.Google"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Correlation.Google"));
//This is just to generate a correlation cookie. Previous step would generate this cookie, but we have reset the handler now.
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = true };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
response = _httpClient.GetAsync("Account/Login").Result;
responseContent = response.Content.ReadAsStringAsync().Result;
@@ -59,15 +59,15 @@ namespace E2ETests
//Post a message to the Google middleware
response = _httpClient.GetAsync("signin-google?code=ValidCode&state=ValidStateData").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
//Correlation cookie not getting cleared after successful signin?
if (!Helpers.RunningOnMono)
{
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Correlation.Google"));
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Correlation.Google"));
}
- Assert.Equal(_applicationBaseUrl + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
Assert.Contains("AspnetvnextTest@gmail.com", responseContent, StringComparison.OrdinalIgnoreCase);
formParameters = new List>
@@ -78,14 +78,14 @@ namespace E2ETests
content = new FormUrlEncodedContent(formParameters.ToArray());
response = _httpClient.PostAsync("Account/ExternalLoginConfirmation", content).Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
Assert.Contains(string.Format("Hello {0}!", "AspnetvnextTest@gmail.com"), responseContent, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
//Verify cookie sent
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
_logger.LogInformation("Successfully signed in with user '{email}'", "AspnetvnextTest@gmail.com");
_logger.LogInformation("Verifying if the middleware notifications were fired");
diff --git a/test/E2ETests/Implementation/MicrosoftAccountAuthenticationScenarios.cs b/test/E2ETests/Implementation/MicrosoftAccountAuthenticationScenarios.cs
index 9c96167dd5..2d08228bd8 100644
--- a/test/E2ETests/Implementation/MicrosoftAccountAuthenticationScenarios.cs
+++ b/test/E2ETests/Implementation/MicrosoftAccountAuthenticationScenarios.cs
@@ -9,15 +9,15 @@ using Xunit;
namespace E2ETests
{
- public partial class SmokeTests
+ public partial class Validator
{
- private void LoginWithMicrosoftAccount()
+ public void LoginWithMicrosoftAccount()
{
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = false };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
var response = _httpClient.GetAsync("Account/Login").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
var responseContent = response.Content.ReadAsStringAsync().Result;
_logger.LogInformation("Signing in with Microsoft account");
var formParameters = new List>
@@ -33,17 +33,17 @@ namespace E2ETests
var queryItems = new ReadableStringCollection(QueryHelpers.ParseQuery(response.Headers.Location.Query));
Assert.Equal("code", queryItems["response_type"]);
Assert.Equal("[ClientId]", queryItems["client_id"]);
- Assert.Equal(_applicationBaseUrl + "signin-microsoft", queryItems["redirect_uri"]);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "signin-microsoft", queryItems["redirect_uri"]);
Assert.Equal("wl.basic wl.signin", queryItems["scope"]);
Assert.Equal("ValidStateData", queryItems["state"]);
Assert.Equal("custom", queryItems["custom_redirect_uri"]);
//Check for the correlation cookie
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Correlation.Microsoft"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Correlation.Microsoft"));
//This is just to generate a correlation cookie. Previous step would generate this cookie, but we have reset the handler now.
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = true };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
response = _httpClient.GetAsync("Account/Login").Result;
responseContent = response.Content.ReadAsStringAsync().Result;
@@ -59,15 +59,15 @@ namespace E2ETests
//Post a message to the MicrosoftAccount middleware
response = _httpClient.GetAsync("signin-microsoft?code=ValidCode&state=ValidStateData").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
//Correlation cookie not getting cleared after successful signin?
if (!Helpers.RunningOnMono)
{
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Correlation.Microsoft"));
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Correlation.Microsoft"));
}
- Assert.Equal(_applicationBaseUrl + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
formParameters = new List>
{
@@ -77,14 +77,14 @@ namespace E2ETests
content = new FormUrlEncodedContent(formParameters.ToArray());
response = _httpClient.PostAsync("Account/ExternalLoginConfirmation", content).Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
Assert.Contains(string.Format("Hello {0}!", "microsoft@test.com"), responseContent, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
//Verify cookie sent
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
_logger.LogInformation("Successfully signed in with user '{email}'", "microsoft@test.com");
_logger.LogInformation("Verifying if the middleware notifications were fired");
diff --git a/test/E2ETests/Implementation/OpenIdConnectLoginScenarios.cs b/test/E2ETests/Implementation/OpenIdConnectLoginScenarios.cs
index f190622c42..94e3d8794b 100644
--- a/test/E2ETests/Implementation/OpenIdConnectLoginScenarios.cs
+++ b/test/E2ETests/Implementation/OpenIdConnectLoginScenarios.cs
@@ -9,15 +9,15 @@ using Xunit;
namespace E2ETests
{
- public partial class SmokeTests
+ public partial class Validator
{
- private void LoginWithOpenIdConnect()
+ public void LoginWithOpenIdConnect()
{
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = false };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
var response = _httpClient.GetAsync("Account/Login").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
var responseContent = response.Content.ReadAsStringAsync().Result;
_logger.LogInformation("Signing in with OpenIdConnect account");
var formParameters = new List>
@@ -37,12 +37,12 @@ namespace E2ETests
Assert.Equal("openid profile", queryItems["scope"]);
Assert.Equal("OpenIdConnect.AuthenticationProperties=ValidStateData", queryItems["state"]);
Assert.NotNull(queryItems["nonce"]);
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.OpenIdConnect.Nonce.protectedString"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.OpenIdConnect.Nonce.protectedString"));
// This is just enable the auto-redirect.
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = true };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
- _httpClientHandler.CookieContainer.Add(new Uri(_applicationBaseUrl), new Cookie(".AspNet.OpenIdConnect.Nonce.protectedString", "N"));
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
+ _httpClientHandler.CookieContainer.Add(new Uri(_deploymentResult.ApplicationBaseUri), new Cookie(".AspNet.OpenIdConnect.Nonce.protectedString", "N"));
//Post a message to the OpenIdConnect middleware
var token = new List>
@@ -54,9 +54,9 @@ namespace E2ETests
};
response = _httpClient.PostAsync(string.Empty, new FormUrlEncodedContent(token.ToArray())).Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
- Assert.Equal(_applicationBaseUrl + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
formParameters = new List>
{
@@ -66,14 +66,14 @@ namespace E2ETests
content = new FormUrlEncodedContent(formParameters.ToArray());
response = _httpClient.PostAsync("Account/ExternalLoginConfirmation", content).Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
Assert.Contains(string.Format("Hello {0}!", "User3@aspnettest.onmicrosoft.com"), responseContent, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
//Verify cookie sent
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
_logger.LogInformation("Successfully signed in with user '{email}'", "User3@aspnettest.onmicrosoft.com");
_logger.LogInformation("Verifying if the middleware notifications were fired");
@@ -85,7 +85,7 @@ namespace E2ETests
_logger.LogInformation("Verifying the OpenIdConnect logout flow..");
response = _httpClient.GetAsync(string.Empty).Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
ValidateLayoutPage(responseContent);
formParameters = new List>
@@ -96,16 +96,16 @@ namespace E2ETests
content = new FormUrlEncodedContent(formParameters.ToArray());
// Need a non-redirecting handler
var handler = new HttpClientHandler() { AllowAutoRedirect = false };
- handler.CookieContainer.Add(new Uri(_applicationBaseUrl), _httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)));
- _httpClient = new HttpClient(handler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ handler.CookieContainer.Add(new Uri(_deploymentResult.ApplicationBaseUri), _httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)));
+ _httpClient = new HttpClient(handler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
response = _httpClient.PostAsync("Account/LogOff", content).Result;
- Assert.Null(handler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
+ Assert.Null(handler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
Assert.Equal(
"https://login.windows.net/4afbc689-805b-48cf-a24c-d4aa3248a248/oauth2/logout",
response.Headers.Location.AbsoluteUri.Replace(response.Headers.Location.Query, string.Empty));
queryItems = new ReadableStringCollection(QueryHelpers.ParseQuery(response.Headers.Location.Query));
- Assert.Equal(_applicationBaseUrl + "Account/Login", queryItems["post_logout_redirect_uri"]);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "Account/Login", queryItems["post_logout_redirect_uri"]);
}
}
}
\ No newline at end of file
diff --git a/test/E2ETests/Implementation/TwitterLoginScenarios.cs b/test/E2ETests/Implementation/TwitterLoginScenarios.cs
index d1879a870d..3c9663bb23 100644
--- a/test/E2ETests/Implementation/TwitterLoginScenarios.cs
+++ b/test/E2ETests/Implementation/TwitterLoginScenarios.cs
@@ -12,15 +12,15 @@ namespace E2ETests
///
/// Summary description for TwitterLoginScenarios
///
- public partial class SmokeTests
+ public partial class Validator
{
- private void LoginWithTwitter()
+ public void LoginWithTwitter()
{
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = false };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
var response = _httpClient.GetAsync("Account/Login").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
var responseContent = response.Content.ReadAsStringAsync().Result;
_logger.LogInformation("Signing in with Twitter account");
var formParameters = new List>
@@ -37,11 +37,11 @@ namespace E2ETests
Assert.Equal("custom", queryItems["custom_redirect_uri"]);
Assert.Equal("valid_oauth_token", queryItems["oauth_token"]);
//Check for the correlation cookie
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl))["__TwitterState"]);
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri))["__TwitterState"]);
//This is just to generate a correlation cookie. Previous step would generate this cookie, but we have reset the handler now.
_httpClientHandler = new HttpClientHandler() { AllowAutoRedirect = true };
- _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_applicationBaseUrl) };
+ _httpClient = new HttpClient(_httpClientHandler) { BaseAddress = new Uri(_deploymentResult.ApplicationBaseUri) };
response = _httpClient.GetAsync("Account/Login").Result;
responseContent = response.Content.ReadAsStringAsync().Result;
@@ -57,15 +57,15 @@ namespace E2ETests
//Post a message to the Facebook middleware
response = _httpClient.GetAsync("signin-twitter?oauth_token=valid_oauth_token&oauth_verifier=valid_oauth_verifier").Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
//Check correlation cookie not getting cleared after successful signin
if (!Helpers.RunningOnMono)
{
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl))["__TwitterState"]);
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri))["__TwitterState"]);
}
- Assert.Equal(_applicationBaseUrl + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
+ Assert.Equal(_deploymentResult.ApplicationBaseUri + "Account/ExternalLoginCallback?ReturnUrl=%2F", response.RequestMessage.RequestUri.AbsoluteUri);
//Twitter does not give back the email claim for some reason.
//Assert.Contains("AspnetvnextTest@gmail.com", responseContent, StringComparison.OrdinalIgnoreCase);
@@ -77,14 +77,14 @@ namespace E2ETests
content = new FormUrlEncodedContent(formParameters.ToArray());
response = _httpClient.PostAsync("Account/ExternalLoginConfirmation", content).Result;
- ThrowIfResponseStatusNotOk(response);
+ Helpers.ThrowIfResponseStatusNotOk(response, _logger);
responseContent = response.Content.ReadAsStringAsync().Result;
Assert.Contains(string.Format("Hello {0}!", "twitter@test.com"), responseContent, StringComparison.OrdinalIgnoreCase);
Assert.Contains("Log off", responseContent, StringComparison.OrdinalIgnoreCase);
//Verify cookie sent
- Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
- Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_applicationBaseUrl)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
+ Assert.NotNull(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.Application"));
+ Assert.Null(_httpClientHandler.CookieContainer.GetCookies(new Uri(_deploymentResult.ApplicationBaseUri)).GetCookieWithName(".AspNet.Microsoft.AspNet.Identity.ExternalLogin"));
_logger.LogInformation("Successfully signed in with user '{email}'", "twitter@test.com");
_logger.LogInformation("Verifying if the middleware notifications were fired");
diff --git a/test/E2ETests/Implementation/Scenarios.cs b/test/E2ETests/Implementation/Validator.cs
similarity index 77%
rename from test/E2ETests/Implementation/Scenarios.cs
rename to test/E2ETests/Implementation/Validator.cs
index 72dd1a5ab3..a6b8a45a4b 100644
--- a/test/E2ETests/Implementation/Scenarios.cs
+++ b/test/E2ETests/Implementation/Validator.cs
@@ -4,45 +4,46 @@ using System.Linq;
using System.Net;
using System.Net.Http;
using System.Threading;
+using DeploymentHelpers;
using Microsoft.AspNet.SignalR.Client;
using Microsoft.Framework.Logging;
using Xunit;
namespace E2ETests
{
- public partial class SmokeTests
+ public partial class Validator
{
- private void VerifyStaticContentServed()
+ private HttpClient _httpClient;
+ private HttpClientHandler _httpClientHandler;
+ private readonly ILogger _logger;
+ private readonly DeploymentResult _deploymentResult;
+
+ public Validator(
+ HttpClient httpClient,
+ HttpClientHandler httpClientHandler,
+ ILogger logger,
+ DeploymentResult deploymentResult)
{
- _logger.LogInformation("Validating if static contents are served..");
- _logger.LogInformation("Fetching favicon.ico..");
- var response = _httpClient.GetAsync("favicon.ico").Result;
- ThrowIfResponseStatusNotOk(response);
- _logger.LogInformation("Etag received: {etag}", response.Headers.ETag.Tag);
-
- //Check if you receive a NotModified on sending an etag
- _logger.LogInformation("Sending an IfNoneMatch header with e-tag");
- _httpClient.DefaultRequestHeaders.IfNoneMatch.Add(response.Headers.ETag);
- response = _httpClient.GetAsync("favicon.ico").Result;
- Assert.Equal(HttpStatusCode.NotModified, response.StatusCode);
- _httpClient.DefaultRequestHeaders.IfNoneMatch.Clear();
- _logger.LogInformation("Successfully received a NotModified status");
-
- _logger.LogInformation("Fetching /Content/bootstrap.css..");
- response = _httpClient.GetAsync("Content/bootstrap.css").Result;
- ThrowIfResponseStatusNotOk(response);
- _logger.LogInformation("Verified static contents are served successfully");
+ _httpClient = httpClient;
+ _httpClientHandler = httpClientHandler;
+ _logger = logger;
+ _deploymentResult = deploymentResult;
}
- private void VerifyHomePage(HttpResponseMessage response, string responseContent, bool useNtlmAuthentication = false)
+ public void VerifyHomePage(
+ HttpResponseMessage response,
+ bool useNtlmAuthentication = false)
{
- // This seems to not print anything if the successive Assert fails.
- //_logger.WriteVerbose("Home page content : {0}", responseContent);
+ var responseContent = response.Content.ReadAsStringAsync().Result;
+
+ if (response.StatusCode != HttpStatusCode.OK)
+ {
+ Console.WriteLine("Home page content : {0}", responseContent);
+ }
- Console.WriteLine("Home page content : {0}", responseContent);
Assert.Equal(HttpStatusCode.OK, response.StatusCode);
ValidateLayoutPage(responseContent);
- Assert.Contains(PrefixBaseAddress("Home Page – ASP.NET MVC Music Store", responseContent, StringComparison.OrdinalIgnoreCase);
if (!useNtlmAuthentication)
@@ -57,24 +58,77 @@ namespace E2ETests
_logger.LogInformation("Application initialization successful.");
_logger.LogInformation("Application runtime information");
- var runtimeResponse = _httpClient.GetAsync("runtimeinfo").Result;
+ //var runtimeResponse = _httpClient.GetAsync("runtimeinfo").Result;
- if (_startParameters.RuntimeFlavor != RuntimeFlavor.CoreClr)
+ // https://github.com/aspnet/Diagnostics/issues/108
+ if (_deploymentResult.DeploymentParameters.RuntimeFlavor != RuntimeFlavor.coreclr)
{
- // Runtime info middleware broken on coreclr.
- ThrowIfResponseStatusNotOk(runtimeResponse);
+ //Helpers.ThrowIfResponseStatusNotOk(runtimeResponse, _logger);
}
- var runtimeInfo = runtimeResponse.Content.ReadAsStringAsync().Result;
- _logger.LogInformation(runtimeInfo);
+ //var runtimeInfo = runtimeResponse.Content.ReadAsStringAsync().Result;
+ //_logger.LogInformation(runtimeInfo);
+ }
+
+ public void VerifyNtlmHomePage(HttpResponseMessage response)
+ {
+ VerifyHomePage(response, useNtlmAuthentication: true);
+
+ var homePageContent = response.Content.ReadAsStringAsync().Result;
+
+ //Check if the user name appears in the page
+ Assert.Contains(
+ string.Format("{0}\\{1}", Environment.GetEnvironmentVariable("USERDOMAIN"), Environment.GetEnvironmentVariable("USERNAME")),
+ homePageContent, StringComparison.OrdinalIgnoreCase);
+ }
+
+ public void ValidateLayoutPage(string responseContent)
+ {
+ Assert.Contains("ASP.NET MVC Music Store", responseContent, StringComparison.OrdinalIgnoreCase);
+ Assert.Contains(Helpers.PrefixBaseAddress("Home", _deploymentResult.DeploymentParameters.ServerType), responseContent, StringComparison.OrdinalIgnoreCase);
+ Assert.Contains(Helpers.PrefixBaseAddress("Store ", _deploymentResult.DeploymentParameters.ServerType), responseContent, StringComparison.OrdinalIgnoreCase);
+ Assert.Contains("