From 2286b9a4110f77f6acbc59127d432d7d13c98d78 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Fri, 11 Sep 2026 08:55:21 +0800 Subject: [PATCH 1/2] Isolate AKS destroy tests from the real Helm runner --- .../AzureKubernetesInfrastructureTests.cs | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesInfrastructureTests.cs b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesInfrastructureTests.cs index 21d5bd317d2..1e50ee844b2 100644 --- a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesInfrastructureTests.cs +++ b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesInfrastructureTests.cs @@ -453,6 +453,7 @@ public async Task DestroyPipelineUsesPersistedAksOutputAndScopeWithoutProvisioni ["Namespace"] = "default" }); var azArguments = new List(); + var fakeHelm = new FakeHelmRunner(); using var builder = TestDistributedApplicationBuilder.Create( DistributedApplicationOperation.Publish, @@ -460,6 +461,7 @@ public async Task DestroyPipelineUsesPersistedAksOutputAndScopeWithoutProvisioni step: WellKnownPipelineSteps.Destroy); builder.Services.AddSingleton(stateManager); builder.Services.AddSingleton(); + builder.Services.AddSingleton(fakeHelm); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); aks.Resource.AzCliPathResolverForTesting = () => "/fake/az"; @@ -495,6 +497,10 @@ public async Task DestroyPipelineUsesPersistedAksOutputAndScopeWithoutProvisioni ], azArguments); Assert.Empty(aks.Resource.Outputs); + Assert.NotNull(aks.Resource.KubernetesEnvironment.KubeConfigPath); + Assert.Equal( + ["version --short", $"uninstall aks --namespace default --ignore-not-found --kubeconfig \"{aks.Resource.KubernetesEnvironment.KubeConfigPath}\""], + fakeHelm.Arguments); } [Fact] @@ -527,6 +533,7 @@ public async Task DestroyPipelineUsesPersistedAksResourceIdWhenScopeIsAbsent() ["Namespace"] = "default" }); var azArguments = new List(); + var fakeHelm = new FakeHelmRunner(); using var builder = TestDistributedApplicationBuilder.Create( DistributedApplicationOperation.Publish, @@ -534,6 +541,7 @@ public async Task DestroyPipelineUsesPersistedAksResourceIdWhenScopeIsAbsent() step: WellKnownPipelineSteps.Destroy); builder.Services.AddSingleton(stateManager); builder.Services.AddSingleton(); + builder.Services.AddSingleton(fakeHelm); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -573,6 +581,10 @@ public async Task DestroyPipelineUsesPersistedAksResourceIdWhenScopeIsAbsent() ], azArguments); Assert.Empty(aks.Resource.Outputs); + Assert.NotNull(aks.Resource.KubernetesEnvironment.KubeConfigPath); + Assert.Equal( + ["version --short", $"uninstall aks --namespace default --ignore-not-found --kubeconfig \"{aks.Resource.KubernetesEnvironment.KubeConfigPath}\""], + fakeHelm.Arguments); } [Fact] From 5409b2ec33600c22c0120e6d5447b844fbedd977 Mon Sep 17 00:00:00 2001 From: James Newton-King Date: Fri, 11 Sep 2026 09:42:17 +0800 Subject: [PATCH 2/2] Use shared AKS test application builder --- ...ureKubernetesEnvironmentExtensionsTests.cs | 174 ++++++++--- .../AzureKubernetesFoundryReferenceTests.cs | 10 +- .../AzureKubernetesHelmChartTests.cs | 33 ++- .../AzureKubernetesInfrastructureTests.cs | 272 +++++++++--------- .../AzureKubernetesIngressTests.cs | 22 +- .../AzureKubernetesPersistentVolumeTests.cs | 14 +- .../AzureKubernetesTestBuilder.cs | 41 +++ 7 files changed, 344 insertions(+), 222 deletions(-) create mode 100644 tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesTestBuilder.cs diff --git a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesEnvironmentExtensionsTests.cs b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesEnvironmentExtensionsTests.cs index efd63a6312c..079f1d928ba 100644 --- a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesEnvironmentExtensionsTests.cs +++ b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesEnvironmentExtensionsTests.cs @@ -15,12 +15,16 @@ namespace Aspire.Hosting.Azure.Tests; -public class AzureKubernetesEnvironmentExtensionsTests +public class AzureKubernetesEnvironmentExtensionsTests(ITestOutputHelper outputHelper) { [Fact] public async Task AddAzureKubernetesEnvironment_BasicConfiguration() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -36,7 +40,11 @@ public async Task AddAzureKubernetesEnvironment_BasicConfiguration() [Fact] public void AddNodePool_ReturnsNodePoolResource() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); var gpuPool = aks.AddNodePool("gpu", "Standard_NC6s_v3", 0, 5); @@ -56,7 +64,11 @@ public void AddNodePool_ReturnsNodePoolResource() [Fact] public void AddAzureKubernetesEnvironment_DefaultNodePool() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -72,7 +84,11 @@ public void AddAzureKubernetesEnvironment_DefaultNodePool() [Fact] public void AddAzureKubernetesEnvironment_DefaultConfiguration() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -87,7 +103,11 @@ public void AddAzureKubernetesEnvironment_DefaultConfiguration() [Fact] public void AddAzureKubernetesEnvironment_HasInternalKubernetesEnvironment() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -99,8 +119,8 @@ public void AddAzureKubernetesEnvironment_HasInternalKubernetesEnvironment() [Fact] public void AddAzureKubernetesEnvironment_AddsOnlyAksComputeEnvironmentToModel() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -116,8 +136,8 @@ public void AddAzureKubernetesEnvironment_AddsOnlyAksComputeEnvironmentToModel() [Fact] public async Task AddAzureKubernetesEnvironment_AllowsKubernetesServiceCustomizationWithoutVisibleKubernetesEnvironment() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); builder.AddAzureKubernetesEnvironment("aks"); builder.AddContainer("api", "myimage") @@ -140,7 +160,11 @@ public void AddAzureKubernetesEnvironment_ThrowsOnNullBuilder() [Fact] public void AddAzureKubernetesEnvironment_ThrowsOnEmptyName() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); Assert.Throws(() => builder.AddAzureKubernetesEnvironment("")); @@ -149,7 +173,11 @@ public void AddAzureKubernetesEnvironment_ThrowsOnEmptyName() [Fact] public void WithWorkloadIdentity_EnablesOidcAndWorkloadIdentity() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks") .WithWorkloadIdentity(); @@ -161,7 +189,11 @@ public void WithWorkloadIdentity_EnablesOidcAndWorkloadIdentity() [Fact] public void WithAzureUserAssignedIdentity_WorksWithAks() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); var identity = builder.AddAzureUserAssignedIdentity("myIdentity"); @@ -176,7 +208,11 @@ public void WithAzureUserAssignedIdentity_WorksWithAks() [Fact] public void AzureKubernetesEnvironment_ImplementsIAzureComputeEnvironmentResource() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); Assert.IsAssignableFrom(aks.Resource); } @@ -184,7 +220,11 @@ public void AzureKubernetesEnvironment_ImplementsIAzureComputeEnvironmentResourc [Fact] public void AzureKubernetesEnvironment_ImplementsIAzureNspAssociationTarget() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); Assert.IsAssignableFrom(aks.Resource); } @@ -192,7 +232,11 @@ public void AzureKubernetesEnvironment_ImplementsIAzureNspAssociationTarget() [Fact] public void AsExisting_WorksOnAksResource() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var nameParam = builder.AddParameter("aks-name"); var rgParam = builder.AddParameter("aks-rg"); @@ -206,8 +250,8 @@ public void AsExisting_WorksOnAksResource() [Fact] public void WithSubnet_OnNodePool_StoresPerPoolSubnet() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var defaultSubnet = vnet.AddSubnet("default-subnet", "10.0.0.0/22"); @@ -233,8 +277,8 @@ public void WithSubnet_OnNodePool_StoresPerPoolSubnet() [Fact] public void WithSubnet_OnNodePool_WithoutEnvironmentSubnet() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var gpuSubnet = vnet.AddSubnet("gpu-subnet", "10.0.4.0/24"); @@ -256,7 +300,11 @@ public void WithSubnet_OnNodePool_WithoutEnvironmentSubnet() [Fact] public void WithNodePool_AddsAnnotation() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); var gpuPool = aks.AddNodePool("gpu", "Standard_NC6s_v3", 0, 5); @@ -272,7 +320,11 @@ public void WithNodePool_AddsAnnotation() [Fact] public void AddNodePool_MultiplePoolsSupported() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); var pool1 = aks.AddNodePool("cpu", "Standard_D2s_v5", 1, 10); @@ -287,8 +339,8 @@ public void AddNodePool_MultiplePoolsSupported() [Fact] public void AddAzureKubernetesEnvironment_AutoCreatesDefaultRegistry() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -299,8 +351,8 @@ public void AddAzureKubernetesEnvironment_AutoCreatesDefaultRegistry() [Fact] public void WithContainerRegistry_ReplacesDefault() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var explicitAcr = builder.AddAzureContainerRegistry("my-acr"); @@ -318,8 +370,8 @@ public void WithContainerRegistry_ReplacesDefault() [Fact] public async Task ContainerRegistry_FlowsToInnerKubernetesEnvironment() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var container = builder.AddContainer("myapi", "myimage"); @@ -338,7 +390,11 @@ public async Task ContainerRegistry_FlowsToInnerKubernetesEnvironment() [Fact] public void WithSystemNodePool_CustomVmSize() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks") .WithSystemNodePool("Standard_B2s"); @@ -354,7 +410,11 @@ public void WithSystemNodePool_CustomVmSize() [Fact] public void WithSystemNodePool_CustomVmSizeAndScaling() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks") .WithSystemNodePool("Standard_B4ms", minCount: 2, maxCount: 5); @@ -368,7 +428,11 @@ public void WithSystemNodePool_CustomVmSizeAndScaling() [Fact] public void WithSystemNodePool_ReplacesDefaultSystemPool() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -386,7 +450,11 @@ public void WithSystemNodePool_ReplacesDefaultSystemPool() [Fact] public void WithSystemNodePool_CalledMultipleTimesUsesLastValue() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks") .WithSystemNodePool("Standard_B2s") @@ -402,7 +470,11 @@ public void WithSystemNodePool_CalledMultipleTimesUsesLastValue() [Fact] public void WithSystemNodePool_ChainsWithAddNodePool() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks") .WithSystemNodePool("Standard_B2s"); @@ -418,7 +490,11 @@ public void WithSystemNodePool_ChainsWithAddNodePool() [Fact] public void WithSystemNodePool_RejectsZeroMinCount() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); Assert.Throws(() => aks.WithSystemNodePool("Standard_B2s", minCount: 0)); @@ -427,7 +503,11 @@ public void WithSystemNodePool_RejectsZeroMinCount() [Fact] public async Task WithSystemNodePool_BicepReflectsCustomVmSize() { - using var builder = TestDistributedApplicationBuilder.Create(); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks") .WithSystemNodePool("Standard_B2s"); @@ -442,7 +522,8 @@ public async Task WithSystemNodePool_BicepReflectsCustomVmSize() [Fact] public async Task AddLoadBalancer_BicepEnablesIngressProfileAndUsesPreviewApi() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var aksSubnet = vnet.AddSubnet("aksnodes", "10.0.0.0/22"); @@ -458,7 +539,8 @@ public async Task AddLoadBalancer_BicepEnablesIngressProfileAndUsesPreviewApi() [Fact] public void AddLoadBalancer_AppliesSubnetDelegation() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var albSubnet = vnet.AddSubnet("alb", "10.0.4.0/24"); @@ -478,7 +560,8 @@ public void AddLoadBalancer_AppliesSubnetDelegation() [Fact] public void AddLoadBalancer_RegistersPerLBPipelineStep() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var albSubnet = vnet.AddSubnet("alb", "10.0.4.0/24"); @@ -495,7 +578,8 @@ public void AddLoadBalancer_RegistersPerLBPipelineStep() [Fact] public void AddLoadBalancer_MultipleLBs_AllStepsRegistered() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var alb1 = vnet.AddSubnet("alb1", "10.0.4.0/24"); @@ -524,7 +608,8 @@ public void AddLoadBalancer_MultipleLBs_AllStepsRegistered() [Fact] public void AddLoadBalancer_OnUserDelegatedSubnet_ReplacesDelegationAndRecordsDisplaced() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); @@ -547,7 +632,8 @@ public void AddLoadBalancer_OnUserDelegatedSubnet_ReplacesDelegationAndRecordsDi [Fact] public void AddLoadBalancer_SharedSubnet_KeepsSingleDelegationWithNoDisplacement() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var albSubnet = vnet.AddSubnet("alb", "10.0.4.0/24"); @@ -568,7 +654,8 @@ public void AddLoadBalancer_SharedSubnet_KeepsSingleDelegationWithNoDisplacement [Fact] public void AddLoadBalancer_EquivalentDelegationWithDifferentCasing_DoesNotRecordDisplacement() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var albSubnet = vnet.AddSubnet("alb", "10.0.4.0/24") @@ -585,7 +672,8 @@ public void AddLoadBalancer_EquivalentDelegationWithDifferentCasing_DoesNotRecor [Fact] public void AddLoadBalancer_OnSubnetWithMultipleDirectDelegations_CollapsesToSingle() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); diff --git a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesFoundryReferenceTests.cs b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesFoundryReferenceTests.cs index 23ae7f7d853..4f92f792ebb 100644 --- a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesFoundryReferenceTests.cs +++ b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesFoundryReferenceTests.cs @@ -6,10 +6,6 @@ using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Foundry; -using Aspire.Hosting.Publishing; -using Aspire.Hosting.Tests; -using Aspire.Hosting.Utils; -using Microsoft.Extensions.DependencyInjection; namespace Aspire.Hosting.Azure.Tests; @@ -19,11 +15,7 @@ public class AzureKubernetesFoundryReferenceTests(ITestOutputHelper outputHelper public async Task EndpointReferenceToFoundryHostedAgentIsResolvedAcrossComputeEnvironments() { using var workspace = TemporaryWorkspace.Create(outputHelper); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path); - - builder.Services.AddSingleton(); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); diff --git a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesHelmChartTests.cs b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesHelmChartTests.cs index 72b9d19637a..ff429de35ad 100644 --- a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesHelmChartTests.cs +++ b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesHelmChartTests.cs @@ -6,16 +6,16 @@ using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Azure.Kubernetes; using Aspire.Hosting.Kubernetes; -using Aspire.Hosting.Utils; namespace Aspire.Hosting.Azure.Tests; -public class AzureKubernetesHelmChartTests +public class AzureKubernetesHelmChartTests(ITestOutputHelper outputHelper) { [Fact] public void AksAddHelmChart_HasCorrectParent() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var chart = aks.AddHelmChart("cert-manager", "oci://quay.io/jetstack/charts/cert-manager", "1.17.0"); @@ -28,7 +28,8 @@ public void AksAddHelmChart_HasCorrectParent() [Fact] public void AksAddHelmChart_BasicProperties() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var chart = aks.AddHelmChart("cert-manager", "oci://quay.io/jetstack/charts/cert-manager", "1.17.0"); @@ -41,7 +42,8 @@ public void AksAddHelmChart_BasicProperties() [Fact] public void AksAddHelmChart_WithHelmValue_StoresValues() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var chart = aks.AddHelmChart("cert-manager", "oci://quay.io/jetstack/charts/cert-manager", "1.17.0") @@ -56,7 +58,8 @@ public void AksAddHelmChart_WithHelmValue_StoresValues() [Fact] public void AksAddHelmChart_WithNamespace_SetsNamespace() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var chart = aks.AddHelmChart("nginx", "oci://ghcr.io/nginx/charts/nginx-ingress", "1.5.0") @@ -68,7 +71,8 @@ public void AksAddHelmChart_WithNamespace_SetsNamespace() [Fact] public void AksAddHelmChart_WithReleaseName_SetsReleaseName() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var chart = aks.AddHelmChart("nginx", "oci://ghcr.io/nginx/charts/nginx-ingress", "1.5.0") @@ -80,7 +84,8 @@ public void AksAddHelmChart_WithReleaseName_SetsReleaseName() [Fact] public void AksAddHelmChart_WithDestroy_OptsIn() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var chart = aks.AddHelmChart("podinfo", "oci://ghcr.io/stefanprodan/charts/podinfo", "6.7.1") @@ -92,7 +97,8 @@ public void AksAddHelmChart_WithDestroy_OptsIn() [Fact] public void AksAddHelmChart_DestroyDefaultsToFalse() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var chart = aks.AddHelmChart("podinfo", "oci://ghcr.io/stefanprodan/charts/podinfo", "6.7.1"); @@ -117,7 +123,8 @@ public void AksAddHelmChart_ThrowsOnNullBuilder() [InlineData("test", "oci://example.com/chart", "")] public void AksAddHelmChart_ThrowsOnNullOrEmptyArgs(string? name, string? chartReference, string? chartVersion) { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); Assert.ThrowsAny(() => aks.AddHelmChart(name!, chartReference!, chartVersion!)); @@ -126,7 +133,8 @@ public void AksAddHelmChart_ThrowsOnNullOrEmptyArgs(string? name, string? chartR [Fact] public void AksAddHelmChart_RejectsInvalidChartVersion() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); Assert.Throws(() => @@ -136,7 +144,8 @@ public void AksAddHelmChart_RejectsInvalidChartVersion() [Fact] public void AksAddHelmChart_RejectsMaliciousChartReference() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); Assert.Throws(() => diff --git a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesInfrastructureTests.cs b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesInfrastructureTests.cs index 1e50ee844b2..ae1cd7e564a 100644 --- a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesInfrastructureTests.cs +++ b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesInfrastructureTests.cs @@ -13,7 +13,6 @@ using Aspire.Hosting.Azure.Kubernetes; using Aspire.Hosting.Kubernetes; using Aspire.Hosting.Pipelines; -using Aspire.Hosting.Publishing; using Aspire.Hosting.Tests; using Aspire.Hosting.Utils; using Microsoft.Extensions.DependencyInjection; @@ -27,8 +26,8 @@ public class AzureKubernetesInfrastructureTests(ITestOutputHelper output) [Fact] public async Task NoUserPool_CreatesDefaultWorkloadPool() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(output); + using var builder = AzureKubernetesTestBuilder.Create(output, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -54,8 +53,8 @@ public async Task NoUserPool_CreatesDefaultWorkloadPool() [Fact] public async Task ExplicitUserPool_NoDefaultCreated() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(output); + using var builder = AzureKubernetesTestBuilder.Create(output, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var gpuPool = aks.AddNodePool("gpu", "Standard_NC6s_v3", 0, 5); @@ -77,8 +76,8 @@ public async Task ExplicitUserPool_NoDefaultCreated() [Fact] public async Task ExplicitAffinity_NotOverridden() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(output); + using var builder = AzureKubernetesTestBuilder.Create(output, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var gpuPool = aks.AddNodePool("gpu", "Standard_NC6s_v3", 0, 5); @@ -98,8 +97,8 @@ public async Task ExplicitAffinity_NotOverridden() [Fact] public async Task ComputeResource_GetsDeploymentTargetFromKubernetesInfrastructure() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(output); + using var builder = AzureKubernetesTestBuilder.Create(output, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var container = builder.AddContainer("myapi", "myimage"); @@ -125,8 +124,8 @@ public async Task ComputeResource_GetsDeploymentTargetFromKubernetesInfrastructu [Fact] public async Task MultiEnv_ResourcesMatchCorrectEnvironment() { - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(output); + using var builder = AzureKubernetesTestBuilder.Create(output, workspace); var registry = builder.AddAzureContainerRegistry("registry"); var enva = builder.AddAzureKubernetesEnvironment("enva") @@ -169,14 +168,12 @@ public async Task MultiEnv_ResourcesMatchCorrectEnvironment() public async Task KubernetesPipelineStepsFlowThroughAksEnvironment() { using var workspace = TemporaryWorkspace.Create(output); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Diagnostics); - var reporter = new TestPipelineActivityReporter(output); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Diagnostics, + activityReporter: reporter); builder.AddAzureKubernetesEnvironment("aks"); builder.AddContainer("api", "myimage") @@ -201,14 +198,12 @@ public async Task KubernetesPipelineStepsFlowThroughAksEnvironment() public async Task DestroyPipelineFetchesCredentialsBeforeClusterCleanupAndDeletesAzureLast() { using var workspace = TemporaryWorkspace.Create(output); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Diagnostics); - var reporter = new TestPipelineActivityReporter(output); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Diagnostics, + activityReporter: reporter); var aks = builder.AddAzureKubernetesEnvironment("aks"); aks.AddHelmChart("podinfo", "oci://ghcr.io/stefanprodan/charts/podinfo", "6.7.1") @@ -314,14 +309,13 @@ public async Task DestroyRetryAfterExternalChartCleanupStillReachesAzureDeletion async Task RunDestroyAsync() { var reporter = new TestPipelineActivityReporter(output); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Destroy); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); - builder.Services.AddSingleton(fakeHelm); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Destroy, + deploymentStateManager: stateManager, + activityReporter: reporter, + helmRunner: fakeHelm); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -373,14 +367,12 @@ async Task RunDestroyAsync() public async Task DestroyPipelineUsesMatchingCredentialsForEachAksEnvironment() { using var workspace = TemporaryWorkspace.Create(output); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Diagnostics); - var reporter = new TestPipelineActivityReporter(output); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Diagnostics, + activityReporter: reporter); var east = builder.AddAzureKubernetesEnvironment("east"); var west = builder.AddAzureKubernetesEnvironment("west"); @@ -455,13 +447,12 @@ public async Task DestroyPipelineUsesPersistedAksOutputAndScopeWithoutProvisioni var azArguments = new List(); var fakeHelm = new FakeHelmRunner(); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Destroy); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(fakeHelm); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Destroy, + deploymentStateManager: stateManager, + helmRunner: fakeHelm); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); aks.Resource.AzCliPathResolverForTesting = () => "/fake/az"; @@ -535,13 +526,12 @@ public async Task DestroyPipelineUsesPersistedAksResourceIdWhenScopeIsAbsent() var azArguments = new List(); var fakeHelm = new FakeHelmRunner(); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Destroy); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(fakeHelm); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Destroy, + deploymentStateManager: stateManager, + helmRunner: fakeHelm); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -603,13 +593,12 @@ public async Task DestroyPipelineSkipsClusterCleanupWhenAksDeploymentStateHasNoI }); var reporter = new TestPipelineActivityReporter(output); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Destroy); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Destroy, + deploymentStateManager: stateManager, + activityReporter: reporter); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); aks.Resource.AzCliPathResolverForTesting = () => @@ -651,13 +640,12 @@ public async Task DestroyPipelineSkipsClusterCleanupWhenPersistedAksIdentityHasN }); var reporter = new TestPipelineActivityReporter(output); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Destroy); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Destroy, + deploymentStateManager: stateManager, + activityReporter: reporter); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -688,13 +676,12 @@ public async Task DestroyPipelineSkipsClusterCleanupForNeverDeployedAksEnvironme var reporter = new TestPipelineActivityReporter(output); var stateManager = new InMemoryDeploymentStateManager(); stateManager.SetSection("Sentinel", new JsonObject { ["Value"] = "cleared-by-destroy" }); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: WellKnownPipelineSteps.Destroy); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: WellKnownPipelineSteps.Destroy, + deploymentStateManager: stateManager, + activityReporter: reporter); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -727,13 +714,12 @@ public async Task DirectAzureDestroySkipsClusterCleanupWithoutPersistedAksIdenti { ["Location"] = "westus2" }); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: "destroy-azure-azure-environment"); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: "destroy-azure-azure-environment", + deploymentStateManager: stateManager, + activityReporter: reporter); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -777,13 +763,12 @@ public async Task DirectAzureDestroySkipsClusterCleanupWhenPersistedAksIdentityH }.ToJsonString() }); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: "destroy-azure-azure-environment"); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: "destroy-azure-azure-environment", + deploymentStateManager: stateManager, + activityReporter: reporter); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -840,14 +825,13 @@ public async Task DirectAzureDestroySkipsClusterCleanupWhenPersistedAksNoLongerE var fakeHelm = new FakeHelmRunner { ThrowOnVersion = true }; var azArguments = new List(); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: "destroy-azure-azure-environment"); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); - builder.Services.AddSingleton(fakeHelm); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: "destroy-azure-azure-environment", + deploymentStateManager: stateManager, + activityReporter: reporter, + helmRunner: fakeHelm); builder.Services.Configure(o => o.SkipConfirmation = true); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -904,14 +888,13 @@ public async Task DirectMainHelmUninstallSkipsAbsentClusterWithoutResolvingParam var fakeHelm = new FakeHelmRunner { ThrowOnVersion = true }; var azArguments = new List(); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: "helm-uninstall-aks"); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); - builder.Services.AddSingleton(fakeHelm); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: "helm-uninstall-aks", + deploymentStateManager: stateManager, + activityReporter: reporter, + helmRunner: fakeHelm); var releaseParameter = builder.AddParameter("helm-release"); var namespaceParameter = builder.AddParameter("helm-namespace"); @@ -977,14 +960,13 @@ public async Task DirectMainHelmUninstallSkipsAbsentClusterWithoutResolvingProvi var fakeHelm = new FakeHelmRunner { ThrowOnVersion = true }; var azArguments = new List(); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: "helm-uninstall-aks"); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); - builder.Services.AddSingleton(fakeHelm); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: "helm-uninstall-aks", + deploymentStateManager: stateManager, + activityReporter: reporter, + helmRunner: fakeHelm); var aks = builder.AddAzureKubernetesEnvironment("aks"); // A direct cleanup never provisions the AKS resource, so resolving this output would wait @@ -1047,13 +1029,12 @@ public async Task DirectMainHelmUninstallUsesPersistedAksCredentials() var fakeHelm = new FakeHelmRunner(); var azArguments = new List(); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: "helm-uninstall-aks"); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(fakeHelm); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: "helm-uninstall-aks", + deploymentStateManager: stateManager, + helmRunner: fakeHelm); var aks = builder.AddAzureKubernetesEnvironment("aks"); aks.Resource.KubernetesEnvironment.Annotations.Add( new HelmReleaseNameAnnotation(ReferenceExpression.Create($"main-release"))); @@ -1096,14 +1077,12 @@ public async Task DirectKubernetesCleanupFailsForNeverDeployedAksEnvironment() using var workspace = TemporaryWorkspace.Create(output); var reporter = new TestPipelineActivityReporter(output); var stateManager = new InMemoryDeploymentStateManager(); - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish, - workspace.Path, - step: "helm-uninstall-same-name-as-ambient-release"); - builder.Services.AddSingleton(stateManager); - builder.Services.AddSingleton(); - builder.Services.AddSingleton(reporter); - builder.Services.AddSingleton(); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + step: "helm-uninstall-same-name-as-ambient-release", + deploymentStateManager: stateManager, + activityReporter: reporter); var aks = builder.AddAzureKubernetesEnvironment("aks"); aks.AddHelmChart("same-name-as-ambient-release", "oci://example.com/chart", "1.0.0") @@ -1352,15 +1331,16 @@ public async Task GetCredentialsStepScopesEveryAzureCliCallToDeploymentSubscript const string subscriptionId = "00000000-0000-0000-0000-000000000001"; const string clusterName = "provisioned-aks"; - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); - + using var workspace = TemporaryWorkspace.Create(output); var deploymentStateManager = new InMemoryDeploymentStateManager(); deploymentStateManager.SetSection("Azure", new JsonObject { ["SubscriptionId"] = subscriptionId }); - builder.Services.AddSingleton(deploymentStateManager); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + deploymentStateManager: deploymentStateManager); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -1450,9 +1430,7 @@ public async Task GetCredentialsStepUsesExistingClusterScopeInsteadOfDeploymentS const string clusterResourceGroup = "shared-platform-rg"; const string clusterName = "shared-aks"; - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); - + using var workspace = TemporaryWorkspace.Create(output); // The app deploys into its own subscription and resource group... var deploymentStateManager = new InMemoryDeploymentStateManager(); deploymentStateManager.SetSection("Azure", new JsonObject @@ -1460,7 +1438,10 @@ public async Task GetCredentialsStepUsesExistingClusterScopeInsteadOfDeploymentS ["SubscriptionId"] = appSubscriptionId, ["ResourceGroup"] = "app-rg" }); - builder.Services.AddSingleton(deploymentStateManager); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + deploymentStateManager: deploymentStateManager); // ...but the cluster it targets already exists somewhere else entirely. var aks = builder.AddAzureKubernetesEnvironment("aks") @@ -1661,16 +1642,17 @@ public async Task GetCredentialsStepPrefersExplicitScopeOverExistingResourceAnno const string scopeResourceGroup = "scope-assigned-rg"; const string clusterName = "scoped-aks"; - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); - + using var workspace = TemporaryWorkspace.Create(output); var deploymentStateManager = new InMemoryDeploymentStateManager(); deploymentStateManager.SetSection("Azure", new JsonObject { ["SubscriptionId"] = "00000000-0000-0000-0000-000000000001", ["ResourceGroup"] = "app-rg" }); - builder.Services.AddSingleton(deploymentStateManager); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + deploymentStateManager: deploymentStateManager); var aks = builder.AddAzureKubernetesEnvironment("aks") .AsExistingInResourceGroup(clusterName, "annotation-rg", "00000000-0000-0000-0000-000000000002"); @@ -1731,16 +1713,17 @@ public async Task GetCredentialsStepFallsBackToDeploymentStateForSubscriptionSco const string subscriptionId = "00000000-0000-0000-0000-000000000001"; const string clusterName = "subscription-scoped-aks"; - using var builder = TestDistributedApplicationBuilder.Create( - DistributedApplicationOperation.Publish); - + using var workspace = TemporaryWorkspace.Create(output); var deploymentStateManager = new InMemoryDeploymentStateManager(); deploymentStateManager.SetSection("Azure", new JsonObject { ["SubscriptionId"] = subscriptionId, ["ResourceGroup"] = "app-rg" }); - builder.Services.AddSingleton(deploymentStateManager); + using var builder = AzureKubernetesTestBuilder.Create( + output, + workspace, + deploymentStateManager: deploymentStateManager); var aks = builder.AddAzureKubernetesEnvironment("aks"); @@ -1829,4 +1812,5 @@ private static ServiceProvider CreateServicesWithAzureState(string subscriptionI .AddSingleton(deploymentStateManager) .BuildServiceProvider(); } + } diff --git a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesIngressTests.cs b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesIngressTests.cs index cf8a25b6aa0..251a9d6dba9 100644 --- a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesIngressTests.cs +++ b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesIngressTests.cs @@ -4,7 +4,6 @@ #pragma warning disable ASPIREAZURE003 using Aspire.Hosting.Kubernetes; -using Aspire.Hosting.Utils; namespace Aspire.Hosting.Azure.Tests; @@ -14,7 +13,7 @@ public class AzureKubernetesIngressTests(ITestOutputHelper outputHelper) public async Task AksAddIngress_WithPath_GeneratesIngressInHelmOutput() { using var workspace = TemporaryWorkspace.Create(outputHelper); - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish, workspace.Path); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var ingress = aks.AddIngress("public") @@ -41,7 +40,8 @@ public async Task AksAddIngress_WithPath_GeneratesIngressInHelmOutput() [Fact] public void AksAddIngress_HasCorrectParent() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var ingress = aks.AddIngress("public"); @@ -53,7 +53,8 @@ public void AksAddIngress_HasCorrectParent() [Fact] public void AksAddGateway_HasCorrectParent() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var gateway = aks.AddGateway("public"); @@ -64,7 +65,8 @@ public void AksAddGateway_HasCorrectParent() [Fact] public async Task WithLoadBalancer_OnGateway_AnnotatesAndDefaultsClass() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var albSubnet = vnet.AddSubnet("alb", "10.0.4.0/24"); @@ -87,7 +89,8 @@ public async Task WithLoadBalancer_OnGateway_AnnotatesAndDefaultsClass() [Fact] public async Task WithLoadBalancer_OnIngress_AnnotatesAndDefaultsClass() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var albSubnet = vnet.AddSubnet("alb", "10.0.4.0/24"); @@ -110,7 +113,8 @@ public async Task WithLoadBalancer_OnIngress_AnnotatesAndDefaultsClass() [Fact] public async Task WithLoadBalancer_RespectsExplicitGatewayClass() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var vnet = builder.AddAzureVirtualNetwork("vnet", "10.0.0.0/16"); var albSubnet = vnet.AddSubnet("alb", "10.0.4.0/24"); @@ -135,7 +139,7 @@ public async Task WithLoadBalancer_RespectsExplicitGatewayClass() public void AksAddIngress_WithPath_NonExternalEndpoint_ThrowsOnPublish() { using var workspace = TemporaryWorkspace.Create(outputHelper); - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish, workspace.Path); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var ingress = aks.AddIngress("public").WithIngressClass("nginx"); @@ -157,7 +161,7 @@ public void AksAddIngress_WithPath_NonExternalEndpoint_ThrowsOnPublish() public void AksAddGateway_WithRoute_NonExternalEndpoint_ThrowsOnPublish() { using var workspace = TemporaryWorkspace.Create(outputHelper); - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish, workspace.Path); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var gateway = aks.AddGateway("public").WithGatewayClass("nginx"); diff --git a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesPersistentVolumeTests.cs b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesPersistentVolumeTests.cs index 6f09083b79e..b9d0c676760 100644 --- a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesPersistentVolumeTests.cs +++ b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesPersistentVolumeTests.cs @@ -3,7 +3,6 @@ #pragma warning disable ASPIREAZURE003, ASPIRECOMPUTE002 -using Aspire.Hosting.Utils; using Aspire.Hosting.ApplicationModel; using Aspire.Hosting.Kubernetes; using Aspire.Hosting.Tests.Utils; @@ -16,7 +15,8 @@ public class AzureKubernetesPersistentVolumeTests(ITestOutputHelper outputHelper [Fact] public void AksAddPersistentVolume_HasCorrectParent() { - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var volume = aks.AddPersistentVolume("data"); @@ -28,7 +28,7 @@ public void AksAddPersistentVolume_HasCorrectParent() public async Task AksAddPersistentVolume_GeneratesClaimUsingClusterDefaults() { using var workspace = TemporaryWorkspace.Create(outputHelper); - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish, workspace.Path); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); aks.AddPersistentVolume("data") @@ -47,7 +47,11 @@ public async Task AksAddPersistentVolume_GeneratesClaimUsingClusterDefaults() [Fact] public async Task AksPersistentVolumeEnvironmentUsesAspireStoreInRunMode() { - using var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Run); + using var workspace = TemporaryWorkspace.Create(outputHelper); + using var builder = AzureKubernetesTestBuilder.Create( + outputHelper, + workspace, + operation: DistributedApplicationOperation.Run); var aks = builder.AddAzureKubernetesEnvironment("aks"); var volume = aks.AddPersistentVolume("data"); var executable = builder.AddExecutable("executable", "test-command", ".") @@ -74,7 +78,7 @@ public async Task AksPersistentVolume_PublishesWhenWorkloadImplicitlyTargetsSole // the AKS resource rather than null. This mirrors the AKS deployment E2E AppHost, which // binds a persistent volume without calling WithComputeEnvironment. using var workspace = TemporaryWorkspace.Create(outputHelper); - var builder = TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish, workspace.Path); + using var builder = AzureKubernetesTestBuilder.Create(outputHelper, workspace); var aks = builder.AddAzureKubernetesEnvironment("aks"); var volume = aks.AddPersistentVolume("data").WithCapacity("5Gi"); diff --git a/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesTestBuilder.cs b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesTestBuilder.cs new file mode 100644 index 00000000000..4576c59f43c --- /dev/null +++ b/tests/Aspire.Hosting.Azure.Kubernetes.Tests/AzureKubernetesTestBuilder.cs @@ -0,0 +1,41 @@ +// Licensed to the .NET Foundation under one or more agreements. +// The .NET Foundation licenses this file to you under the MIT license. + +#pragma warning disable ASPIREPIPELINES001 +#pragma warning disable ASPIREPIPELINES002 +#pragma warning disable ASPIREPIPELINES003 + +using Aspire.Hosting.Kubernetes; +using Aspire.Hosting.Pipelines; +using Aspire.Hosting.Publishing; +using Aspire.Hosting.Testing; +using Aspire.Hosting.Tests; +using Aspire.Hosting.Utils; +using Microsoft.Extensions.DependencyInjection; + +namespace Aspire.Hosting.Azure.Tests; + +internal static class AzureKubernetesTestBuilder +{ + public static IDistributedApplicationTestingBuilder Create( + ITestOutputHelper outputHelper, + TemporaryWorkspace workspace, + DistributedApplicationOperation operation = DistributedApplicationOperation.Publish, + string? step = WellKnownPipelineSteps.Publish, + IDeploymentStateManager? deploymentStateManager = null, + IResourceContainerImageManager? imageManager = null, + IPipelineActivityReporter? activityReporter = null, + IHelmRunner? helmRunner = null) + { + var builder = TestDistributedApplicationBuilder + .Create(operation, workspace.Path, step: step) + .WithTestAndResourceLogging(outputHelper); + + builder.Services.AddSingleton(deploymentStateManager ?? new InMemoryDeploymentStateManager()); + builder.Services.AddSingleton(imageManager ?? new MockImageBuilder()); + builder.Services.AddSingleton(activityReporter ?? new TestPipelineActivityReporter(outputHelper)); + builder.Services.AddSingleton(helmRunner ?? new FakeHelmRunner()); + + return builder; + } +} \ No newline at end of file