| File: KubernetesDeployWithValkeyTests.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 Hex1b.Automation; using Xunit; namespace Aspire.Cli.EndToEnd.Tests; /// <summary> /// E2E test for <c>aspire deploy</c> to Kubernetes: DeployK8sWithValkey. /// </summary> public sealed class KubernetesDeployWithValkeyTests(ITestOutputHelper output) { private const string ProjectName = "K8sDeployTest"; [Fact] [CaptureWorkspaceOnFailure] public async Task DeployK8sWithValkey() { var repoRoot = CliE2ETestHelpers.GetRepoRoot(); var strategy = CliInstallStrategy.Detect(output.WriteLine); using var workspace = TemporaryWorkspace.Create(output); var clusterName = KubernetesDeployTestHelpers.GenerateUniqueClusterName(); var k8sNamespace = $"test-{clusterName[..16]}"; output.WriteLine($"Cluster name: {clusterName}"); output.WriteLine($"Namespace: {k8sNamespace}"); 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); await auto.InstallAspireCliAsync(strategy, counter); await auto.VerifyPullRequestCliVersionAsync(counter); try { await auto.InstallKindAndHelmAsync(counter); await auto.CreateKindClusterWithRegistryAsync(counter, clusterName); var appHostCode = $$""" #pragma warning disable ASPIRECOMPUTE003 using Aspire.Hosting; using Aspire.Hosting.Kubernetes; var builder = DistributedApplication.CreateBuilder(args); var registryEndpoint = builder.AddParameter("registryendpoint"); var registry = builder.AddContainerRegistry("registry", registryEndpoint); var cache = builder.AddValkey("cache"); var api = builder.AddProject<Projects.{{ProjectName}}_ApiService>("server") .WithReference(cache) .WaitFor(cache) .WithExternalHttpEndpoints(); builder.AddKubernetesEnvironment("env") .WithHelm(helm => { helm.WithNamespace(builder.AddParameter("namespace")); helm.WithChartVersion(builder.AddParameter("chartversion")); }); builder.Build().Run(); """; // Valkey is Redis-protocol compatible, so we use the Redis client var apiProgramCode = """ using StackExchange.Redis; var builder = WebApplication.CreateBuilder(args); builder.AddServiceDefaults(); builder.AddRedisClient("cache"); var app = builder.Build(); app.MapDefaultEndpoints(); app.MapGet("/test-deployment", async (IConnectionMultiplexer redis) => { var db = redis.GetDatabase(); var testKey = $"test-{Guid.NewGuid():N}"; await db.StringSetAsync(testKey, "hello-from-valkey"); var value = await db.StringGetAsync(testKey); await db.KeyDeleteAsync(testKey); if (value == "hello-from-valkey") { return Results.Ok("PASSED: Valkey SET+GET works"); } return Results.Problem($"FAILED: expected 'hello-from-valkey', got '{value}'"); }); app.Run(); """; await auto.ScaffoldK8sDeployProjectAsync( counter, ProjectName, Path.Combine(workspace.WorkspaceRoot.FullName, ProjectName), appHostHostingPackages: ["Aspire.Hosting.Kubernetes", "Aspire.Hosting.Valkey"], apiClientPackages: ["Aspire.StackExchange.Redis"], appHostCode: appHostCode, apiProgramCode: apiProgramCode, output: output); await auto.AspireDeployInteractiveAsync( counter, parameterResponses: [ ("registryendpoint", "localhost:5001"), ("namespace", k8sNamespace), ("chartversion", "0.1.0"), ]); await auto.VerifyDeploymentAsync( counter, @namespace: k8sNamespace, serviceName: "server", localPort: 18088, testPath: "/test-deployment"); await auto.CleanupKubernetesDeploymentAsync(counter, clusterName); } finally { await KubernetesDeployTestHelpers.CleanupKindClusterOutOfBandAsync(clusterName, output); } } }