| File: DoctorCommandTests.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.Cli.Tests.Utils; using Hex1b.Automation; using Xunit; namespace Aspire.Cli.EndToEnd.Tests; /// <summary> /// End-to-end tests for Aspire CLI doctor command, specifically testing /// certificate trust level detection on Linux. /// </summary> public sealed class DoctorCommandTests(ITestOutputHelper output) { [Fact] public async Task DoctorCommand_WithoutSslCertDir_ShowsPartiallyTrusted() { var repoRoot = CliE2ETestHelpers.GetRepoRoot(); var installMode = CliE2ETestHelpers.DetectDockerInstallMode(repoRoot); var workspace = TemporaryWorkspace.Create(output); using var terminal = CliE2ETestHelpers.CreateDockerTestTerminal(repoRoot, installMode, output, workspace: workspace); var pendingRun = terminal.RunAsync(TestContext.Current.CancellationToken); var counter = new SequenceCounter(); var auto = new Hex1bTerminalAutomator(terminal, defaultTimeout: TimeSpan.FromSeconds(500)); await auto.PrepareDockerEnvironmentAsync(counter, workspace); await auto.InstallAspireCliInDockerAsync(installMode, counter); // Generate and trust dev certs inside the container (Docker images don't have them by default) await auto.TypeAsync("dotnet dev-certs https --trust 2>/dev/null || dotnet dev-certs https"); await auto.EnterAsync(); await auto.WaitForSuccessPromptAsync(counter); // Unset SSL_CERT_DIR to trigger partial trust detection on Linux await auto.TypeAsync("unset SSL_CERT_DIR"); await auto.EnterAsync(); await auto.WaitForSuccessPromptAsync(counter); await auto.TypeAsync("aspire doctor"); await auto.EnterAsync(); await auto.WaitUntilAsync( s => s.ContainsText("dev-certs") && s.ContainsText("partially trusted"), timeout: TimeSpan.FromSeconds(60), description: "doctor to complete with partial trust warning"); await auto.WaitForSuccessPromptAsync(counter); await auto.TypeAsync("exit"); await auto.EnterAsync(); await pendingRun; } [Fact] public async Task DoctorCommand_WithSslCertDir_ShowsTrusted() { var repoRoot = CliE2ETestHelpers.GetRepoRoot(); var installMode = CliE2ETestHelpers.DetectDockerInstallMode(repoRoot); var workspace = TemporaryWorkspace.Create(output); using var terminal = CliE2ETestHelpers.CreateDockerTestTerminal(repoRoot, installMode, output, workspace: workspace); var pendingRun = terminal.RunAsync(TestContext.Current.CancellationToken); var counter = new SequenceCounter(); var auto = new Hex1bTerminalAutomator(terminal, defaultTimeout: TimeSpan.FromSeconds(500)); await auto.PrepareDockerEnvironmentAsync(counter, workspace); await auto.InstallAspireCliInDockerAsync(installMode, counter); // Generate and trust dev certs inside the container (Docker images don't have them by default) await auto.TypeAsync("dotnet dev-certs https --trust 2>/dev/null || dotnet dev-certs https"); await auto.EnterAsync(); await auto.WaitForSuccessPromptAsync(counter); // Set SSL_CERT_DIR to include dev-certs trust path for full trust await auto.TypeAsync("export SSL_CERT_DIR=\"/etc/ssl/certs:$HOME/.aspnet/dev-certs/trust\""); await auto.EnterAsync(); await auto.WaitForSuccessPromptAsync(counter); await auto.TypeAsync("aspire doctor"); await auto.EnterAsync(); await auto.WaitUntilAsync(s => { // Wait for doctor to complete if (!s.ContainsText("dev-certs")) { return false; } // Fail if we see partial trust when SSL_CERT_DIR is configured if (s.ContainsText("partially trusted")) { throw new InvalidOperationException( "Unexpected 'partially trusted' message when SSL_CERT_DIR is configured!"); } return s.ContainsText("certificate is trusted"); }, timeout: TimeSpan.FromSeconds(60), description: "doctor to complete with trusted certificate"); await auto.WaitForSuccessPromptAsync(counter); await auto.TypeAsync("exit"); await auto.EnterAsync(); await pendingRun; } }