From 35d54ab682fa12b971be4a79c3566b58fdd61704 Mon Sep 17 00:00:00 2001 From: Bryce Lampe Date: Thu, 12 Dec 2024 10:30:35 -0800 Subject: [PATCH] Consolidate integration tests (#4910) This moves integration tests currently under `provider` into the `examples` directory, and removes `provider_test` defined in `extraTests`. These integration tests will now benefit from https://github.com/pulumi/ci-mgmt/issues/1033 as a result, and https://github.com/pulumi/pulumi-aws/pull/4911 is no longer necessary. --- .ci-mgmt.yaml | 72 +- .github/workflows/aws-upstream-tests.yml | 2 +- .github/workflows/master.yml | 72 +- .github/workflows/nightly-test.yml | 2 +- .github/workflows/prerelease.yml | 72 +- .github/workflows/release.yml | 72 +- .github/workflows/run-acceptance-tests.yml | 72 +- examples/examples_nodejs_test.go | 404 ++++++- examples/examples_py_test.go | 94 +- examples/examples_yaml_test.go | 1036 +++++++++++++++- examples/go.mod | 10 +- {provider => examples}/provider_test.go | 18 +- .../test-programs/acm/Pulumi.yaml | 0 .../Pulumi.yaml | 0 .../apigateway-methodreponse/Pulumi.yaml | 0 .../apigateway-resource-response/Pulumi.yaml | 0 .../apigateway-resource/Pulumi.yaml | 0 .../assume-role-session-tags/Pulumi.yaml | 0 .../test-programs/bucket-obj/.gitignore | 0 .../test-programs/bucket-obj/Pulumi.yaml | 0 .../test-programs/bucket/Pulumi.yaml | 0 .../test-programs/changing-region/.gitignore | 0 .../test-programs/changing-region/Pulumi.yaml | 0 .../test-programs/changing-region/index.ts | 0 .../changing-region/package.json | 0 .../changing-region/tsconfig.json | 0 .../cloudfront-distribution/.gitignore | 0 .../cloudfront-distribution/Pulumi.yaml | 0 .../cloudwatch-eventrule/Pulumi.yaml | 0 .../cloudwatch-loggroup/Pulumi.yaml | 0 .../disappearing-bucket-object/Pulumi.yaml | 0 .../disappearing-bucket-object/index.ts | 0 .../disappearing-bucket-object/package.json | 0 .../disappearing-bucket-object/tsconfig.json | 0 .../test-programs/dynamodb-table/Pulumi.yaml | 0 .../test-programs/ec2-instance/.gitignore | 0 .../test-programs/ec2-instance/Pulumi.yaml | 0 .../test-programs/ec2-networking/Pulumi.yaml | 0 .../ec2-string-for-int/.gitignore | 0 .../ec2-string-for-int/Pulumi.yaml | 0 .../test-programs/ec2-string-for-int/index.ts | 0 .../ec2-string-for-int/package.json | 0 .../ec2-string-for-int/tsconfig.json | 0 .../ecr-lifecyclepolicy/Pulumi.yaml | 0 .../test-programs/ecr-repository/Pulumi.yaml | 0 .../test-programs/ecs-service/Pulumi.yaml | 0 .../test-programs/eks-cluster/Pulumi.yaml | 0 .../gamelift-typescript/.gitignore | 0 .../gamelift-typescript/Pulumi.yaml | 0 .../gamelift-typescript/index.ts | 0 .../gamelift-typescript/package.json | 0 .../gamelift-typescript/tsconfig.json | 0 .../iam-instanceprofile/Pulumi.yaml | 0 .../iam-openidconnectprovider/Pulumi.yaml | 0 .../test-programs/iam-user/Pulumi.yaml | 0 .../imds-auth/imds-v2/Pulumi.yaml | 0 .../imds-v2/remote-program/Pulumi.yaml | 0 .../test-programs/job-queue/Pulumi.yaml | 0 .../test-programs/job-queue/index.ts | 0 .../test-programs/job-queue/package.json | 0 .../test-programs/job-queue/tsconfig.json | 0 .../test-programs/kms-key/Pulumi.yaml | 0 .../test-programs/lb/Pulumi.yaml | 0 .../non-idempotent-sns-topic/Pulumi.yaml | 0 .../parallel-lambdas/Pulumi.yaml | 0 .../test-programs/parallel-lambdas/index.ts | 0 .../parallel-lambdas/package.json | 0 .../parallel-lambdas/tsconfig.json | 0 .../test-programs/rds-instance/Pulumi.yaml | 0 .../test-programs/regress-2534/.gitignore | 0 .../test-programs/regress-2534/Pulumi.yaml | 0 .../test-programs/regress-2534/__main__.py | 0 .../regress-2534/requirements.txt | 0 .../test-programs/regress-2796/Pulumi.yaml | 0 .../test-programs/regress-3094/.gitignore | 0 .../test-programs/regress-3094/Pulumi.yaml | 0 .../test-programs/regress-3094/index.ts | 0 .../test-programs/regress-3094/package.json | 0 .../test-programs/regress-3094/tsconfig.json | 0 .../test-programs/regress-3196/Pulumi.yaml | 0 .../test-programs/regress-3196/__main__.py | 0 .../regress-3196/requirements.txt | 0 .../test-programs/regress-3674/Pulumi.yaml | 0 .../test-programs/regress-3835/.gitignore | 0 .../test-programs/regress-3835/Pulumi.yaml | 0 .../test-programs/regress-3835/index.ts | 0 .../test-programs/regress-3835/package.json | 0 .../test-programs/regress-3835/tsconfig.json | 0 .../test-programs/regress-3887/Pulumi.yaml | 0 .../test-programs/regress-3887/__main__.py | 0 .../regress-3887/requirements.txt | 0 .../regress-3887/step-1/__main__.py | 0 .../regress-3887/step-2/__main__.py | 0 .../test-programs/regress-4079/Pulumi.yaml | 0 .../test-programs/regress-4079/index.ts | 0 .../test-programs/regress-4079/package.json | 0 .../test-programs/regress-4079/tsconfig.json | 0 .../test-programs/regress-4128/Pulumi.yaml | 0 .../test-programs/regress-4128/index.ts | 0 .../test-programs/regress-4128/package.json | 0 .../test-programs/regress-4128/tsconfig.json | 0 .../test-programs/regress-4446/Pulumi.yaml | 0 .../test-programs/regress-4446/index.ts | 0 .../test-programs/regress-4446/package.json | 0 .../test-programs/regress-4446/tsconfig.json | 0 .../test-programs/regress-4457/Pulumi.yaml | 0 .../test-programs/regress-4457/__main__.py | 0 .../regress-4457/requirements.txt | 0 .../test-programs/regress-4568/Pulumi.yaml | 0 .../test-programs/regress-4568/index.ts | 0 .../test-programs/regress-4568/package.json | 0 .../test-programs/regress-4568/tsconfig.json | 0 .../route53-resolver-endpoint/Pulumi.yaml | 0 .../secretsmanager-secret/Pulumi.yaml | 0 .../test-programs/secretversion/.gitignore | 0 .../test-programs/secretversion/Pulumi.yaml | 0 .../test-programs/sns-topic/Pulumi.yaml | 0 .../test-programs/subnet-group/.gitignore | 0 .../test-programs/subnet-group/Pulumi.yaml | 0 .../new-version/plan.json | 0 .../upgrade/stack.json | 0 .../TestProviderUpgrade/acm/5.42.0/grpc.json | 0 .../5.42.0/grpc.json | 0 .../5.42.0/stack.json | 0 .../apigateway-methodreponse/5.42.0/grpc.json | 0 .../5.42.0/stack.json | 0 .../5.42.0/grpc.json | 0 .../5.42.0/stack.json | 0 .../apigateway-resource/5.42.0/grpc.json | 0 .../apigateway-resource/5.42.0/stack.json | 0 .../bucket-obj/5.42.0/grpc.json | 0 .../bucket-obj/5.42.0/stack.json | 0 .../bucket/5.42.0/grpc.json | 0 .../bucket/5.42.0/stack.json | 0 .../cloudfront-distribution/6.10.0/grpc.json | 0 .../cloudfront-distribution/6.10.0/stack.json | 0 .../cloudwatch-eventrule/5.42.0/grpc.json | 0 .../cloudwatch-eventrule/5.42.0/stack.json | 0 .../cloudwatch-loggroup/5.42.0/grpc.json | 0 .../cloudwatch-loggroup/5.42.0/stack.json | 0 .../cloudwatch/5.42.0/grpc.json | 0 .../cloudwatch/5.42.0/stack.json | 0 .../dynamodb-table/5.42.0/grpc.json | 0 .../dynamodb-table/5.42.0/stack.json | 0 .../ec2-instance/5.42.0/grpc.json | 0 .../ec2-instance/5.42.0/stack.json | 0 .../ec2-networking/5.42.0/grpc.json | 0 .../ec2-networking/5.42.0/stack.json | 0 .../ecr-lifecyclepolicy/5.42.0/grpc.json | 0 .../ecr-lifecyclepolicy/5.42.0/stack.json | 0 .../ecr-repository/5.42.0/grpc.json | 0 .../ecr-repository/5.42.0/stack.json | 0 .../ecs-service/5.42.0/grpc.json | 0 .../ecs-service/5.42.0/stack.json | 0 .../eks-cluster/5.42.0/grpc.json | 0 .../eks-cluster/5.42.0/stack.json | 0 .../eventbus/5.42.0/grpc.json | 0 .../eventbus/5.42.0/stack.json | 0 .../iam-instanceprofile/5.42.0/grpc.json | 0 .../iam-instanceprofile/5.42.0/stack.json | 0 .../5.42.0/grpc.json | 0 .../5.42.0/stack.json | 0 .../iam-user/5.42.0/grpc.json | 0 .../iam-user/5.42.0/stack.json | 0 .../job-queue/5.42.0/grpc.json | 0 .../job-queue/5.42.0/stack.json | 0 .../kms-key/5.42.0/grpc.json | 0 .../kms-key/5.42.0/stack.json | 0 .../lambda-layer-new/5.42.0/grpc.json | 0 .../lambda-layer-new/5.42.0/stack.json | 0 .../TestProviderUpgrade/lb/5.42.0/grpc.json | 0 .../TestProviderUpgrade/lb/5.42.0/stack.json | 0 .../logGroup/5.42.0/grpc.json | 0 .../logGroup/5.42.0/stack.json | 0 .../non-idempotent-sns-topic/grpc.json | 0 .../non-idempotent-sns-topic/state.json | 0 .../queue/5.42.0/grpc.json | 0 .../queue/5.42.0/stack.json | 0 .../rds-instance/5.42.0/grpc.json | 0 .../rds-instance/5.42.0/stack.json | 0 .../5.42.0/grpc.json | 0 .../5.42.0/stack.json | 0 .../route53/5.42.0/grpc.json | 0 .../route53/5.42.0/stack.json | 0 .../secretsmanager-secret/5.42.0/grpc.json | 0 .../secretsmanager-secret/5.42.0/stack.json | 0 .../secretversion/5.42.0/grpc.json | 0 .../secretversion/5.42.0/stack.json | 0 .../sns-topic/5.42.0/grpc.json | 0 .../sns-topic/5.42.0/stack.json | 0 .../subnet-group/5.42.0/grpc.json | 0 .../subnet-group/5.42.0/stack.json | 0 provider/go.mod | 8 +- provider/provider_dotnet_test.go | 6 - provider/provider_nodejs_test.go | 439 ------- provider/provider_python_test.go | 120 -- provider/provider_yaml_test.go | 1055 ----------------- 197 files changed, 1546 insertions(+), 2008 deletions(-) rename {provider => examples}/provider_test.go (96%) rename {provider => examples}/test-programs/acm/Pulumi.yaml (100%) rename {provider => examples}/test-programs/apigateway-integrationresponse/Pulumi.yaml (100%) rename {provider => examples}/test-programs/apigateway-methodreponse/Pulumi.yaml (100%) rename {provider => examples}/test-programs/apigateway-resource-response/Pulumi.yaml (100%) rename {provider => examples}/test-programs/apigateway-resource/Pulumi.yaml (100%) rename {provider => examples}/test-programs/assume-role-session-tags/Pulumi.yaml (100%) rename {provider => examples}/test-programs/bucket-obj/.gitignore (100%) rename {provider => examples}/test-programs/bucket-obj/Pulumi.yaml (100%) rename {provider => examples}/test-programs/bucket/Pulumi.yaml (100%) rename {provider => examples}/test-programs/changing-region/.gitignore (100%) rename {provider => examples}/test-programs/changing-region/Pulumi.yaml (100%) rename {provider => examples}/test-programs/changing-region/index.ts (100%) rename {provider => examples}/test-programs/changing-region/package.json (100%) rename {provider => examples}/test-programs/changing-region/tsconfig.json (100%) rename {provider => examples}/test-programs/cloudfront-distribution/.gitignore (100%) rename {provider => examples}/test-programs/cloudfront-distribution/Pulumi.yaml (100%) rename {provider => examples}/test-programs/cloudwatch-eventrule/Pulumi.yaml (100%) rename {provider => examples}/test-programs/cloudwatch-loggroup/Pulumi.yaml (100%) rename {provider => examples}/test-programs/disappearing-bucket-object/Pulumi.yaml (100%) rename {provider => examples}/test-programs/disappearing-bucket-object/index.ts (100%) rename {provider => examples}/test-programs/disappearing-bucket-object/package.json (100%) rename {provider => examples}/test-programs/disappearing-bucket-object/tsconfig.json (100%) rename {provider => examples}/test-programs/dynamodb-table/Pulumi.yaml (100%) rename {provider => examples}/test-programs/ec2-instance/.gitignore (100%) rename {provider => examples}/test-programs/ec2-instance/Pulumi.yaml (100%) rename {provider => examples}/test-programs/ec2-networking/Pulumi.yaml (100%) rename {provider => examples}/test-programs/ec2-string-for-int/.gitignore (100%) rename {provider => examples}/test-programs/ec2-string-for-int/Pulumi.yaml (100%) rename {provider => examples}/test-programs/ec2-string-for-int/index.ts (100%) rename {provider => examples}/test-programs/ec2-string-for-int/package.json (100%) rename {provider => examples}/test-programs/ec2-string-for-int/tsconfig.json (100%) rename {provider => examples}/test-programs/ecr-lifecyclepolicy/Pulumi.yaml (100%) rename {provider => examples}/test-programs/ecr-repository/Pulumi.yaml (100%) rename {provider => examples}/test-programs/ecs-service/Pulumi.yaml (100%) rename {provider => examples}/test-programs/eks-cluster/Pulumi.yaml (100%) rename {provider => examples}/test-programs/gamelift-typescript/.gitignore (100%) rename {provider => examples}/test-programs/gamelift-typescript/Pulumi.yaml (100%) rename {provider => examples}/test-programs/gamelift-typescript/index.ts (100%) rename {provider => examples}/test-programs/gamelift-typescript/package.json (100%) rename {provider => examples}/test-programs/gamelift-typescript/tsconfig.json (100%) rename {provider => examples}/test-programs/iam-instanceprofile/Pulumi.yaml (100%) rename {provider => examples}/test-programs/iam-openidconnectprovider/Pulumi.yaml (100%) rename {provider => examples}/test-programs/iam-user/Pulumi.yaml (100%) rename {provider => examples}/test-programs/imds-auth/imds-v2/Pulumi.yaml (100%) rename {provider => examples}/test-programs/imds-auth/imds-v2/remote-program/Pulumi.yaml (100%) rename {provider => examples}/test-programs/job-queue/Pulumi.yaml (100%) rename {provider => examples}/test-programs/job-queue/index.ts (100%) rename {provider => examples}/test-programs/job-queue/package.json (100%) rename {provider => examples}/test-programs/job-queue/tsconfig.json (100%) rename {provider => examples}/test-programs/kms-key/Pulumi.yaml (100%) rename {provider => examples}/test-programs/lb/Pulumi.yaml (100%) rename {provider => examples}/test-programs/non-idempotent-sns-topic/Pulumi.yaml (100%) rename {provider => examples}/test-programs/parallel-lambdas/Pulumi.yaml (100%) rename {provider => examples}/test-programs/parallel-lambdas/index.ts (100%) rename {provider => examples}/test-programs/parallel-lambdas/package.json (100%) rename {provider => examples}/test-programs/parallel-lambdas/tsconfig.json (100%) rename {provider => examples}/test-programs/rds-instance/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-2534/.gitignore (100%) rename {provider => examples}/test-programs/regress-2534/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-2534/__main__.py (100%) rename {provider => examples}/test-programs/regress-2534/requirements.txt (100%) rename {provider => examples}/test-programs/regress-2796/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-3094/.gitignore (100%) rename {provider => examples}/test-programs/regress-3094/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-3094/index.ts (100%) rename {provider => examples}/test-programs/regress-3094/package.json (100%) rename {provider => examples}/test-programs/regress-3094/tsconfig.json (100%) rename {provider => examples}/test-programs/regress-3196/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-3196/__main__.py (100%) rename {provider => examples}/test-programs/regress-3196/requirements.txt (100%) rename {provider => examples}/test-programs/regress-3674/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-3835/.gitignore (100%) rename {provider => examples}/test-programs/regress-3835/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-3835/index.ts (100%) rename {provider => examples}/test-programs/regress-3835/package.json (100%) rename {provider => examples}/test-programs/regress-3835/tsconfig.json (100%) rename {provider => examples}/test-programs/regress-3887/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-3887/__main__.py (100%) rename {provider => examples}/test-programs/regress-3887/requirements.txt (100%) rename {provider => examples}/test-programs/regress-3887/step-1/__main__.py (100%) rename {provider => examples}/test-programs/regress-3887/step-2/__main__.py (100%) rename {provider => examples}/test-programs/regress-4079/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-4079/index.ts (100%) rename {provider => examples}/test-programs/regress-4079/package.json (100%) rename {provider => examples}/test-programs/regress-4079/tsconfig.json (100%) rename {provider => examples}/test-programs/regress-4128/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-4128/index.ts (100%) rename {provider => examples}/test-programs/regress-4128/package.json (100%) rename {provider => examples}/test-programs/regress-4128/tsconfig.json (100%) rename {provider => examples}/test-programs/regress-4446/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-4446/index.ts (100%) rename {provider => examples}/test-programs/regress-4446/package.json (100%) rename {provider => examples}/test-programs/regress-4446/tsconfig.json (100%) rename {provider => examples}/test-programs/regress-4457/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-4457/__main__.py (100%) rename {provider => examples}/test-programs/regress-4457/requirements.txt (100%) rename {provider => examples}/test-programs/regress-4568/Pulumi.yaml (100%) rename {provider => examples}/test-programs/regress-4568/index.ts (100%) rename {provider => examples}/test-programs/regress-4568/package.json (100%) rename {provider => examples}/test-programs/regress-4568/tsconfig.json (100%) rename {provider => examples}/test-programs/route53-resolver-endpoint/Pulumi.yaml (100%) rename {provider => examples}/test-programs/secretsmanager-secret/Pulumi.yaml (100%) rename {provider => examples}/test-programs/secretversion/.gitignore (100%) rename {provider => examples}/test-programs/secretversion/Pulumi.yaml (100%) rename {provider => examples}/test-programs/sns-topic/Pulumi.yaml (100%) rename {provider => examples}/test-programs/subnet-group/.gitignore (100%) rename {provider => examples}/test-programs/subnet-group/Pulumi.yaml (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/new-version/plan.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/upgrade/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/acm/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/lb/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/lb/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/state.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/queue/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/queue/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/route53/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/route53/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/stack.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/grpc.json (100%) rename {provider => examples}/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/stack.json (100%) delete mode 100644 provider/provider_dotnet_test.go delete mode 100644 provider/provider_nodejs_test.go delete mode 100644 provider/provider_python_test.go delete mode 100644 provider/provider_yaml_test.go diff --git a/.ci-mgmt.yaml b/.ci-mgmt.yaml index 10f498951f9..be647daf9d1 100644 --- a/.ci-mgmt.yaml +++ b/.ci-mgmt.yaml @@ -58,7 +58,7 @@ actions: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-region: ${{ env.AWS_REGION }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 + role-duration-seconds: 7200 role-session-name: aws@githubActions role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - name: Make upstream @@ -126,73 +126,3 @@ extraTests: run: | cd upstream make provider-lint - - provider_test: - name: provider_test - needs: build_sdk - permissions: - contents: read - id-token: write - runs-on: ubuntu-latest - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - with: - swap-storage: false - tool-cache: false - - name: Checkout Repo - uses: actions/checkout@v4 - with: - ref: ${{ env.PR_COMMIT_SHA }} - submodules: true - - uses: pulumi/provider-version-action@v1 - with: - set-env: 'PROVIDER_VERSION' - - name: Setup tools - uses: ./.github/actions/setup-tools - with: - tools: pulumictl, pulumi, go, node, dotnet, python, java - - name: Prepare local workspace - run: make prepare_local_workspace - - name: Download bin - uses: ./.github/actions/download-bin - - name: Download SDK - uses: ./.github/actions/download-sdk - with: - language: ${{ matrix.language }} - - name: Restore makefile progress - run: make --touch provider schema build_${{ matrix.language }} - - name: Update path - run: echo "${{ github.workspace }}/bin" >> "$GITHUB_PATH" - - name: Install Python deps - run: |- - pip3 install virtualenv==20.0.23 - pip3 install pipenv - - name: Install dependencies - run: make install_${{ matrix.language}}_sdk - - name: Install gotestfmt - uses: GoTestTools/gotestfmt-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - version: v2.5.0 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-region: ${{ env.AWS_REGION }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 - role-session-name: aws@githubActions - role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - - name: Run provider tests - run: | - cd provider && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt - strategy: - fail-fast: false - matrix: - language: - - nodejs - - python - - dotnet - - go - - java diff --git a/.github/workflows/aws-upstream-tests.yml b/.github/workflows/aws-upstream-tests.yml index d3d8bd7ae5e..648f36a8efa 100644 --- a/.github/workflows/aws-upstream-tests.yml +++ b/.github/workflows/aws-upstream-tests.yml @@ -66,7 +66,7 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-region: ${{ env.AWS_REGION }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 + role-duration-seconds: 7200 role-session-name: aws@githubActions role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - name: Test ${{ matrix.service }} diff --git a/.github/workflows/master.yml b/.github/workflows/master.yml index f2a2f9a69f8..d7c0f9bb82c 100644 --- a/.github/workflows/master.yml +++ b/.github/workflows/master.yml @@ -100,7 +100,6 @@ jobs: - test - license_check - go_test_shim - - provider_test - upstream_lint uses: ./.github/workflows/publish.yml secrets: inherit @@ -187,7 +186,7 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-region: ${{ env.AWS_REGION }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 + role-duration-seconds: 7200 role-session-name: aws@githubActions role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - name: Make upstream @@ -237,75 +236,6 @@ jobs: name: Upload coverage reports to Codecov uses: codecov/codecov-action@v4 timeout-minutes: 60 - provider_test: - name: provider_test - needs: build_sdk - permissions: - contents: read - id-token: write - runs-on: ubuntu-latest - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - with: - swap-storage: false - tool-cache: false - - name: Checkout Repo - uses: actions/checkout@v4 - with: - ref: ${{ env.PR_COMMIT_SHA }} - submodules: true - - uses: pulumi/provider-version-action@v1 - with: - set-env: PROVIDER_VERSION - - name: Setup tools - uses: ./.github/actions/setup-tools - with: - tools: pulumictl, pulumi, go, node, dotnet, python, java - - name: Prepare local workspace - run: make prepare_local_workspace - - name: Download bin - uses: ./.github/actions/download-bin - - name: Download SDK - uses: ./.github/actions/download-sdk - with: - language: ${{ matrix.language }} - - name: Restore makefile progress - run: make --touch provider schema build_${{ matrix.language }} - - name: Update path - run: echo "${{ github.workspace }}/bin" >> "$GITHUB_PATH" - - name: Install Python deps - run: |- - pip3 install virtualenv==20.0.23 - pip3 install pipenv - - name: Install dependencies - run: make install_${{ matrix.language}}_sdk - - name: Install gotestfmt - uses: GoTestTools/gotestfmt-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - version: v2.5.0 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-region: ${{ env.AWS_REGION }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 - role-session-name: aws@githubActions - role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - - name: Run provider tests - run: | - cd provider && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt - strategy: - fail-fast: false - matrix: - language: - - nodejs - - python - - dotnet - - go - - java upstream_lint: name: Run upstream provider-lint runs-on: ubuntu-latest diff --git a/.github/workflows/nightly-test.yml b/.github/workflows/nightly-test.yml index f514c942252..fbce58b63dd 100644 --- a/.github/workflows/nightly-test.yml +++ b/.github/workflows/nightly-test.yml @@ -103,7 +103,7 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-region: ${{ env.AWS_REGION }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 + role-duration-seconds: 7200 role-session-name: aws@githubActions role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - name: Make upstream diff --git a/.github/workflows/prerelease.yml b/.github/workflows/prerelease.yml index c7993ab00f9..8f65781b374 100644 --- a/.github/workflows/prerelease.yml +++ b/.github/workflows/prerelease.yml @@ -60,7 +60,6 @@ jobs: - test - license_check - go_test_shim - - provider_test - upstream_lint uses: ./.github/workflows/publish.yml secrets: inherit @@ -127,7 +126,7 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-region: ${{ env.AWS_REGION }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 + role-duration-seconds: 7200 role-session-name: aws@githubActions role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - name: Make upstream @@ -177,75 +176,6 @@ jobs: name: Upload coverage reports to Codecov uses: codecov/codecov-action@v4 timeout-minutes: 60 - provider_test: - name: provider_test - needs: build_sdk - permissions: - contents: read - id-token: write - runs-on: ubuntu-latest - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - with: - swap-storage: false - tool-cache: false - - name: Checkout Repo - uses: actions/checkout@v4 - with: - ref: ${{ env.PR_COMMIT_SHA }} - submodules: true - - uses: pulumi/provider-version-action@v1 - with: - set-env: PROVIDER_VERSION - - name: Setup tools - uses: ./.github/actions/setup-tools - with: - tools: pulumictl, pulumi, go, node, dotnet, python, java - - name: Prepare local workspace - run: make prepare_local_workspace - - name: Download bin - uses: ./.github/actions/download-bin - - name: Download SDK - uses: ./.github/actions/download-sdk - with: - language: ${{ matrix.language }} - - name: Restore makefile progress - run: make --touch provider schema build_${{ matrix.language }} - - name: Update path - run: echo "${{ github.workspace }}/bin" >> "$GITHUB_PATH" - - name: Install Python deps - run: |- - pip3 install virtualenv==20.0.23 - pip3 install pipenv - - name: Install dependencies - run: make install_${{ matrix.language}}_sdk - - name: Install gotestfmt - uses: GoTestTools/gotestfmt-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - version: v2.5.0 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-region: ${{ env.AWS_REGION }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 - role-session-name: aws@githubActions - role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - - name: Run provider tests - run: | - cd provider && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt - strategy: - fail-fast: false - matrix: - language: - - nodejs - - python - - dotnet - - go - - java upstream_lint: name: Run upstream provider-lint runs-on: ubuntu-latest diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 2dd22eb98c0..1005b295a09 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -66,7 +66,6 @@ jobs: - test - license_check - go_test_shim - - provider_test - upstream_lint uses: ./.github/workflows/publish.yml secrets: inherit @@ -133,7 +132,7 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-region: ${{ env.AWS_REGION }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 + role-duration-seconds: 7200 role-session-name: aws@githubActions role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - name: Make upstream @@ -183,75 +182,6 @@ jobs: name: Upload coverage reports to Codecov uses: codecov/codecov-action@v4 timeout-minutes: 60 - provider_test: - name: provider_test - needs: build_sdk - permissions: - contents: read - id-token: write - runs-on: ubuntu-latest - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - with: - swap-storage: false - tool-cache: false - - name: Checkout Repo - uses: actions/checkout@v4 - with: - ref: ${{ env.PR_COMMIT_SHA }} - submodules: true - - uses: pulumi/provider-version-action@v1 - with: - set-env: PROVIDER_VERSION - - name: Setup tools - uses: ./.github/actions/setup-tools - with: - tools: pulumictl, pulumi, go, node, dotnet, python, java - - name: Prepare local workspace - run: make prepare_local_workspace - - name: Download bin - uses: ./.github/actions/download-bin - - name: Download SDK - uses: ./.github/actions/download-sdk - with: - language: ${{ matrix.language }} - - name: Restore makefile progress - run: make --touch provider schema build_${{ matrix.language }} - - name: Update path - run: echo "${{ github.workspace }}/bin" >> "$GITHUB_PATH" - - name: Install Python deps - run: |- - pip3 install virtualenv==20.0.23 - pip3 install pipenv - - name: Install dependencies - run: make install_${{ matrix.language}}_sdk - - name: Install gotestfmt - uses: GoTestTools/gotestfmt-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - version: v2.5.0 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-region: ${{ env.AWS_REGION }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 - role-session-name: aws@githubActions - role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - - name: Run provider tests - run: | - cd provider && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt - strategy: - fail-fast: false - matrix: - language: - - nodejs - - python - - dotnet - - go - - java upstream_lint: name: Run upstream provider-lint runs-on: ubuntu-latest diff --git a/.github/workflows/run-acceptance-tests.yml b/.github/workflows/run-acceptance-tests.yml index 579615f90dd..33d110083df 100644 --- a/.github/workflows/run-acceptance-tests.yml +++ b/.github/workflows/run-acceptance-tests.yml @@ -95,7 +95,6 @@ jobs: - build_provider - license_check - go_test_shim - - provider_test - upstream_lint runs-on: ubuntu-latest steps: @@ -179,7 +178,7 @@ jobs: aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} aws-region: ${{ env.AWS_REGION }} aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 + role-duration-seconds: 7200 role-session-name: aws@githubActions role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - name: Make upstream @@ -238,75 +237,6 @@ jobs: name: Upload coverage reports to Codecov uses: codecov/codecov-action@v4 timeout-minutes: 60 - provider_test: - name: provider_test - needs: build_sdk - permissions: - contents: read - id-token: write - runs-on: ubuntu-latest - steps: - - name: Free Disk Space (Ubuntu) - uses: jlumbroso/free-disk-space@main - with: - swap-storage: false - tool-cache: false - - name: Checkout Repo - uses: actions/checkout@v4 - with: - ref: ${{ env.PR_COMMIT_SHA }} - submodules: true - - uses: pulumi/provider-version-action@v1 - with: - set-env: PROVIDER_VERSION - - name: Setup tools - uses: ./.github/actions/setup-tools - with: - tools: pulumictl, pulumi, go, node, dotnet, python, java - - name: Prepare local workspace - run: make prepare_local_workspace - - name: Download bin - uses: ./.github/actions/download-bin - - name: Download SDK - uses: ./.github/actions/download-sdk - with: - language: ${{ matrix.language }} - - name: Restore makefile progress - run: make --touch provider schema build_${{ matrix.language }} - - name: Update path - run: echo "${{ github.workspace }}/bin" >> "$GITHUB_PATH" - - name: Install Python deps - run: |- - pip3 install virtualenv==20.0.23 - pip3 install pipenv - - name: Install dependencies - run: make install_${{ matrix.language}}_sdk - - name: Install gotestfmt - uses: GoTestTools/gotestfmt-action@v2 - with: - token: ${{ secrets.GITHUB_TOKEN }} - version: v2.5.0 - - name: Configure AWS Credentials - uses: aws-actions/configure-aws-credentials@v4 - with: - aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }} - aws-region: ${{ env.AWS_REGION }} - aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }} - role-duration-seconds: 3600 - role-session-name: aws@githubActions - role-to-assume: ${{ secrets.AWS_CI_ROLE_ARN }} - - name: Run provider tests - run: | - cd provider && go test -v -json -count=1 -cover -timeout 2h -tags=${{ matrix.language }} -parallel 4 . 2>&1 | tee /tmp/gotest.log | gotestfmt - strategy: - fail-fast: false - matrix: - language: - - nodejs - - python - - dotnet - - go - - java upstream_lint: name: Run upstream provider-lint runs-on: ubuntu-latest diff --git a/examples/examples_nodejs_test.go b/examples/examples_nodejs_test.go index dd2a14b3a9a..fddb5420765 100644 --- a/examples/examples_nodejs_test.go +++ b/examples/examples_nodejs_test.go @@ -1,12 +1,14 @@ -// Copyright 2016-2017, Pulumi Corporation. All rights reserved. +// Copyright 2016-2024, Pulumi Corporation. All rights reserved. //go:build nodejs || all // +build nodejs all package examples import ( + "archive/zip" "bytes" "context" + "crypto/rand" "encoding/json" "io" "os" @@ -23,7 +25,10 @@ import ( "github.com/aws/aws-sdk-go/service/s3" "github.com/pulumi/providertest/pulumitest" "github.com/pulumi/providertest/pulumitest/opttest" + "github.com/pulumi/pulumi-aws/provider/v6/pkg/elb" "github.com/pulumi/pulumi/pkg/v3/testing/integration" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -788,3 +793,400 @@ func TestAccEcrImage(t *testing.T) { integration.ProgramTest(t, &test) } + +func TestLambdaLayerNewUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("lambda-layer-new"), nodeProviderUpgradeOpts()) +} + +func TestCloudWatchUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("cloudwatch"), nodeProviderUpgradeOpts()) +} + +func TestLogGroupUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("logGroup"), nodeProviderUpgradeOpts()) +} + +func TestQueueUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("queue"), nodeProviderUpgradeOpts()) +} + +func TestRoute53Upgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("route53"), nodeProviderUpgradeOpts()) +} + +func TestJobQueueUpgrade(t *testing.T) { + opts := nodeProviderUpgradeOpts() + opts.setEnvRegion = false + opts.region = "us-west-2" // has to match the snapshot-recorded region + opts.extraOpts = []opttest.Option{ + opttest.Env("PULUMI_ENABLE_PLAN_RESOURCE_CHANGE", "true"), + } + testProviderUpgrade(t, filepath.Join("test-programs", "job-queue"), opts) +} + +func nodeProviderUpgradeOpts() *testProviderUpgradeOptions { + return &testProviderUpgradeOptions{ + linkNodeSDK: true, + installDeps: true, + setEnvRegion: true, + } +} + +func TestRegress3094(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "regress-3094") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + upResult := test.Up(t) + t.Logf("#%v", upResult.Summary) +} + +func TestRegress3835(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "regress-3835") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + result := test.Preview(t) + t.Logf("#%v", result.ChangeSummary) +} + +func TestChangingRegion(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "changing-region") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + } + + t.Run("default provider", func(t *testing.T) { + test := pulumitest.NewPulumiTest(t, dir, options...) + for _, region := range []string{"us-east-1", "us-west-1"} { + test.SetConfig(t, "aws:region", region) + res := test.Up(t) + require.Equal(t, region, res.Outputs["actualRegion"].Value) + } + }) + + t.Run("explicit provider", func(t *testing.T) { + test := pulumitest.NewPulumiTest(t, dir, options...) + for _, region := range []string{"us-east-1", "us-west-1"} { + test.SetConfig(t, "desired-region", region) + res := test.Up(t) + require.Equal(t, region, res.Outputs["actualRegion"].Value) + } + }) +} + +func TestRegressAttributeMustBeWholeNumber(t *testing.T) { + // pulumi/pulumi-terraform-bridge#1940 + skipIfShort(t) + dir := filepath.Join("test-programs", "ec2-string-for-int") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + result := test.Preview(t) + t.Logf("#%v", result.ChangeSummary) +} + +func TestRegress4079(t *testing.T) { + skipIfShort(t) + ctx := context.Background() + dir := filepath.Join("test-programs", "regress-4079") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + + test.SetConfig(t, "targetGroupCount", "2") + r1 := test.Up(t) + t.Logf("Stdout: %v", r1.StdOut) + t.Logf("Stderr: %v", r1.StdErr) + + listenerARN := r1.Outputs["listenerARN"].Value.(string) + err = elb.ModifyListenerDefaultActions(ctx, listenerARN, func(as []elb.Action) []elb.Action { + r := []elb.Action{} + for _, a := range as { + b := a + t.Logf("BEFORE: len(ForwardConfig.TargetGroups)=%d", len(b.ForwardConfig.TargetGroups)) + b.ForwardConfig.TargetGroups = []elb.TargetGroupTuple{ + b.ForwardConfig.TargetGroups[0], + } + t.Logf("AFTER: len(ForwardConfig.TargetGroups)=%d", len(b.ForwardConfig.TargetGroups)) + r = append(r, b) + } + return r + }) + require.NoError(t, err) + + rr := test.Refresh(t) + t.Logf("Stdout: %v", rr.StdOut) + t.Logf("Stderr: %v", rr.StdErr) + + refreshedState := test.ExportStack(t) + + type resource struct { + Type string `json:"type"` + Outputs map[string]any `json:"outputs"` + } + type deployment struct { + Resources []resource `json:"resources"` + } + var data deployment + err = json.Unmarshal(refreshedState.Deployment, &data) + require.NoError(t, err) + + for _, r := range data.Resources { + if r.Type != "aws:lb/listener:Listener" { + continue + } + defaultAction1 := r.Outputs["defaultActions"].([]any)[0].(map[string]any) + t.Logf("defaultActions includes: %#v", defaultAction1) + require.NotNil(t, defaultAction1["forward"], "forward should be set in defaultActions") + require.Emptyf(t, defaultAction1["targetGroupArn"], "targetGroupArn should be empty in defaultActions") + } +} + +func TestParallelLambdaCreation(t *testing.T) { + // This test is flaky and needs to be fixed. It occasionally fails to find the lambda zip archive + t.Skipf("TODO[pulumi/pulumi-aws#4731]") + if testing.Short() { + t.Skipf("Skipping test in -short mode because it needs cloud credentials") + return + } + + tempFile, err := createLambdaArchive(25 * 1024 * 1024) + require.NoError(t, err) + defer os.Remove(tempFile) + + maxDuration(5*time.Minute, t, func(t *testing.T) { + test := getJSBaseOptions(t). + With(integration.ProgramTestOptions{ + Dir: filepath.Join("test-programs", "parallel-lambdas"), + Config: map[string]string{ + "lambda:archivePath": tempFile, + }, + // Lambdas have diffs on every update (source code hash) + AllowEmptyPreviewChanges: true, + SkipRefresh: true, + }) + + integration.ProgramTest(t, &test) + }) +} + +func TestRegress4128(t *testing.T) { + if testing.Short() { + t.Skipf("Skipping test in -short mode because it needs cloud credentials") + return + } + + test := getJSBaseOptions(t). + With(integration.ProgramTestOptions{ + Dir: filepath.Join("test-programs", "regress-4128"), + SkipRefresh: true, + }, + ) + // Disable envRegion mangling + test.Config = nil + integration.ProgramTest(t, &test) +} + +func TestGameLift(t *testing.T) { + if testing.Short() { + t.Skipf("Skipping test in -short mode because it needs cloud credentials") + return + } + + ptest := pulumiTest(t, filepath.Join("test-programs", "gamelift-typescript")) + ptest.SetConfig(t, "customData", "A") + result1 := ptest.Up(t) + require.Equal(t, "A", result1.Outputs["CustomEventData"].Value) + ptest.SetConfig(t, "customData", "B") + result2 := ptest.Up(t) + require.Equal(t, "B", result2.Outputs["CustomEventData"].Value) +} + +func TestRegress4446(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "regress-4446") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + upResult := test.Up(t) + t.Logf("#%v", upResult.Summary) + result := test.Preview(t, optpreview.ExpectNoChanges()) + t.Logf("#%v", result.ChangeSummary) +} + +func TestRegress4568(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "regress-4568") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + upResult := test.Up(t) + t.Logf("#%v", upResult.Summary) + + // The singular lifecyclePolicy should contain the first value + assert.Equal(t, map[string]interface{}{ + "transitionToIa": "AFTER_30_DAYS", + "transitionToArchive": "", + "transitionToPrimaryStorageClass": "", + }, upResult.Outputs["lifecyclePolicy"].Value, "lifecyclePolicy should be set") + + // The plural lifecyclePolicies should contain both values + lifecyclePolicies := upResult.Outputs["lifecyclePolicies"].Value.([]interface{}) + assert.Len(t, lifecyclePolicies, 2, "lifecyclePolicies should have two elements") + + assert.Contains(t, lifecyclePolicies, map[string]interface{}{ + "transitionToIa": "AFTER_30_DAYS", + "transitionToArchive": "", + "transitionToPrimaryStorageClass": "", + }) + assert.Contains(t, lifecyclePolicies, map[string]interface{}{ + "transitionToPrimaryStorageClass": "AFTER_1_ACCESS", + "transitionToIa": "", + "transitionToArchive": "", + }) +} + +// Tests that there are no diagnostics by default on simple programs. +func TestNoExtranousLogOutput(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "bucket-obj") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + result := test.Preview(t) + assert.NotContainsf(t, result.StdOut, "Diagnostics:", + "No diagnostics should be emitted to stdout for simple programs") + assert.NotContainsf(t, result.StdErr, "Diagnostics:", + "No diagnostics should be emitted to stderr for simple programs") +} + +// Since AWS is doing something non-standard with logging, double-check that `log.Printf` messages do get propagated +// when TF_LOG=DEBUG is set. One such message is set by aws.s3.Bucketv2 when refresh finds that the bucket no longer +// exists. Emulate this situation and assert that the message has propagated. +func TestUpstreamWarningsPropagated(t *testing.T) { + skipIfShort(t) + dir := filepath.Join("test-programs", "disappearing-bucket-object") + cwd, err := os.Getwd() + require.NoError(t, err) + providerName := "aws" + options := []opttest.Option{ + opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), + opttest.YarnLink("@pulumi/aws"), + opttest.Env("TF_LOG", "DEBUG"), + } + test := pulumitest.NewPulumiTest(t, dir, options...) + + t.Logf("Creating the bucket object") + test.Up(t) + + state := test.ExportStack(t) + + t.Logf("Deleting the bucket object") + test.SetConfig(t, "bucket-object", "exclude") + test.Up(t) + + t.Logf("Resetting the state back") + test.ImportStack(t, state) + + t.Logf("Refreshing the stack and expecting bucket to be deleted from the state") + rr := test.Refresh(t) + t.Logf("%v%v", rr.StdOut, rr.StdErr) + + // Upstream code has this line: + // + // log.Printf("[WARN] S3 Object (%s) not found, removing from state", d.Id()) + // + assert.Containsf(t, + rr.StdErr+rr.StdOut, + "warning: S3 Object (index.ts) not found, removing from state", + "Expected upstream log.Printf to propagate under TF_LOG=DEBUG") +} + +func createLambdaArchive(size int64) (string, error) { + // Create a temporary file to save the zip archive + tempFile, err := os.CreateTemp("", "archive-*.zip") + if err != nil { + return "", err + } + defer tempFile.Close() + + // Create a new zip archive + zipWriter := zip.NewWriter(tempFile) + defer func() { + err := zipWriter.Close() + contract.AssertNoErrorf(err, "Failed closing zip archive") + err = tempFile.Close() + contract.AssertNoErrorf(err, "Failed closing temporary file") + }() + + randomDataReader := io.LimitReader(rand.Reader, size) + + // Create the index.js file for the lambda + indexWriter, err := zipWriter.Create("index.js") + if err != nil { + return "", err + } + _, err = indexWriter.Write([]byte("const { version } = require(\"@aws-sdk/client-s3/package.json\");\n\nexports.handler = async () => ({ version });\n")) + if err != nil { + return "", err + } + + randomDataWriter, err := zipWriter.Create("random.txt") + if err != nil { + return "", err + } + _, err = io.Copy(randomDataWriter, randomDataReader) + if err != nil { + return "", err + } + + // Get the path of the temporary file + archivePath, err := filepath.Abs(tempFile.Name()) + if err != nil { + return "", err + } + + return archivePath, nil +} diff --git a/examples/examples_py_test.go b/examples/examples_py_test.go index a30dc421155..03625401d6b 100644 --- a/examples/examples_py_test.go +++ b/examples/examples_py_test.go @@ -1,19 +1,24 @@ -// Copyright 2016-2017, Pulumi Corporation. All rights reserved. +// Copyright 2016-2024, Pulumi Corporation. All rights reserved. //go:build python || all // +build python all package examples import ( + "bytes" "context" "os" "path/filepath" + "strings" "testing" + "time" "github.com/aws/aws-sdk-go-v2/config" iamsdk "github.com/aws/aws-sdk-go-v2/service/iam" "github.com/pulumi/pulumi/pkg/v3/testing/integration" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview" "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" ) func TestAccBucketPy(t *testing.T) { @@ -117,7 +122,94 @@ func TestRegress4031(t *testing.T) { integration.ProgramTest(t, &test) } +func TestRegress3196(t *testing.T) { + if testing.Short() { + t.Skipf("Skipping test in -short mode because it needs cloud credentials") + return + } + maxDuration(6*time.Minute, t, func(t *testing.T) { + test := getPythonBaseOptions(t). + With(integration.ProgramTestOptions{ + Quick: true, + SkipRefresh: true, + Dir: filepath.Join("test-programs", "regress-3196"), + ExpectFailure: true, + }) + integration.ProgramTest(t, &test) + }) +} + +func TestRegress3887(t *testing.T) { + if testing.Short() { + t.Skipf("Skipping test in -short mode because it needs cloud credentials") + return + } + test := getPythonBaseOptions(t). + With(integration.ProgramTestOptions{ + Quick: true, + SkipRefresh: true, + Dir: filepath.Join("test-programs", "regress-3887"), + EditDirs: []integration.EditDir{ + { + Dir: filepath.Join("test-programs", "regress-3887", "step-1"), + Additive: true, + }, + { + Dir: filepath.Join("test-programs", "regress-3887", "step-2"), + Additive: true, + }, + }, + }) + integration.ProgramTest(t, &test) +} + +// Make sure that importing an AWS targetGroup succeeds. +func TestRegress2534(t *testing.T) { + ptest := pulumiTest(t, filepath.Join("test-programs", "regress-2534")) + upResult := ptest.Up(t) + targetGroupArn := upResult.Outputs["targetGroupArn"].Value.(string) + targetGroupUrn := upResult.Outputs["targetGroupUrn"].Value.(string) + workspace := ptest.CurrentStack().Workspace() + t.Logf("Provisioned target group with arn=%s", targetGroupArn) + workdir := workspace.WorkDir() + t.Logf("workdir = %s", workdir) + + execPulumi(t, ptest, workdir, "import", "aws:lb/targetGroup:TargetGroup", "newtg", targetGroupArn, "--yes") + execPulumi(t, ptest, workdir, "state", "unprotect", strings.ReplaceAll(targetGroupUrn, "::test", "::newtg"), "--yes") +} + +func TestRegress4457(t *testing.T) { + ptest := pulumiTest(t, filepath.Join("test-programs", "regress-4457")) + upResult := ptest.Up(t) + autoGroupArn := upResult.Outputs["autoGroupArn"].Value.(string) + autoGroupUrn := upResult.Outputs["autoGroupUrn"].Value.(string) + autoGroupName := upResult.Outputs["autoGroupName"].Value.(string) + workspace := ptest.CurrentStack().Workspace() + + t.Logf("Provisioned autoscaling group with arn=%s and urn=%s and name=%s", autoGroupArn, autoGroupUrn, autoGroupName) + workdir := workspace.WorkDir() + t.Logf("workdir = %s", workdir) + + importResult := ptest.Import(t, "aws:autoscaling/group:Group", "newag", autoGroupName, "" /* providerUrn */) + + t.Logf("Editing the program to add the code recommended by import") + i := strings.Index(importResult.Stdout, "import pulumi") + extraCode := importResult.Stdout[i:] + mainPy := filepath.Join(ptest.WorkingDir(), "__main__.py") + pyBytes, err := os.ReadFile(mainPy) + require.NoError(t, err) + updatedPyBytes := bytes.ReplaceAll(pyBytes, []byte("# EXTRA CODE HERE"), []byte(extraCode)) + err = os.WriteFile(mainPy, updatedPyBytes, 0600) + require.NoError(t, err) + + t.Logf("Previewing the edited program") + previewResult := ptest.Preview(t, optpreview.ExpectNoChanges()) + t.Logf("%s", previewResult.StdOut) + t.Logf("%s", previewResult.StdErr) +} + func getPythonBaseOptions(t *testing.T) integration.ProgramTestOptions { + t.Helper() envRegion := getEnvRegion(t) pythonBase := integration.ProgramTestOptions{ Config: map[string]string{ diff --git a/examples/examples_yaml_test.go b/examples/examples_yaml_test.go index f7cc0d79437..5d0a9c9fd16 100644 --- a/examples/examples_yaml_test.go +++ b/examples/examples_yaml_test.go @@ -1,4 +1,4 @@ -// Copyright 2016-2023, Pulumi Corporation. +// Copyright 2016-2024, Pulumi Corporation. // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. @@ -12,24 +12,46 @@ // See the License for the specific language governing permissions and // limitations under the License. -//go:build nodejs || all -// +build nodejs all +//go:build java || all +// +build java all package examples // NOTE about build tags: CI does not understand yaml-specific tags yet, but splits builds per language to run on -// separate runners. This file piggy-backs on the nodejs tag so yaml tests will run on the same runner as node tests. +// separate runners. This file piggy-backs on the java tag so yaml tests will run on the same runner as java tests. import ( + "bytes" + "context" "fmt" + "io" + "math/rand" "os" + "os/exec" "path/filepath" + "runtime" "sort" "strconv" "strings" "testing" + "github.com/aws/aws-sdk-go-v2/aws" + "github.com/aws/aws-sdk-go-v2/config" + appconfigsdk "github.com/aws/aws-sdk-go-v2/service/appconfig" + tagsdk "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi" + s3sdk "github.com/aws/aws-sdk-go-v2/service/s3" + "github.com/aws/aws-sdk-go-v2/service/s3/types" + "github.com/pulumi/providertest/pulumitest" + "github.com/pulumi/providertest/pulumitest/assertpreview" + "github.com/pulumi/providertest/pulumitest/opttest" "github.com/pulumi/pulumi/pkg/v3/testing/integration" + "github.com/pulumi/pulumi/sdk/v3/go/auto" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optrefresh" + "github.com/pulumi/pulumi/sdk/v3/go/auto/optup" + "github.com/pulumi/pulumi/sdk/v3/go/common/apitype" + "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" + "github.com/pulumi/pulumi/sdk/v3/go/pulumi" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) @@ -45,6 +67,1012 @@ func TestAccPluginFramework(t *testing.T) { integration.ProgramTest(t, &test) } +func TestBucketUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "bucket"), nil) +} + +func TestEKSClusterUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "eks-cluster"), nil) +} + +func TestRdsInstanceUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "rds-instance"), nil) +} + +func TestRoute53ResolverEndpointUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "route53-resolver-endpoint"), nil) +} + +func TestSnsTopicUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "sns-topic"), nil) +} + +func TestApiGatewayIntegrationResponseUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "apigateway-integrationresponse"), nil) +} + +func TestApiGatewayMethodResponseUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "apigateway-methodreponse"), nil) +} + +func TestApiGatewayResourceUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "apigateway-resource"), nil) +} + +func TestApiGatewayResourceResponseUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "apigateway-resource-response"), nil) +} + +func TestCloudwatchEventRuleUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "cloudwatch-eventrule"), nil) +} + +func TestCloudwatchLogGroupUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "cloudwatch-loggroup"), nil) +} + +func TestDynamoTableUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "dynamodb-table"), nil) +} + +func TestEcrLifecyclePolicyUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "ecr-lifecyclepolicy"), nil) +} + +func TestEcrRepositoryUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "ecr-repository"), nil) +} + +func TestIamInstanceProfileUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "iam-instanceprofile"), nil) +} + +func TestIamOpenIDConnectProviderUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "iam-openidconnectprovider"), nil) +} + +func TestKmsKeyUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "kms-key"), nil) +} + +func TestSecretsManagerSecretUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "secretsmanager-secret"), nil) +} + +func TestEC2NetworkingUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "ec2-networking"), nil) +} + +func TestECSServiceUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "ecs-service"), nil) +} + +func TestIAMUserUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "iam-user"), nil) +} + +func TestLBUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "lb"), nil) +} + +func TestACMUpgrade(t *testing.T) { + t.Skip("Blocked by https://github.com/pulumi/pulumi-aws/issues/3617") + testProviderUpgrade(t, filepath.Join("test-programs", "acm"), nil) +} + +func TestBucketObjUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "bucket-obj"), nil) +} + +func TestSubnetGroupUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "subnet-group"), nil) +} + +func TestEC2InstanceUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "ec2-instance"), nil) +} + +func TestCloudfrontDistributionUpgrade(t *testing.T) { + // Baseline version is needed because of https://github.com/pulumi/providertest/issues/76 + testProviderUpgrade(t, filepath.Join("test-programs", "cloudfront-distribution"), &testProviderUpgradeOptions{ + baselineVersion: "6.10.0", + }) +} + +func TestSecretVersionUpgrade(t *testing.T) { + testProviderUpgrade(t, filepath.Join("test-programs", "secretversion"), nil) +} + +func TestRdsParameterGroupUnclearDiff(t *testing.T) { + t.Parallel() + if testing.Short() { + t.Skipf("Skipping in testing.Short() mode, assuming this is a CI run without credentials") + } + + type yamlProgram string + + const yaml yamlProgram = ` +name: project +runtime: yaml +config: + applyMethod: + type: string + value: + type: string + randSuffix: + type: string +resources: + default: + type: aws:rds/parameterGroup:ParameterGroup + properties: + name: securitygroup${randSuffix} + family: postgres14 + parameters: + - name: track_io_timing + value: ${value} + applyMethod: ${applyMethod} + - name: "log_checkpoints" + applyMethod: "pending-reboot" + value: "1" +` + + const noApplyYaml yamlProgram = ` +name: project +runtime: yaml +config: + value: + type: string + randSuffix: + type: string +resources: + default: + type: aws:rds/parameterGroup:ParameterGroup + properties: + name: securitygroup${randSuffix} + family: postgres14 + parameters: + - name: track_io_timing + value: ${value} + - name: "log_checkpoints" + applyMethod: "pending-reboot" + value: "1" +` + + type applyMethod string + + var immediate applyMethod = "immediate" + var pendingReboot applyMethod = "pending-reboot" + + type testCase struct { + name string + applyMethod1 *applyMethod + value1 string + file1 yamlProgram + applyMethod2 *applyMethod + value2 string + file2 yamlProgram + expectChanges bool + } + + testCases := []testCase{ + {"non-nil apply method, apply method change", &immediate, "1", yaml, &pendingReboot, "1", yaml, false}, + {"non-nil apply method, value change", &immediate, "1", yaml, &immediate, "0", yaml, true}, + {"non-nil apply method, both change", &immediate, "1", yaml, &pendingReboot, "0", yaml, true}, + {"non-nil to nil apply method, apply method change", &pendingReboot, "1", yaml, nil, "1", noApplyYaml, false}, + {"non-nil to nil apply method, value change", &immediate, "1", yaml, nil, "0", noApplyYaml, true}, + {"non-nil to nil apply method, both change", &immediate, "1", yaml, nil, "0", noApplyYaml, true}, + {"nil to non-nil apply method, apply method change", nil, "1", noApplyYaml, &pendingReboot, "1", yaml, false}, + {"nil to non-nil apply method, value change", nil, "1", noApplyYaml, &immediate, "0", yaml, true}, + {"nil to non-nil apply method, both change", nil, "1", noApplyYaml, &immediate, "0", yaml, true}, + {"nil apply method, value change", nil, "1", noApplyYaml, nil, "0", noApplyYaml, true}, + } + + cwd, err := os.Getwd() + require.NoError(t, err) + + for _, tc := range testCases { + tc := tc + + t.Run(tc.name, func(t *testing.T) { + t.Parallel() + workdir := t.TempDir() + + err := os.WriteFile(filepath.Join(workdir, "Pulumi.yaml"), []byte(tc.file1), 0o600) + require.NoError(t, err) + + pt := pulumitest.NewPulumiTest(t, workdir, + opttest.SkipInstall(), + opttest.TestInPlace(), + opttest.LocalProviderPath("aws", filepath.Join(cwd, "..", "bin")), + ) + + pt.SetConfig(t, "randSuffix", fmt.Sprintf("%d-x", rand.Intn(1024*1024))) + + if tc.applyMethod1 != nil { + pt.SetConfig(t, "applyMethod", string(*tc.applyMethod1)) + } + pt.SetConfig(t, "value", tc.value1) + + pt.Up(t) + + assertpreview.HasNoChanges(t, pt.Preview(t)) + + err = os.WriteFile(filepath.Join(workdir, "Pulumi.yaml"), []byte(tc.file2), 0o600) + require.NoError(t, err) + + if tc.applyMethod2 != nil { + if tc.file2 == noApplyYaml { + t.Errorf("WRONG FILE!") + } + pt.SetConfig(t, "applyMethod", string(*tc.applyMethod2)) + } + pt.SetConfig(t, "value", tc.value2) + + if tc.expectChanges { + pr := pt.Preview(t) + assert.Equal(t, 1, pr.ChangeSummary[apitype.OpUpdate]) + } else { + assertpreview.HasNoChanges(t, pt.Preview(t)) + } + + upr := pt.Up(t) + t.Logf("stdout: %s", upr.StdOut) + t.Logf("stderr: %s", upr.StdErr) + + assertpreview.HasNoChanges(t, pt.Preview(t)) + }) + } +} + +var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") + +func randSeq(n int) string { + b := make([]rune, n) + for i := range b { + b[i] = letters[rand.Intn(len(letters))] + } + return string(b) +} + +func TestNonIdempotentSnsTopic(t *testing.T) { + t.Parallel() + ptest := pulumiTest(t, filepath.Join("test-programs", "non-idempotent-sns-topic"), opttest.SkipInstall()) + + ptest.InstallStack(t, "test") + // generate random name + topic_name := randSeq(12) + ptest.SetConfig(t, "snsTopicName", topic_name) + + _, err := ptest.CurrentStack().Up(ptest.Context()) + require.ErrorContains(t, err, "already exists") +} + +func TestOpenZfsFileSystemUpgrade(t *testing.T) { + t.Parallel() + if testing.Short() { + t.Skipf("Skipping in testing.Short() mode, assuming this is a CI run without credentials") + } + const pulumiYaml = ` +name: openzfs +runtime: yaml +resources: + MyFileSystem: + properties: + deploymentType: SINGLE_AZ_1 + storageCapacity: 64 + %s + throughputCapacity: 64 + type: aws:fsx:OpenZfsFileSystem + MySubnet: + properties: + cidrBlock: "10.0.1.0/24" + vpcId: ${MyVPC.id} + type: aws:ec2:Subnet + MyVPC: + properties: + cidrBlock: "10.0.0.0/16" + type: aws:ec2:Vpc +` + + var ( + providerName string = "aws" + baselineVersion string = "6.41.0" + ) + cwd, err := os.Getwd() + assert.NoError(t, err) + workdir := t.TempDir() + + firstProgram := []byte(fmt.Sprintf(pulumiYaml, "subnetIds: ${MySubnet.id}")) + secondProgram := []byte(fmt.Sprintf(pulumiYaml, "subnetIds:\n - ${MySubnet.id}")) + // test that we can upgrade from the previous version which accepted a string for `subnetIds` + // to the new version which accepts a list + t.Run("upgrade", func(t *testing.T) { + pulumiTest := testProviderCodeChanges(t, &testProviderCodeChangesOptions{ + firstProgram: firstProgram, + firstProgramOptions: []opttest.Option{ + opttest.DownloadProviderVersion(providerName, baselineVersion), + }, + secondProgram: secondProgram, + secondProgramOptions: []opttest.Option{ + opttest.LocalProviderPath("aws", filepath.Join(cwd, "..", "bin")), + }, + }) + + res := pulumiTest.Preview(t) + t.Logf("stdout: %s \n", res.StdOut) + t.Logf("stderr: %s \n", res.StdErr) + assertpreview.HasNoChanges(t, res) + + upResult := pulumiTest.Up(t) + t.Logf("stdout: %s \n", upResult.StdOut) + t.Logf("stderr: %s \n", upResult.StdErr) + }) + + // test that we can deploy a new filesystem with a list of subnetIds + // we use a test with a snapshot since this test is only useful the first time, once + // we know it works it should continue to work. + t.Run("new-version", func(t *testing.T) { + t.Parallel() + err = os.WriteFile(filepath.Join(workdir, "Pulumi.yaml"), secondProgram, 0o600) + assert.NoError(t, err) + pulumiTest := pulumitest.NewPulumiTest(t, workdir, + opttest.SkipInstall(), + opttest.LocalProviderPath("aws", filepath.Join(cwd, "..", "bin")), + ) + + pulumiTest.SetConfig(t, "aws:region", "us-east-2") + + pulumiUpWithSnapshot(t, pulumiTest) + }) +} + +// Make sure that legacy Bucket supports deleting tags out of band and detecting drift. +func TestRegress3674(t *testing.T) { + t.Parallel() + ptest := pulumiTest(t, filepath.Join("test-programs", "regress-3674"), opttest.SkipInstall()) + upResult := ptest.Up(t) + bucketName := upResult.Outputs["bucketName"].Value.(string) + deleteBucketTagging(ptest.Context(), bucketName) + result := ptest.Refresh(t) + t.Logf("%s", result.StdOut) + require.Equal(t, 1, (*result.Summary.ResourceChanges)["update"]) + state, err := ptest.ExportStack(t).Deployment.MarshalJSON() + require.NoError(t, err) + require.NotContainsf(t, string(state), "MyTestTag", "Expected MyTestTag to be removed") +} + +// Ensure that pulumi-aws can authenticate using IMDS API when Pulumi is running in a context where that is made +// available such as an EC2 instance. +func TestIMDSAuth(t *testing.T) { + t.Parallel() + var localProviderBuild string + actual := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) + expected := "linux/amd64" + cwd, err := os.Getwd() + require.NoError(t, err) + if actual == expected { + currentBinary, err := filepath.Abs(filepath.Join(cwd, "..", "bin", "pulumi-resource-aws")) + require.NoError(t, err) + t.Logf("Reusing prebuilt binary from %s to test %q", currentBinary, expected) + localProviderBuild = currentBinary + } else { + t.Logf("Cross-compiling provider-resource-aws under test to %q", expected) + localProviderBuild = filepath.Join(os.TempDir(), "pulumi-resource-aws") + ldFlags := []string{ + "-X", "github.com/pulumi/pulumi-aws/provider/v6/pkg/version.Version=6.0.0-alpha.0+dev", + "-X", "github.com/hashicorp/terraform-provider-aws/version.ProviderVersion=6.0.0-alpha.0+dev", + } + args := []string{ + "build", "-o", localProviderBuild, + "-ldflags", strings.Join(ldFlags, " "), + } + cmd := exec.Command("go", args...) + cmd.Dir = filepath.Join(cwd, "cmd", "pulumi-resource-aws") + cmd.Env = os.Environ() + cmd.Env = append(cmd.Env, + fmt.Sprintf("GOOS=linux"), + fmt.Sprintf("GOARCH=amd64"), + ) + var stderr, stdout bytes.Buffer + cmd.Stderr = &stderr + cmd.Stdout = &stdout + if err := cmd.Run(); err != nil { + t.Logf("go %s failed\nStdout:\n%s\nStderr:\n%s\n", strings.Join(args, " "), + stdout.String(), stderr.String()) + require.NoError(t, err) + } + } + t.Run("IDMSv2", func(t *testing.T) { + t.Parallel() + ptest := pulumiTest(t, filepath.Join("test-programs", "imds-auth", "imds-v2"), opttest.SkipInstall()) + dir := ptest.WorkingDir() + localLocation := filepath.Join(dir, "pulumi-resource-aws") + // need to copy the provider to the local directory for BucketObjectV2 to pick it up + // otherwise you get an error `Argument must be a constant or contained in the project dir` + err := copyFile(localProviderBuild, localLocation) + assert.NoError(t, err) + ptest.SetConfig(t, "localProviderBuild", localLocation) + result := ptest.Up(t) + t.Logf("stdout: %s", result.StdOut) + t.Logf("stderr: %s", result.StdErr) + t.Logf("commandOut: %v", result.Outputs["commandOut"].Value) + }) +} + +func copyFile(src, dst string) error { + srcFile, err := os.Open(src) + if err != nil { + return err + } + defer srcFile.Close() + + dstFile, err := os.Create(dst) + if err != nil { + return err + } + defer dstFile.Close() + + _, err = io.Copy(dstFile, srcFile) + if err != nil { + return err + } + + err = dstFile.Sync() + return err +} + +// Assert that the provider does not regress on emitting an unexpected deprecation. +// +// use the aws_s3_object resource instead +// +// See https://github.com/pulumi/pulumi-aws/issues/2796 +func TestS3BucketObjectDeprecation(t *testing.T) { + t.Parallel() + ptest := pulumiTest(t, filepath.Join("test-programs", "regress-2796"), opttest.SkipInstall()) + result := ptest.Up(t) + t.Logf("STDOUT: %v", result.StdOut) + t.Logf("STDERR: %v", result.StdErr) + require.NotContains(t, result.StdOut+result.StdErr, "aws_s3_object") +} + +type tagsTestStep struct { + // The name of the Pulumi program + name string + + // The type token of the resource, i.e. aws:s3:Bucket + token string + + // The pulumi type of the resource, i.e. aws:s3/bucket:Bucket + typ string + + // Constant properties for the primary resource under test. + // + // This cannot include the tags property, which will be adjusted by the test. + properties map[string]interface{} + + // List of tags to add to the resource + tags map[string]interface{} + + // List of default tags to add to the provider + defaultTags map[string]interface{} + + // List of tag keys to add to the provider `ignoreTags.Keys` property + ignoreTagKeys []string + + // Function to run prior to _any_ import step + preImportHook func(t *testing.T, outputs auto.OutputMap) + + // Function to run after running the first up. This can be used to + // run extra validation + postUpHook func(t *testing.T, outputs auto.OutputMap) + + // Other is a string that is inserted into the test program. It is intended to be + // used to provision supporting resources in tests. + other string + + // If skip is non-empty, the test will be skipped with `skip` as the given reason. + skip string +} + +// TestAccDefaultTags tries to test all the scenarios that might affect provider defaultTags / resource tags +// i.e. up, refresh, preview, import, etc +func TestAccDefaultTagsWithImport(t *testing.T) { + t.Parallel() + if testing.Short() { + t.Skipf("Skipping in testing.Short() mode, assuming this is a CI run without credentials") + } + + isNil := func(val interface{}) bool { + if val == nil { + return true + } + v, ok := val.(map[string]interface{}) + return ok && len(v) == 0 + } + validateOutputTags := func(outputs auto.OutputMap, expectedTags map[string]interface{}) { + stackOutputTags := outputs["actual"] + if !isNil(expectedTags) || !isNil(stackOutputTags) { + assert.Equal(t, expectedTags, stackOutputTags.Value) + } + } + + steps := []tagsTestStep{ + // Pulumi maintains it's own version of aws:s3:Bucket in + // `s3legacy/bucket_legacy.go`. Because we don't have any + // terraform-provider-aws maintainers to ensure our tagging works the same + // way as other resource's tagging, we give our own bucket special testing + // to make sure that tags work. + { + name: "legacy", token: "aws:s3:Bucket", typ: "aws:s3/bucket:Bucket", + tags: map[string]interface{}{ + "LocalTag": "foo", + }, + defaultTags: map[string]interface{}{ + "GlobalTag": "bar", + }, + postUpHook: func(t *testing.T, outputs auto.OutputMap) { + validateOutputTags(outputs, map[string]interface{}{ + "LocalTag": "foo", + "GlobalTag": "bar", + }) + bucketName := outputs["id"].Value.(string) + tags := getBucketTagging(context.Background(), bucketName) + assert.Equal(t, tags, []types.Tag{ + { + Key: pulumi.StringRef("LocalTag"), + Value: pulumi.StringRef("foo"), + }, + { + Key: pulumi.StringRef("GlobalTag"), + Value: pulumi.StringRef("bar"), + }, + }) + }, + }, + { + name: "legacy_ignore_tags", token: "aws:s3:Bucket", typ: "aws:s3/bucket:Bucket", + tags: map[string]interface{}{ + "LocalTag": "foo", + }, + ignoreTagKeys: []string{"IgnoreKey"}, + preImportHook: func(t *testing.T, outputs auto.OutputMap) { + t.Helper() + resArn := outputs["resArn"].Value.(string) + addResourceTags(context.Background(), resArn, map[string]string{ + "IgnoreKey": "foo", + }) + }, + defaultTags: map[string]interface{}{ + "GlobalTag": "bar", + }, + postUpHook: func(t *testing.T, outputs auto.OutputMap) { + validateOutputTags(outputs, map[string]interface{}{ + "LocalTag": "foo", + "GlobalTag": "bar", + }) + }, + }, + + // Both aws:cognito:UserPool and aws:s3:BucketV2 are full SDKv2 resources managed + // by Terraform, but they have different requirements for successful tag + // interactions. That is why we have tests for both resources. + { + name: "bucket", token: "aws:s3:BucketV2", typ: "aws:s3/bucketV2:BucketV2", + tags: map[string]interface{}{ + "LocalTag": "foo", + }, + postUpHook: func(t *testing.T, outputs auto.OutputMap) { + validateOutputTags(outputs, map[string]interface{}{ + "LocalTag": "foo", + "GlobalTag": "bar", + }) + }, + defaultTags: map[string]interface{}{ + "GlobalTag": "bar", + }, + }, + { + name: "bucket_ignore_tags", token: "aws:s3:BucketV2", typ: "aws:s3/bucketV2:BucketV2", + tags: map[string]interface{}{ + "LocalTag": "foo", + }, + postUpHook: func(t *testing.T, outputs auto.OutputMap) { + validateOutputTags(outputs, map[string]interface{}{ + "LocalTag": "foo", + "GlobalTag": "bar", + }) + }, + defaultTags: map[string]interface{}{ + "GlobalTag": "bar", + }, + ignoreTagKeys: []string{"IgnoreKey"}, + preImportHook: func(t *testing.T, outputs auto.OutputMap) { + t.Helper() + resArn := outputs["resArn"].Value.(string) + addResourceTags(context.Background(), resArn, map[string]string{ + "IgnoreKey": "foo", + }) + }, + }, + { + name: "sdkv2", token: "aws:cognito:UserPool", typ: "aws:cognito/userPool:UserPool", + tags: map[string]interface{}{ + "LocalTag": "foo", + }, + defaultTags: map[string]interface{}{ + "GlobalTag": "bar", + }, + postUpHook: func(t *testing.T, outputs auto.OutputMap) { + validateOutputTags(outputs, map[string]interface{}{ + "LocalTag": "foo", + "GlobalTag": "bar", + }) + }, + properties: map[string]interface{}{ + // aliasAttributes is necessary because otherwise we don't + // see a clean initial refresh + "aliasAttributes": []interface{}{"email"}, + }, + }, + + // A PF resource (appconfig:Environment) + // PF resources deal with tags differently + { + name: "pf", token: "aws:appconfig:Environment", typ: "aws:appconfig/environment:Environment", + tags: map[string]interface{}{ + "LocalTag": "foo", + }, + defaultTags: map[string]interface{}{ + "GlobalTag": "bar", + }, + postUpHook: func(t *testing.T, outputs auto.OutputMap) { + validateOutputTags(outputs, map[string]interface{}{ + "LocalTag": "foo", + "GlobalTag": "bar", + }) + }, + other: ` + app: + type: aws:appconfig:Application`, + properties: map[string]interface{}{ + "applicationId": "${app.id}", + }, + }, + { + name: "pf_ignore_tags", token: "aws:appconfig:Environment", typ: "aws:appconfig/environment:Environment", + tags: map[string]interface{}{ + "LocalTag": "foo", + }, + ignoreTagKeys: []string{"IgnoreKey"}, + preImportHook: func(t *testing.T, outputs auto.OutputMap) { + t.Helper() + resArn := outputs["resArn"].Value.(string) + addResourceTags(context.Background(), resArn, map[string]string{ + "IgnoreKey": "foo", + }) + }, + defaultTags: map[string]interface{}{ + "GlobalTag": "bar", + }, + postUpHook: func(t *testing.T, outputs auto.OutputMap) { + validateOutputTags(outputs, map[string]interface{}{ + "LocalTag": "foo", + "GlobalTag": "bar", + }) + }, + other: ` + app: + type: aws:appconfig:Application`, + properties: map[string]interface{}{ + "applicationId": "${app.id}", + }, + }, + } + + for _, step := range steps { + step := step + t.Run(step.name, func(t *testing.T) { + t.Parallel() + if reason := step.skip; reason != "" { + t.Skipf(reason) + } + testTagsPulumiLifecycle(t, step) + }) + } +} + +func TestAssumeRoleSessionTags(t *testing.T) { + t.Parallel() + ptest := pulumiTest(t, filepath.Join("test-programs", "assume-role-session-tags"), opttest.SkipInstall()) + result := ptest.Up(t) + t.Logf("STDOUT: %v", result.StdOut) + t.Logf("STDERR: %v", result.StdErr) + + require.Contains(t, result.Outputs, "bucketArn") + assert.NotEmpty(t, result.Outputs["bucketArn"].Value.(string)) +} + +// testTagsPulumiLifecycle tests the complete lifecycle of a pulumi program +// Scenarios that this tests: +// 1. `Up` with both provider `defaultTags`/`ignoreTags` and resource level `tags` +// 1a. Run validations on result +// 2. `Refresh` with no changes +// 3. `Import` using the resource option. Ensures resource can be successfully imported +// 3a. Allows for a hook to be run prior to import being run. e.g. Add tags remotely +// 4. `Import` using the CLI. Ensures resources can be successfully imported +// 4a. Allows for a hook to be run prior to import being run. e.g. Add tags remotely +// 5. `Refresh` with no changes +func testTagsPulumiLifecycle(t *testing.T, step tagsTestStep) { + t.Helper() + ctx := context.Background() + + stepDir, err := os.MkdirTemp(os.TempDir(), step.name) + assert.NoError(t, err) + fpath := filepath.Join(stepDir, "Pulumi.yaml") + + generateTagsTest(t, step, fpath, "") + ptest := pulumiTest(t, stepDir, opttest.TestInPlace(), opttest.SkipInstall()) + stack := ptest.CurrentStack() + + t.Log("Initial deployment...") + upRes, err := stack.Up(ctx) + assert.NoError(t, err) + outputs := upRes.Outputs + urn := outputs["urn"].Value.(string) + id := outputs["id"].Value.(string) + providerUrn := outputs["providerUrn"].Value.(string) + if step.postUpHook != nil { + step.postUpHook(t, outputs) + } + + t.Log("refresh...") + _, err = stack.Refresh(ctx, optrefresh.ExpectNoChanges()) + assert.NoError(t, err) + + t.Log("delete state...") + execPulumi(t, ptest, stepDir, "state", "delete", urn) + + // import using the import resource option + t.Log("up with import...") + if step.preImportHook != nil { + step.preImportHook(t, outputs) + } + generateTagsTest(t, step, fpath, id) + upRes, err = stack.Up(ctx, optup.Diff()) + assert.NoError(t, err) + changes := *upRes.Summary.ResourceChanges + assert.Equal(t, 1, changes["import"]) + + t.Log("delete state...") + execPulumi(t, ptest, stepDir, "state", "delete", urn) + + t.Log("import from cli...") + if step.preImportHook != nil { + step.preImportHook(t, outputs) + } + generateTagsTest(t, step, fpath, "") + execPulumi(t, ptest, stepDir, "import", step.typ, "res", id, "--provider", fmt.Sprintf("aws-provider=%s", providerUrn), "--yes") + execPulumi(t, ptest, stepDir, "state", "unprotect", urn, "--yes") + + // need to run an up to fix the state. It should be a no-op + // re https://github.com/pulumi/pulumi-aws/issues/4204 + upRes, err = stack.Up(ctx) + assert.NoError(t, err) + for k := range *upRes.Summary.ResourceChanges { + if k != "same" { + t.Fatal("expected no changes") + } + } + + t.Log("preview with refresh...") + _, err = stack.Preview(ctx, optpreview.Refresh(), optpreview.ExpectNoChanges()) + assert.NoError(t, err) +} + +// generateTagsTest generates a pulumi program for the given test step +// and writes it to the test directory +func generateTagsTest(t *testing.T, step tagsTestStep, testPath string, importId string) { + template := `name: test-aws-%s +runtime: yaml +resources: + aws-provider: + type: pulumi:providers:aws%s%s + res: + type: %s%s%s +outputs: + actual: ${res.tags} + urn: ${res.urn} + id: ${res.id} + resArn: ${res.arn} + providerUrn: ${aws-provider.urn}` + + options := map[string]interface{}{ + "provider": "${aws-provider}", + } + + if importId != "" { + options["import"] = importId + } + + var expandMap func(level int, v interface{}) string + expandMap = func(level int, v interface{}) string { + indent := "\n" + strings.Repeat(" ", level) + + var body string + switch v := v.(type) { + case nil: + return "" + case string: + body = v + case []string: + for _, v := range v { + body += indent + "- " + strings.TrimSpace(expandMap(level+1, v)) + } + case []interface{}: + for _, v := range v { + body += indent + "- " + strings.TrimSpace(expandMap(level+1, v)) + } + case map[string]interface{}: + sortedKeys := make([]string, len(v)) + for k := range v { + sortedKeys = append(sortedKeys, k) + } + sort.Strings(sortedKeys) + for _, k := range sortedKeys { + v := v[k] + + val := expandMap(level+1, v) + if val == "" { + continue + } + body += indent + k + ": " + val + } + default: + t.Logf("Unknown value type %T", v) + t.FailNow() + } + + return body + } + + expandProps := func(key string, props ...map[string]interface{}) string { + a := map[string]interface{}{} + for _, arg := range props { + for k, v := range arg { + a[k] = v + } + } + + return expandMap(2, map[string]interface{}{ + key: a, + }) + } + + providerProps := map[string]interface{}{ + "defaultTags": map[string]interface{}{ + "tags": step.defaultTags, + }, + } + if step.ignoreTagKeys != nil { + providerProps["ignoreTags"] = map[string]interface{}{ + "keys": step.ignoreTagKeys, + } + } + + body := fmt.Sprintf(template, step.name, + expandProps("properties", providerProps), step.other, step.token, + expandProps("options", options), + expandProps("properties", map[string]interface{}{ + "tags": step.tags, + }, step.properties)) + + t.Logf("template for %s: \n%s", step.name, body) + require.NoError(t, os.WriteFile(testPath, []byte(body), 0600)) +} + +func loadAwsDefaultConfig() aws.Config { + loadOpts := []func(*config.LoadOptions) error{} + if p, ok := os.LookupEnv("AWS_PROFILE"); ok { + loadOpts = append(loadOpts, config.WithSharedConfigProfile(p)) + } + if r, ok := os.LookupEnv("AWS_REGION"); ok { + loadOpts = append(loadOpts, config.WithRegion(r)) + } + cfg, err := config.LoadDefaultConfig(context.TODO(), loadOpts...) + contract.AssertNoErrorf(err, "failed to load AWS config") + + return cfg +} + +func configureS3() *s3sdk.Client { + cfg := loadAwsDefaultConfig() + return s3sdk.NewFromConfig(cfg) +} + +func configureAppconfig() *appconfigsdk.Client { + cfg := loadAwsDefaultConfig() + return appconfigsdk.NewFromConfig(cfg) +} + +func configureTagSdk() *tagsdk.Client { + cfg := loadAwsDefaultConfig() + return tagsdk.NewFromConfig(cfg) +} + +func addResourceTags(ctx context.Context, arn string, tags map[string]string) { + tag := configureTagSdk() + _, err := tag.TagResources(ctx, &tagsdk.TagResourcesInput{ + ResourceARNList: []string{arn}, + Tags: tags, + }) + contract.AssertNoErrorf(err, "error tagging resource") +} + +func addAppconfigEnvironmentTags(ctx context.Context, envArn string, tags map[string]string) { + appconfig := configureAppconfig() + existingTags, err := appconfig.ListTagsForResource(ctx, &appconfigsdk.ListTagsForResourceInput{ + ResourceArn: &envArn, + }) + contract.AssertNoErrorf(err, "failed to list tags for appconfig env") + + for k, v := range existingTags.Tags { + if _, exists := tags[k]; !exists { + tags[k] = v + } + } + + _, err = appconfig.TagResource(ctx, &appconfigsdk.TagResourceInput{ + ResourceArn: &envArn, + Tags: tags, + }) + contract.AssertNoErrorf(err, "error tagging appconfig env") +} + +func getBucketTagging(ctx context.Context, awsBucket string) []types.Tag { + s3 := configureS3() + tagging, err := s3.GetBucketTagging(ctx, &s3sdk.GetBucketTaggingInput{ + Bucket: &awsBucket, + }) + contract.AssertNoErrorf(err, "failed to get bucket tagging") + return tagging.TagSet +} + +func addBucketTags(ctx context.Context, bucketName string, tags map[string]string) { + s3 := configureS3() + existingTags := getBucketTagging(ctx, bucketName) + + newTags := []types.Tag{} + + for k, v := range tags { + newTags = append(newTags, types.Tag{ + Key: &k, + Value: &v, + }) + } + + for _, v := range existingTags { + if _, exists := tags[*v.Key]; !exists { + newTags = append(newTags, v) + } + } + + _, err := s3.PutBucketTagging(ctx, &s3sdk.PutBucketTaggingInput{ + Bucket: &bucketName, + Tagging: &types.Tagging{ + TagSet: newTags, + }, + }) + contract.AssertNoErrorf(err, "error putting bucket tags") +} + +func deleteBucketTagging(ctx context.Context, awsBucket string) { + s3 := configureS3() + _, err := s3.DeleteBucketTagging(ctx, &s3sdk.DeleteBucketTaggingInput{ + Bucket: &awsBucket, + }) + contract.AssertNoErrorf(err, "failed to delete bucket tagging") +} + func getYamlBaseOptions(t *testing.T) integration.ProgramTestOptions { config := map[string]string{} _, usingProfiles := os.LookupEnv("AWS_PROFILE") diff --git a/examples/go.mod b/examples/go.mod index c0d43f02e39..7589196f561 100644 --- a/examples/go.mod +++ b/examples/go.mod @@ -4,12 +4,17 @@ go 1.23.3 require ( github.com/aws/aws-sdk-go v1.55.5 + github.com/aws/aws-sdk-go-v2 v1.32.6 github.com/aws/aws-sdk-go-v2/config v1.28.6 + github.com/aws/aws-sdk-go-v2/service/appconfig v1.36.1 github.com/aws/aws-sdk-go-v2/service/iam v1.38.2 + github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.25.7 + github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 github.com/pulumi/providertest v0.1.3 github.com/pulumi/pulumi-aws/provider/v6 v6.0.0-00010101000000-000000000000 github.com/pulumi/pulumi-terraform-bridge/v3 v3.97.1 github.com/pulumi/pulumi/pkg/v3 v3.142.0 + github.com/pulumi/pulumi/sdk/v3 v3.142.0 github.com/stretchr/testify v1.9.0 ) @@ -56,7 +61,6 @@ require ( github.com/apparentlymart/go-textseg/v15 v15.0.0 // indirect github.com/armon/go-radix v1.0.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect - github.com/aws/aws-sdk-go-v2 v1.32.6 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.47 // indirect github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 // indirect @@ -73,7 +77,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/amplify v1.27.5 // indirect github.com/aws/aws-sdk-go-v2/service/apigateway v1.28.1 // indirect github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.24.7 // indirect - github.com/aws/aws-sdk-go-v2/service/appconfig v1.36.1 // indirect github.com/aws/aws-sdk-go-v2/service/appfabric v1.11.7 // indirect github.com/aws/aws-sdk-go-v2/service/appflow v1.45.8 // indirect github.com/aws/aws-sdk-go-v2/service/appintegrations v1.30.7 // indirect @@ -257,7 +260,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/resiliencehub v1.28.1 // indirect github.com/aws/aws-sdk-go-v2/service/resourceexplorer2 v1.16.2 // indirect github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.27.7 // indirect - github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.25.7 // indirect github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.16.7 // indirect github.com/aws/aws-sdk-go-v2/service/route53 v1.46.3 // indirect github.com/aws/aws-sdk-go-v2/service/route53domains v1.27.7 // indirect @@ -266,7 +268,6 @@ require ( github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness v1.21.7 // indirect github.com/aws/aws-sdk-go-v2/service/route53resolver v1.34.2 // indirect github.com/aws/aws-sdk-go-v2/service/rum v1.21.7 // indirect - github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 // indirect github.com/aws/aws-sdk-go-v2/service/s3control v1.52.0 // indirect github.com/aws/aws-sdk-go-v2/service/s3outposts v1.28.7 // indirect github.com/aws/aws-sdk-go-v2/service/s3tables v1.0.0 // indirect @@ -453,7 +454,6 @@ require ( github.com/pulumi/inflector v0.1.1 // indirect github.com/pulumi/pulumi-java/pkg v0.18.0 // indirect github.com/pulumi/pulumi-yaml v1.12.0 // indirect - github.com/pulumi/pulumi/sdk/v3 v3.142.0 // indirect github.com/pulumi/schema-tools v0.1.2 // indirect github.com/pulumi/terraform-diff-reader v0.0.2 // indirect github.com/rivo/uniseg v0.4.4 // indirect diff --git a/provider/provider_test.go b/examples/provider_test.go similarity index 96% rename from provider/provider_test.go rename to examples/provider_test.go index 349c8d3ae30..a7e1d63b253 100644 --- a/provider/provider_test.go +++ b/examples/provider_test.go @@ -1,5 +1,5 @@ -// Copyright 2016-2023, Pulumi Corporation. All rights reserved. -package provider +// Copyright 2016-2024, Pulumi Corporation. All rights reserved. +package examples import ( "bytes" @@ -28,14 +28,6 @@ func TestUpgradeCoverage(t *testing.T) { providertest.ReportUpgradeCoverage(t) } -func getEnvRegion(t *testing.T) string { - envRegion := os.Getenv("AWS_REGION") - if envRegion == "" { - envRegion = "us-west-2" - } - return envRegion -} - func execPulumi(t *testing.T, ptest *pulumitest.PulumiTest, workdir string, args ...string) { ctx := context.Background() var env []string @@ -63,12 +55,6 @@ type testProviderUpgradeOptions struct { extraOpts []opttest.Option } -func skipIfShort(t *testing.T) { - if testing.Short() { - t.Skipf("Skipping in testing.Short() mode, assuming this is a CI run without credentials") - } - -} func testProviderUpgrade(t *testing.T, dir string, opts *testProviderUpgradeOptions) { skipIfShort(t) t.Parallel() diff --git a/provider/test-programs/acm/Pulumi.yaml b/examples/test-programs/acm/Pulumi.yaml similarity index 100% rename from provider/test-programs/acm/Pulumi.yaml rename to examples/test-programs/acm/Pulumi.yaml diff --git a/provider/test-programs/apigateway-integrationresponse/Pulumi.yaml b/examples/test-programs/apigateway-integrationresponse/Pulumi.yaml similarity index 100% rename from provider/test-programs/apigateway-integrationresponse/Pulumi.yaml rename to examples/test-programs/apigateway-integrationresponse/Pulumi.yaml diff --git a/provider/test-programs/apigateway-methodreponse/Pulumi.yaml b/examples/test-programs/apigateway-methodreponse/Pulumi.yaml similarity index 100% rename from provider/test-programs/apigateway-methodreponse/Pulumi.yaml rename to examples/test-programs/apigateway-methodreponse/Pulumi.yaml diff --git a/provider/test-programs/apigateway-resource-response/Pulumi.yaml b/examples/test-programs/apigateway-resource-response/Pulumi.yaml similarity index 100% rename from provider/test-programs/apigateway-resource-response/Pulumi.yaml rename to examples/test-programs/apigateway-resource-response/Pulumi.yaml diff --git a/provider/test-programs/apigateway-resource/Pulumi.yaml b/examples/test-programs/apigateway-resource/Pulumi.yaml similarity index 100% rename from provider/test-programs/apigateway-resource/Pulumi.yaml rename to examples/test-programs/apigateway-resource/Pulumi.yaml diff --git a/provider/test-programs/assume-role-session-tags/Pulumi.yaml b/examples/test-programs/assume-role-session-tags/Pulumi.yaml similarity index 100% rename from provider/test-programs/assume-role-session-tags/Pulumi.yaml rename to examples/test-programs/assume-role-session-tags/Pulumi.yaml diff --git a/provider/test-programs/bucket-obj/.gitignore b/examples/test-programs/bucket-obj/.gitignore similarity index 100% rename from provider/test-programs/bucket-obj/.gitignore rename to examples/test-programs/bucket-obj/.gitignore diff --git a/provider/test-programs/bucket-obj/Pulumi.yaml b/examples/test-programs/bucket-obj/Pulumi.yaml similarity index 100% rename from provider/test-programs/bucket-obj/Pulumi.yaml rename to examples/test-programs/bucket-obj/Pulumi.yaml diff --git a/provider/test-programs/bucket/Pulumi.yaml b/examples/test-programs/bucket/Pulumi.yaml similarity index 100% rename from provider/test-programs/bucket/Pulumi.yaml rename to examples/test-programs/bucket/Pulumi.yaml diff --git a/provider/test-programs/changing-region/.gitignore b/examples/test-programs/changing-region/.gitignore similarity index 100% rename from provider/test-programs/changing-region/.gitignore rename to examples/test-programs/changing-region/.gitignore diff --git a/provider/test-programs/changing-region/Pulumi.yaml b/examples/test-programs/changing-region/Pulumi.yaml similarity index 100% rename from provider/test-programs/changing-region/Pulumi.yaml rename to examples/test-programs/changing-region/Pulumi.yaml diff --git a/provider/test-programs/changing-region/index.ts b/examples/test-programs/changing-region/index.ts similarity index 100% rename from provider/test-programs/changing-region/index.ts rename to examples/test-programs/changing-region/index.ts diff --git a/provider/test-programs/changing-region/package.json b/examples/test-programs/changing-region/package.json similarity index 100% rename from provider/test-programs/changing-region/package.json rename to examples/test-programs/changing-region/package.json diff --git a/provider/test-programs/changing-region/tsconfig.json b/examples/test-programs/changing-region/tsconfig.json similarity index 100% rename from provider/test-programs/changing-region/tsconfig.json rename to examples/test-programs/changing-region/tsconfig.json diff --git a/provider/test-programs/cloudfront-distribution/.gitignore b/examples/test-programs/cloudfront-distribution/.gitignore similarity index 100% rename from provider/test-programs/cloudfront-distribution/.gitignore rename to examples/test-programs/cloudfront-distribution/.gitignore diff --git a/provider/test-programs/cloudfront-distribution/Pulumi.yaml b/examples/test-programs/cloudfront-distribution/Pulumi.yaml similarity index 100% rename from provider/test-programs/cloudfront-distribution/Pulumi.yaml rename to examples/test-programs/cloudfront-distribution/Pulumi.yaml diff --git a/provider/test-programs/cloudwatch-eventrule/Pulumi.yaml b/examples/test-programs/cloudwatch-eventrule/Pulumi.yaml similarity index 100% rename from provider/test-programs/cloudwatch-eventrule/Pulumi.yaml rename to examples/test-programs/cloudwatch-eventrule/Pulumi.yaml diff --git a/provider/test-programs/cloudwatch-loggroup/Pulumi.yaml b/examples/test-programs/cloudwatch-loggroup/Pulumi.yaml similarity index 100% rename from provider/test-programs/cloudwatch-loggroup/Pulumi.yaml rename to examples/test-programs/cloudwatch-loggroup/Pulumi.yaml diff --git a/provider/test-programs/disappearing-bucket-object/Pulumi.yaml b/examples/test-programs/disappearing-bucket-object/Pulumi.yaml similarity index 100% rename from provider/test-programs/disappearing-bucket-object/Pulumi.yaml rename to examples/test-programs/disappearing-bucket-object/Pulumi.yaml diff --git a/provider/test-programs/disappearing-bucket-object/index.ts b/examples/test-programs/disappearing-bucket-object/index.ts similarity index 100% rename from provider/test-programs/disappearing-bucket-object/index.ts rename to examples/test-programs/disappearing-bucket-object/index.ts diff --git a/provider/test-programs/disappearing-bucket-object/package.json b/examples/test-programs/disappearing-bucket-object/package.json similarity index 100% rename from provider/test-programs/disappearing-bucket-object/package.json rename to examples/test-programs/disappearing-bucket-object/package.json diff --git a/provider/test-programs/disappearing-bucket-object/tsconfig.json b/examples/test-programs/disappearing-bucket-object/tsconfig.json similarity index 100% rename from provider/test-programs/disappearing-bucket-object/tsconfig.json rename to examples/test-programs/disappearing-bucket-object/tsconfig.json diff --git a/provider/test-programs/dynamodb-table/Pulumi.yaml b/examples/test-programs/dynamodb-table/Pulumi.yaml similarity index 100% rename from provider/test-programs/dynamodb-table/Pulumi.yaml rename to examples/test-programs/dynamodb-table/Pulumi.yaml diff --git a/provider/test-programs/ec2-instance/.gitignore b/examples/test-programs/ec2-instance/.gitignore similarity index 100% rename from provider/test-programs/ec2-instance/.gitignore rename to examples/test-programs/ec2-instance/.gitignore diff --git a/provider/test-programs/ec2-instance/Pulumi.yaml b/examples/test-programs/ec2-instance/Pulumi.yaml similarity index 100% rename from provider/test-programs/ec2-instance/Pulumi.yaml rename to examples/test-programs/ec2-instance/Pulumi.yaml diff --git a/provider/test-programs/ec2-networking/Pulumi.yaml b/examples/test-programs/ec2-networking/Pulumi.yaml similarity index 100% rename from provider/test-programs/ec2-networking/Pulumi.yaml rename to examples/test-programs/ec2-networking/Pulumi.yaml diff --git a/provider/test-programs/ec2-string-for-int/.gitignore b/examples/test-programs/ec2-string-for-int/.gitignore similarity index 100% rename from provider/test-programs/ec2-string-for-int/.gitignore rename to examples/test-programs/ec2-string-for-int/.gitignore diff --git a/provider/test-programs/ec2-string-for-int/Pulumi.yaml b/examples/test-programs/ec2-string-for-int/Pulumi.yaml similarity index 100% rename from provider/test-programs/ec2-string-for-int/Pulumi.yaml rename to examples/test-programs/ec2-string-for-int/Pulumi.yaml diff --git a/provider/test-programs/ec2-string-for-int/index.ts b/examples/test-programs/ec2-string-for-int/index.ts similarity index 100% rename from provider/test-programs/ec2-string-for-int/index.ts rename to examples/test-programs/ec2-string-for-int/index.ts diff --git a/provider/test-programs/ec2-string-for-int/package.json b/examples/test-programs/ec2-string-for-int/package.json similarity index 100% rename from provider/test-programs/ec2-string-for-int/package.json rename to examples/test-programs/ec2-string-for-int/package.json diff --git a/provider/test-programs/ec2-string-for-int/tsconfig.json b/examples/test-programs/ec2-string-for-int/tsconfig.json similarity index 100% rename from provider/test-programs/ec2-string-for-int/tsconfig.json rename to examples/test-programs/ec2-string-for-int/tsconfig.json diff --git a/provider/test-programs/ecr-lifecyclepolicy/Pulumi.yaml b/examples/test-programs/ecr-lifecyclepolicy/Pulumi.yaml similarity index 100% rename from provider/test-programs/ecr-lifecyclepolicy/Pulumi.yaml rename to examples/test-programs/ecr-lifecyclepolicy/Pulumi.yaml diff --git a/provider/test-programs/ecr-repository/Pulumi.yaml b/examples/test-programs/ecr-repository/Pulumi.yaml similarity index 100% rename from provider/test-programs/ecr-repository/Pulumi.yaml rename to examples/test-programs/ecr-repository/Pulumi.yaml diff --git a/provider/test-programs/ecs-service/Pulumi.yaml b/examples/test-programs/ecs-service/Pulumi.yaml similarity index 100% rename from provider/test-programs/ecs-service/Pulumi.yaml rename to examples/test-programs/ecs-service/Pulumi.yaml diff --git a/provider/test-programs/eks-cluster/Pulumi.yaml b/examples/test-programs/eks-cluster/Pulumi.yaml similarity index 100% rename from provider/test-programs/eks-cluster/Pulumi.yaml rename to examples/test-programs/eks-cluster/Pulumi.yaml diff --git a/provider/test-programs/gamelift-typescript/.gitignore b/examples/test-programs/gamelift-typescript/.gitignore similarity index 100% rename from provider/test-programs/gamelift-typescript/.gitignore rename to examples/test-programs/gamelift-typescript/.gitignore diff --git a/provider/test-programs/gamelift-typescript/Pulumi.yaml b/examples/test-programs/gamelift-typescript/Pulumi.yaml similarity index 100% rename from provider/test-programs/gamelift-typescript/Pulumi.yaml rename to examples/test-programs/gamelift-typescript/Pulumi.yaml diff --git a/provider/test-programs/gamelift-typescript/index.ts b/examples/test-programs/gamelift-typescript/index.ts similarity index 100% rename from provider/test-programs/gamelift-typescript/index.ts rename to examples/test-programs/gamelift-typescript/index.ts diff --git a/provider/test-programs/gamelift-typescript/package.json b/examples/test-programs/gamelift-typescript/package.json similarity index 100% rename from provider/test-programs/gamelift-typescript/package.json rename to examples/test-programs/gamelift-typescript/package.json diff --git a/provider/test-programs/gamelift-typescript/tsconfig.json b/examples/test-programs/gamelift-typescript/tsconfig.json similarity index 100% rename from provider/test-programs/gamelift-typescript/tsconfig.json rename to examples/test-programs/gamelift-typescript/tsconfig.json diff --git a/provider/test-programs/iam-instanceprofile/Pulumi.yaml b/examples/test-programs/iam-instanceprofile/Pulumi.yaml similarity index 100% rename from provider/test-programs/iam-instanceprofile/Pulumi.yaml rename to examples/test-programs/iam-instanceprofile/Pulumi.yaml diff --git a/provider/test-programs/iam-openidconnectprovider/Pulumi.yaml b/examples/test-programs/iam-openidconnectprovider/Pulumi.yaml similarity index 100% rename from provider/test-programs/iam-openidconnectprovider/Pulumi.yaml rename to examples/test-programs/iam-openidconnectprovider/Pulumi.yaml diff --git a/provider/test-programs/iam-user/Pulumi.yaml b/examples/test-programs/iam-user/Pulumi.yaml similarity index 100% rename from provider/test-programs/iam-user/Pulumi.yaml rename to examples/test-programs/iam-user/Pulumi.yaml diff --git a/provider/test-programs/imds-auth/imds-v2/Pulumi.yaml b/examples/test-programs/imds-auth/imds-v2/Pulumi.yaml similarity index 100% rename from provider/test-programs/imds-auth/imds-v2/Pulumi.yaml rename to examples/test-programs/imds-auth/imds-v2/Pulumi.yaml diff --git a/provider/test-programs/imds-auth/imds-v2/remote-program/Pulumi.yaml b/examples/test-programs/imds-auth/imds-v2/remote-program/Pulumi.yaml similarity index 100% rename from provider/test-programs/imds-auth/imds-v2/remote-program/Pulumi.yaml rename to examples/test-programs/imds-auth/imds-v2/remote-program/Pulumi.yaml diff --git a/provider/test-programs/job-queue/Pulumi.yaml b/examples/test-programs/job-queue/Pulumi.yaml similarity index 100% rename from provider/test-programs/job-queue/Pulumi.yaml rename to examples/test-programs/job-queue/Pulumi.yaml diff --git a/provider/test-programs/job-queue/index.ts b/examples/test-programs/job-queue/index.ts similarity index 100% rename from provider/test-programs/job-queue/index.ts rename to examples/test-programs/job-queue/index.ts diff --git a/provider/test-programs/job-queue/package.json b/examples/test-programs/job-queue/package.json similarity index 100% rename from provider/test-programs/job-queue/package.json rename to examples/test-programs/job-queue/package.json diff --git a/provider/test-programs/job-queue/tsconfig.json b/examples/test-programs/job-queue/tsconfig.json similarity index 100% rename from provider/test-programs/job-queue/tsconfig.json rename to examples/test-programs/job-queue/tsconfig.json diff --git a/provider/test-programs/kms-key/Pulumi.yaml b/examples/test-programs/kms-key/Pulumi.yaml similarity index 100% rename from provider/test-programs/kms-key/Pulumi.yaml rename to examples/test-programs/kms-key/Pulumi.yaml diff --git a/provider/test-programs/lb/Pulumi.yaml b/examples/test-programs/lb/Pulumi.yaml similarity index 100% rename from provider/test-programs/lb/Pulumi.yaml rename to examples/test-programs/lb/Pulumi.yaml diff --git a/provider/test-programs/non-idempotent-sns-topic/Pulumi.yaml b/examples/test-programs/non-idempotent-sns-topic/Pulumi.yaml similarity index 100% rename from provider/test-programs/non-idempotent-sns-topic/Pulumi.yaml rename to examples/test-programs/non-idempotent-sns-topic/Pulumi.yaml diff --git a/provider/test-programs/parallel-lambdas/Pulumi.yaml b/examples/test-programs/parallel-lambdas/Pulumi.yaml similarity index 100% rename from provider/test-programs/parallel-lambdas/Pulumi.yaml rename to examples/test-programs/parallel-lambdas/Pulumi.yaml diff --git a/provider/test-programs/parallel-lambdas/index.ts b/examples/test-programs/parallel-lambdas/index.ts similarity index 100% rename from provider/test-programs/parallel-lambdas/index.ts rename to examples/test-programs/parallel-lambdas/index.ts diff --git a/provider/test-programs/parallel-lambdas/package.json b/examples/test-programs/parallel-lambdas/package.json similarity index 100% rename from provider/test-programs/parallel-lambdas/package.json rename to examples/test-programs/parallel-lambdas/package.json diff --git a/provider/test-programs/parallel-lambdas/tsconfig.json b/examples/test-programs/parallel-lambdas/tsconfig.json similarity index 100% rename from provider/test-programs/parallel-lambdas/tsconfig.json rename to examples/test-programs/parallel-lambdas/tsconfig.json diff --git a/provider/test-programs/rds-instance/Pulumi.yaml b/examples/test-programs/rds-instance/Pulumi.yaml similarity index 100% rename from provider/test-programs/rds-instance/Pulumi.yaml rename to examples/test-programs/rds-instance/Pulumi.yaml diff --git a/provider/test-programs/regress-2534/.gitignore b/examples/test-programs/regress-2534/.gitignore similarity index 100% rename from provider/test-programs/regress-2534/.gitignore rename to examples/test-programs/regress-2534/.gitignore diff --git a/provider/test-programs/regress-2534/Pulumi.yaml b/examples/test-programs/regress-2534/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-2534/Pulumi.yaml rename to examples/test-programs/regress-2534/Pulumi.yaml diff --git a/provider/test-programs/regress-2534/__main__.py b/examples/test-programs/regress-2534/__main__.py similarity index 100% rename from provider/test-programs/regress-2534/__main__.py rename to examples/test-programs/regress-2534/__main__.py diff --git a/provider/test-programs/regress-2534/requirements.txt b/examples/test-programs/regress-2534/requirements.txt similarity index 100% rename from provider/test-programs/regress-2534/requirements.txt rename to examples/test-programs/regress-2534/requirements.txt diff --git a/provider/test-programs/regress-2796/Pulumi.yaml b/examples/test-programs/regress-2796/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-2796/Pulumi.yaml rename to examples/test-programs/regress-2796/Pulumi.yaml diff --git a/provider/test-programs/regress-3094/.gitignore b/examples/test-programs/regress-3094/.gitignore similarity index 100% rename from provider/test-programs/regress-3094/.gitignore rename to examples/test-programs/regress-3094/.gitignore diff --git a/provider/test-programs/regress-3094/Pulumi.yaml b/examples/test-programs/regress-3094/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-3094/Pulumi.yaml rename to examples/test-programs/regress-3094/Pulumi.yaml diff --git a/provider/test-programs/regress-3094/index.ts b/examples/test-programs/regress-3094/index.ts similarity index 100% rename from provider/test-programs/regress-3094/index.ts rename to examples/test-programs/regress-3094/index.ts diff --git a/provider/test-programs/regress-3094/package.json b/examples/test-programs/regress-3094/package.json similarity index 100% rename from provider/test-programs/regress-3094/package.json rename to examples/test-programs/regress-3094/package.json diff --git a/provider/test-programs/regress-3094/tsconfig.json b/examples/test-programs/regress-3094/tsconfig.json similarity index 100% rename from provider/test-programs/regress-3094/tsconfig.json rename to examples/test-programs/regress-3094/tsconfig.json diff --git a/provider/test-programs/regress-3196/Pulumi.yaml b/examples/test-programs/regress-3196/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-3196/Pulumi.yaml rename to examples/test-programs/regress-3196/Pulumi.yaml diff --git a/provider/test-programs/regress-3196/__main__.py b/examples/test-programs/regress-3196/__main__.py similarity index 100% rename from provider/test-programs/regress-3196/__main__.py rename to examples/test-programs/regress-3196/__main__.py diff --git a/provider/test-programs/regress-3196/requirements.txt b/examples/test-programs/regress-3196/requirements.txt similarity index 100% rename from provider/test-programs/regress-3196/requirements.txt rename to examples/test-programs/regress-3196/requirements.txt diff --git a/provider/test-programs/regress-3674/Pulumi.yaml b/examples/test-programs/regress-3674/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-3674/Pulumi.yaml rename to examples/test-programs/regress-3674/Pulumi.yaml diff --git a/provider/test-programs/regress-3835/.gitignore b/examples/test-programs/regress-3835/.gitignore similarity index 100% rename from provider/test-programs/regress-3835/.gitignore rename to examples/test-programs/regress-3835/.gitignore diff --git a/provider/test-programs/regress-3835/Pulumi.yaml b/examples/test-programs/regress-3835/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-3835/Pulumi.yaml rename to examples/test-programs/regress-3835/Pulumi.yaml diff --git a/provider/test-programs/regress-3835/index.ts b/examples/test-programs/regress-3835/index.ts similarity index 100% rename from provider/test-programs/regress-3835/index.ts rename to examples/test-programs/regress-3835/index.ts diff --git a/provider/test-programs/regress-3835/package.json b/examples/test-programs/regress-3835/package.json similarity index 100% rename from provider/test-programs/regress-3835/package.json rename to examples/test-programs/regress-3835/package.json diff --git a/provider/test-programs/regress-3835/tsconfig.json b/examples/test-programs/regress-3835/tsconfig.json similarity index 100% rename from provider/test-programs/regress-3835/tsconfig.json rename to examples/test-programs/regress-3835/tsconfig.json diff --git a/provider/test-programs/regress-3887/Pulumi.yaml b/examples/test-programs/regress-3887/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-3887/Pulumi.yaml rename to examples/test-programs/regress-3887/Pulumi.yaml diff --git a/provider/test-programs/regress-3887/__main__.py b/examples/test-programs/regress-3887/__main__.py similarity index 100% rename from provider/test-programs/regress-3887/__main__.py rename to examples/test-programs/regress-3887/__main__.py diff --git a/provider/test-programs/regress-3887/requirements.txt b/examples/test-programs/regress-3887/requirements.txt similarity index 100% rename from provider/test-programs/regress-3887/requirements.txt rename to examples/test-programs/regress-3887/requirements.txt diff --git a/provider/test-programs/regress-3887/step-1/__main__.py b/examples/test-programs/regress-3887/step-1/__main__.py similarity index 100% rename from provider/test-programs/regress-3887/step-1/__main__.py rename to examples/test-programs/regress-3887/step-1/__main__.py diff --git a/provider/test-programs/regress-3887/step-2/__main__.py b/examples/test-programs/regress-3887/step-2/__main__.py similarity index 100% rename from provider/test-programs/regress-3887/step-2/__main__.py rename to examples/test-programs/regress-3887/step-2/__main__.py diff --git a/provider/test-programs/regress-4079/Pulumi.yaml b/examples/test-programs/regress-4079/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-4079/Pulumi.yaml rename to examples/test-programs/regress-4079/Pulumi.yaml diff --git a/provider/test-programs/regress-4079/index.ts b/examples/test-programs/regress-4079/index.ts similarity index 100% rename from provider/test-programs/regress-4079/index.ts rename to examples/test-programs/regress-4079/index.ts diff --git a/provider/test-programs/regress-4079/package.json b/examples/test-programs/regress-4079/package.json similarity index 100% rename from provider/test-programs/regress-4079/package.json rename to examples/test-programs/regress-4079/package.json diff --git a/provider/test-programs/regress-4079/tsconfig.json b/examples/test-programs/regress-4079/tsconfig.json similarity index 100% rename from provider/test-programs/regress-4079/tsconfig.json rename to examples/test-programs/regress-4079/tsconfig.json diff --git a/provider/test-programs/regress-4128/Pulumi.yaml b/examples/test-programs/regress-4128/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-4128/Pulumi.yaml rename to examples/test-programs/regress-4128/Pulumi.yaml diff --git a/provider/test-programs/regress-4128/index.ts b/examples/test-programs/regress-4128/index.ts similarity index 100% rename from provider/test-programs/regress-4128/index.ts rename to examples/test-programs/regress-4128/index.ts diff --git a/provider/test-programs/regress-4128/package.json b/examples/test-programs/regress-4128/package.json similarity index 100% rename from provider/test-programs/regress-4128/package.json rename to examples/test-programs/regress-4128/package.json diff --git a/provider/test-programs/regress-4128/tsconfig.json b/examples/test-programs/regress-4128/tsconfig.json similarity index 100% rename from provider/test-programs/regress-4128/tsconfig.json rename to examples/test-programs/regress-4128/tsconfig.json diff --git a/provider/test-programs/regress-4446/Pulumi.yaml b/examples/test-programs/regress-4446/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-4446/Pulumi.yaml rename to examples/test-programs/regress-4446/Pulumi.yaml diff --git a/provider/test-programs/regress-4446/index.ts b/examples/test-programs/regress-4446/index.ts similarity index 100% rename from provider/test-programs/regress-4446/index.ts rename to examples/test-programs/regress-4446/index.ts diff --git a/provider/test-programs/regress-4446/package.json b/examples/test-programs/regress-4446/package.json similarity index 100% rename from provider/test-programs/regress-4446/package.json rename to examples/test-programs/regress-4446/package.json diff --git a/provider/test-programs/regress-4446/tsconfig.json b/examples/test-programs/regress-4446/tsconfig.json similarity index 100% rename from provider/test-programs/regress-4446/tsconfig.json rename to examples/test-programs/regress-4446/tsconfig.json diff --git a/provider/test-programs/regress-4457/Pulumi.yaml b/examples/test-programs/regress-4457/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-4457/Pulumi.yaml rename to examples/test-programs/regress-4457/Pulumi.yaml diff --git a/provider/test-programs/regress-4457/__main__.py b/examples/test-programs/regress-4457/__main__.py similarity index 100% rename from provider/test-programs/regress-4457/__main__.py rename to examples/test-programs/regress-4457/__main__.py diff --git a/provider/test-programs/regress-4457/requirements.txt b/examples/test-programs/regress-4457/requirements.txt similarity index 100% rename from provider/test-programs/regress-4457/requirements.txt rename to examples/test-programs/regress-4457/requirements.txt diff --git a/provider/test-programs/regress-4568/Pulumi.yaml b/examples/test-programs/regress-4568/Pulumi.yaml similarity index 100% rename from provider/test-programs/regress-4568/Pulumi.yaml rename to examples/test-programs/regress-4568/Pulumi.yaml diff --git a/provider/test-programs/regress-4568/index.ts b/examples/test-programs/regress-4568/index.ts similarity index 100% rename from provider/test-programs/regress-4568/index.ts rename to examples/test-programs/regress-4568/index.ts diff --git a/provider/test-programs/regress-4568/package.json b/examples/test-programs/regress-4568/package.json similarity index 100% rename from provider/test-programs/regress-4568/package.json rename to examples/test-programs/regress-4568/package.json diff --git a/provider/test-programs/regress-4568/tsconfig.json b/examples/test-programs/regress-4568/tsconfig.json similarity index 100% rename from provider/test-programs/regress-4568/tsconfig.json rename to examples/test-programs/regress-4568/tsconfig.json diff --git a/provider/test-programs/route53-resolver-endpoint/Pulumi.yaml b/examples/test-programs/route53-resolver-endpoint/Pulumi.yaml similarity index 100% rename from provider/test-programs/route53-resolver-endpoint/Pulumi.yaml rename to examples/test-programs/route53-resolver-endpoint/Pulumi.yaml diff --git a/provider/test-programs/secretsmanager-secret/Pulumi.yaml b/examples/test-programs/secretsmanager-secret/Pulumi.yaml similarity index 100% rename from provider/test-programs/secretsmanager-secret/Pulumi.yaml rename to examples/test-programs/secretsmanager-secret/Pulumi.yaml diff --git a/provider/test-programs/secretversion/.gitignore b/examples/test-programs/secretversion/.gitignore similarity index 100% rename from provider/test-programs/secretversion/.gitignore rename to examples/test-programs/secretversion/.gitignore diff --git a/provider/test-programs/secretversion/Pulumi.yaml b/examples/test-programs/secretversion/Pulumi.yaml similarity index 100% rename from provider/test-programs/secretversion/Pulumi.yaml rename to examples/test-programs/secretversion/Pulumi.yaml diff --git a/provider/test-programs/sns-topic/Pulumi.yaml b/examples/test-programs/sns-topic/Pulumi.yaml similarity index 100% rename from provider/test-programs/sns-topic/Pulumi.yaml rename to examples/test-programs/sns-topic/Pulumi.yaml diff --git a/provider/test-programs/subnet-group/.gitignore b/examples/test-programs/subnet-group/.gitignore similarity index 100% rename from provider/test-programs/subnet-group/.gitignore rename to examples/test-programs/subnet-group/.gitignore diff --git a/provider/test-programs/subnet-group/Pulumi.yaml b/examples/test-programs/subnet-group/Pulumi.yaml similarity index 100% rename from provider/test-programs/subnet-group/Pulumi.yaml rename to examples/test-programs/subnet-group/Pulumi.yaml diff --git a/provider/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/new-version/plan.json b/examples/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/new-version/plan.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/new-version/plan.json rename to examples/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/new-version/plan.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/upgrade/stack.json b/examples/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/upgrade/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/upgrade/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/TestOpenZfsFileSystemUpgrade/upgrade/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/acm/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/acm/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/acm/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/acm/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/apigateway-integrationresponse/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/apigateway-methodreponse/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/apigateway-resource-response/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/apigateway-resource/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/bucket-obj/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/bucket/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/cloudfront-distribution/6.10.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/cloudwatch-eventrule/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/cloudwatch-loggroup/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/cloudwatch/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/dynamodb-table/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/ec2-instance/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/ec2-networking/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/ecr-lifecyclepolicy/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/ecr-repository/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/ecs-service/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/eks-cluster/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/eventbus/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/iam-instanceprofile/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/iam-openidconnectprovider/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/iam-user/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/job-queue/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/kms-key/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/lambda-layer-new/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/lb/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/lb/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/lb/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/lb/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/lb/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/lb/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/lb/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/lb/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/logGroup/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/state.json b/examples/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/state.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/state.json rename to examples/testdata/recorded/TestProviderUpgrade/non-idempotent-sns-topic/state.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/queue/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/queue/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/queue/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/queue/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/queue/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/queue/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/queue/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/queue/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/rds-instance/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/route53-resolver-endpoint/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/route53/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/route53/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/route53/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/route53/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/route53/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/route53/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/route53/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/route53/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/secretsmanager-secret/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/secretversion/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/sns-topic/5.42.0/stack.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/grpc.json b/examples/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/grpc.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/grpc.json rename to examples/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/grpc.json diff --git a/provider/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/stack.json b/examples/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/stack.json similarity index 100% rename from provider/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/stack.json rename to examples/testdata/recorded/TestProviderUpgrade/subnet-group/5.42.0/stack.json diff --git a/provider/go.mod b/provider/go.mod index 028257d2cff..5acfe1d0639 100644 --- a/provider/go.mod +++ b/provider/go.mod @@ -8,13 +8,9 @@ go 1.23.3 godebug tlskyber=0 require ( - github.com/aws/aws-sdk-go-v2 v1.32.6 github.com/aws/aws-sdk-go-v2/config v1.28.6 github.com/aws/aws-sdk-go-v2/feature/ec2/imds v1.16.21 - github.com/aws/aws-sdk-go-v2/service/appconfig v1.36.1 github.com/aws/aws-sdk-go-v2/service/elasticloadbalancingv2 v1.43.1 - github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.25.7 - github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 github.com/hashicorp/aws-sdk-go-base/v2 v2.0.0-beta.59 github.com/hashicorp/terraform-plugin-sdk/v2 v2.35.0 github.com/hashicorp/terraform-provider-aws v1.60.1-0.20220923175450-ca71523cdc36 @@ -71,6 +67,7 @@ require ( github.com/armon/go-radix v1.0.0 // indirect github.com/atotto/clipboard v0.1.4 // indirect github.com/aws/aws-sdk-go v1.55.5 // indirect + github.com/aws/aws-sdk-go-v2 v1.32.6 // indirect github.com/aws/aws-sdk-go-v2/aws/protocol/eventstream v1.6.7 // indirect github.com/aws/aws-sdk-go-v2/credentials v1.17.47 // indirect github.com/aws/aws-sdk-go-v2/feature/s3/manager v1.17.43 // indirect @@ -86,6 +83,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/amplify v1.27.5 // indirect github.com/aws/aws-sdk-go-v2/service/apigateway v1.28.1 // indirect github.com/aws/aws-sdk-go-v2/service/apigatewayv2 v1.24.7 // indirect + github.com/aws/aws-sdk-go-v2/service/appconfig v1.36.1 // indirect github.com/aws/aws-sdk-go-v2/service/appfabric v1.11.7 // indirect github.com/aws/aws-sdk-go-v2/service/appflow v1.45.8 // indirect github.com/aws/aws-sdk-go-v2/service/appintegrations v1.30.7 // indirect @@ -269,6 +267,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/resiliencehub v1.28.1 // indirect github.com/aws/aws-sdk-go-v2/service/resourceexplorer2 v1.16.2 // indirect github.com/aws/aws-sdk-go-v2/service/resourcegroups v1.27.7 // indirect + github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi v1.25.7 // indirect github.com/aws/aws-sdk-go-v2/service/rolesanywhere v1.16.7 // indirect github.com/aws/aws-sdk-go-v2/service/route53 v1.46.3 // indirect github.com/aws/aws-sdk-go-v2/service/route53domains v1.27.7 // indirect @@ -277,6 +276,7 @@ require ( github.com/aws/aws-sdk-go-v2/service/route53recoveryreadiness v1.21.7 // indirect github.com/aws/aws-sdk-go-v2/service/route53resolver v1.34.2 // indirect github.com/aws/aws-sdk-go-v2/service/rum v1.21.7 // indirect + github.com/aws/aws-sdk-go-v2/service/s3 v1.71.0 // indirect github.com/aws/aws-sdk-go-v2/service/s3control v1.52.0 // indirect github.com/aws/aws-sdk-go-v2/service/s3outposts v1.28.7 // indirect github.com/aws/aws-sdk-go-v2/service/s3tables v1.0.0 // indirect diff --git a/provider/provider_dotnet_test.go b/provider/provider_dotnet_test.go deleted file mode 100644 index 31a843bfbcd..00000000000 --- a/provider/provider_dotnet_test.go +++ /dev/null @@ -1,6 +0,0 @@ -// Copyright 2016-2024, Pulumi Corporation. All rights reserved. - -//go:build !go && !yaml && !nodejs && !python && !java -// +build !go,!yaml,!nodejs,!python,!java - -package provider diff --git a/provider/provider_nodejs_test.go b/provider/provider_nodejs_test.go deleted file mode 100644 index c8997e81aed..00000000000 --- a/provider/provider_nodejs_test.go +++ /dev/null @@ -1,439 +0,0 @@ -// Copyright 2016-2023, Pulumi Corporation. All rights reserved. - -//go:build !go && !yaml && !python && !dotnet && !java -// +build !go,!yaml,!python,!dotnet,!java - -package provider - -import ( - "archive/zip" - "context" - "crypto/rand" - "encoding/json" - "io" - "os" - "path/filepath" - "testing" - "time" - - "github.com/pulumi/providertest/pulumitest" - "github.com/pulumi/providertest/pulumitest/opttest" - "github.com/pulumi/pulumi-aws/provider/v6/pkg/elb" - "github.com/pulumi/pulumi/pkg/v3/testing/integration" - "github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview" - "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestLambdaLayerNewUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("..", "examples", "lambda-layer-new"), nodeProviderUpgradeOpts()) -} - -func TestCloudWatchUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("..", "examples", "cloudwatch"), nodeProviderUpgradeOpts()) -} - -func TestLogGroupUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("..", "examples", "logGroup"), nodeProviderUpgradeOpts()) -} - -func TestQueueUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("..", "examples", "queue"), nodeProviderUpgradeOpts()) -} - -func TestRoute53Upgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("..", "examples", "route53"), nodeProviderUpgradeOpts()) -} - -func TestJobQueueUpgrade(t *testing.T) { - opts := nodeProviderUpgradeOpts() - opts.setEnvRegion = false - opts.region = "us-west-2" // has to match the snapshot-recorded region - opts.extraOpts = []opttest.Option{ - opttest.Env("PULUMI_ENABLE_PLAN_RESOURCE_CHANGE", "true"), - } - testProviderUpgrade(t, filepath.Join("test-programs", "job-queue"), opts) -} - -func nodeProviderUpgradeOpts() *testProviderUpgradeOptions { - return &testProviderUpgradeOptions{ - linkNodeSDK: true, - installDeps: true, - setEnvRegion: true, - } -} - -func TestRegress3094(t *testing.T) { - skipIfShort(t) - dir := filepath.Join("test-programs", "regress-3094") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - opttest.YarnLink("@pulumi/aws"), - } - test := pulumitest.NewPulumiTest(t, dir, options...) - upResult := test.Up(t) - t.Logf("#%v", upResult.Summary) -} - -func TestRegress3835(t *testing.T) { - skipIfShort(t) - dir := filepath.Join("test-programs", "regress-3835") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - opttest.YarnLink("@pulumi/aws"), - } - test := pulumitest.NewPulumiTest(t, dir, options...) - result := test.Preview(t) - t.Logf("#%v", result.ChangeSummary) -} - -func TestChangingRegion(t *testing.T) { - skipIfShort(t) - dir := filepath.Join("test-programs", "changing-region") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - opttest.YarnLink("@pulumi/aws"), - } - - t.Run("default provider", func(t *testing.T) { - test := pulumitest.NewPulumiTest(t, dir, options...) - for _, region := range []string{"us-east-1", "us-west-1"} { - test.SetConfig(t, "aws:region", region) - res := test.Up(t) - require.Equal(t, region, res.Outputs["actualRegion"].Value) - } - }) - - t.Run("explicit provider", func(t *testing.T) { - test := pulumitest.NewPulumiTest(t, dir, options...) - for _, region := range []string{"us-east-1", "us-west-1"} { - test.SetConfig(t, "desired-region", region) - res := test.Up(t) - require.Equal(t, region, res.Outputs["actualRegion"].Value) - } - }) -} - -func TestRegressAttributeMustBeWholeNumber(t *testing.T) { - // pulumi/pulumi-terraform-bridge#1940 - skipIfShort(t) - dir := filepath.Join("test-programs", "ec2-string-for-int") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - opttest.YarnLink("@pulumi/aws"), - } - test := pulumitest.NewPulumiTest(t, dir, options...) - result := test.Preview(t) - t.Logf("#%v", result.ChangeSummary) -} - -func TestRegress4079(t *testing.T) { - skipIfShort(t) - ctx := context.Background() - dir := filepath.Join("test-programs", "regress-4079") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - opttest.YarnLink("@pulumi/aws"), - } - test := pulumitest.NewPulumiTest(t, dir, options...) - - test.SetConfig(t, "targetGroupCount", "2") - r1 := test.Up(t) - t.Logf("Stdout: %v", r1.StdOut) - t.Logf("Stderr: %v", r1.StdErr) - - listenerARN := r1.Outputs["listenerARN"].Value.(string) - err = elb.ModifyListenerDefaultActions(ctx, listenerARN, func(as []elb.Action) []elb.Action { - r := []elb.Action{} - for _, a := range as { - b := a - t.Logf("BEFORE: len(ForwardConfig.TargetGroups)=%d", len(b.ForwardConfig.TargetGroups)) - b.ForwardConfig.TargetGroups = []elb.TargetGroupTuple{ - b.ForwardConfig.TargetGroups[0], - } - t.Logf("AFTER: len(ForwardConfig.TargetGroups)=%d", len(b.ForwardConfig.TargetGroups)) - r = append(r, b) - } - return r - }) - require.NoError(t, err) - - rr := test.Refresh(t) - t.Logf("Stdout: %v", rr.StdOut) - t.Logf("Stderr: %v", rr.StdErr) - - refreshedState := test.ExportStack(t) - - type resource struct { - Type string `json:"type"` - Outputs map[string]any `json:"outputs"` - } - type deployment struct { - Resources []resource `json:"resources"` - } - var data deployment - err = json.Unmarshal(refreshedState.Deployment, &data) - require.NoError(t, err) - - for _, r := range data.Resources { - if r.Type != "aws:lb/listener:Listener" { - continue - } - defaultAction1 := r.Outputs["defaultActions"].([]any)[0].(map[string]any) - t.Logf("defaultActions includes: %#v", defaultAction1) - require.NotNil(t, defaultAction1["forward"], "forward should be set in defaultActions") - require.Emptyf(t, defaultAction1["targetGroupArn"], "targetGroupArn should be empty in defaultActions") - } -} - -func TestParallelLambdaCreation(t *testing.T) { - // This test is flaky and needs to be fixed. It occasionally fails to find the lambda zip archive - t.Skipf("TODO[pulumi/pulumi-aws#4731]") - if testing.Short() { - t.Skipf("Skipping test in -short mode because it needs cloud credentials") - return - } - - tempFile, err := createLambdaArchive(25 * 1024 * 1024) - require.NoError(t, err) - defer os.Remove(tempFile) - - maxDuration(5*time.Minute, t, func(t *testing.T) { - test := getJSBaseOptions(t). - With(integration.ProgramTestOptions{ - Dir: filepath.Join("test-programs", "parallel-lambdas"), - Config: map[string]string{ - "lambda:archivePath": tempFile, - }, - // Lambdas have diffs on every update (source code hash) - AllowEmptyPreviewChanges: true, - SkipRefresh: true, - }) - - integration.ProgramTest(t, &test) - }) -} - -func TestRegress4128(t *testing.T) { - if testing.Short() { - t.Skipf("Skipping test in -short mode because it needs cloud credentials") - return - } - - test := getJSBaseOptions(t). - With(integration.ProgramTestOptions{ - Dir: filepath.Join("test-programs", "regress-4128"), - SkipRefresh: true, - }, - ) - // Disable envRegion mangling - test.Config = nil - integration.ProgramTest(t, &test) -} - -func TestGameLift(t *testing.T) { - if testing.Short() { - t.Skipf("Skipping test in -short mode because it needs cloud credentials") - return - } - - ptest := pulumiTest(t, filepath.Join("test-programs", "gamelift-typescript")) - ptest.SetConfig(t, "customData", "A") - result1 := ptest.Up(t) - require.Equal(t, "A", result1.Outputs["CustomEventData"].Value) - ptest.SetConfig(t, "customData", "B") - result2 := ptest.Up(t) - require.Equal(t, "B", result2.Outputs["CustomEventData"].Value) -} - -func TestRegress4446(t *testing.T) { - skipIfShort(t) - dir := filepath.Join("test-programs", "regress-4446") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - opttest.YarnLink("@pulumi/aws"), - } - test := pulumitest.NewPulumiTest(t, dir, options...) - upResult := test.Up(t) - t.Logf("#%v", upResult.Summary) - result := test.Preview(t, optpreview.ExpectNoChanges()) - t.Logf("#%v", result.ChangeSummary) -} - -func TestRegress4568(t *testing.T) { - skipIfShort(t) - dir := filepath.Join("test-programs", "regress-4568") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - opttest.YarnLink("@pulumi/aws"), - } - test := pulumitest.NewPulumiTest(t, dir, options...) - upResult := test.Up(t) - t.Logf("#%v", upResult.Summary) - - // The singular lifecyclePolicy should contain the first value - assert.Equal(t, map[string]interface{}{ - "transitionToIa": "AFTER_30_DAYS", - "transitionToArchive": "", - "transitionToPrimaryStorageClass": "", - }, upResult.Outputs["lifecyclePolicy"].Value, "lifecyclePolicy should be set") - - // The plural lifecyclePolicies should contain both values - lifecyclePolicies := upResult.Outputs["lifecyclePolicies"].Value.([]interface{}) - assert.Len(t, lifecyclePolicies, 2, "lifecyclePolicies should have two elements") - - assert.Contains(t, lifecyclePolicies, map[string]interface{}{ - "transitionToIa": "AFTER_30_DAYS", - "transitionToArchive": "", - "transitionToPrimaryStorageClass": "", - }) - assert.Contains(t, lifecyclePolicies, map[string]interface{}{ - "transitionToPrimaryStorageClass": "AFTER_1_ACCESS", - "transitionToIa": "", - "transitionToArchive": "", - }) -} - -// Tests that there are no diagnostics by default on simple programs. -func TestNoExtranousLogOutput(t *testing.T) { - skipIfShort(t) - dir := filepath.Join("test-programs", "bucket-obj") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - } - test := pulumitest.NewPulumiTest(t, dir, options...) - result := test.Preview(t) - assert.NotContainsf(t, result.StdOut, "Diagnostics:", - "No diagnostics should be emitted to stdout for simple programs") - assert.NotContainsf(t, result.StdErr, "Diagnostics:", - "No diagnostics should be emitted to stderr for simple programs") -} - -// Since AWS is doing something non-standard with logging, double-check that `log.Printf` messages do get propagated -// when TF_LOG=DEBUG is set. One such message is set by aws.s3.Bucketv2 when refresh finds that the bucket no longer -// exists. Emulate this situation and assert that the message has propagated. -func TestUpstreamWarningsPropagated(t *testing.T) { - skipIfShort(t) - dir := filepath.Join("test-programs", "disappearing-bucket-object") - cwd, err := os.Getwd() - require.NoError(t, err) - providerName := "aws" - options := []opttest.Option{ - opttest.LocalProviderPath(providerName, filepath.Join(cwd, "..", "bin")), - opttest.YarnLink("@pulumi/aws"), - opttest.Env("TF_LOG", "DEBUG"), - } - test := pulumitest.NewPulumiTest(t, dir, options...) - - t.Logf("Creating the bucket object") - test.Up(t) - - state := test.ExportStack(t) - - t.Logf("Deleting the bucket object") - test.SetConfig(t, "bucket-object", "exclude") - test.Up(t) - - t.Logf("Resetting the state back") - test.ImportStack(t, state) - - t.Logf("Refreshing the stack and expecting bucket to be deleted from the state") - rr := test.Refresh(t) - t.Logf("%v%v", rr.StdOut, rr.StdErr) - - // Upstream code has this line: - // - // log.Printf("[WARN] S3 Object (%s) not found, removing from state", d.Id()) - // - assert.Containsf(t, - rr.StdErr+rr.StdOut, - "warning: S3 Object (index.ts) not found, removing from state", - "Expected upstream log.Printf to propagate under TF_LOG=DEBUG") -} - -func getJSBaseOptions(t *testing.T) integration.ProgramTestOptions { - envRegion := getEnvRegion(t) - baseJS := integration.ProgramTestOptions{ - Config: map[string]string{ - "aws:region": "INVALID_REGION", - "aws:envRegion": envRegion, - }, - Dependencies: []string{ - "@pulumi/aws", - }, - } - - return baseJS -} - -func createLambdaArchive(size int64) (string, error) { - // Create a temporary file to save the zip archive - tempFile, err := os.CreateTemp("", "archive-*.zip") - if err != nil { - return "", err - } - defer tempFile.Close() - - // Create a new zip archive - zipWriter := zip.NewWriter(tempFile) - defer func() { - err := zipWriter.Close() - contract.AssertNoErrorf(err, "Failed closing zip archive") - err = tempFile.Close() - contract.AssertNoErrorf(err, "Failed closing temporary file") - }() - - randomDataReader := io.LimitReader(rand.Reader, size) - - // Create the index.js file for the lambda - indexWriter, err := zipWriter.Create("index.js") - if err != nil { - return "", err - } - _, err = indexWriter.Write([]byte("const { version } = require(\"@aws-sdk/client-s3/package.json\");\n\nexports.handler = async () => ({ version });\n")) - if err != nil { - return "", err - } - - randomDataWriter, err := zipWriter.Create("random.txt") - if err != nil { - return "", err - } - _, err = io.Copy(randomDataWriter, randomDataReader) - if err != nil { - return "", err - } - - // Get the path of the temporary file - archivePath, err := filepath.Abs(tempFile.Name()) - if err != nil { - return "", err - } - - return archivePath, nil -} diff --git a/provider/provider_python_test.go b/provider/provider_python_test.go deleted file mode 100644 index 6732178ec45..00000000000 --- a/provider/provider_python_test.go +++ /dev/null @@ -1,120 +0,0 @@ -// Copyright 2016-2023, Pulumi Corporation. All rights reserved. - -//go:build !go && !yaml && !nodejs && !dotnet && !java -// +build !go,!yaml,!nodejs,!dotnet,!java - -package provider - -import ( - "bytes" - "os" - "path/filepath" - "strings" - "testing" - "time" - - "github.com/pulumi/pulumi/pkg/v3/testing/integration" - "github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview" - "github.com/stretchr/testify/require" -) - -func TestRegress3196(t *testing.T) { - if testing.Short() { - t.Skipf("Skipping test in -short mode because it needs cloud credentials") - return - } - maxDuration(6*time.Minute, t, func(t *testing.T) { - test := getPythonBaseOptions(t). - With(integration.ProgramTestOptions{ - Quick: true, - SkipRefresh: true, - Dir: filepath.Join("test-programs", "regress-3196"), - ExpectFailure: true, - }) - integration.ProgramTest(t, &test) - }) -} - -func TestRegress3887(t *testing.T) { - if testing.Short() { - t.Skipf("Skipping test in -short mode because it needs cloud credentials") - return - } - test := getPythonBaseOptions(t). - With(integration.ProgramTestOptions{ - Quick: true, - SkipRefresh: true, - Dir: filepath.Join("test-programs", "regress-3887"), - EditDirs: []integration.EditDir{ - { - Dir: filepath.Join("test-programs", "regress-3887", "step-1"), - Additive: true, - }, - { - Dir: filepath.Join("test-programs", "regress-3887", "step-2"), - Additive: true, - }, - }, - }) - integration.ProgramTest(t, &test) -} - -// Make sure that importing an AWS targetGroup succeeds. -func TestRegress2534(t *testing.T) { - ptest := pulumiTest(t, filepath.Join("test-programs", "regress-2534")) - upResult := ptest.Up(t) - targetGroupArn := upResult.Outputs["targetGroupArn"].Value.(string) - targetGroupUrn := upResult.Outputs["targetGroupUrn"].Value.(string) - workspace := ptest.CurrentStack().Workspace() - t.Logf("Provisioned target group with arn=%s", targetGroupArn) - workdir := workspace.WorkDir() - t.Logf("workdir = %s", workdir) - - execPulumi(t, ptest, workdir, "import", "aws:lb/targetGroup:TargetGroup", "newtg", targetGroupArn, "--yes") - execPulumi(t, ptest, workdir, "state", "unprotect", strings.ReplaceAll(targetGroupUrn, "::test", "::newtg"), "--yes") -} - -func TestRegress4457(t *testing.T) { - ptest := pulumiTest(t, filepath.Join("test-programs", "regress-4457")) - upResult := ptest.Up(t) - autoGroupArn := upResult.Outputs["autoGroupArn"].Value.(string) - autoGroupUrn := upResult.Outputs["autoGroupUrn"].Value.(string) - autoGroupName := upResult.Outputs["autoGroupName"].Value.(string) - workspace := ptest.CurrentStack().Workspace() - - t.Logf("Provisioned autoscaling group with arn=%s and urn=%s and name=%s", autoGroupArn, autoGroupUrn, autoGroupName) - workdir := workspace.WorkDir() - t.Logf("workdir = %s", workdir) - - importResult := ptest.Import(t, "aws:autoscaling/group:Group", "newag", autoGroupName, "" /* providerUrn */) - - t.Logf("Editing the program to add the code recommended by import") - i := strings.Index(importResult.Stdout, "import pulumi") - extraCode := importResult.Stdout[i:] - mainPy := filepath.Join(ptest.WorkingDir(), "__main__.py") - pyBytes, err := os.ReadFile(mainPy) - require.NoError(t, err) - updatedPyBytes := bytes.ReplaceAll(pyBytes, []byte("# EXTRA CODE HERE"), []byte(extraCode)) - err = os.WriteFile(mainPy, updatedPyBytes, 0600) - require.NoError(t, err) - - t.Logf("Previewing the edited program") - previewResult := ptest.Preview(t, optpreview.ExpectNoChanges()) - t.Logf("%s", previewResult.StdOut) - t.Logf("%s", previewResult.StdErr) -} - -func getPythonBaseOptions(t *testing.T) integration.ProgramTestOptions { - t.Helper() - envRegion := getEnvRegion(t) - pythonBase := integration.ProgramTestOptions{ - Config: map[string]string{ - "aws:region": envRegion, - }, - Dependencies: []string{ - filepath.Join("..", "sdk", "python", "bin"), - }, - } - - return pythonBase -} diff --git a/provider/provider_yaml_test.go b/provider/provider_yaml_test.go deleted file mode 100644 index ac53193443d..00000000000 --- a/provider/provider_yaml_test.go +++ /dev/null @@ -1,1055 +0,0 @@ -// Copyright 2016-2024, Pulumi Corporation. All rights reserved. - -//go:build !go && !nodejs && !python && !dotnet -// +build !go,!nodejs,!python,!dotnet - -package provider - -import ( - "bytes" - "context" - "fmt" - "io" - "math/rand" - "os" - "os/exec" - "path/filepath" - "runtime" - "sort" - "strings" - "testing" - - "github.com/aws/aws-sdk-go-v2/aws" - "github.com/aws/aws-sdk-go-v2/config" - appconfigsdk "github.com/aws/aws-sdk-go-v2/service/appconfig" - tagsdk "github.com/aws/aws-sdk-go-v2/service/resourcegroupstaggingapi" - s3sdk "github.com/aws/aws-sdk-go-v2/service/s3" - "github.com/aws/aws-sdk-go-v2/service/s3/types" - "github.com/pulumi/providertest/pulumitest" - "github.com/pulumi/providertest/pulumitest/assertpreview" - "github.com/pulumi/providertest/pulumitest/opttest" - "github.com/pulumi/pulumi/sdk/v3/go/auto" - "github.com/pulumi/pulumi/sdk/v3/go/auto/optpreview" - "github.com/pulumi/pulumi/sdk/v3/go/auto/optrefresh" - "github.com/pulumi/pulumi/sdk/v3/go/auto/optup" - "github.com/pulumi/pulumi/sdk/v3/go/common/apitype" - "github.com/pulumi/pulumi/sdk/v3/go/common/util/contract" - "github.com/pulumi/pulumi/sdk/v3/go/pulumi" - "github.com/stretchr/testify/assert" - "github.com/stretchr/testify/require" -) - -func TestBucketUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "bucket"), nil) -} - -func TestEKSClusterUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "eks-cluster"), nil) -} - -func TestRdsInstanceUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "rds-instance"), nil) -} - -func TestRoute53ResolverEndpointUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "route53-resolver-endpoint"), nil) -} - -func TestSnsTopicUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "sns-topic"), nil) -} - -func TestApiGatewayIntegrationResponseUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "apigateway-integrationresponse"), nil) -} - -func TestApiGatewayMethodResponseUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "apigateway-methodreponse"), nil) -} - -func TestApiGatewayResourceUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "apigateway-resource"), nil) -} - -func TestApiGatewayResourceResponseUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "apigateway-resource-response"), nil) -} - -func TestCloudwatchEventRuleUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "cloudwatch-eventrule"), nil) -} - -func TestCloudwatchLogGroupUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "cloudwatch-loggroup"), nil) -} - -func TestDynamoTableUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "dynamodb-table"), nil) -} - -func TestEcrLifecyclePolicyUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "ecr-lifecyclepolicy"), nil) -} - -func TestEcrRepositoryUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "ecr-repository"), nil) -} - -func TestIamInstanceProfileUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "iam-instanceprofile"), nil) -} - -func TestIamOpenIDConnectProviderUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "iam-openidconnectprovider"), nil) -} - -func TestKmsKeyUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "kms-key"), nil) -} - -func TestSecretsManagerSecretUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "secretsmanager-secret"), nil) -} - -func TestEC2NetworkingUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "ec2-networking"), nil) -} - -func TestECSServiceUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "ecs-service"), nil) -} - -func TestIAMUserUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "iam-user"), nil) -} - -func TestLBUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "lb"), nil) -} - -func TestACMUpgrade(t *testing.T) { - t.Skip("Blocked by https://github.com/pulumi/pulumi-aws/issues/3617") - testProviderUpgrade(t, filepath.Join("test-programs", "acm"), nil) -} - -func TestBucketObjUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "bucket-obj"), nil) -} - -func TestSubnetGroupUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "subnet-group"), nil) -} - -func TestEC2InstanceUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "ec2-instance"), nil) -} - -func TestCloudfrontDistributionUpgrade(t *testing.T) { - // Baseline version is needed because of https://github.com/pulumi/providertest/issues/76 - testProviderUpgrade(t, filepath.Join("test-programs", "cloudfront-distribution"), &testProviderUpgradeOptions{ - baselineVersion: "6.10.0", - }) -} - -func TestSecretVersionUpgrade(t *testing.T) { - testProviderUpgrade(t, filepath.Join("test-programs", "secretversion"), nil) -} - -func TestRdsParameterGroupUnclearDiff(t *testing.T) { - t.Parallel() - if testing.Short() { - t.Skipf("Skipping in testing.Short() mode, assuming this is a CI run without credentials") - } - - type yamlProgram string - - const yaml yamlProgram = ` -name: project -runtime: yaml -config: - applyMethod: - type: string - value: - type: string - randSuffix: - type: string -resources: - default: - type: aws:rds/parameterGroup:ParameterGroup - properties: - name: securitygroup${randSuffix} - family: postgres14 - parameters: - - name: track_io_timing - value: ${value} - applyMethod: ${applyMethod} - - name: "log_checkpoints" - applyMethod: "pending-reboot" - value: "1" -` - - const noApplyYaml yamlProgram = ` -name: project -runtime: yaml -config: - value: - type: string - randSuffix: - type: string -resources: - default: - type: aws:rds/parameterGroup:ParameterGroup - properties: - name: securitygroup${randSuffix} - family: postgres14 - parameters: - - name: track_io_timing - value: ${value} - - name: "log_checkpoints" - applyMethod: "pending-reboot" - value: "1" -` - - type applyMethod string - - var immediate applyMethod = "immediate" - var pendingReboot applyMethod = "pending-reboot" - - type testCase struct { - name string - applyMethod1 *applyMethod - value1 string - file1 yamlProgram - applyMethod2 *applyMethod - value2 string - file2 yamlProgram - expectChanges bool - } - - testCases := []testCase{ - {"non-nil apply method, apply method change", &immediate, "1", yaml, &pendingReboot, "1", yaml, false}, - {"non-nil apply method, value change", &immediate, "1", yaml, &immediate, "0", yaml, true}, - {"non-nil apply method, both change", &immediate, "1", yaml, &pendingReboot, "0", yaml, true}, - {"non-nil to nil apply method, apply method change", &pendingReboot, "1", yaml, nil, "1", noApplyYaml, false}, - {"non-nil to nil apply method, value change", &immediate, "1", yaml, nil, "0", noApplyYaml, true}, - {"non-nil to nil apply method, both change", &immediate, "1", yaml, nil, "0", noApplyYaml, true}, - {"nil to non-nil apply method, apply method change", nil, "1", noApplyYaml, &pendingReboot, "1", yaml, false}, - {"nil to non-nil apply method, value change", nil, "1", noApplyYaml, &immediate, "0", yaml, true}, - {"nil to non-nil apply method, both change", nil, "1", noApplyYaml, &immediate, "0", yaml, true}, - {"nil apply method, value change", nil, "1", noApplyYaml, nil, "0", noApplyYaml, true}, - } - - cwd, err := os.Getwd() - require.NoError(t, err) - - for _, tc := range testCases { - tc := tc - - t.Run(tc.name, func(t *testing.T) { - t.Parallel() - workdir := t.TempDir() - - err := os.WriteFile(filepath.Join(workdir, "Pulumi.yaml"), []byte(tc.file1), 0o600) - require.NoError(t, err) - - pt := pulumitest.NewPulumiTest(t, workdir, - opttest.SkipInstall(), - opttest.TestInPlace(), - opttest.LocalProviderPath("aws", filepath.Join(cwd, "..", "bin")), - ) - - pt.SetConfig(t, "randSuffix", fmt.Sprintf("%d-x", rand.Intn(1024*1024))) - - if tc.applyMethod1 != nil { - pt.SetConfig(t, "applyMethod", string(*tc.applyMethod1)) - } - pt.SetConfig(t, "value", tc.value1) - - pt.Up(t) - - assertpreview.HasNoChanges(t, pt.Preview(t)) - - err = os.WriteFile(filepath.Join(workdir, "Pulumi.yaml"), []byte(tc.file2), 0o600) - require.NoError(t, err) - - if tc.applyMethod2 != nil { - if tc.file2 == noApplyYaml { - t.Errorf("WRONG FILE!") - } - pt.SetConfig(t, "applyMethod", string(*tc.applyMethod2)) - } - pt.SetConfig(t, "value", tc.value2) - - if tc.expectChanges { - pr := pt.Preview(t) - assert.Equal(t, 1, pr.ChangeSummary[apitype.OpUpdate]) - } else { - assertpreview.HasNoChanges(t, pt.Preview(t)) - } - - upr := pt.Up(t) - t.Logf("stdout: %s", upr.StdOut) - t.Logf("stderr: %s", upr.StdErr) - - assertpreview.HasNoChanges(t, pt.Preview(t)) - }) - } -} - -var letters = []rune("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ") - -func randSeq(n int) string { - b := make([]rune, n) - for i := range b { - b[i] = letters[rand.Intn(len(letters))] - } - return string(b) -} - -func TestNonIdempotentSnsTopic(t *testing.T) { - t.Parallel() - ptest := pulumiTest(t, filepath.Join("test-programs", "non-idempotent-sns-topic"), opttest.SkipInstall()) - - ptest.InstallStack(t, "test") - // generate random name - topic_name := randSeq(12) - ptest.SetConfig(t, "snsTopicName", topic_name) - - _, err := ptest.CurrentStack().Up(ptest.Context()) - require.ErrorContains(t, err, "already exists") -} - -func TestOpenZfsFileSystemUpgrade(t *testing.T) { - t.Parallel() - if testing.Short() { - t.Skipf("Skipping in testing.Short() mode, assuming this is a CI run without credentials") - } - const pulumiYaml = ` -name: openzfs -runtime: yaml -resources: - MyFileSystem: - properties: - deploymentType: SINGLE_AZ_1 - storageCapacity: 64 - %s - throughputCapacity: 64 - type: aws:fsx:OpenZfsFileSystem - MySubnet: - properties: - cidrBlock: "10.0.1.0/24" - vpcId: ${MyVPC.id} - type: aws:ec2:Subnet - MyVPC: - properties: - cidrBlock: "10.0.0.0/16" - type: aws:ec2:Vpc -` - - var ( - providerName string = "aws" - baselineVersion string = "6.41.0" - ) - cwd, err := os.Getwd() - assert.NoError(t, err) - workdir := t.TempDir() - - firstProgram := []byte(fmt.Sprintf(pulumiYaml, "subnetIds: ${MySubnet.id}")) - secondProgram := []byte(fmt.Sprintf(pulumiYaml, "subnetIds:\n - ${MySubnet.id}")) - // test that we can upgrade from the previous version which accepted a string for `subnetIds` - // to the new version which accepts a list - t.Run("upgrade", func(t *testing.T) { - pulumiTest := testProviderCodeChanges(t, &testProviderCodeChangesOptions{ - firstProgram: firstProgram, - firstProgramOptions: []opttest.Option{ - opttest.DownloadProviderVersion(providerName, baselineVersion), - }, - secondProgram: secondProgram, - secondProgramOptions: []opttest.Option{ - opttest.LocalProviderPath("aws", filepath.Join(cwd, "..", "bin")), - }, - }) - - res := pulumiTest.Preview(t) - t.Logf("stdout: %s \n", res.StdOut) - t.Logf("stderr: %s \n", res.StdErr) - assertpreview.HasNoChanges(t, res) - - upResult := pulumiTest.Up(t) - t.Logf("stdout: %s \n", upResult.StdOut) - t.Logf("stderr: %s \n", upResult.StdErr) - }) - - // test that we can deploy a new filesystem with a list of subnetIds - // we use a test with a snapshot since this test is only useful the first time, once - // we know it works it should continue to work. - t.Run("new-version", func(t *testing.T) { - t.Parallel() - err = os.WriteFile(filepath.Join(workdir, "Pulumi.yaml"), secondProgram, 0o600) - assert.NoError(t, err) - pulumiTest := pulumitest.NewPulumiTest(t, workdir, - opttest.SkipInstall(), - opttest.LocalProviderPath("aws", filepath.Join(cwd, "..", "bin")), - ) - - pulumiTest.SetConfig(t, "aws:region", "us-east-2") - - pulumiUpWithSnapshot(t, pulumiTest) - }) -} - -// Make sure that legacy Bucket supports deleting tags out of band and detecting drift. -func TestRegress3674(t *testing.T) { - t.Parallel() - ptest := pulumiTest(t, filepath.Join("test-programs", "regress-3674"), opttest.SkipInstall()) - upResult := ptest.Up(t) - bucketName := upResult.Outputs["bucketName"].Value.(string) - deleteBucketTagging(ptest.Context(), bucketName) - result := ptest.Refresh(t) - t.Logf("%s", result.StdOut) - require.Equal(t, 1, (*result.Summary.ResourceChanges)["update"]) - state, err := ptest.ExportStack(t).Deployment.MarshalJSON() - require.NoError(t, err) - require.NotContainsf(t, string(state), "MyTestTag", "Expected MyTestTag to be removed") -} - -// Ensure that pulumi-aws can authenticate using IMDS API when Pulumi is running in a context where that is made -// available such as an EC2 instance. -func TestIMDSAuth(t *testing.T) { - t.Parallel() - var localProviderBuild string - actual := fmt.Sprintf("%s/%s", runtime.GOOS, runtime.GOARCH) - expected := "linux/amd64" - cwd, err := os.Getwd() - require.NoError(t, err) - if actual == expected { - currentBinary, err := filepath.Abs(filepath.Join(cwd, "..", "bin", "pulumi-resource-aws")) - require.NoError(t, err) - t.Logf("Reusing prebuilt binary from %s to test %q", currentBinary, expected) - localProviderBuild = currentBinary - } else { - t.Logf("Cross-compiling provider-resource-aws under test to %q", expected) - localProviderBuild = filepath.Join(os.TempDir(), "pulumi-resource-aws") - ldFlags := []string{ - "-X", "github.com/pulumi/pulumi-aws/provider/v6/pkg/version.Version=6.0.0-alpha.0+dev", - "-X", "github.com/hashicorp/terraform-provider-aws/version.ProviderVersion=6.0.0-alpha.0+dev", - } - args := []string{ - "build", "-o", localProviderBuild, - "-ldflags", strings.Join(ldFlags, " "), - } - cmd := exec.Command("go", args...) - cmd.Dir = filepath.Join(cwd, "cmd", "pulumi-resource-aws") - cmd.Env = os.Environ() - cmd.Env = append(cmd.Env, - fmt.Sprintf("GOOS=linux"), - fmt.Sprintf("GOARCH=amd64"), - ) - var stderr, stdout bytes.Buffer - cmd.Stderr = &stderr - cmd.Stdout = &stdout - if err := cmd.Run(); err != nil { - t.Logf("go %s failed\nStdout:\n%s\nStderr:\n%s\n", strings.Join(args, " "), - stdout.String(), stderr.String()) - require.NoError(t, err) - } - } - t.Run("IDMSv2", func(t *testing.T) { - t.Parallel() - ptest := pulumiTest(t, filepath.Join("test-programs", "imds-auth", "imds-v2"), opttest.SkipInstall()) - dir := ptest.WorkingDir() - localLocation := filepath.Join(dir, "pulumi-resource-aws") - // need to copy the provider to the local directory for BucketObjectV2 to pick it up - // otherwise you get an error `Argument must be a constant or contained in the project dir` - err := copyFile(localProviderBuild, localLocation) - assert.NoError(t, err) - ptest.SetConfig(t, "localProviderBuild", localLocation) - result := ptest.Up(t) - t.Logf("stdout: %s", result.StdOut) - t.Logf("stderr: %s", result.StdErr) - t.Logf("commandOut: %v", result.Outputs["commandOut"].Value) - }) -} - -func copyFile(src, dst string) error { - srcFile, err := os.Open(src) - if err != nil { - return err - } - defer srcFile.Close() - - dstFile, err := os.Create(dst) - if err != nil { - return err - } - defer dstFile.Close() - - _, err = io.Copy(dstFile, srcFile) - if err != nil { - return err - } - - err = dstFile.Sync() - return err -} - -// Assert that the provider does not regress on emitting an unexpected deprecation. -// -// use the aws_s3_object resource instead -// -// See https://github.com/pulumi/pulumi-aws/issues/2796 -func TestS3BucketObjectDeprecation(t *testing.T) { - t.Parallel() - ptest := pulumiTest(t, filepath.Join("test-programs", "regress-2796"), opttest.SkipInstall()) - result := ptest.Up(t) - t.Logf("STDOUT: %v", result.StdOut) - t.Logf("STDERR: %v", result.StdErr) - require.NotContains(t, result.StdOut+result.StdErr, "aws_s3_object") -} - -type tagsTestStep struct { - // The name of the Pulumi program - name string - - // The type token of the resource, i.e. aws:s3:Bucket - token string - - // The pulumi type of the resource, i.e. aws:s3/bucket:Bucket - typ string - - // Constant properties for the primary resource under test. - // - // This cannot include the tags property, which will be adjusted by the test. - properties map[string]interface{} - - // List of tags to add to the resource - tags map[string]interface{} - - // List of default tags to add to the provider - defaultTags map[string]interface{} - - // List of tag keys to add to the provider `ignoreTags.Keys` property - ignoreTagKeys []string - - // Function to run prior to _any_ import step - preImportHook func(t *testing.T, outputs auto.OutputMap) - - // Function to run after running the first up. This can be used to - // run extra validation - postUpHook func(t *testing.T, outputs auto.OutputMap) - - // Other is a string that is inserted into the test program. It is intended to be - // used to provision supporting resources in tests. - other string - - // If skip is non-empty, the test will be skipped with `skip` as the given reason. - skip string -} - -// TestAccDefaultTags tries to test all the scenarios that might affect provider defaultTags / resource tags -// i.e. up, refresh, preview, import, etc -func TestAccDefaultTagsWithImport(t *testing.T) { - t.Parallel() - if testing.Short() { - t.Skipf("Skipping in testing.Short() mode, assuming this is a CI run without credentials") - } - - isNil := func(val interface{}) bool { - if val == nil { - return true - } - v, ok := val.(map[string]interface{}) - return ok && len(v) == 0 - } - validateOutputTags := func(outputs auto.OutputMap, expectedTags map[string]interface{}) { - stackOutputTags := outputs["actual"] - if !isNil(expectedTags) || !isNil(stackOutputTags) { - assert.Equal(t, expectedTags, stackOutputTags.Value) - } - } - - steps := []tagsTestStep{ - // Pulumi maintains it's own version of aws:s3:Bucket in - // `s3legacy/bucket_legacy.go`. Because we don't have any - // terraform-provider-aws maintainers to ensure our tagging works the same - // way as other resource's tagging, we give our own bucket special testing - // to make sure that tags work. - { - name: "legacy", token: "aws:s3:Bucket", typ: "aws:s3/bucket:Bucket", - tags: map[string]interface{}{ - "LocalTag": "foo", - }, - defaultTags: map[string]interface{}{ - "GlobalTag": "bar", - }, - postUpHook: func(t *testing.T, outputs auto.OutputMap) { - validateOutputTags(outputs, map[string]interface{}{ - "LocalTag": "foo", - "GlobalTag": "bar", - }) - bucketName := outputs["id"].Value.(string) - tags := getBucketTagging(context.Background(), bucketName) - assert.Equal(t, tags, []types.Tag{ - { - Key: pulumi.StringRef("LocalTag"), - Value: pulumi.StringRef("foo"), - }, - { - Key: pulumi.StringRef("GlobalTag"), - Value: pulumi.StringRef("bar"), - }, - }) - }, - }, - { - name: "legacy_ignore_tags", token: "aws:s3:Bucket", typ: "aws:s3/bucket:Bucket", - tags: map[string]interface{}{ - "LocalTag": "foo", - }, - ignoreTagKeys: []string{"IgnoreKey"}, - preImportHook: func(t *testing.T, outputs auto.OutputMap) { - t.Helper() - resArn := outputs["resArn"].Value.(string) - addResourceTags(context.Background(), resArn, map[string]string{ - "IgnoreKey": "foo", - }) - }, - defaultTags: map[string]interface{}{ - "GlobalTag": "bar", - }, - postUpHook: func(t *testing.T, outputs auto.OutputMap) { - validateOutputTags(outputs, map[string]interface{}{ - "LocalTag": "foo", - "GlobalTag": "bar", - }) - }, - }, - - // Both aws:cognito:UserPool and aws:s3:BucketV2 are full SDKv2 resources managed - // by Terraform, but they have different requirements for successful tag - // interactions. That is why we have tests for both resources. - { - name: "bucket", token: "aws:s3:BucketV2", typ: "aws:s3/bucketV2:BucketV2", - tags: map[string]interface{}{ - "LocalTag": "foo", - }, - postUpHook: func(t *testing.T, outputs auto.OutputMap) { - validateOutputTags(outputs, map[string]interface{}{ - "LocalTag": "foo", - "GlobalTag": "bar", - }) - }, - defaultTags: map[string]interface{}{ - "GlobalTag": "bar", - }, - }, - { - name: "bucket_ignore_tags", token: "aws:s3:BucketV2", typ: "aws:s3/bucketV2:BucketV2", - tags: map[string]interface{}{ - "LocalTag": "foo", - }, - postUpHook: func(t *testing.T, outputs auto.OutputMap) { - validateOutputTags(outputs, map[string]interface{}{ - "LocalTag": "foo", - "GlobalTag": "bar", - }) - }, - defaultTags: map[string]interface{}{ - "GlobalTag": "bar", - }, - ignoreTagKeys: []string{"IgnoreKey"}, - preImportHook: func(t *testing.T, outputs auto.OutputMap) { - t.Helper() - resArn := outputs["resArn"].Value.(string) - addResourceTags(context.Background(), resArn, map[string]string{ - "IgnoreKey": "foo", - }) - }, - }, - { - name: "sdkv2", token: "aws:cognito:UserPool", typ: "aws:cognito/userPool:UserPool", - tags: map[string]interface{}{ - "LocalTag": "foo", - }, - defaultTags: map[string]interface{}{ - "GlobalTag": "bar", - }, - postUpHook: func(t *testing.T, outputs auto.OutputMap) { - validateOutputTags(outputs, map[string]interface{}{ - "LocalTag": "foo", - "GlobalTag": "bar", - }) - }, - properties: map[string]interface{}{ - // aliasAttributes is necessary because otherwise we don't - // see a clean initial refresh - "aliasAttributes": []interface{}{"email"}, - }, - }, - - // A PF resource (appconfig:Environment) - // PF resources deal with tags differently - { - name: "pf", token: "aws:appconfig:Environment", typ: "aws:appconfig/environment:Environment", - tags: map[string]interface{}{ - "LocalTag": "foo", - }, - defaultTags: map[string]interface{}{ - "GlobalTag": "bar", - }, - postUpHook: func(t *testing.T, outputs auto.OutputMap) { - validateOutputTags(outputs, map[string]interface{}{ - "LocalTag": "foo", - "GlobalTag": "bar", - }) - }, - other: ` - app: - type: aws:appconfig:Application`, - properties: map[string]interface{}{ - "applicationId": "${app.id}", - }, - }, - { - name: "pf_ignore_tags", token: "aws:appconfig:Environment", typ: "aws:appconfig/environment:Environment", - tags: map[string]interface{}{ - "LocalTag": "foo", - }, - ignoreTagKeys: []string{"IgnoreKey"}, - preImportHook: func(t *testing.T, outputs auto.OutputMap) { - t.Helper() - resArn := outputs["resArn"].Value.(string) - addResourceTags(context.Background(), resArn, map[string]string{ - "IgnoreKey": "foo", - }) - }, - defaultTags: map[string]interface{}{ - "GlobalTag": "bar", - }, - postUpHook: func(t *testing.T, outputs auto.OutputMap) { - validateOutputTags(outputs, map[string]interface{}{ - "LocalTag": "foo", - "GlobalTag": "bar", - }) - }, - other: ` - app: - type: aws:appconfig:Application`, - properties: map[string]interface{}{ - "applicationId": "${app.id}", - }, - }, - } - - for _, step := range steps { - step := step - t.Run(step.name, func(t *testing.T) { - t.Parallel() - if reason := step.skip; reason != "" { - t.Skipf(reason) - } - testTagsPulumiLifecycle(t, step) - }) - } -} - -func TestAssumeRoleSessionTags(t *testing.T) { - t.Parallel() - ptest := pulumiTest(t, filepath.Join("test-programs", "assume-role-session-tags"), opttest.SkipInstall()) - result := ptest.Up(t) - t.Logf("STDOUT: %v", result.StdOut) - t.Logf("STDERR: %v", result.StdErr) - - require.Contains(t, result.Outputs, "bucketArn") - assert.NotEmpty(t, result.Outputs["bucketArn"].Value.(string)) -} - -// testTagsPulumiLifecycle tests the complete lifecycle of a pulumi program -// Scenarios that this tests: -// 1. `Up` with both provider `defaultTags`/`ignoreTags` and resource level `tags` -// 1a. Run validations on result -// 2. `Refresh` with no changes -// 3. `Import` using the resource option. Ensures resource can be successfully imported -// 3a. Allows for a hook to be run prior to import being run. e.g. Add tags remotely -// 4. `Import` using the CLI. Ensures resources can be successfully imported -// 4a. Allows for a hook to be run prior to import being run. e.g. Add tags remotely -// 5. `Refresh` with no changes -func testTagsPulumiLifecycle(t *testing.T, step tagsTestStep) { - t.Helper() - ctx := context.Background() - - stepDir, err := os.MkdirTemp(os.TempDir(), step.name) - assert.NoError(t, err) - fpath := filepath.Join(stepDir, "Pulumi.yaml") - - generateTagsTest(t, step, fpath, "") - ptest := pulumiTest(t, stepDir, opttest.TestInPlace(), opttest.SkipInstall()) - stack := ptest.CurrentStack() - - t.Log("Initial deployment...") - upRes, err := stack.Up(ctx) - assert.NoError(t, err) - outputs := upRes.Outputs - urn := outputs["urn"].Value.(string) - id := outputs["id"].Value.(string) - providerUrn := outputs["providerUrn"].Value.(string) - if step.postUpHook != nil { - step.postUpHook(t, outputs) - } - - t.Log("refresh...") - _, err = stack.Refresh(ctx, optrefresh.ExpectNoChanges()) - assert.NoError(t, err) - - t.Log("delete state...") - execPulumi(t, ptest, stepDir, "state", "delete", urn) - - // import using the import resource option - t.Log("up with import...") - if step.preImportHook != nil { - step.preImportHook(t, outputs) - } - generateTagsTest(t, step, fpath, id) - upRes, err = stack.Up(ctx, optup.Diff()) - assert.NoError(t, err) - changes := *upRes.Summary.ResourceChanges - assert.Equal(t, 1, changes["import"]) - - t.Log("delete state...") - execPulumi(t, ptest, stepDir, "state", "delete", urn) - - t.Log("import from cli...") - if step.preImportHook != nil { - step.preImportHook(t, outputs) - } - generateTagsTest(t, step, fpath, "") - execPulumi(t, ptest, stepDir, "import", step.typ, "res", id, "--provider", fmt.Sprintf("aws-provider=%s", providerUrn), "--yes") - execPulumi(t, ptest, stepDir, "state", "unprotect", urn, "--yes") - - // need to run an up to fix the state. It should be a no-op - // re https://github.com/pulumi/pulumi-aws/issues/4204 - upRes, err = stack.Up(ctx) - assert.NoError(t, err) - for k := range *upRes.Summary.ResourceChanges { - if k != "same" { - t.Fatal("expected no changes") - } - } - - t.Log("preview with refresh...") - _, err = stack.Preview(ctx, optpreview.Refresh(), optpreview.ExpectNoChanges()) - assert.NoError(t, err) -} - -// generateTagsTest generates a pulumi program for the given test step -// and writes it to the test directory -func generateTagsTest(t *testing.T, step tagsTestStep, testPath string, importId string) { - template := `name: test-aws-%s -runtime: yaml -resources: - aws-provider: - type: pulumi:providers:aws%s%s - res: - type: %s%s%s -outputs: - actual: ${res.tags} - urn: ${res.urn} - id: ${res.id} - resArn: ${res.arn} - providerUrn: ${aws-provider.urn}` - - options := map[string]interface{}{ - "provider": "${aws-provider}", - } - - if importId != "" { - options["import"] = importId - } - - var expandMap func(level int, v interface{}) string - expandMap = func(level int, v interface{}) string { - indent := "\n" + strings.Repeat(" ", level) - - var body string - switch v := v.(type) { - case nil: - return "" - case string: - body = v - case []string: - for _, v := range v { - body += indent + "- " + strings.TrimSpace(expandMap(level+1, v)) - } - case []interface{}: - for _, v := range v { - body += indent + "- " + strings.TrimSpace(expandMap(level+1, v)) - } - case map[string]interface{}: - sortedKeys := make([]string, len(v)) - for k := range v { - sortedKeys = append(sortedKeys, k) - } - sort.Strings(sortedKeys) - for _, k := range sortedKeys { - v := v[k] - - val := expandMap(level+1, v) - if val == "" { - continue - } - body += indent + k + ": " + val - } - default: - t.Logf("Unknown value type %T", v) - t.FailNow() - } - - return body - } - - expandProps := func(key string, props ...map[string]interface{}) string { - a := map[string]interface{}{} - for _, arg := range props { - for k, v := range arg { - a[k] = v - } - } - - return expandMap(2, map[string]interface{}{ - key: a, - }) - } - - providerProps := map[string]interface{}{ - "defaultTags": map[string]interface{}{ - "tags": step.defaultTags, - }, - } - if step.ignoreTagKeys != nil { - providerProps["ignoreTags"] = map[string]interface{}{ - "keys": step.ignoreTagKeys, - } - } - - body := fmt.Sprintf(template, step.name, - expandProps("properties", providerProps), step.other, step.token, - expandProps("options", options), - expandProps("properties", map[string]interface{}{ - "tags": step.tags, - }, step.properties)) - - t.Logf("template for %s: \n%s", step.name, body) - require.NoError(t, os.WriteFile(testPath, []byte(body), 0600)) -} - -func loadAwsDefaultConfig() aws.Config { - loadOpts := []func(*config.LoadOptions) error{} - if p, ok := os.LookupEnv("AWS_PROFILE"); ok { - loadOpts = append(loadOpts, config.WithSharedConfigProfile(p)) - } - if r, ok := os.LookupEnv("AWS_REGION"); ok { - loadOpts = append(loadOpts, config.WithRegion(r)) - } - cfg, err := config.LoadDefaultConfig(context.TODO(), loadOpts...) - contract.AssertNoErrorf(err, "failed to load AWS config") - - return cfg -} - -func configureS3() *s3sdk.Client { - cfg := loadAwsDefaultConfig() - return s3sdk.NewFromConfig(cfg) -} - -func configureAppconfig() *appconfigsdk.Client { - cfg := loadAwsDefaultConfig() - return appconfigsdk.NewFromConfig(cfg) -} - -func configureTagSdk() *tagsdk.Client { - cfg := loadAwsDefaultConfig() - return tagsdk.NewFromConfig(cfg) -} - -func addResourceTags(ctx context.Context, arn string, tags map[string]string) { - tag := configureTagSdk() - _, err := tag.TagResources(ctx, &tagsdk.TagResourcesInput{ - ResourceARNList: []string{arn}, - Tags: tags, - }) - contract.AssertNoErrorf(err, "error tagging resource") -} - -func addAppconfigEnvironmentTags(ctx context.Context, envArn string, tags map[string]string) { - appconfig := configureAppconfig() - existingTags, err := appconfig.ListTagsForResource(ctx, &appconfigsdk.ListTagsForResourceInput{ - ResourceArn: &envArn, - }) - contract.AssertNoErrorf(err, "failed to list tags for appconfig env") - - for k, v := range existingTags.Tags { - if _, exists := tags[k]; !exists { - tags[k] = v - } - } - - _, err = appconfig.TagResource(ctx, &appconfigsdk.TagResourceInput{ - ResourceArn: &envArn, - Tags: tags, - }) - contract.AssertNoErrorf(err, "error tagging appconfig env") -} - -func getBucketTagging(ctx context.Context, awsBucket string) []types.Tag { - s3 := configureS3() - tagging, err := s3.GetBucketTagging(ctx, &s3sdk.GetBucketTaggingInput{ - Bucket: &awsBucket, - }) - contract.AssertNoErrorf(err, "failed to get bucket tagging") - return tagging.TagSet -} - -func addBucketTags(ctx context.Context, bucketName string, tags map[string]string) { - s3 := configureS3() - existingTags := getBucketTagging(ctx, bucketName) - - newTags := []types.Tag{} - - for k, v := range tags { - newTags = append(newTags, types.Tag{ - Key: &k, - Value: &v, - }) - } - - for _, v := range existingTags { - if _, exists := tags[*v.Key]; !exists { - newTags = append(newTags, v) - } - } - - _, err := s3.PutBucketTagging(ctx, &s3sdk.PutBucketTaggingInput{ - Bucket: &bucketName, - Tagging: &types.Tagging{ - TagSet: newTags, - }, - }) - contract.AssertNoErrorf(err, "error putting bucket tags") -} - -func deleteBucketTagging(ctx context.Context, awsBucket string) { - s3 := configureS3() - _, err := s3.DeleteBucketTagging(ctx, &s3sdk.DeleteBucketTaggingInput{ - Bucket: &awsBucket, - }) - contract.AssertNoErrorf(err, "failed to delete bucket tagging") -} - -func getCwd(t *testing.T) string { - cwd, err := os.Getwd() - if err != nil { - t.FailNow() - } - - return cwd -}