/
githubmirror
/
aspnetcore
Обзор
Документация
Войти
/
githubmirror
/
aspnetcore
Код
Запросы
0
Пакеты
0
Релизы
0
Аналитика
Безопасность
main
src/Hosting/test/FunctionalTests/ShutdownTests.cs
144 строки
5 KB
dotnet-maestro[bot]
[main] Source code updates from dotnet/dotnet (#62019)
23 май 2025, 01:49
Не верифицирован
23 май 2025, 01:49
5678f22
Код
Авторство
О чём код?
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using System.Diagnostics; using System.Globalization; using Microsoft.AspNetCore.Server.IntegrationTesting; using Microsoft.AspNetCore.InternalTesting; using Xunit.Abstractions; namespace Microsoft.AspNetCore.Hosting.FunctionalTests; public class ShutdownTests : LoggedTest { private static readonly string StartedMessage = "Started"; private static readonly string CompletionMessage = "Stopping firing\n" + "Stopping end\n" + "Stopped firing\n" + "Stopped end"; public ShutdownTests(ITestOutputHelper output) : base(output) { } [ConditionalFact] [OSSkipCondition(OperatingSystems.Windows)] [OSSkipCondition(OperatingSystems.MacOSX)] public async Task ShutdownTestRun() { await ExecuteShutdownTest(nameof(ShutdownTestRun), "Run"); } [ConditionalFact] [OSSkipCondition(OperatingSystems.Windows)] [OSSkipCondition(OperatingSystems.MacOSX)] public async Task ShutdownTestWaitForShutdown() { await ExecuteShutdownTest(nameof(ShutdownTestWaitForShutdown), "WaitForShutdown"); } private async Task ExecuteShutdownTest(string testName, string shutdownMechanic) { using (StartLog(out var loggerFactory)) { var logger = loggerFactory.CreateLogger(testName); // https://github.com/dotnet/aspnetcore/issues/8247 #pragma warning disable 0618 var applicationPath = Path.Combine(TestPathUtilities.GetSolutionRootDirectory("Hosting"), "test", "testassets", "Microsoft.AspNetCore.Hosting.TestSites"); #pragma warning restore 0618 var deploymentParameters = new DeploymentParameters( applicationPath, ServerType.Kestrel, RuntimeFlavor.CoreClr, RuntimeArchitectures.Current) { EnvironmentName = "Shutdown", TargetFramework = Tfm.Default, ApplicationType = ApplicationType.Portable, PublishApplicationBeforeDeployment = true, StatusMessagesEnabled = false }; deploymentParameters.EnvironmentVariables["ASPNETCORE_STARTMECHANIC"] = shutdownMechanic; using (var deployer = new SelfHostDeployer(deploymentParameters, loggerFactory)) { var startedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var completedTcs = new TaskCompletionSource(TaskCreationOptions.RunContinuationsAsynchronously); var output = string.Empty; deployer.ProcessOutputListener = (data) => { if (!string.IsNullOrEmpty(data) && data.StartsWith(StartedMessage, StringComparison.Ordinal)) { startedTcs.TrySetResult(); output += data.Substring(StartedMessage.Length) + '\n'; } else { output += data + '\n'; } if (output.Contains(CompletionMessage)) { completedTcs.TrySetResult(); } }; await deployer.DeployAsync(); try { await startedTcs.Task.TimeoutAfter(TimeSpan.FromMinutes(1)); } catch (TimeoutException ex) { throw new InvalidOperationException("Timeout while waiting for host process to output started message.", ex); } SendSIGTERM(deployer.HostProcess.Id); WaitForExitOrKill(deployer.HostProcess); try { await completedTcs.Task.TimeoutAfter(TimeSpan.FromMinutes(1)); } catch (TimeoutException ex) { throw new InvalidOperationException($"Timeout while waiting for host process to output completion message. The received output is: {output}", ex); } output = output.Trim('\n'); Assert.Equal(CompletionMessage, output); } } } private static void SendSIGTERM(int processId) { var startInfo = new ProcessStartInfo { FileName = "kill", Arguments = processId.ToString(CultureInfo.InvariantCulture), RedirectStandardOutput = true, UseShellExecute = false }; var process = Process.Start(startInfo); WaitForExitOrKill(process); } private static void WaitForExitOrKill(Process process) { process.WaitForExit(5 * 1000); if (!process.HasExited) { process.Kill(); } Assert.Equal(0, process.ExitCode); } }