Add test for SIGTERM functionality (#878)
This commit is contained in:
Родитель
911da31476
Коммит
1ee27971a5
33
Hosting.sln
33
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
|
||||
|
|
|
@ -16,7 +16,7 @@ namespace Microsoft.AspNetCore.Server.IntegrationTesting
|
|||
/// </summary>
|
||||
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)
|
||||
{
|
||||
|
|
|
@ -32,6 +32,7 @@
|
|||
"type": "build",
|
||||
"version": "1.1.0-*"
|
||||
},
|
||||
"Microsoft.Extensions.PlatformAbstractions": "1.1.0-*",
|
||||
"NETStandard.Library": "1.6.1-*"
|
||||
},
|
||||
"frameworks": {
|
||||
|
|
|
@ -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}");
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,17 @@
|
|||
<?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>fc578f4e-171c-4f82-b301-3abf6318d082</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
Двоичный файл не отображается.
|
@ -0,0 +1,17 @@
|
|||
<?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>542d4600-b232-4b17-a08c-e31ebfa0d74e</ProjectGuid>
|
||||
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
|
||||
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<SchemaVersion>2.0</SchemaVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VSToolsPath)\DNX\Microsoft.DNX.targets" Condition="'$(VSToolsPath)' != ''" />
|
||||
</Project>
|
|
@ -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<TContext>(IHttpApplication<TContext> application)
|
||||
{
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -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");
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
Загрузка…
Ссылка в новой задаче