From 15945e831ba746e959effaa7270b378c0aa4fce1 Mon Sep 17 00:00:00 2001 From: Elad Ben-Israel Date: Wed, 3 Jun 2020 13:11:00 +0300 Subject: [PATCH] add integration test to verify docker bootstrapping and publishing --- .../lib/api/bootstrap/bootstrap-template.yaml | 4 ++++ packages/aws-cdk/test/integ/cli/README.md | 2 +- .../aws-cdk/test/integ/cli/aws-helpers.ts | 5 ++++ .../test/integ/cli/bootstrapping.integtest.ts | 23 +++++++++++++++++++ .../aws-cdk/test/integ/cli/cdk-helpers.ts | 8 +++++-- packages/cdk-assets/lib/private/shell.ts | 6 ++++- 6 files changed, 44 insertions(+), 4 deletions(-) diff --git a/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml b/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml index 76edaac88b06b..5b61c2e99e7dd 100644 --- a/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml +++ b/packages/aws-cdk/lib/api/bootstrap/bootstrap-template.yaml @@ -347,6 +347,10 @@ Outputs: Description: The domain name of the S3 bucket owned by the CDK toolkit stack Value: Fn::Sub: "${StagingBucket.RegionalDomainName}" + ImageRepositoryName: + Description: The name of the ECR repository which hosts docker image assets + Value: + Fn::Sub: "${ContainerAssetsRepository}" BootstrapVersion: Description: The version of the bootstrap resources that are currently mastered in this stack diff --git a/packages/aws-cdk/test/integ/cli/README.md b/packages/aws-cdk/test/integ/cli/README.md index 44d531623e112..dd0935e96de11 100644 --- a/packages/aws-cdk/test/integ/cli/README.md +++ b/packages/aws-cdk/test/integ/cli/README.md @@ -34,7 +34,7 @@ Compilation of the tests is done as part of the normal package build, at which point it is using the dependencies brought in by the containing `aws-cdk` package's `package.json`. -When run in a non-develompent repo (as done during integ tests or canary runs), +When run in a non-development repo (as done during integ tests or canary runs), the required dependencies are brought in just-in-time via `test-jest.sh`. Any new dependencies added for the tests should be added there as well. But, better yet, don't add any dependencies at all. You shouldn't need to, these tests diff --git a/packages/aws-cdk/test/integ/cli/aws-helpers.ts b/packages/aws-cdk/test/integ/cli/aws-helpers.ts index 92cb7a77131a3..fb54db4f60bcd 100644 --- a/packages/aws-cdk/test/integ/cli/aws-helpers.ts +++ b/packages/aws-cdk/test/integ/cli/aws-helpers.ts @@ -20,6 +20,7 @@ export let testEnv = async (): Promise => { export const cloudFormation = makeAwsCaller(AWS.CloudFormation); export const s3 = makeAwsCaller(AWS.S3); +export const ecr = makeAwsCaller(AWS.ECR); export const sns = makeAwsCaller(AWS.SNS); export const iam = makeAwsCaller(AWS.IAM); export const lambda = makeAwsCaller(AWS.Lambda); @@ -188,6 +189,10 @@ export async function emptyBucket(bucketName: string) { }); } +export async function deleteImageRepository(repositoryName: string) { + await ecr('deleteRepository', { repositoryName, force: true }); +} + export async function deleteBucket(bucketName: string) { try { await emptyBucket(bucketName); diff --git a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts index 3c674470abe4c..07b81fd9cf998 100644 --- a/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts +++ b/packages/aws-cdk/test/integ/cli/bootstrapping.integtest.ts @@ -92,6 +92,29 @@ test('deploy new style synthesis to new style bootstrap', async () => { }); }); +test('deploy new style synthesis to new style bootstrap (with docker image)', async () => { + const bootstrapStackName = fullStackName('bootstrap-stack'); + + await cdk(['bootstrap', + '--toolkit-stack-name', bootstrapStackName, + '--qualifier', QUALIFIER, + '--cloudformation-execution-policies', 'arn:aws:iam::aws:policy/AdministratorAccess', + ], { + modEnv: { + CDK_NEW_BOOTSTRAP: '1', + }, + }); + + // Deploy stack that uses file assets + await cdkDeploy('docker', { + options: [ + '--toolkit-stack-name', bootstrapStackName, + '--context', `@aws-cdk/core:bootstrapQualifier=${QUALIFIER}`, + '--context', '@aws-cdk/core:newStyleStackSynthesis=1', + ], + }); +}); + test('deploy old style synthesis to new style bootstrap', async () => { const bootstrapStackName = fullStackName('bootstrap-stack'); diff --git a/packages/aws-cdk/test/integ/cli/cdk-helpers.ts b/packages/aws-cdk/test/integ/cli/cdk-helpers.ts index d43e7bfe23000..410b8d71d9e71 100644 --- a/packages/aws-cdk/test/integ/cli/cdk-helpers.ts +++ b/packages/aws-cdk/test/integ/cli/cdk-helpers.ts @@ -1,7 +1,7 @@ import * as child_process from 'child_process'; import * as os from 'os'; import * as path from 'path'; -import { cloudFormation, deleteBucket, deleteStacks, emptyBucket, outputFromStack, testEnv } from './aws-helpers'; +import { cloudFormation, deleteBucket, deleteImageRepository, deleteStacks, emptyBucket, outputFromStack, testEnv } from './aws-helpers'; export const INTEG_TEST_DIR = path.join(os.tmpdir(), 'cdk-integ-test2'); @@ -155,6 +155,10 @@ export async function cleanup(): Promise { const bucketNames = stacksToDelete.map(stack => outputFromStack('BucketName', stack)).filter(defined); await Promise.all(bucketNames.map(emptyBucket)); + // Bootstrap stacks have ECR repositories with images which should be deleted + const imageRepositoryNames = stacksToDelete.map(stack => outputFromStack('ImageRepositoryName', stack)).filter(defined); + await Promise.all(imageRepositoryNames.map(deleteImageRepository)); + await deleteStacks(...stacksToDelete.map(s => s.StackName)); // We might have leaked some buckets by upgrading the bootstrap stack. Be @@ -209,7 +213,7 @@ export async function shell(command: string[], options: ShellOptions = {}): Prom if (code === 0 || options.allowErrExit) { resolve((Buffer.concat(stdout).toString('utf-8') + Buffer.concat(stderr).toString('utf-8')).trim()); } else { - reject(new Error(`'${command.join(' ')}' exited with error code ${code}`)); + reject(new Error(`'${command.join(' ')}' exited with error code ${code}: ${Buffer.concat(stderr).toString('utf-8').trim()}`)); } }); }); diff --git a/packages/cdk-assets/lib/private/shell.ts b/packages/cdk-assets/lib/private/shell.ts index fd145cf517704..1ae57dba1b062 100644 --- a/packages/cdk-assets/lib/private/shell.ts +++ b/packages/cdk-assets/lib/private/shell.ts @@ -30,6 +30,7 @@ export async function shell(command: string[], options: ShellOptions = {}): Prom } const stdout = new Array(); + const stderr = new Array(); // Both write to stdout and collect child.stdout.on('data', chunk => { @@ -43,6 +44,8 @@ export async function shell(command: string[], options: ShellOptions = {}): Prom if (!options.quiet) { process.stderr.write(chunk); } + + stderr.push(chunk); }); child.once('error', reject); @@ -51,7 +54,8 @@ export async function shell(command: string[], options: ShellOptions = {}): Prom if (code === 0) { resolve(Buffer.concat(stdout).toString('utf-8')); } else { - reject(new ProcessFailed(code, `${renderCommandLine(command)} exited with error code ${code}`)); + const out = Buffer.concat(stderr).toString('utf-8').trim(); + reject(new ProcessFailed(code, `${renderCommandLine(command)} exited with error code ${code}: ${out}`)); } }); });