| File: LogLevelTests.cs | Web Access |
| Project: src\tests\Aspire.Cli.EndToEnd.Tests\Aspire.Cli.EndToEnd.Tests.csproj (Aspire.Cli.EndToEnd.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.EndToEnd.Tests.Helpers; using Aspire.TestUtilities; using Hex1b.Automation; using Xunit; namespace Aspire.Cli.EndToEnd.Tests; /// <summary> /// End-to-end tests verifying --log-level propagation to the CLI file logger and the AppHost. /// </summary> public sealed class LogLevelTests(ITestOutputHelper output) { [Fact] [CaptureWorkspaceOnFailure] [QuarantinedTest("https://github.com/microsoft/aspire/issues/17485")] public async Task LogLevelTrace_ProducesTraceEntriesInCliLogFile() { var repoRoot = CliE2ETestHelpers.GetRepoRoot(); var strategy = CliInstallStrategy.Detect(output.WriteLine); using var workspace = TemporaryWorkspace.Create(output); using var terminal = CliE2ETestHelpers.CreateDockerTestTerminal(repoRoot, strategy, output, mountDockerSocket: true, workspace: workspace); var counter = new SequenceCounter(); var auto = new Hex1bTerminalAutomator(terminal, defaultTimeout: TimeSpan.FromSeconds(500)); await using var terminalRun = CliE2ETestHelpers.StartRun(terminal, workspace, auto, counter, output, TestContext.Current.CancellationToken); await auto.PrepareDockerEnvironmentAsync(counter, workspace, enableDcpDiagnostics: true); await auto.InstallAspireCliAsync(strategy, counter); // Create a new empty AppHost project await auto.AspireNewCSharpEmptyAppHostAsync("LogLevelApp", counter); // Navigate to the AppHost directory await auto.TypeAsync("cd LogLevelApp"); await auto.EnterAsync(); await auto.WaitForSuccessPromptAsync(counter); // Start the AppHost with --log-level trace so both the CLI and the // AppHost produce trace-level output in the CLI log file. await auto.TypeAsync("aspire start --log-level trace"); await auto.EnterAsync(); await auto.WaitForSuccessPromptAsync(counter, timeout: TimeSpan.FromMinutes(3)); // Stop the AppHost so the log file is flushed and closed. await auto.AspireStopAsync(counter); // Find the most recent CLI log file (the detached child writes its own log). // The detached process log usually contains "detach" in the name. await auto.TypeAsync( "DETACH_LOG=$(ls -t ~/.aspire/logs/cli_*detach*.log 2>/dev/null | head -1); " + "if [ -z \"$DETACH_LOG\" ]; then DETACH_LOG=$(ls -t ~/.aspire/logs/cli_*.log 2>/dev/null | head -1); fi; " + "echo \"LOG_FILE:$DETACH_LOG\""); await auto.EnterAsync(); await auto.WaitForSuccessPromptAsync(counter); // Check for trace-level AppHost log entry (format: [TRCE] [AppHost/...]) await auto.RunCommandAsync( "test -n \"$DETACH_LOG\" && grep -q '\\[TRCE\\] \\[AppHost/' \"$DETACH_LOG\"", counter, TimeSpan.FromSeconds(10)); // Check for trace-level CLI log entry from the Features category await auto.RunCommandAsync( "test -n \"$DETACH_LOG\" && grep -q '\\[TRCE\\] \\[Features\\]' \"$DETACH_LOG\"", counter, TimeSpan.FromSeconds(10)); } }