| File: Helpers\DeploymentE2EAutomatorHelpers.cs | Web Access |
| Project: src\tests\Aspire.Deployment.EndToEnd.Tests\Aspire.Deployment.EndToEnd.Tests.csproj (Aspire.Deployment.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 Hex1b.Automation; using Xunit; namespace Aspire.Deployment.EndToEnd.Tests.Helpers; /// <summary> /// Extension methods for <see cref="Hex1bTerminalAutomator"/> providing deployment E2E test patterns. /// </summary> internal static class DeploymentE2EAutomatorHelpers { /// <summary> /// Prepares the terminal environment with a custom prompt for command tracking. /// </summary> internal static async Task PrepareEnvironmentAsync( this Hex1bTerminalAutomator auto, TemporaryWorkspace workspace, SequenceCounter counter) { await auto.PrepareBashEnvironmentAsync(workspace.WorkspaceRoot.FullName, counter, TimeSpan.FromSeconds(10)); } /// <summary> /// Installs the Aspire CLI in a non-Docker shell using the given install strategy. /// </summary> internal static async Task InstallAspireCliAsync( this Hex1bTerminalAutomator auto, CliInstallStrategy strategy, SequenceCounter counter, bool includeBundlePath = false) { switch (strategy.Mode) { case CliInstallMode.LocalHive: var archivePath = strategy.ArchivePath ?? throw new InvalidOperationException("LocalHive strategy is missing the archive path."); await auto.ExtractLocalHiveArchiveAsync(archivePath, counter); await auto.SourceAspireEnvironmentAsync(counter, includeBundlePath); await auto.ConfigureLocalHiveAsync(counter); break; case CliInstallMode.Preinstalled: await auto.SourceAspireEnvironmentAsync(counter, includeBundlePath); break; case CliInstallMode.PullRequest: var prNumber = DeploymentE2ETestHelpers.GetPrNumber(); if (prNumber <= 0) { throw new InvalidOperationException("PullRequest strategy requires a positive GITHUB_PR_NUMBER."); } if (includeBundlePath) { await auto.RunCommandAsync( AspireCliShellCommandHelpers.GetBundlePullRequestInstallCommand(prNumber), counter, TimeSpan.FromSeconds(300)); } else { await auto.RunCommandAsync( AspireCliShellCommandHelpers.GetPullRequestInstallCommand(prNumber, AspireCliShellCommandHelpers.MainPullRequestInstallCommandPrefix), counter, TimeSpan.FromSeconds(300)); } await auto.SourceAspireEnvironmentAsync(counter, includeBundlePath); break; case CliInstallMode.LocalArchive: var archiveDir = strategy.ArchiveDir ?? throw new InvalidOperationException("LocalArchive strategy is missing the archive directory."); await auto.RunCommandAsync( AspireCliShellCommandHelpers.GetLocalArchiveInstallCommandFromCurrentRef(archiveDir), counter, TimeSpan.FromSeconds(120)); await auto.SourceAspireEnvironmentAsync(counter, includeBundlePath); break; case CliInstallMode.InstallScript: await auto.RunCommandAsync( AspireCliShellCommandHelpers.GetInstallScriptCommand(strategy, AspireCliShellCommandHelpers.AkaMsInstallScriptCommandPrefix), counter, TimeSpan.FromSeconds(300)); await auto.SourceAspireEnvironmentAsync(counter, includeBundlePath); break; case CliInstallMode.DotnetTool: throw new InvalidOperationException( "DotnetTool install mode is not supported for deployment E2E tests. " + "Deployment tests require the native CLI. Clear ASPIRE_E2E_DOTNET_TOOL* environment variables and retry."); default: throw new ArgumentOutOfRangeException(nameof(strategy), strategy.Mode, "Unknown install mode"); } await auto.LogAspireCliVersionAsync(counter); } /// <summary> /// Logs and installs the specified Aspire CLI strategy for a deployment test step. /// </summary> internal static async Task<CliInstallStrategy> InstallAspireCliAsync( this Hex1bTerminalAutomator auto, CliInstallStrategy strategy, SequenceCounter counter, ITestOutputHelper output, string stepLabel = "Step 2", bool includeBundlePath = false, string artifactName = "CLI") { output.WriteLine($"{stepLabel}: Installing Aspire {artifactName} using {strategy}..."); await auto.InstallAspireCliAsync(strategy, counter, includeBundlePath); return strategy; } /// <summary> /// Installs the current-build Aspire CLI using the deployment test defaults. /// </summary> internal static Task<CliInstallStrategy> InstallCurrentBuildAspireCliAsync( this Hex1bTerminalAutomator auto, SequenceCounter counter, ITestOutputHelper output, string stepLabel = "Step 2") { return auto.InstallAspireCliAsync( DeploymentE2ETestHelpers.GetCurrentBuildCliInstallStrategy(), counter, output, stepLabel); } /// <summary> /// Installs the current-build Aspire bundle using the deployment test defaults. /// </summary> internal static Task<CliInstallStrategy> InstallCurrentBuildAspireBundleAsync( this Hex1bTerminalAutomator auto, SequenceCounter counter, ITestOutputHelper output, string stepLabel = "Step 2") { return auto.InstallAspireCliAsync( DeploymentE2ETestHelpers.GetCurrentBuildCliInstallStrategy(), counter, output, stepLabel, includeBundlePath: true, artifactName: "bundle"); } /// <summary> /// Configures the PATH and environment variables for the Aspire CLI. /// </summary> internal static async Task SourceAspireCliEnvironmentAsync( this Hex1bTerminalAutomator auto, SequenceCounter counter) { await auto.SourceAspireEnvironmentAsync(counter, includeBundlePath: false); } /// <summary> /// Destroys the current deployment using <c>aspire destroy --yes</c> and waits for pipeline success. /// </summary> internal static async Task AspireDestroyAsync( this Hex1bTerminalAutomator auto, SequenceCounter counter, TimeSpan? timeout = null) { timeout ??= TimeSpan.FromMinutes(5); await auto.TypeAsync("aspire destroy --yes"); await auto.EnterAsync(); await auto.WaitForPipelineSuccessAsync(timeout: timeout.Value); await auto.WaitForSuccessPromptAsync(counter, TimeSpan.FromMinutes(2)); } }