diff --git a/Hosting.sln b/Hosting.sln
index e00cee06..96a30a67 100644
--- a/Hosting.sln
+++ b/Hosting.sln
@@ -1,7 +1,6 @@
-
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 14
-VisualStudioVersion = 14.0.24720.0
+VisualStudioVersion = 14.0.25420.1
MinimumVisualStudioVersion = 10.0.40219.1
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{E0497F39-AFFB-4819-A116-E39E361915AB}"
EndProject
@@ -32,6 +31,10 @@ Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "SampleStartups", "samples\S
EndProject
Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Hosting.WindowsServices", "src\Microsoft.AspNetCore.Hosting.WindowsServices\Microsoft.AspNetCore.Hosting.WindowsServices.xproj", "{03148731-EA95-40A2-BAE8-A12315EA1748}"
EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Hosting.FunctionalTests", "test\Microsoft.AspNetCore.Hosting.FunctionalTests\Microsoft.AspNetCore.Hosting.FunctionalTests.xproj", "{FC578F4E-171C-4F82-B301-3ABF6318D082}"
+EndProject
+Project("{8BB2217D-0F2D-49D1-97BC-3654ED321F3B}") = "Microsoft.AspNetCore.Hosting.TestSites", "test\Microsoft.AspNetCore.Hosting.TestSites\Microsoft.AspNetCore.Hosting.TestSites.xproj", "{542D4600-B232-4B17-A08C-E31EBFA0D74E}"
+EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
@@ -142,6 +145,30 @@ Global
{03148731-EA95-40A2-BAE8-A12315EA1748}.Release|Mixed Platforms.Build.0 = Release|Any CPU
{03148731-EA95-40A2-BAE8-A12315EA1748}.Release|x86.ActiveCfg = Release|Any CPU
{03148731-EA95-40A2-BAE8-A12315EA1748}.Release|x86.Build.0 = Release|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Debug|x86.Build.0 = Debug|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Release|Any CPU.Build.0 = Release|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Release|x86.ActiveCfg = Release|Any CPU
+ {FC578F4E-171C-4F82-B301-3ABF6318D082}.Release|x86.Build.0 = Release|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Debug|Mixed Platforms.ActiveCfg = Debug|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Debug|Mixed Platforms.Build.0 = Debug|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Debug|x86.ActiveCfg = Debug|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Debug|x86.Build.0 = Debug|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Release|Any CPU.Build.0 = Release|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Release|Mixed Platforms.ActiveCfg = Release|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Release|Mixed Platforms.Build.0 = Release|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Release|x86.ActiveCfg = Release|Any CPU
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
@@ -156,5 +183,7 @@ Global
{3DA89347-6731-4366-80C4-548F24E8607B} = {E0497F39-AFFB-4819-A116-E39E361915AB}
{485B6745-7648-400A-A969-F68FCF194E46} = {9C7520A0-F2EB-411C-8BB2-80B39C937217}
{03148731-EA95-40A2-BAE8-A12315EA1748} = {E0497F39-AFFB-4819-A116-E39E361915AB}
+ {FC578F4E-171C-4F82-B301-3ABF6318D082} = {FEB39027-9158-4DE2-997F-7ADAEF8188D0}
+ {542D4600-B232-4B17-A08C-E31EBFA0D74E} = {FEB39027-9158-4DE2-997F-7ADAEF8188D0}
EndGlobalSection
EndGlobal
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs
index 7148c6fb..d7764c02 100644
--- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/Deployers/SelfHostDeployer.cs
@@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
///
public class SelfHostDeployer : ApplicationDeployer
{
- private Process _hostProcess;
+ public Process HostProcess { get; private set; }
public SelfHostDeployer(DeploymentParameters deploymentParameters, ILogger logger)
: base(deploymentParameters, logger)
@@ -103,32 +103,32 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
AddEnvironmentVariablesToProcess(startInfo, DeploymentParameters.EnvironmentVariables);
- _hostProcess = new Process() { StartInfo = startInfo };
- _hostProcess.ErrorDataReceived += (sender, dataArgs) => { Logger.LogError(dataArgs.Data ?? string.Empty); };
- _hostProcess.OutputDataReceived += (sender, dataArgs) => { Logger.LogInformation(dataArgs.Data ?? string.Empty); };
- _hostProcess.EnableRaisingEvents = true;
+ HostProcess = new Process() { StartInfo = startInfo };
+ HostProcess.ErrorDataReceived += (sender, dataArgs) => { Logger.LogError(dataArgs.Data ?? string.Empty); };
+ HostProcess.OutputDataReceived += (sender, dataArgs) => { Logger.LogInformation(dataArgs.Data ?? string.Empty); };
+ HostProcess.EnableRaisingEvents = true;
var hostExitTokenSource = new CancellationTokenSource();
- _hostProcess.Exited += (sender, e) =>
+ HostProcess.Exited += (sender, e) =>
{
TriggerHostShutdown(hostExitTokenSource);
};
- _hostProcess.Start();
- _hostProcess.BeginErrorReadLine();
- _hostProcess.BeginOutputReadLine();
+ HostProcess.Start();
+ HostProcess.BeginErrorReadLine();
+ HostProcess.BeginOutputReadLine();
- if (_hostProcess.HasExited)
+ if (HostProcess.HasExited)
{
- Logger.LogError("Host process {processName} exited with code {exitCode} or failed to start.", startInfo.FileName, _hostProcess.ExitCode);
+ Logger.LogError("Host process {processName} exited with code {exitCode} 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);
+ Logger.LogInformation("Started {fileName}. Process Id : {processId}", startInfo.FileName, HostProcess.Id);
return hostExitTokenSource.Token;
}
public override void Dispose()
{
- ShutDownIfAnyHostProcess(_hostProcess);
+ ShutDownIfAnyHostProcess(HostProcess);
if (DeploymentParameters.PublishApplicationBeforeDeployment)
{
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/project.json b/src/Microsoft.AspNetCore.Server.IntegrationTesting/project.json
index 98b6d395..a7e2cb5e 100644
--- a/src/Microsoft.AspNetCore.Server.IntegrationTesting/project.json
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/project.json
@@ -32,6 +32,7 @@
"type": "build",
"version": "1.1.0-*"
},
+ "Microsoft.Extensions.PlatformAbstractions": "1.1.0-*",
"NETStandard.Library": "1.6.1-*"
},
"frameworks": {
diff --git a/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/TestProjectHelpers.cs b/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/TestProjectHelpers.cs
new file mode 100644
index 00000000..76a3dc6d
--- /dev/null
+++ b/src/Microsoft.AspNetCore.Server.IntegrationTesting/xunit/TestProjectHelpers.cs
@@ -0,0 +1,32 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.IO;
+using Microsoft.Extensions.PlatformAbstractions;
+
+namespace Microsoft.AspNetCore.Server.IntegrationTesting.xunit
+{
+ public class TestProjectHelpers
+ {
+ public static string GetProjectRoot()
+ {
+ var applicationBasePath = PlatformServices.Default.Application.ApplicationBasePath;
+
+ var directoryInfo = new DirectoryInfo(applicationBasePath);
+ do
+ {
+ var projectFileInfo = new FileInfo(Path.Combine(directoryInfo.FullName, "project.json"));
+ if (projectFileInfo.Exists)
+ {
+ return projectFileInfo.DirectoryName;
+ }
+
+ directoryInfo = directoryInfo.Parent;
+ }
+ while (directoryInfo.Parent != null);
+
+ throw new Exception($"Project root could not be found using {applicationBasePath}");
+ }
+ }
+ }
diff --git a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.xproj b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.xproj
new file mode 100644
index 00000000..3e17cac8
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/Microsoft.AspNetCore.Hosting.FunctionalTests.xproj
@@ -0,0 +1,17 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ fc578f4e-171c-4f82-b301-3abf6318d082
+ .\obj
+ .\bin\
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs
new file mode 100644
index 00000000..c794cbc9
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs
@@ -0,0 +1,94 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using System.Diagnostics;
+using System.IO;
+using System.Net.Http;
+using System.Threading.Tasks;
+using Microsoft.AspNetCore.Server.IntegrationTesting;
+using Microsoft.AspNetCore.Server.IntegrationTesting.xunit;
+using Microsoft.AspNetCore.Testing.xunit;
+using Microsoft.Extensions.Logging;
+using Xunit;
+using Xunit.Sdk;
+
+namespace Microsoft.AspNetCore.Hosting.FunctionalTests
+{
+ public class ShutdownTests
+ {
+ [ConditionalFact]
+ [OSSkipCondition(OperatingSystems.Windows)]
+ [OSSkipCondition(OperatingSystems.MacOSX)]
+ public void ShutdownTest()
+ {
+ var logger = new LoggerFactory()
+ .AddConsole()
+ .CreateLogger(nameof(ShutdownTest));
+
+ string applicationPath = Path.Combine(TestProjectHelpers.GetProjectRoot(), "..",
+ "Microsoft.AspNetCore.Hosting.TestSites");
+
+ var deploymentParameters = new DeploymentParameters(
+ applicationPath,
+ ServerType.Kestrel,
+ RuntimeFlavor.CoreClr,
+ RuntimeArchitecture.x64)
+ {
+ EnvironmentName = "Shutdown",
+ TargetFramework = "netcoreapp1.1",
+ ApplicationType = ApplicationType.Portable,
+ PublishApplicationBeforeDeployment = true
+ };
+
+ using (var deployer = new SelfHostDeployer(deploymentParameters, logger))
+ {
+ deployer.Deploy();
+
+ // Wait for application to start
+ System.Threading.Thread.Sleep(1000);
+
+ string output = string.Empty;
+ deployer.HostProcess.OutputDataReceived += (sender, args) => output += args.Data + '\n';
+
+ SendSIGINT(deployer.HostProcess.Id);
+
+ WaitForExitOrKill(deployer.HostProcess);
+
+ output = output.Trim('\n');
+
+ Assert.Equal(output, "Application is shutting down...\n" +
+ "Stopping firing\n" +
+ "Stopping end\n" +
+ "Stopped firing\n" +
+ "Stopped end");
+ }
+ }
+
+
+ private static void SendSIGINT(int processId)
+ {
+ var startInfo = new ProcessStartInfo
+ {
+ FileName = "kill",
+ Arguments = processId.ToString(),
+ RedirectStandardOutput = true,
+ UseShellExecute = false
+ };
+
+ var process = Process.Start(startInfo);
+ WaitForExitOrKill(process);
+ }
+
+ private static void WaitForExitOrKill(Process process)
+ {
+ process.WaitForExit(1000);
+ if (!process.HasExited)
+ {
+ process.Kill();
+ }
+
+ Assert.Equal(0, process.ExitCode);
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Hosting.FunctionalTests/project.json b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/project.json
new file mode 100644
index 00000000..0abc059b
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Hosting.FunctionalTests/project.json
@@ -0,0 +1,34 @@
+{
+ "buildOptions": {
+ "warningsAsErrors": true,
+ "keyFile": "../../tools/Key.snk",
+ "copyToOutput": {
+ "include": [
+ "testroot/**/*"
+ ]
+ }
+ },
+ "publishOptions": {
+ "include": [
+ "testroot/**/*"
+ ]
+ },
+ "dependencies": {
+ "dotnet-test-xunit": "2.2.0-*",
+ "Microsoft.AspNetCore.Server.IntegrationTesting": "0.2.0-*",
+ "Microsoft.AspNetCore.Hosting": "1.1.0-*",
+ "Microsoft.Extensions.Logging.Console": "1.1.0-*",
+ "xunit": "2.2.0-*"
+ },
+ "frameworks": {
+ "netcoreapp1.1": {
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "version": "1.1.0-*",
+ "type": "platform"
+ }
+ }
+ }
+ },
+ "testRunner": "xunit"
+}
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Hosting.TestSites/.Program.cs.swp b/test/Microsoft.AspNetCore.Hosting.TestSites/.Program.cs.swp
new file mode 100644
index 00000000..ef1c7881
Binary files /dev/null and b/test/Microsoft.AspNetCore.Hosting.TestSites/.Program.cs.swp differ
diff --git a/test/Microsoft.AspNetCore.Hosting.TestSites/Microsoft.AspNetCore.Hosting.TestSites.xproj b/test/Microsoft.AspNetCore.Hosting.TestSites/Microsoft.AspNetCore.Hosting.TestSites.xproj
new file mode 100644
index 00000000..05732b74
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Hosting.TestSites/Microsoft.AspNetCore.Hosting.TestSites.xproj
@@ -0,0 +1,17 @@
+
+
+
+ 14.0
+ $(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)
+
+
+
+ 542d4600-b232-4b17-a08c-e31ebfa0d74e
+ .\obj
+ .\bin\
+
+
+ 2.0
+
+
+
\ No newline at end of file
diff --git a/test/Microsoft.AspNetCore.Hosting.TestSites/Program.cs b/test/Microsoft.AspNetCore.Hosting.TestSites/Program.cs
new file mode 100644
index 00000000..33332152
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Hosting.TestSites/Program.cs
@@ -0,0 +1,44 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using Microsoft.AspNetCore.Hosting;
+using Microsoft.Extensions.Configuration;
+using System.Threading;
+using Microsoft.AspNetCore.Hosting.Server;
+using Microsoft.AspNetCore.Http.Features;
+
+namespace ServerComparison.TestSites
+{
+ public static class Program
+ {
+ public static void Main(string[] args)
+ {
+ var config = new ConfigurationBuilder()
+ .AddCommandLine(args)
+ .Build();
+
+ var builder = new WebHostBuilder()
+ .UseServer(new NoopServer())
+ .UseConfiguration(config)
+ .UseStartup("Microsoft.AspNetCore.Hosting.TestSites");
+
+ var host = builder.Build();
+
+ host.Run();
+ }
+ }
+
+ public class NoopServer : IServer
+ {
+ public void Dispose()
+ {
+ }
+
+ public IFeatureCollection Features { get; } = new FeatureCollection();
+
+ public void Start(IHttpApplication application)
+ {
+ }
+ }
+}
+
diff --git a/test/Microsoft.AspNetCore.Hosting.TestSites/StartupShutdown.cs b/test/Microsoft.AspNetCore.Hosting.TestSites/StartupShutdown.cs
new file mode 100644
index 00000000..b8a5b8b7
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Hosting.TestSites/StartupShutdown.cs
@@ -0,0 +1,37 @@
+// Copyright (c) .NET Foundation. All rights reserved.
+// Licensed under the Apache License, Version 2.0. See License.txt in the project root for license information.
+
+using System;
+using Microsoft.AspNetCore.Builder;
+using Microsoft.AspNetCore.Http;
+using Microsoft.Extensions.Logging;
+
+namespace Microsoft.AspNetCore.Hosting.TestSites
+{
+ public class StartupShutdown
+ {
+ public void Configure(IApplicationBuilder app, ILoggerFactory loggerFactory, IApplicationLifetime lifetime)
+ {
+ lifetime.ApplicationStopping.Register(() =>
+ {
+ Console.WriteLine("Stopping firing");
+ System.Threading.Thread.Sleep(200);
+ Console.WriteLine("Stopping end");
+ });
+ lifetime.ApplicationStopped.Register(() =>
+ {
+ Console.WriteLine("Stopped firing");
+ System.Threading.Thread.Sleep(200);
+ Console.WriteLine("Stopped end");
+ });
+
+
+ loggerFactory.AddConsole(minLevel: LogLevel.Warning);
+
+ app.Run(context =>
+ {
+ return context.Response.WriteAsync("Hello World");
+ });
+ }
+ }
+}
diff --git a/test/Microsoft.AspNetCore.Hosting.TestSites/project.json b/test/Microsoft.AspNetCore.Hosting.TestSites/project.json
new file mode 100644
index 00000000..5dc04cc3
--- /dev/null
+++ b/test/Microsoft.AspNetCore.Hosting.TestSites/project.json
@@ -0,0 +1,23 @@
+{
+ "version": "1.1.0-*",
+ "dependencies": {
+ "Microsoft.AspNetCore.Hosting": "1.1.0-*",
+ "Microsoft.Extensions.Configuration": "1.1.0-*",
+ "Microsoft.Extensions.Configuration.CommandLine": "1.1.0-*",
+ "Microsoft.Extensions.Logging.Console": "1.1.0-*"
+ },
+ "buildOptions": {
+ "emitEntryPoint": true
+ },
+ "frameworks": {
+ "net451": {},
+ "netcoreapp1.1": {
+ "dependencies": {
+ "Microsoft.NETCore.App": {
+ "version": "1.1.0-*",
+ "type": "platform"
+ }
+ }
+ }
+ }
+}