| File: Layout\LayoutProcessRunnerTests.cs | Web Access |
| Project: src\tests\Aspire.Cli.Tests\Aspire.Cli.Tests.csproj (Aspire.Cli.Tests) |
// Licensed to the .NET Foundation under one or more agreements. // The .NET Foundation licenses this file to you under the MIT license. using Aspire.Cli.DotNet; using Aspire.Cli.Layout; using Aspire.Cli.Tests.TestServices; using Aspire.Shared; namespace Aspire.Cli.Tests.LayoutTests; public class LayoutProcessRunnerTests { [Theory] [InlineData(false)] [InlineData(true)] public async Task HelpersUseOwnedTreeWithoutCooperativeWatchdog(bool background) { IDictionary<string, string>? capturedEnvironment = null; ProcessInvocationOptions? capturedOptions = null; var factory = new TestProcessExecutionFactory { AssertionCallback = (_, environment, _, options) => { capturedEnvironment = environment; capturedOptions = options; } }; var runner = new LayoutProcessRunner(factory); if (background) { await using var execution = await runner.StartAsync("tool", ["arg"]); } else { await runner.RunAsync("tool", ["arg"], ct: TestContext.Current.CancellationToken); } Assert.NotNull(capturedOptions); Assert.Equal(ChildProcessLifetime.OwnedTree, capturedOptions.Lifetime); Assert.NotNull(capturedEnvironment); Assert.Empty(capturedEnvironment); } [Theory] [InlineData(false)] [InlineData(true)] public async Task HelpersPreserveCallerEnvironmentWithoutMutatingIt(bool background) { IDictionary<string, string>? capturedEnvironment = null; var factory = new TestProcessExecutionFactory { AssertionCallback = (_, environment, _, _) => capturedEnvironment = environment }; var runner = new LayoutProcessRunner(factory); var environment = new Dictionary<string, string> { ["CUSTOM"] = "value" }; if (background) { await using var execution = await runner.StartAsync("tool", ["arg"], environmentVariables: environment); } else { await runner.RunAsync("tool", ["arg"], environmentVariables: environment, ct: TestContext.Current.CancellationToken); } Assert.NotNull(capturedEnvironment); Assert.Equal(new KeyValuePair<string, string>("CUSTOM", "value"), Assert.Single(capturedEnvironment)); Assert.Equal(new KeyValuePair<string, string>("CUSTOM", "value"), Assert.Single(environment)); Assert.NotSame(environment, capturedEnvironment); } [Theory] [InlineData(false)] [InlineData(true)] public async Task StartAsync_ClonesOptionsAndPreservesParentExitOptIn(bool optInArgument) { ProcessInvocationOptions? capturedOptions = null; var factory = new TestProcessExecutionFactory { AssertionCallback = (_, _, _, options) => capturedOptions = options }; var runner = new LayoutProcessRunner(factory); var callerOptions = new ProcessInvocationOptions { KillOnParentExit = !optInArgument }; await using var execution = await runner.StartAsync("tool", ["arg"], options: callerOptions, killOnParentExit: optInArgument); Assert.NotNull(capturedOptions); Assert.True(capturedOptions.KillOnParentExit); Assert.Equal(ChildProcessLifetime.OwnedTree, capturedOptions.Lifetime); Assert.NotSame(callerOptions, capturedOptions); Assert.Equal(!optInArgument, callerOptions.KillOnParentExit); Assert.Equal(ChildProcessLifetime.CallerManaged, callerOptions.Lifetime); } [Fact] public async Task StartAsync_DetachedChildDoesNotBecomeAnOwnedTree() { ProcessInvocationOptions? capturedOptions = null; var factory = new TestProcessExecutionFactory { AssertionCallback = (_, _, _, options) => capturedOptions = options }; var runner = new LayoutProcessRunner(factory); await using var execution = await runner.StartAsync("tool", ["arg"], options: new ProcessInvocationOptions { Detached = true }); Assert.NotNull(capturedOptions); Assert.True(capturedOptions.Detached); Assert.Equal(ChildProcessLifetime.CallerManaged, capturedOptions.Lifetime); } [Fact] public async Task StartAsync_AppHostKeepsItsDistinctCleanupPolicy() { ProcessInvocationOptions? capturedOptions = null; var factory = new TestProcessExecutionFactory { AssertionCallback = (_, _, _, options) => capturedOptions = options }; var runner = new LayoutProcessRunner(factory); await using var execution = await runner.StartAsync("tool", ["arg"], options: new ProcessInvocationOptions { Lifetime = ChildProcessLifetime.AppHost }, killOnParentExit: true); Assert.NotNull(capturedOptions); Assert.True(capturedOptions.KillOnParentExit); Assert.Equal(ChildProcessLifetime.AppHost, capturedOptions.Lifetime); } }