| File: Publishing\ProviderScopeBicepEmissionTests.cs | Web Access |
| Project: src\tests\Aspire.Hosting.Radius.Tests\Aspire.Hosting.Radius.Tests.csproj (Aspire.Hosting.Radius.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.Hosting.ApplicationModel; using Aspire.Hosting.Radius.Publishing; using Microsoft.Extensions.DependencyInjection; using Microsoft.Extensions.Logging.Abstractions; namespace Aspire.Hosting.Radius.Tests.Publishing; public class ProviderScopeBicepEmissionTests { private const string SubId = "11111111-1111-1111-1111-111111111111"; private const string Rg = "rg-test"; private const string TenantId = "22222222-2222-2222-2222-222222222222"; private const string ClientId = "33333333-3333-3333-3333-333333333333"; [Fact] public void Azure_Provider_EmitsSubscriptionAndResourceGroup_AndNoSecretLiterals() { using var builder = Aspire.Hosting.Utils.TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); var secret = builder.AddParameter("azureClientSecret", "secret-XYZ", secret: true); var env = builder.AddRadiusEnvironment("radius") .WithAzureProvider(SubId, Rg, azure => azure.WithServicePrincipal(TenantId, ClientId, secret)); builder.AddContainer("api", "nginx"); using var app = builder.Build(); var model = app.Services.GetRequiredService<DistributedApplicationModel>(); var envResource = model.Resources.OfType<RadiusEnvironmentResource>().Single(); RadiusTestHelper.AttachDeploymentTargets(envResource, model); var ctx = new RadiusBicepPublishingContext(envResource); var bicep = ctx.GenerateBicep(model, NullLogger.Instance); // The native Radius.Core/environments schema models the Azure provider with // discrete subscriptionId/resourceGroupName fields (not a single legacy scope path). Assert.Contains($"subscriptionId: '{SubId}'", bicep); Assert.Contains($"resourceGroupName: '{Rg}'", bicep); Assert.DoesNotContain("secret-XYZ", bicep); Assert.DoesNotContain(TenantId, bicep); Assert.DoesNotContain(ClientId, bicep); } [Fact] public void Without_Provider_DoesNotEmit_ProvidersAzure() { using var builder = Aspire.Hosting.Utils.TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); builder.AddRadiusEnvironment("radius"); builder.AddContainer("api", "nginx"); using var app = builder.Build(); var model = app.Services.GetRequiredService<DistributedApplicationModel>(); var envResource = model.Resources.OfType<RadiusEnvironmentResource>().Single(); RadiusTestHelper.AttachDeploymentTargets(envResource, model); var ctx = new RadiusBicepPublishingContext(envResource); var bicep = ctx.GenerateBicep(model, NullLogger.Instance); // Assert on tokens that actually appear when an Azure provider IS emitted. The Bicep shape // is `providers: { kubernetes: {...} azure: { subscriptionId: ... resourceGroupName: ... } }`, // so the `providers:` block is always present (kubernetes) and the literal "providers.azure" // would never appear — asserting its absence proves nothing. These tokens appear only for an // Azure provider, so their absence is meaningful. Assert.DoesNotContain("azure:", bicep, StringComparison.OrdinalIgnoreCase); Assert.DoesNotContain("subscriptionId:", bicep, StringComparison.OrdinalIgnoreCase); Assert.DoesNotContain("resourceGroupName:", bicep, StringComparison.OrdinalIgnoreCase); } [Fact] public void Aws_Provider_EmitsAccountAndRegion_AndNoSecretLiterals() { using var builder = Aspire.Hosting.Utils.TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); var keyId = builder.AddParameter("awsKeyId", "AKIAEXAMPLE", secret: true); var keySecret = builder.AddParameter("awsKeySecret", "AKIA-XYZ-secret", secret: true); builder.AddRadiusEnvironment("radius") .WithAwsProvider("123456789012", "us-west-2", aws => aws.WithAccessKey(keyId, keySecret)); builder.AddContainer("api", "nginx"); using var app = builder.Build(); var model = app.Services.GetRequiredService<DistributedApplicationModel>(); var envResource = model.Resources.OfType<RadiusEnvironmentResource>().Single(); RadiusTestHelper.AttachDeploymentTargets(envResource, model); var ctx = new RadiusBicepPublishingContext(envResource); var bicep = ctx.GenerateBicep(model, NullLogger.Instance); // The native Radius.Core/environments schema models the AWS provider with // discrete accountId/region fields (not a single legacy scope path). Assert.Contains("accountId: '123456789012'", bicep); Assert.Contains("region: 'us-west-2'", bicep); Assert.DoesNotContain("AKIA-XYZ-secret", bicep); Assert.DoesNotContain("AKIAEXAMPLE", bicep); } [Fact] public void Hybrid_Provider_EmitsBothProviders() { using var builder = Aspire.Hosting.Utils.TestDistributedApplicationBuilder.Create(DistributedApplicationOperation.Publish); var secret = builder.AddParameter("s", "v", secret: true); builder.AddRadiusEnvironment("radius") .WithAzureProvider(SubId, Rg, azure => azure.WithServicePrincipal(TenantId, ClientId, secret)) .WithAwsProvider("123456789012", "us-east-1", aws => aws.WithIrsa("arn:aws:iam::123456789012:role/r")); builder.AddContainer("api", "nginx"); using var app = builder.Build(); var model = app.Services.GetRequiredService<DistributedApplicationModel>(); var envResource = model.Resources.OfType<RadiusEnvironmentResource>().Single(); RadiusTestHelper.AttachDeploymentTargets(envResource, model); var ctx = new RadiusBicepPublishingContext(envResource); var bicep = ctx.GenerateBicep(model, NullLogger.Instance); Assert.Contains($"subscriptionId: '{SubId}'", bicep); Assert.Contains($"resourceGroupName: '{Rg}'", bicep); Assert.Contains("accountId: '123456789012'", bicep); Assert.Contains("region: 'us-east-1'", bicep); } }