Deployment helpers moved to hosting repo.
This commit is contained in:
parent
94ff5f85f0
commit
c384fcc3c2
|
|
@ -28,8 +28,6 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MusicStore.Test", "test\Mus
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MusicStore.Spa.Test", "test\MusicStore.Spa.Test\MusicStore.Spa.Test.xproj", "{9D3326C4-1F12-4526-9F25-712A1463B3FA}"
|
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "MusicStore.Spa.Test", "test\MusicStore.Spa.Test\MusicStore.Spa.Test.xproj", "{9D3326C4-1F12-4526-9F25-712A1463B3FA}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "DeploymentHelpers", "test\DeploymentHelpers\DeploymentHelpers.xproj", "{C98E54D3-F4C6-4D16-A5A6-E86A636A7311}"
|
|
||||||
EndProject
|
|
||||||
Global
|
Global
|
||||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||||
Debug|Any CPU = Debug|Any CPU
|
Debug|Any CPU = Debug|Any CPU
|
||||||
|
|
@ -114,18 +112,6 @@ Global
|
||||||
{9D3326C4-1F12-4526-9F25-712A1463B3FA}.Release|Mixed Platforms.Build.0 = Release|Any CPU
|
{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.ActiveCfg = Release|Any CPU
|
||||||
{9D3326C4-1F12-4526-9F25-712A1463B3FA}.Release|x86.Build.0 = 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
|
EndGlobalSection
|
||||||
GlobalSection(SolutionProperties) = preSolution
|
GlobalSection(SolutionProperties) = preSolution
|
||||||
HideSolutionNode = FALSE
|
HideSolutionNode = FALSE
|
||||||
|
|
@ -138,6 +124,5 @@ Global
|
||||||
{93891170-A8D5-46FD-A291-40F90CF258C2} = {B7B176B6-8D4D-4EF1-BBD2-DDA650C78FFF}
|
{93891170-A8D5-46FD-A291-40F90CF258C2} = {B7B176B6-8D4D-4EF1-BBD2-DDA650C78FFF}
|
||||||
{CA663205-77DE-4E55-B300-85594181B5A9} = {363D2681-31A6-48C9-90BB-9ACFF4A41F06}
|
{CA663205-77DE-4E55-B300-85594181B5A9} = {363D2681-31A6-48C9-90BB-9ACFF4A41F06}
|
||||||
{9D3326C4-1F12-4526-9F25-712A1463B3FA} = {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
|
EndGlobalSection
|
||||||
EndGlobal
|
EndGlobal
|
||||||
|
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Parameters to control application deployment.
|
|
||||||
/// </summary>
|
|
||||||
public class DeploymentParameters
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Creates an instance of <see cref="DeploymentParameters"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="applicationPath">Source code location of the target location to be deployed.</param>
|
|
||||||
/// <param name="serverType">Where to be deployed on.</param>
|
|
||||||
/// <param name="runtimeFlavor">Flavor of the clr to run against.</param>
|
|
||||||
/// <param name="runtimeArchitecture">Architecture of the DNX to be used.</param>
|
|
||||||
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; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Suggested base url for the deployed application. The final deployed url could be
|
|
||||||
/// different than this. Use <see cref="DeploymentResult.ApplicationBaseUri"/> for the
|
|
||||||
/// deployed url.
|
|
||||||
/// </summary>
|
|
||||||
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; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// To publish the application before deployment.
|
|
||||||
/// </summary>
|
|
||||||
public bool PublishApplicationBeforeDeployment { get; set; }
|
|
||||||
|
|
||||||
public string PublishedApplicationRootPath { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Passes the --no-source option when publishing.
|
|
||||||
/// </summary>
|
|
||||||
public bool PublishWithNoSource { get; set; }
|
|
||||||
|
|
||||||
public string DnxRuntime { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Environment variables to be set before starting the host.
|
|
||||||
/// Not applicable for IIS Scenarios.
|
|
||||||
/// </summary>
|
|
||||||
public List<KeyValuePair<string, string>> EnvironmentVariables { get; private set; } = new List<KeyValuePair<string, string>>();
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// For any application level cleanup to be invoked after performing host cleanup.
|
|
||||||
/// </summary>
|
|
||||||
public Action<DeploymentParameters> UserAdditionalCleanup { get; set; }
|
|
||||||
|
|
||||||
public override string ToString()
|
|
||||||
{
|
|
||||||
return string.Format(
|
|
||||||
"[Variation] :: ServerType={0}, Runtime={1}, Arch={2}, BaseUrlHint={3}, Publish={4}, NoSource={5}",
|
|
||||||
ServerType,
|
|
||||||
RuntimeFlavor,
|
|
||||||
RuntimeArchitecture,
|
|
||||||
ApplicationBaseUriHint,
|
|
||||||
PublishApplicationBeforeDeployment,
|
|
||||||
PublishWithNoSource);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
using System.Threading;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Result of a deployment.
|
|
||||||
/// </summary>
|
|
||||||
public class DeploymentResult
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Base Uri of the deployment application.
|
|
||||||
/// </summary>
|
|
||||||
public string ApplicationBaseUri { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The web root folder where the application is hosted. This path can be different from the
|
|
||||||
/// original application source location if published before deployment.
|
|
||||||
/// </summary>
|
|
||||||
public string WebRootLocation { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Original deployment parameters used for this deployment.
|
|
||||||
/// </summary>
|
|
||||||
public DeploymentParameters DeploymentParameters { get; set; }
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Triggered when the host process dies or pulled down.
|
|
||||||
/// </summary>
|
|
||||||
public CancellationToken HostShutdownToken { get; set; }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,8 +0,0 @@
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
public enum RuntimeArchitecture
|
|
||||||
{
|
|
||||||
x64,
|
|
||||||
x86
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
public enum RuntimeFlavor
|
|
||||||
{
|
|
||||||
Clr,
|
|
||||||
CoreClr,
|
|
||||||
Mono
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,71 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Net;
|
|
||||||
using System.Net.Http;
|
|
||||||
using System.Threading;
|
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Framework.Logging;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
public class RetryHelper
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Retries every 1 sec for 60 times by default.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="retryBlock"></param>
|
|
||||||
/// <param name="logger"></param>
|
|
||||||
/// <param name="cancellationToken"></param>
|
|
||||||
/// <param name="retryCount"></param>
|
|
||||||
public static async Task<HttpResponseMessage> RetryRequest(
|
|
||||||
Func<Task<HttpResponseMessage>> retryBlock,
|
|
||||||
ILogger logger,
|
|
||||||
CancellationToken cancellationToken = default(CancellationToken),
|
|
||||||
int retryCount = 60)
|
|
||||||
{
|
|
||||||
for (int retry = 0; retry < retryCount; retry++)
|
|
||||||
{
|
|
||||||
try
|
|
||||||
{
|
|
||||||
if (cancellationToken.IsCancellationRequested)
|
|
||||||
{
|
|
||||||
logger.LogInformation("Stopping retry as cancellation token is triggered.");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
logger.LogWarning("Retry count {retryCount}..", retry + 1);
|
|
||||||
var response = await retryBlock();
|
|
||||||
|
|
||||||
if (response.StatusCode == HttpStatusCode.ServiceUnavailable)
|
|
||||||
{
|
|
||||||
// Automatically retry on 503. May be application is still booting.
|
|
||||||
logger.LogWarning("Retrying a service unavailable error.");
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return response; //Went through successfully
|
|
||||||
}
|
|
||||||
catch (Exception exception)
|
|
||||||
{
|
|
||||||
if (retry == retryCount - 1)
|
|
||||||
{
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (exception is HttpRequestException
|
|
||||||
#if DNX451
|
|
||||||
|| exception is System.Net.WebException
|
|
||||||
#endif
|
|
||||||
)
|
|
||||||
{
|
|
||||||
logger.LogWarning("Failed to complete the request : {0}.", exception.Message);
|
|
||||||
Thread.Sleep(1 * 1000); //Wait for a while before retry.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +0,0 @@
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
public enum ServerType
|
|
||||||
{
|
|
||||||
IISExpress,
|
|
||||||
IIS,
|
|
||||||
IISNativeModule,
|
|
||||||
WebListener,
|
|
||||||
Kestrel
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,223 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Text;
|
|
||||||
using System.Text.RegularExpressions;
|
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.Framework.Logging;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Abstract base class of all deplolyers with a back bone implementation of some of the common helpers.
|
|
||||||
/// </summary>
|
|
||||||
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; }
|
|
||||||
|
|
||||||
protected Stopwatch StopWatch { get; private set; } = new Stopwatch();
|
|
||||||
|
|
||||||
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
|
|
||||||
|
|
||||||
SetEnvironmentVariable(environment, "ASPNET_ENV", DeploymentParameters.EnvironmentName);
|
|
||||||
|
|
||||||
// Work around for https://github.com/aspnet/dnx/issues/1515
|
|
||||||
if (DeploymentParameters.PublishWithNoSource)
|
|
||||||
{
|
|
||||||
SetEnvironmentVariable(environment, "DNX_PACKAGES", null);
|
|
||||||
}
|
|
||||||
|
|
||||||
SetEnvironmentVariable(environment, "DNX_DEFAULT_LIB", null);
|
|
||||||
|
|
||||||
foreach (var environmentVariable in DeploymentParameters.EnvironmentVariables)
|
|
||||||
{
|
|
||||||
SetEnvironmentVariable(environment, environmentVariable.Key, environmentVariable.Value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#if DNX451
|
|
||||||
protected void SetEnvironmentVariable(System.Collections.Specialized.StringDictionary environment, string name, string value)
|
|
||||||
{
|
|
||||||
#elif DNXCORE50
|
|
||||||
protected void SetEnvironmentVariable(System.Collections.Generic.IDictionary<string, string> environment, string name, string value)
|
|
||||||
{
|
|
||||||
#endif
|
|
||||||
if (value == null)
|
|
||||||
{
|
|
||||||
Logger.LogInformation("Removing environment variable {name}", name);
|
|
||||||
environment.Remove(name);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Logger.LogInformation("SET {name}={value}", name, value);
|
|
||||||
environment[name] = 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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void TriggerHostShutdown(CancellationTokenSource hostShutdownSource)
|
|
||||||
{
|
|
||||||
Logger.LogInformation("Host process shutting down.");
|
|
||||||
try
|
|
||||||
{
|
|
||||||
hostShutdownSource.Cancel();
|
|
||||||
}
|
|
||||||
catch (Exception)
|
|
||||||
{
|
|
||||||
// Suppress errors.
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void StartTimer()
|
|
||||||
{
|
|
||||||
Logger.LogInformation("Deploying {VariationDetails}", DeploymentParameters.ToString());
|
|
||||||
StopWatch.Start();
|
|
||||||
}
|
|
||||||
|
|
||||||
protected void StopTimer()
|
|
||||||
{
|
|
||||||
StopWatch.Stop();
|
|
||||||
Logger.LogInformation("[Time]: Total time taken for this test variation '{t}' seconds", StopWatch.Elapsed.TotalSeconds);
|
|
||||||
}
|
|
||||||
|
|
||||||
public abstract void Dispose();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,54 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.Framework.Logging;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Factory to create an appropriate deployer based on <see cref="DeploymentParameters"/>.
|
|
||||||
/// </summary>
|
|
||||||
public class ApplicationDeployerFactory
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Creates a deployer instance based on settings in <see cref="DeploymentParameters"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <param name="deploymentParameters"></param>
|
|
||||||
/// <param name="logger"></param>
|
|
||||||
/// <returns></returns>
|
|
||||||
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)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,16 +0,0 @@
|
||||||
using System;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Common operations on an application deployer.
|
|
||||||
/// </summary>
|
|
||||||
public interface IApplicationDeployer : IDisposable
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Deploys the application to the target with specified <see cref="DeploymentParameters"/>.
|
|
||||||
/// </summary>
|
|
||||||
/// <returns></returns>
|
|
||||||
DeploymentResult Deploy();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,210 +0,0 @@
|
||||||
#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
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Deployer for IIS (Both Helios and NativeModule).
|
|
||||||
/// </summary>
|
|
||||||
public class IISDeployer : ApplicationDeployer
|
|
||||||
{
|
|
||||||
private IISApplication _application;
|
|
||||||
private CancellationTokenSource _hostShutdownToken = new CancellationTokenSource();
|
|
||||||
private static object _syncObject = new object();
|
|
||||||
|
|
||||||
public IISDeployer(DeploymentParameters startParameters, ILogger logger)
|
|
||||||
: base(startParameters, logger)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DeploymentResult Deploy()
|
|
||||||
{
|
|
||||||
// Start timer
|
|
||||||
StartTimer();
|
|
||||||
|
|
||||||
// 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();
|
|
||||||
}
|
|
||||||
|
|
||||||
lock (_syncObject)
|
|
||||||
{
|
|
||||||
// To prevent modifying the IIS setup concurrently.
|
|
||||||
_application.Deploy();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Warm up time for IIS setup.
|
|
||||||
Thread.Sleep(1 * 1000);
|
|
||||||
Logger.LogInformation("Successfully finished IIS application directory setup.");
|
|
||||||
|
|
||||||
return new DeploymentResult
|
|
||||||
{
|
|
||||||
WebRootLocation = DeploymentParameters.ApplicationPath,
|
|
||||||
DeploymentParameters = DeploymentParameters,
|
|
||||||
// Accomodate the vdir name.
|
|
||||||
ApplicationBaseUri = new UriBuilder(Uri.UriSchemeHttp, "localhost", IISApplication.Port, _application.VirtualDirectoryName).Uri.AbsoluteUri + "/",
|
|
||||||
HostShutdownToken = _hostShutdownToken.Token
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
|
||||||
lock (_syncObject)
|
|
||||||
{
|
|
||||||
// Sequentialize IIS operations.
|
|
||||||
_application.StopAndDeleteAppPool();
|
|
||||||
}
|
|
||||||
|
|
||||||
TriggerHostShutdown(_hostShutdownToken);
|
|
||||||
}
|
|
||||||
|
|
||||||
CleanPublishedOutput();
|
|
||||||
InvokeUserApplicationCleanup();
|
|
||||||
|
|
||||||
StopTimer();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class IISApplication
|
|
||||||
{
|
|
||||||
private const string WEBSITE_NAME = "ASPNETTESTRUNS";
|
|
||||||
private const string NATIVE_MODULE_MANAGED_RUNTIME_VERSION = "vCoreFX";
|
|
||||||
|
|
||||||
private readonly ServerManager _serverManager = new ServerManager();
|
|
||||||
private readonly DeploymentParameters _deploymentParameters;
|
|
||||||
private readonly ILogger _logger;
|
|
||||||
private ApplicationPool _applicationPool;
|
|
||||||
private Application _application;
|
|
||||||
private Site _website;
|
|
||||||
|
|
||||||
public string VirtualDirectoryName { get; set; }
|
|
||||||
|
|
||||||
// Always create website with the same port.
|
|
||||||
public const int Port = 5100;
|
|
||||||
|
|
||||||
public string WebSiteRootFolder
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Path.Combine(
|
|
||||||
Environment.GetEnvironmentVariable("SystemDrive") + @"\",
|
|
||||||
"inetpub",
|
|
||||||
WEBSITE_NAME);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IISApplication(DeploymentParameters deploymentParameters, ILogger logger)
|
|
||||||
{
|
|
||||||
_deploymentParameters = deploymentParameters;
|
|
||||||
_logger = logger;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Deploy()
|
|
||||||
{
|
|
||||||
VirtualDirectoryName = new DirectoryInfo(_deploymentParameters.ApplicationPath).Parent.Name;
|
|
||||||
_applicationPool = CreateAppPool(VirtualDirectoryName);
|
|
||||||
_application = Website.Applications.Add("/" + VirtualDirectoryName, _deploymentParameters.ApplicationPath);
|
|
||||||
_application.ApplicationPoolName = _applicationPool.Name;
|
|
||||||
_serverManager.CommitChanges();
|
|
||||||
}
|
|
||||||
|
|
||||||
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 (_deploymentParameters.ServerType == ServerType.IISNativeModule)
|
|
||||||
{
|
|
||||||
// Not assigning a runtime version will choose v4.0 default.
|
|
||||||
applicationPool.ManagedRuntimeVersion = NATIVE_MODULE_MANAGED_RUNTIME_VERSION;
|
|
||||||
}
|
|
||||||
|
|
||||||
applicationPool.Enable32BitAppOnWin64 = (_deploymentParameters.RuntimeArchitecture == RuntimeArchitecture.x86);
|
|
||||||
_logger.LogInformation("Created {bit} application pool '{name}' with runtime version {runtime}.",
|
|
||||||
_deploymentParameters.RuntimeArchitecture, applicationPool.Name,
|
|
||||||
string.IsNullOrEmpty(applicationPool.ManagedRuntimeVersion) ? "that is default" : applicationPool.ManagedRuntimeVersion);
|
|
||||||
return applicationPool;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void StopAndDeleteAppPool()
|
|
||||||
{
|
|
||||||
_logger.LogInformation("Stopping application pool '{name}' and deleting application.", _applicationPool.Name);
|
|
||||||
|
|
||||||
if (_applicationPool != null)
|
|
||||||
{
|
|
||||||
_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
|
|
||||||
|
|
@ -1,205 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.Framework.Logging;
|
|
||||||
using Microsoft.Framework.Runtime;
|
|
||||||
using Microsoft.Framework.Runtime.Infrastructure;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Deployment helper for IISExpress.
|
|
||||||
/// </summary>
|
|
||||||
public class IISExpressDeployer : ApplicationDeployer
|
|
||||||
{
|
|
||||||
private Process _hostProcess;
|
|
||||||
|
|
||||||
public IISExpressDeployer(DeploymentParameters deploymentParameters, ILogger logger)
|
|
||||||
: base(deploymentParameters, logger)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DeploymentResult Deploy()
|
|
||||||
{
|
|
||||||
// Start timer
|
|
||||||
StartTimer();
|
|
||||||
|
|
||||||
DeploymentParameters.DnxRuntime = PopulateChosenRuntimeInformation();
|
|
||||||
|
|
||||||
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
|
||||||
{
|
|
||||||
DnuPublish();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Launch the host process.
|
|
||||||
var hostExitToken = StartHeliosHost();
|
|
||||||
|
|
||||||
return new DeploymentResult
|
|
||||||
{
|
|
||||||
WebRootLocation = DeploymentParameters.ApplicationPath,
|
|
||||||
DeploymentParameters = DeploymentParameters,
|
|
||||||
// Right now this works only for urls like http://localhost:5001/. Does not work for http://localhost:5001/subpath.
|
|
||||||
ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint,
|
|
||||||
HostShutdownToken = hostExitToken
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private CancellationToken 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}\" /trace:error", new Uri(DeploymentParameters.ApplicationBaseUriHint).Port, webroot) :
|
|
||||||
string.Format("/site:{0} /config:{1} /trace:error", 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
|
|
||||||
SetEnvironmentVariable(startInfo.EnvironmentVariables, "PATH", ChosenRuntimePath + ";" + startInfo.EnvironmentVariables["PATH"]);
|
|
||||||
SetEnvironmentVariable(startInfo.EnvironmentVariables, "DNX_APPBASE", DeploymentParameters.ApplicationPath);
|
|
||||||
#elif DNXCORE50
|
|
||||||
SetEnvironmentVariable(startInfo.Environment, "PATH", ChosenRuntimePath + ";" + startInfo.Environment["PATH"]);
|
|
||||||
SetEnvironmentVariable(startInfo.Environment, "DNX_APPBASE", DeploymentParameters.ApplicationPath);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
_hostProcess = Process.Start(startInfo);
|
|
||||||
_hostProcess.EnableRaisingEvents = true;
|
|
||||||
var hostExitTokenSource = new CancellationTokenSource();
|
|
||||||
_hostProcess.Exited += (sender, e) =>
|
|
||||||
{
|
|
||||||
TriggerHostShutdown(hostExitTokenSource);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (_hostProcess.HasExited)
|
|
||||||
{
|
|
||||||
Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, _hostProcess.ExitCode);
|
|
||||||
throw new Exception("Failed to start host");
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.LogInformation("Started iisexpress. Process Id : {processId}", _hostProcess.Id);
|
|
||||||
return hostExitTokenSource.Token;
|
|
||||||
}
|
|
||||||
|
|
||||||
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();
|
|
||||||
|
|
||||||
StopTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,108 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.Framework.Logging;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Deployer for Kestrel on Mono.
|
|
||||||
/// </summary>
|
|
||||||
public class MonoDeployer : ApplicationDeployer
|
|
||||||
{
|
|
||||||
private Process _hostProcess;
|
|
||||||
|
|
||||||
public MonoDeployer(DeploymentParameters deploymentParameters, ILogger logger)
|
|
||||||
: base(deploymentParameters, logger)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DeploymentResult Deploy()
|
|
||||||
{
|
|
||||||
// Start timer
|
|
||||||
StartTimer();
|
|
||||||
|
|
||||||
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.
|
|
||||||
var hostExitToken = StartMonoHost();
|
|
||||||
|
|
||||||
return new DeploymentResult
|
|
||||||
{
|
|
||||||
WebRootLocation = DeploymentParameters.ApplicationPath,
|
|
||||||
DeploymentParameters = DeploymentParameters,
|
|
||||||
ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint,
|
|
||||||
HostShutdownToken = hostExitToken
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private CancellationToken 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
|
|
||||||
};
|
|
||||||
|
|
||||||
_hostProcess = Process.Start(startInfo);
|
|
||||||
_hostProcess.EnableRaisingEvents = true;
|
|
||||||
var hostExitTokenSource = new CancellationTokenSource();
|
|
||||||
_hostProcess.Exited += (sender, e) =>
|
|
||||||
{
|
|
||||||
Logger.LogError("Host process {processName} exited with code {exitCode}.", startInfo.FileName, _hostProcess.ExitCode);
|
|
||||||
TriggerHostShutdown(hostExitTokenSource);
|
|
||||||
};
|
|
||||||
|
|
||||||
Logger.LogInformation("Started {0}. Process Id : {1}", _hostProcess.MainModule.FileName, _hostProcess.Id);
|
|
||||||
|
|
||||||
if (_hostProcess.HasExited)
|
|
||||||
{
|
|
||||||
Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, _hostProcess.ExitCode);
|
|
||||||
throw new Exception("Failed to start host");
|
|
||||||
}
|
|
||||||
|
|
||||||
return hostExitTokenSource.Token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
ShutDownIfAnyHostProcess(_hostProcess);
|
|
||||||
|
|
||||||
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
|
||||||
{
|
|
||||||
CleanPublishedOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
InvokeUserApplicationCleanup();
|
|
||||||
|
|
||||||
StopTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,92 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using System.IO;
|
|
||||||
using System.Threading;
|
|
||||||
using Microsoft.Framework.Logging;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Deployer for WebListener and Kestrel.
|
|
||||||
/// </summary>
|
|
||||||
public class SelfHostDeployer : ApplicationDeployer
|
|
||||||
{
|
|
||||||
private Process _hostProcess;
|
|
||||||
|
|
||||||
public SelfHostDeployer(DeploymentParameters deploymentParameters, ILogger logger)
|
|
||||||
: base(deploymentParameters, logger)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override DeploymentResult Deploy()
|
|
||||||
{
|
|
||||||
// Start timer
|
|
||||||
StartTimer();
|
|
||||||
|
|
||||||
DeploymentParameters.DnxRuntime = PopulateChosenRuntimeInformation();
|
|
||||||
|
|
||||||
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
|
||||||
{
|
|
||||||
DnuPublish();
|
|
||||||
}
|
|
||||||
|
|
||||||
// Launch the host process.
|
|
||||||
var hostExitToken = StartSelfHost();
|
|
||||||
|
|
||||||
return new DeploymentResult
|
|
||||||
{
|
|
||||||
WebRootLocation = DeploymentParameters.ApplicationPath,
|
|
||||||
DeploymentParameters = DeploymentParameters,
|
|
||||||
ApplicationBaseUri = DeploymentParameters.ApplicationBaseUriHint,
|
|
||||||
HostShutdownToken = hostExitToken
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private CancellationToken StartSelfHost()
|
|
||||||
{
|
|
||||||
var commandName = DeploymentParameters.ServerType == ServerType.WebListener ? "web" : "kestrel";
|
|
||||||
Logger.LogInformation("Executing dnx.exe {appPath} {command} --server.urls {url}", DeploymentParameters.ApplicationPath, commandName, DeploymentParameters.ApplicationBaseUriHint);
|
|
||||||
|
|
||||||
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);
|
|
||||||
|
|
||||||
_hostProcess = Process.Start(startInfo);
|
|
||||||
_hostProcess.EnableRaisingEvents = true;
|
|
||||||
var hostExitTokenSource = new CancellationTokenSource();
|
|
||||||
_hostProcess.Exited += (sender, e) =>
|
|
||||||
{
|
|
||||||
TriggerHostShutdown(hostExitTokenSource);
|
|
||||||
};
|
|
||||||
|
|
||||||
if (_hostProcess.HasExited)
|
|
||||||
{
|
|
||||||
Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, _hostProcess.ExitCode);
|
|
||||||
throw new Exception("Failed to start host");
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.LogInformation("Started {fileName}. Process Id : {processId}", startInfo.FileName, _hostProcess.Id);
|
|
||||||
return hostExitTokenSource.Token;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override void Dispose()
|
|
||||||
{
|
|
||||||
ShutDownIfAnyHostProcess(_hostProcess);
|
|
||||||
|
|
||||||
if (DeploymentParameters.PublishApplicationBeforeDeployment)
|
|
||||||
{
|
|
||||||
CleanPublishedOutput();
|
|
||||||
}
|
|
||||||
|
|
||||||
InvokeUserApplicationCleanup();
|
|
||||||
|
|
||||||
StopTimer();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<Project ToolsVersion="14.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
|
||||||
<PropertyGroup>
|
|
||||||
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0</VisualStudioVersion>
|
|
||||||
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.Props" Condition="'$(VSToolsPath)' != ''" />
|
|
||||||
<PropertyGroup Label="Globals">
|
|
||||||
<ProjectGuid>c98e54d3-f4c6-4d16-a5a6-e86a636a7311</ProjectGuid>
|
|
||||||
<RootNamespace>DeploymentHelpers</RootNamespace>
|
|
||||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">..\..\artifacts\obj\$(MSBuildProjectName)</BaseIntermediateOutputPath>
|
|
||||||
<OutputPath Condition="'$(OutputPath)'=='' ">..\..\artifacts\bin\$(MSBuildProjectName)\</OutputPath>
|
|
||||||
</PropertyGroup>
|
|
||||||
|
|
||||||
<PropertyGroup>
|
|
||||||
<SchemaVersion>2.0</SchemaVersion>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'">
|
|
||||||
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
|
|
||||||
</PropertyGroup>
|
|
||||||
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|AnyCPU'">
|
|
||||||
<ProduceOutputsOnBuild>True</ProduceOutputsOnBuild>
|
|
||||||
</PropertyGroup>
|
|
||||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
|
||||||
</Project>
|
|
||||||
|
|
@ -1,31 +0,0 @@
|
||||||
{
|
|
||||||
"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": {
|
|
||||||
"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-*"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.Diagnostics;
|
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
|
||||||
public class SkipIfCurrentRuntimeIsCoreClrAttribute : Attribute, ITestCondition
|
|
||||||
{
|
|
||||||
public bool IsMet
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return !Process.GetCurrentProcess().ProcessName.ToLower().Contains("coreclr");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string SkipReason
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return "Cannot run these test variations using CoreCLR DNX as helpers are not available on CoreCLR.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
|
||||||
public class SkipIfIISNativeVariationsNotEnabledAttribute : Attribute, ITestCondition
|
|
||||||
{
|
|
||||||
public bool IsMet
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Environment.GetEnvironmentVariable("IIS_NATIVE_VARIATIONS_ENABLED") == "true";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string SkipReason
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return "Skipping Native module test since native module variations are not enabled. " +
|
|
||||||
"To run the test, setup the native module and set the environment variable IIS_NATIVE_VARIATIONS_ENABLED=true.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,26 +0,0 @@
|
||||||
using System;
|
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
|
||||||
public class SkipIfIISVariationsNotEnabledAttribute : Attribute, ITestCondition
|
|
||||||
{
|
|
||||||
public bool IsMet
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return Environment.GetEnvironmentVariable("IIS_VARIATIONS_ENABLED") == "true";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string SkipReason
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return "Skipping IIS variation of tests. " +
|
|
||||||
"To run the IIS variations, setup IIS and set the environment variable IIS_VARIATIONS_ENABLED=true.";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,27 +0,0 @@
|
||||||
using System;
|
|
||||||
using System.IO;
|
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
|
||||||
|
|
||||||
namespace DeploymentHelpers
|
|
||||||
{
|
|
||||||
[AttributeUsage(AttributeTargets.Method, AllowMultiple = false)]
|
|
||||||
public class SkipOn32BitOSAttribute : Attribute, ITestCondition
|
|
||||||
{
|
|
||||||
public bool IsMet
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
// Directory found only on 64-bit OS.
|
|
||||||
return Directory.Exists(Path.Combine(Environment.GetEnvironmentVariable("SystemRoot"), "SysWOW64"));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public string SkipReason
|
|
||||||
{
|
|
||||||
get
|
|
||||||
{
|
|
||||||
return "Skipping the AMD64 test since the OS is 32-bit";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using DeploymentHelpers;
|
using Microsoft.AspNet.Server.Testing;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
|
|
||||||
namespace E2ETests
|
namespace E2ETests
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@ using System.Net;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DeploymentHelpers;
|
using Microsoft.AspNet.Server.Testing;
|
||||||
using Microsoft.AspNet.SignalR.Client;
|
using Microsoft.AspNet.SignalR.Client;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DeploymentHelpers;
|
using Microsoft.AspNet.Server.Testing;
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
using Microsoft.AspNet.Testing.xunit;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DeploymentHelpers;
|
using Microsoft.AspNet.Server.Testing;
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
using Microsoft.AspNet.Testing.xunit;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DeploymentHelpers;
|
using Microsoft.AspNet.Server.Testing;
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
using Microsoft.AspNet.Testing.xunit;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,7 @@
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Net.Http;
|
using System.Net.Http;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using DeploymentHelpers;
|
using Microsoft.AspNet.Server.Testing;
|
||||||
using Microsoft.AspNet.Testing.xunit;
|
using Microsoft.AspNet.Testing.xunit;
|
||||||
using Microsoft.Framework.Logging;
|
using Microsoft.Framework.Logging;
|
||||||
using Xunit;
|
using Xunit;
|
||||||
|
|
|
||||||
|
|
@ -6,8 +6,8 @@
|
||||||
"test": "xunit.runner.aspnet"
|
"test": "xunit.runner.aspnet"
|
||||||
},
|
},
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"DeploymentHelpers": "1.0.0-*",
|
|
||||||
"Microsoft.AspNet.Server.IIS": "1.0.0-*",
|
"Microsoft.AspNet.Server.IIS": "1.0.0-*",
|
||||||
|
"Microsoft.AspNet.Server.Testing": "1.0.0-*",
|
||||||
"Microsoft.AspNet.SignalR.Client": "2.1.1",
|
"Microsoft.AspNet.SignalR.Client": "2.1.1",
|
||||||
"Microsoft.AspNet.WebUtilities": "1.0.0-*",
|
"Microsoft.AspNet.WebUtilities": "1.0.0-*",
|
||||||
"Microsoft.Framework.Logging.Console": "1.0.0-*",
|
"Microsoft.Framework.Logging.Console": "1.0.0-*",
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue