diff --git a/examples/ecs-parallel/Pulumi.yaml b/examples/ecs-parallel/Pulumi.yaml new file mode 100644 index 000000000..08546c746 --- /dev/null +++ b/examples/ecs-parallel/Pulumi.yaml @@ -0,0 +1,3 @@ +name: ecs-parallel +runtime: nodejs +description: An ECS cluster with a Fargate service diff --git a/examples/ecs-parallel/index.ts b/examples/ecs-parallel/index.ts new file mode 100644 index 000000000..47785d74e --- /dev/null +++ b/examples/ecs-parallel/index.ts @@ -0,0 +1,50 @@ +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; +import * as awsx from "@pulumi/awsx"; + +const image = "docker.io/memcached:1.6.28" + +const clusterA = new aws.ecs.Cluster("cluster-a", {}); +const clusterB = new aws.ecs.Cluster("cluster-b", {}); + +for (let i = 0; i < 5; i++) { + new awsx.ecs.FargateService(`cluster-a-service-${i}`, { + cluster: clusterA.arn, + assignPublicIp: true, + desiredCount: 1, + taskDefinitionArgs: { + container: { + name: `cluster-a-service-${i}`, + image, + cpu: 128, + memory: 512, + essential: true, + }, + }, + forceNewDeployment: true, + triggers: { + redeployment: Date.now().toString(), + } + }); +} + +for (let i = 0; i < 5; i++) { + new awsx.ecs.FargateService(`cluster-b-service-${i}`, { + cluster: clusterB.arn, + assignPublicIp: true, + desiredCount: 1, + taskDefinitionArgs: { + container: { + name: `cluster-b-service-${i}`, + image, + cpu: 128, + memory: 512, + essential: true, + }, + }, + forceNewDeployment: true, + triggers: { + redeployment: Date.now().toString(), + } + }); +} diff --git a/examples/ecs-parallel/package.json b/examples/ecs-parallel/package.json new file mode 100644 index 000000000..f7dba01b2 --- /dev/null +++ b/examples/ecs-parallel/package.json @@ -0,0 +1,10 @@ +{ + "name": "ecs-parallel", + "devDependencies": { + "@types/node": "^10.0.0" + }, + "dependencies": { + "@pulumi/aws": "^6.0.4", + "@pulumi/pulumi": "^3.0.0" + } +} diff --git a/examples/ecs-parallel/step2/index.ts b/examples/ecs-parallel/step2/index.ts new file mode 100644 index 000000000..dfef8d397 --- /dev/null +++ b/examples/ecs-parallel/step2/index.ts @@ -0,0 +1,50 @@ +import * as pulumi from "@pulumi/pulumi"; +import * as aws from "@pulumi/aws"; +import * as awsx from "@pulumi/awsx"; + +const image = "docker.io/memcached:1.6.29" + +const clusterA = new aws.ecs.Cluster("cluster-a", {}); +const clusterB = new aws.ecs.Cluster("cluster-b", {}); + +for (let i = 0; i < 5; i++) { + new awsx.ecs.FargateService(`cluster-a-service-${i}`, { + cluster: clusterA.arn, + assignPublicIp: true, + desiredCount: 1, + taskDefinitionArgs: { + container: { + name: `cluster-a-service-${i}`, + image, + cpu: 128, + memory: 512, + essential: true, + }, + }, + forceNewDeployment: true, + triggers: { + redeployment: Date.now().toString(), + } + }); +} + +for (let i = 0; i < 5; i++) { + new awsx.ecs.FargateService(`cluster-b-service-${i}`, { + cluster: clusterB.arn, + assignPublicIp: true, + desiredCount: 1, + taskDefinitionArgs: { + container: { + name: `cluster-b-service-${i}`, + image, + cpu: 128, + memory: 512, + essential: true, + }, + }, + forceNewDeployment: true, + triggers: { + redeployment: Date.now().toString(), + } + }); +} diff --git a/examples/ecs-parallel/tsconfig.json b/examples/ecs-parallel/tsconfig.json new file mode 100644 index 000000000..ab65afa61 --- /dev/null +++ b/examples/ecs-parallel/tsconfig.json @@ -0,0 +1,18 @@ +{ + "compilerOptions": { + "strict": true, + "outDir": "bin", + "target": "es2016", + "module": "commonjs", + "moduleResolution": "node", + "sourceMap": true, + "experimentalDecorators": true, + "pretty": true, + "noFallthroughCasesInSwitch": true, + "noImplicitReturns": true, + "forceConsistentCasingInFileNames": true + }, + "files": [ + "index.ts" + ] +} diff --git a/examples/examples_nodejs_test.go b/examples/examples_nodejs_test.go index 5c0fbc109..ba5680dee 100644 --- a/examples/examples_nodejs_test.go +++ b/examples/examples_nodejs_test.go @@ -19,6 +19,7 @@ package examples import ( "path/filepath" "testing" + "time" "github.com/pulumi/pulumi/pkg/v3/testing/integration" "github.com/stretchr/testify/assert" @@ -201,6 +202,24 @@ func TestVpcMultipleSimilarSubnetSpecArgs(t *testing.T) { integration.ProgramTest(t, &test) } +func TestAccEcsParallel(t *testing.T) { + maxDuration(15*time.Minute, t, func(t *testing.T) { + test := getNodeJSBaseOptions(t). + With(integration.ProgramTestOptions{ + RunUpdateTest: false, + Dir: filepath.Join(getCwd(t), "ecs-parallel"), + EditDirs: []integration.EditDir{ + { + Dir: filepath.Join(getCwd(t), "ecs-parallel", "step2"), + Additive: true, + }, + }, + }) + + integration.ProgramTest(t, &test) + }) +} + func getNodeJSBaseOptions(t *testing.T) integration.ProgramTestOptions { base := getBaseOptions(t) nodeBase := base.With(integration.ProgramTestOptions{ diff --git a/examples/examples_test.go b/examples/examples_test.go index 1fbb7387d..37b86312f 100644 --- a/examples/examples_test.go +++ b/examples/examples_test.go @@ -4,6 +4,7 @@ import ( "fmt" "os" "testing" + "time" "github.com/pulumi/pulumi/pkg/v3/testing/integration" ) @@ -40,3 +41,18 @@ func getBaseOptions(t *testing.T) integration.ProgramTestOptions { return baseJS } + +func maxDuration(dur time.Duration, t *testing.T, test func(t *testing.T)) { + t.Helper() + timeout := time.After(dur) + done := make(chan bool) + go func() { + test(t) + done <- true + }() + select { + case <-timeout: + t.Fatalf("Test timed out after %v", dur) + case <-done: + } +}