diff --git a/cli/azd/test/functional/aspire_test.go b/cli/azd/test/functional/aspire_test.go index f5a38c7fd53..b48436cf03c 100644 --- a/cli/azd/test/functional/aspire_test.go +++ b/cli/azd/test/functional/aspire_test.go @@ -4,6 +4,7 @@ package cli_test import ( + "context" "fmt" "os" "path/filepath" @@ -11,6 +12,8 @@ import ( "testing" "time" + "github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/resources/armresources" + "github.com/azure/azure-dev/cli/azd/pkg/azure" "github.com/azure/azure-dev/cli/azd/pkg/exec" "github.com/azure/azure-dev/cli/azd/pkg/project" "github.com/azure/azure-dev/cli/azd/pkg/tools/bicep" @@ -197,7 +200,6 @@ func Test_CLI_Aspire_DetectGen(t *testing.T) { // Test_CLI_Aspire_Deploy tests the full deployment of an Aspire project. func Test_CLI_Aspire_Deploy(t *testing.T) { - t.Parallel() ctx, cancel := newTestContext(t) defer cancel() @@ -230,6 +232,8 @@ func Test_CLI_Aspire_Deploy(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + _, err = cli.RunCommandWithStdIn(ctx, stdinForInit(envName), "init") require.NoError(t, err) @@ -240,6 +244,47 @@ func Test_CLI_Aspire_Deploy(t *testing.T) { require.NoError(t, err) } +// cleanupDeployments deletes all subscription level deployments tagged with `azd-env-name` equal to envName. If the session +// indcates we are in playback mode, this function is a no-op. +func cleanupDeployments(ctx context.Context, t *testing.T, azCLI *azdcli.CLI, session *recording.Session, envName string) { + if session != nil && session.Playback { + return + } + + client, err := armresources.NewDeploymentsClient(cfg.SubscriptionID, azdcli.NewTestCredential(azCLI), nil) + if err != nil { + return + } + + pager := client.NewListAtSubscriptionScopePager(nil) + var deploymentNames []string + + for pager.More() { + resp, err := pager.NextPage(ctx) + if err != nil { + t.Logf("cleanupDeployments: failed to list next deployments page: %v", err) + break + } + + for _, deployment := range resp.Value { + if deployment != nil && deployment.Tags != nil { + tagVal := deployment.Tags[azure.TagKeyAzdEnvName] + if tagVal != nil && *tagVal == envName { + deploymentNames = append(deploymentNames, *deployment.Name) + } + } + } + } + + for _, deploymentName := range deploymentNames { + t.Logf("cleanupDeployments: deleting deployment %s", deploymentName) + _, err := client.BeginDeleteAtSubscriptionScope(ctx, deploymentName, nil) + if err != nil { + t.Logf("cleanupDeployments: failed to delete deployment %s: %v", deploymentName, err) + } + } +} + // Snapshots a file located at targetPath. Saves the snapshot to snapshotRoot/rel, where rel is relative to targetRoot. func snapshotFile( sn *cupaloy.Config, diff --git a/cli/azd/test/functional/cli_test.go b/cli/azd/test/functional/cli_test.go index b9e82b73d27..b22f92feb96 100644 --- a/cli/azd/test/functional/cli_test.go +++ b/cli/azd/test/functional/cli_test.go @@ -155,6 +155,8 @@ func Test_CLI_DevCenter_Init_Up_Down(t *testing.T) { "\n", ) + defer cleanupDeployments(ctx, t, cli, session, envName) + // azd init _, err := cli.RunCommandWithStdIn(ctx, initStdIn, "init") require.NoError(t, err) @@ -213,6 +215,8 @@ func Test_CLI_InfraCreateAndDelete(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "storage") require.NoError(t, err, "failed expanding sample") @@ -299,6 +303,8 @@ func Test_CLI_ProvisionState(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "storage") require.NoError(t, err, "failed expanding sample") @@ -373,6 +379,8 @@ func Test_CLI_ProvisionStateWithDown(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "storage") require.NoError(t, err, "failed expanding sample") @@ -439,6 +447,8 @@ func Test_CLI_InfraCreateAndDeleteUpperCase(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "storage") require.NoError(t, err, "failed expanding sample") @@ -631,6 +641,8 @@ func Test_CLI_InfraBicepParam(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "storage-bicepparam") require.NoError(t, err, "failed expanding sample") diff --git a/cli/azd/test/functional/deployment_stacks_test.go b/cli/azd/test/functional/deployment_stacks_test.go index cabaf4a61de..36a8476679f 100644 --- a/cli/azd/test/functional/deployment_stacks_test.go +++ b/cli/azd/test/functional/deployment_stacks_test.go @@ -42,6 +42,8 @@ func Test_DeploymentStacks(t *testing.T) { "AZURE_LOCATION=eastus2", ) + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "storage") require.NoError(t, err, "failed expanding sample") diff --git a/cli/azd/test/functional/env_refresh_test.go b/cli/azd/test/functional/env_refresh_test.go index 3ea813923fc..4d94e550028 100644 --- a/cli/azd/test/functional/env_refresh_test.go +++ b/cli/azd/test/functional/env_refresh_test.go @@ -33,6 +33,8 @@ func Test_CLI_EnvRefresh_NoBicep(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "storage") require.NoError(t, err, "failed expanding sample") diff --git a/cli/azd/test/functional/remote_state_test.go b/cli/azd/test/functional/remote_state_test.go index edbbe574d16..82ec8ae1dd8 100644 --- a/cli/azd/test/functional/remote_state_test.go +++ b/cli/azd/test/functional/remote_state_test.go @@ -103,6 +103,7 @@ func runTestWithRemoteState(t *testing.T, testFunc remoteStateTestFunc) { envName := randomOrStoredEnvName(session) cli, env := provisionRemoteStateStorage(t, ctx, envName, session) + defer cleanupDeployments(ctx, t, cli, session, envName) defer destroyRemoteStateStorage(t, ctx, cli) accountConfig := &storage.AccountConfig{ diff --git a/cli/azd/test/functional/up_test.go b/cli/azd/test/functional/up_test.go index 73df569c166..78174120376 100644 --- a/cli/azd/test/functional/up_test.go +++ b/cli/azd/test/functional/up_test.go @@ -241,6 +241,8 @@ func Test_CLI_Up_Down_ContainerApp(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "containerapp") require.NoError(t, err, "failed expanding sample") @@ -304,6 +306,8 @@ func Test_CLI_Up_Down_ContainerApp_RemoteBuild(t *testing.T) { cli.Env = append(cli.Env, os.Environ()...) cli.Env = append(cli.Env, "AZURE_LOCATION=eastus2") + defer cleanupDeployments(ctx, t, cli, session, envName) + err := copySample(dir, "containerremotebuildapp") require.NoError(t, err, "failed expanding sample") diff --git a/cli/azd/test/functional/vs_server_test.go b/cli/azd/test/functional/vs_server_test.go index 32634c550d0..492ec16cbec 100644 --- a/cli/azd/test/functional/vs_server_test.go +++ b/cli/azd/test/functional/vs_server_test.go @@ -221,6 +221,10 @@ func Test_CLI_VsServer(t *testing.T) { cmd.Env = append(cmd.Env, pathString) } + if tt.IsLive { + defer cleanupDeployments(ctx, t, cli, session, envName) + } + var stdout bytes.Buffer cmd.Stdout = io.MultiWriter(&stdout, &logWriter{initialTime: time.Now(), t: t, prefix: "[svr-out] "}) cmd.Stderr = &logWriter{initialTime: time.Now(), t: t, prefix: "[svr-err] "} diff --git a/go.mod b/go.mod index d98ae1fc6c4..e580d67b270 100644 --- a/go.mod +++ b/go.mod @@ -55,6 +55,7 @@ require ( github.com/nathan-fiscaletti/consolesize-go v0.0.0-20220204101620-317176b6684d github.com/otiai10/copy v1.9.0 github.com/psanford/memfs v0.0.0-20230130182539-4dbf7e3e865e + github.com/sergi/go-diff v1.3.1 github.com/sethvargo/go-retry v0.2.3 github.com/spf13/cobra v1.3.0 github.com/spf13/pflag v1.0.5 @@ -95,7 +96,6 @@ require ( github.com/rivo/uniseg v0.2.0 // indirect github.com/segmentio/asm v1.1.3 // indirect github.com/segmentio/encoding v0.3.4 // indirect - github.com/sergi/go-diff v1.3.1 // indirect github.com/stretchr/objx v0.5.2 // indirect go.opentelemetry.io/otel/exporters/otlp/internal/retry v1.8.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.8.0 // indirect diff --git a/go.sum b/go.sum index 7bb49d753e6..4d10b19b588 100644 --- a/go.sum +++ b/go.sum @@ -51,16 +51,10 @@ github.com/AlecAivazis/survey/v2 v2.3.2 h1:TqTB+aDDCLYhf9/bD2TwSO8u8jDSmMUd2SUVO github.com/AlecAivazis/survey/v2 v2.3.2/go.mod h1:TH2kPCDU3Kqq7pLbnCWwZXDBjnhZtmsCle5EiYDJ2fg= github.com/Azure/azure-pipeline-go v0.2.1 h1:OLBdZJ3yvOn2MezlWvbrBMTEUQC72zAftRZOMdj5HYo= github.com/Azure/azure-pipeline-go v0.2.1/go.mod h1:UGSo8XybXnIGZ3epmeBw7Jdz+HiUVpqIlpz/HKHylF4= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0 h1:1nGuui+4POelzDwI7RG56yfQJHCnKvwfMoU7VsEp+Zg= -github.com/Azure/azure-sdk-for-go/sdk/azcore v1.12.0/go.mod h1:99EvauvlcJ1U06amZiksfYz/3aFGyIhWGHVyiZXtBAI= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0 h1:nyQWyZvwGTvunIMxi1Y9uXkcyr+I7TeNrr/foo4Kpk8= github.com/Azure/azure-sdk-for-go/sdk/azcore v1.14.0/go.mod h1:l38EPgmsp71HHLq9j7De57JcKOWPyhrsW1Awm1JS6K0= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0 h1:U2rTu3Ef+7w9FHKIAXM6ZyqF3UOWJZ12zIm8zECAFfg= -github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.6.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0 h1:tfLQ34V6F7tVSwoTf/4lH5sE0o6eCJuNDTmH09nDpbc= github.com/Azure/azure-sdk-for-go/sdk/azidentity v1.7.0/go.mod h1:9kIvujWAA58nmPmWB1m23fyWic1kYZMxD9CxaWn4Qpg= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0 h1:H+U3Gk9zY56G3u872L82bk4thcsy2Gghb9ExT4Zvm1o= -github.com/Azure/azure-sdk-for-go/sdk/internal v1.9.0/go.mod h1:mgrmMSgaLp9hmax62XQTd0N4aAqSE5E0DulSpVYK7vc= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0 h1:ywEEhmNahHBihViHepv3xPBn1663uRv2t2q/ESv9seY= github.com/Azure/azure-sdk-for-go/sdk/internal v1.10.0/go.mod h1:iZDifYGJTIgIIkYRNWPENUnqx6bJ2xnSDFI2tjwZNuY= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/apimanagement/armapimanagement v1.0.0 h1:Ai3+BE11JvwQ2PxLGNKAfMNSceYXjeijReLJiCouO6o= @@ -77,8 +71,6 @@ github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthoriza github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization v1.0.0/go.mod h1:lPneRe3TwsoDRKY4O6YDLXHhEWrD+TIRa8XrV/3/fqw= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.1.1 h1:6A4M8smF+y8nM/DYsLNQz9n7n2ZGaEVqfz8ZWQirQkI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/authorization/armauthorization/v2 v2.1.1/go.mod h1:WqyxV5S0VtXD2+2d6oPqOvyhGubCvzLCKSAKgQ004Uk= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cognitiveservices/armcognitiveservices v1.4.1 h1:ynIxbR7wH5nBEJzprbeBFVBtoYTYcQbN39vM7eNS3Xc= -github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cognitiveservices/armcognitiveservices v1.4.1/go.mod h1:nUhnLNlOtAVpn/PRwJKIf3ulXLvdMiWlGk8nufEUaKc= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cognitiveservices/armcognitiveservices v1.6.0 h1:TiYjDq0LCNgtee1teMayYT5FjHmlunWUpthVANUXYPM= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/cognitiveservices/armcognitiveservices v1.6.0/go.mod h1:yErdzWZBzjNJCnbC1DcUcSVhjTgllT4PyOenFSeXSJI= github.com/Azure/azure-sdk-for-go/sdk/resourcemanager/containerregistry/armcontainerregistry v0.6.0 h1:Z5/bDxQL2Zc9t6ZDwdRU60bpLHZvoKOeuaM7XVbf2z0= @@ -576,8 +568,6 @@ golang.org/x/crypto v0.0.0-20190923035154-9ee001bba392/go.mod h1:/lpIB1dKB+9EgE3 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= -golang.org/x/crypto v0.24.0 h1:mnl8DM0o513X8fdIkmyFE/5hTYxbwYOjDS/+rK6qpRI= -golang.org/x/crypto v0.24.0/go.mod h1:Z1PMYSOR5nyMcyAVAIQSKCDwalqy85Aqn1x3Ws4L5DM= golang.org/x/crypto v0.27.0 h1:GXm2NjJrPaiv/h1tb2UH8QfgC/hOf/+z0p6PT8o1w7A= golang.org/x/crypto v0.27.0/go.mod h1:1Xngt8kV6Dvbssa53Ziq6Eqn0HqbZi5Z6R0ZpwQzt70= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= @@ -658,8 +648,6 @@ golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96b golang.org/x/net v0.0.0-20210410081132-afb366fc7cd1/go.mod h1:9tjilg8BloeKEkVJvy7fQ90B1CfIiPueXVOjqfkSzI8= golang.org/x/net v0.0.0-20210503060351-7fd8e65b6420/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20210813160813-60bc85c4be6d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= -golang.org/x/net v0.26.0 h1:soB7SVo0PWrY4vPW/+ay0jKDNScG2X9wFeYlXIvJsOQ= -golang.org/x/net v0.26.0/go.mod h1:5YKkiSynbBIh3p6iOc/vibscux0x38BZDkn8sCUPxHE= golang.org/x/net v0.29.0 h1:5ORfpBpCs4HzDYoodCDBbwHzdR5UrLBZ3sOnUJmFoHo= golang.org/x/net v0.29.0/go.mod h1:gLkgy8jTGERgjzMic6DS9+SP0ajcu6Xu3Orq/SpETg0= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= @@ -763,14 +751,10 @@ golang.org/x/sys v0.0.0-20211205182925-97ca703d548d/go.mod h1:oPkhp1MJrh7nUepCBc golang.org/x/sys v0.0.0-20220715151400-c0bba94af5f8/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.20.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= -golang.org/x/sys v0.21.0 h1:rF+pYz3DAGSQAxAu1CbC7catZg4ebC4UIeIhKxBZvws= -golang.org/x/sys v0.21.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.25.0 h1:r+8e+loiHxRqhXVl6ML1nO3l1+oFoWbnlu2Ehimmi34= golang.org/x/sys v0.25.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210503060354-a79de5458b56/go.mod h1:tfny5GFUkzUvx4ps4ajbZsCe5lw1metzhBm9T3x7oIY= -golang.org/x/term v0.21.0 h1:WVXCp+/EBEHOj53Rvu+7KiT/iElMrO8ACK16SMZ3jaA= -golang.org/x/term v0.21.0/go.mod h1:ooXLefLobQVslOqselCNF4SxFAaoS6KujMbsGzSDmX0= golang.org/x/term v0.24.0 h1:Mh5cbb+Zk2hqqXNO7S1iTjEphVL+jb8ZWaqh/g+JWkM= golang.org/x/term v0.24.0/go.mod h1:lOBK/LVxemqiMij05LGJ0tzNr8xlmwBRJ81PX6wVLH8= golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= @@ -782,8 +766,6 @@ golang.org/x/text v0.3.4/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.5/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= -golang.org/x/text v0.16.0 h1:a94ExnEXNtEwYLGJSIUxnWoxoRz/ZcCsV63ROupILh4= -golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/text v0.18.0 h1:XvMDiNzPAl0jr17s6W9lcaIhGUfUORdGCNsuLmPG224= golang.org/x/text v0.18.0/go.mod h1:BuEKDfySbSR4drPmRPG/7iBdf8hvFMuRexcpahXilzY= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=