Skip to content
This repository has been archived by the owner on Dec 19, 2018. It is now read-only.

Commit

Permalink
Add test for SIGTERM functionality
Browse files Browse the repository at this point in the history
  • Loading branch information
pakrym committed Nov 3, 2016
1 parent 2bddba8 commit f6fb717
Show file tree
Hide file tree
Showing 11 changed files with 379 additions and 15 deletions.
33 changes: 31 additions & 2 deletions Hosting.sln
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -103,32 +103,32 @@ protected CancellationToken StartSelfHost(Uri uri)

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)
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
"type": "build",
"version": "1.1.0-*"
},
"Microsoft.Extensions.PlatformAbstractions": "1.1.0-*",
"NETStandard.Library": "1.6.1-*"
},
"frameworks": {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// 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}");
}

}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>fc578f4e-171c-4f82-b301-3abf6318d082</ProjectGuid>
<RootNamespace>Microsoft.AspNetCore.Hosting.FunctionalTests</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
</PropertyGroup>

<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
106 changes: 106 additions & 0 deletions test/Microsoft.AspNetCore.Hosting.FunctionalTests/ShutdownTests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
// 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)]
public async Task 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))
{
var deploymentResult = deployer.Deploy();
var httpClientHandler = new HttpClientHandler();
var httpClient = new HttpClient(httpClientHandler)
{
BaseAddress = new Uri(deploymentResult.ApplicationBaseUri)
};

var response = await RetryHelper.RetryRequest(
() => httpClient.GetAsync(string.Empty),
logger,
deploymentResult.HostShutdownToken);

var responseText = await response.Content.ReadAsStringAsync();
try
{
Assert.Equal("Hello World", responseText);
}
catch (XunitException)
{
logger.LogWarning(response.ToString());
logger.LogWarning(responseText);
throw;
}

string output = string.Empty;
deployer.HostProcess.OutputDataReceived += (sender, args) => output += args.Data + '\n';

SendSIGINT(deployer.HostProcess.Id);

deployer.HostProcess.WaitForExit();
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);
process.WaitForExit(1000);
if (!process.HasExited)
{
process.Kill();
}

Assert.Equal(0, process.ExitCode);
}
}
}
34 changes: 34 additions & 0 deletions test/Microsoft.AspNetCore.Hosting.FunctionalTests/project.json
Original file line number Diff line number Diff line change
@@ -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"
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0.25420" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<VisualStudioVersion Condition="'$(VisualStudioVersion)' == ''">14.0.25420</VisualStudioVersion>
<VSToolsPath Condition="'$(VSToolsPath)' == ''">$(MSBuildExtensionsPath32)\Microsoft\VisualStudio\v$(VisualStudioVersion)</VSToolsPath>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.Props" Condition="'$(VSToolsPath)' != ''" />
<PropertyGroup Label="Globals">
<ProjectGuid>542d4600-b232-4b17-a08c-e31ebfa0d74e</ProjectGuid>
<RootNamespace>Microsoft.AspNetCore.Hosting.TestSites</RootNamespace>
<BaseIntermediateOutputPath Condition="'$(BaseIntermediateOutputPath)'=='' ">.\obj</BaseIntermediateOutputPath>
<OutputPath Condition="'$(OutputPath)'=='' ">.\bin\</OutputPath>
</PropertyGroup>

<PropertyGroup>
<SchemaVersion>2.0</SchemaVersion>
</PropertyGroup>
<Import Project="$(VSToolsPath)\DotNet\Microsoft.DotNet.targets" Condition="'$(VSToolsPath)' != ''" />
</Project>
49 changes: 49 additions & 0 deletions test/Microsoft.AspNetCore.Hosting.TestSites/Program.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// 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)
.UseKestrel()
.UseStartup("Microsoft.AspNetCore.Hosting.TestSites");

var host = builder.Build();

host.Run();
}
}

public class NoopServer : IServer
{
private readonly ManualResetEventSlim _serverEvent = new ManualResetEventSlim(false);

public void Dispose()
{
_serverEvent.Set();
}

public IFeatureCollection Features { get; } = new FeatureCollection();

public void Start<TContext>(IHttpApplication<TContext> application)
{
_serverEvent.Wait();
}
}
}

Loading

0 comments on commit f6fb717

Please sign in to comment.