From 72dec59f5077ef8dae0fc4f19a1555389c1318d3 Mon Sep 17 00:00:00 2001 From: karakter98 <37190268+karakter98@users.noreply.github.com> Date: Wed, 16 Nov 2022 01:04:38 +0200 Subject: [PATCH 1/2] Added typescript and javascript language presets. --- packages/@aws-cdk/integ-runner/README.md | 16 ++- packages/@aws-cdk/integ-runner/lib/cli.ts | 5 +- .../lib/runner/integration-tests.ts | 76 +++++++++++- .../test/runner/integ-test-runner.test.ts | 28 +++++ .../test/runner/integration-tests.test.ts | 32 +++++ .../cdk.out | 1 + .../integ.json | 12 ++ .../manifest.json | 58 +++++++++ .../test-stack-do-not-diff.template.json | 75 ++++++++++++ .../test-stack.template.json | 75 ++++++++++++ .../tree.json | 114 ++++++++++++++++++ 11 files changed, 485 insertions(+), 7 deletions(-) create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/cdk.out create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/integ.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/manifest.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack-do-not-diff.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/tree.json diff --git a/packages/@aws-cdk/integ-runner/README.md b/packages/@aws-cdk/integ-runner/README.md index 308d6da190f6f..5c17e8022f89e 100644 --- a/packages/@aws-cdk/integ-runner/README.md +++ b/packages/@aws-cdk/integ-runner/README.md @@ -69,10 +69,24 @@ to be a self contained CDK app. The runner will execute the following for each f - `--disable-update-workflow` (default=`false`) If this is set to `true` then the [update workflow](#update-workflow) will be disabled - `--app` - The custom CLI command that will be used to run the test files. You can include {filePath} to specify where in the command the test file path should be inserted. Example: --app="python3.8 {filePath}". + The custom CLI command that will be used to run the test files. You can include {filePath} to specify where in the command the test file path should be inserted. Example: --app="python3.8 {filePath}". + + Takes precedence over language presets. - `--test-regex` Detect integration test files matching this JavaScript regex pattern. If used multiple times, all files matching any one of the patterns are detected. + + Takes precedence over language presets. +- `--language` + The language presets to use. You can discover and run tests written in multiple languages by passing this flag multiple times (`--language javascript --language typescript`). Defaults to all supported languages. Currently supported language presets are: + - `javascript`: + - File RegExp: `^integ\..*\.js$` + - App run command: `node {filePath}` + - `typescript`: + - File RegExp: `^integ\..*(? t.discoveryRelativeFileName).join('\n') + '\n'); return; } @@ -77,6 +79,7 @@ export async function main(args: string[]) { testRegex, tests: requestedTests, exclude, + language, }))); // always run snapshot tests, but if '--force' is passed then diff --git a/packages/@aws-cdk/integ-runner/lib/runner/integration-tests.ts b/packages/@aws-cdk/integ-runner/lib/runner/integration-tests.ts index d7559ea911c10..5a81b2e775271 100644 --- a/packages/@aws-cdk/integ-runner/lib/runner/integration-tests.ts +++ b/packages/@aws-cdk/integ-runner/lib/runner/integration-tests.ts @@ -37,6 +37,22 @@ export interface IntegTestInfo { * Derived information for IntegTests */ export class IntegTest { + private static readonly defaultSuffixes = new Map([ + ['javascript', new RegExp(/\.js$/)], + // Allow files ending in .ts but not in .d.ts + ['typescript', new RegExp(/(?([ + ['javascript', 'node {filePath}'], + ['typescript', 'node -r ts-node/register {filePath}'], + ]); + + private static getLanguage(fileName: string): string | undefined { + const [language] = Array.from(IntegTest.defaultSuffixes.entries()).find(([, regex]) => regex.test(fileName)) ?? [undefined, undefined]; + return language; + } + /** * The name of the file to run * @@ -95,8 +111,12 @@ export class IntegTest { */ readonly appCommand: string; + /** + * Language the test is written in + */ + public readonly language?: string; + constructor(public readonly info: IntegTestInfo) { - this.appCommand = info.appCommand ?? 'node {filePath}'; this.absoluteFileName = path.resolve(info.fileName); this.fileName = path.relative(process.cwd(), info.fileName); @@ -104,6 +124,9 @@ export class IntegTest { this.discoveryRelativeFileName = path.relative(info.discoveryRoot, info.fileName); this.directory = parsed.dir; + this.language = IntegTest.getLanguage(parsed.base); + this.appCommand = info.appCommand ?? this.getDefaultAppCommand(); + // if we are running in a package directory then just use the fileName // as the testname, but if we are running in a parent directory with // multiple packages then use the directory/filename as the testname @@ -119,6 +142,19 @@ export class IntegTest { this.temporaryOutputDir = path.join(this.directory, `${CDK_OUTDIR_PREFIX}.${parsed.base}.snapshot`); } + private getDefaultAppCommand(): string { + if (!this.language) { + throw new Error(`Integration test '${this.fileName}' does not match any of the supported languages.`); + } + + const defaultAppCommand = IntegTest.defaultAppCommands.get(this.language); + if (!defaultAppCommand) { + throw new Error(`No default app run command defined for language ${this.language}`); + } + + return defaultAppCommand; + } + /** * Whether this test matches the user-given name * @@ -172,6 +208,13 @@ export interface IntegrationTestsDiscoveryOptions { * @default - test run command will be `node {filePath}` */ readonly app?: string; + + /** + * List of language presets to discover tests for. + * + * @default - all supported languages + */ + readonly language?: string[]; } @@ -190,6 +233,11 @@ export interface IntegrationTestFileConfig extends IntegrationTestsDiscoveryOpti * Discover integration tests */ export class IntegrationTests { + private static readonly defaultDiscoveryRegexes = new Map([ + ['javascript', new RegExp(/^integ\..*\.js$/)], + // Allow files ending in .ts but not in .d.ts + ['typescript', new RegExp(/^integ\..*(? { - const patterns = options.testRegex ?? ['^integ\\..*\\.js$']; + const languagePresets = options.language ?? Array.from(IntegrationTests.defaultDiscoveryRegexes.keys()); + const patterns = options.testRegex?.map((pattern) => new RegExp(pattern)) + ?? Array.from(IntegrationTests.defaultDiscoveryRegexes.entries()).filter( + ([language]) => languagePresets.includes(language), + ).map(([_, regex]) => regex); const files = await this.readTree(); - const integs = files.filter(fileName => patterns.some((p) => { - const regex = new RegExp(p); + const integs = files.filter(fileName => patterns.some((regex) => { return regex.test(fileName) || regex.test(path.basename(fileName)); })); - return this.request(integs, options); + const discoveredTestNames = new Set(); + const integsWithoutDuplicates = new Array(); + + // Remove tests with duplicate names. + // To make sure the precendence of files is deterministic, iterate the files in lexicographic order. + // Additionally, to give precedence to compiled .js files over their .ts source, + // use ascending lexicographic ordering, so the .ts files are picked up first. + for (const integFileName of integs.sort()) { + const testName = path.parse(integFileName).name; + if (!discoveredTestNames.has(testName)) { + integsWithoutDuplicates.push(integFileName); + } + discoveredTestNames.add(testName); + } + + return this.request(integsWithoutDuplicates, options); } private request(files: string[], options: IntegrationTestsDiscoveryOptions): IntegTest[] { diff --git a/packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts b/packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts index 8a2b9cbfca984..99e11a759bb0a 100644 --- a/packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts +++ b/packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts @@ -588,4 +588,32 @@ describe('IntegTest runIntegTests', () => { app: 'node --no-warnings xxxxx.test-with-snapshot.js', })); }); + + test('with default preset for TypeScript', () => { + // WHEN + const integTest = new IntegTestRunner({ + cdk: cdkMock.cdk, + test: new IntegTest({ + fileName: 'test/test-data/xxxxx.test-with-snapshot.ts', + discoveryRoot: 'test/test-data', + }), + }); + integTest.runIntegTestCase({ + testCaseName: 'xxxxx.test-with-snapshot', + }); + + // THEN + expect(deployMock).toHaveBeenCalledTimes(2); + expect(destroyMock).toHaveBeenCalledTimes(1); + expect(synthFastMock).toHaveBeenCalledTimes(1); + expect(deployMock).toHaveBeenCalledWith(expect.objectContaining({ + app: 'node -r ts-node/register xxxxx.test-with-snapshot.ts', + })); + expect(synthFastMock).toHaveBeenCalledWith(expect.objectContaining({ + execCmd: ['node', '-r', 'ts-node/register', 'xxxxx.test-with-snapshot.ts'], + })); + expect(destroyMock).toHaveBeenCalledWith(expect.objectContaining({ + app: 'node -r ts-node/register xxxxx.test-with-snapshot.ts', + })); + }); }); diff --git a/packages/@aws-cdk/integ-runner/test/runner/integration-tests.test.ts b/packages/@aws-cdk/integ-runner/test/runner/integration-tests.test.ts index 9b93709abdc75..e1bcaf1d3da30 100644 --- a/packages/@aws-cdk/integ-runner/test/runner/integration-tests.test.ts +++ b/packages/@aws-cdk/integ-runner/test/runner/integration-tests.test.ts @@ -11,8 +11,14 @@ describe('IntegrationTests', () => { mockfs({ 'test/test-data': { 'integ.integ-test1.js': 'content', + 'integ.integ-test1.ts': 'content', + 'integ.integ-test1.d.ts': 'should not match', 'integ.integ-test2.js': 'content', + 'integ.integ-test2.ts': 'content', + 'integ.integ-test2.d.ts': 'should not match', 'integ.integ-test3.js': 'content', + 'integ.integ-test3.ts': 'content', + 'integ.integ-test3.d.ts': 'should not match', 'integration.test.js': 'should not match', }, 'other/other-data': { @@ -166,5 +172,31 @@ describe('IntegrationTests', () => { expect(integTests.length).toEqual(3); expect(integTests[0].appCommand).toEqual('node --no-warnings {filePath}'); }); + + test('TypeScript compiled to JavaScript, does not pick up the compiled tests for both .ts and .js versions', async () => { + const tsCompiledTests = new IntegrationTests('test'); + const integTests = await tsCompiledTests.fromCliArgs(); + + expect(integTests.length).toEqual(3); + }); + + test('TypeScript compiled to JavaScript, gives precedence to JavaScript files', async () => { + const tsCompiledTests = new IntegrationTests('test'); + const integTests = await tsCompiledTests.fromCliArgs(); + + for (const test of integTests) { + expect(test.fileName).toEqual(expect.stringMatching(/integ.integ-test[1-3].js/)); + } + }); + + test('TypeScript .d.ts files should be ignored', async () => { + writeConfig({ language: ['typescript'] }); + + const tsCompiledTests = new IntegrationTests('test'); + const integTests = await tsCompiledTests.fromFile(configFile); + + expect(integTests.length).toEqual(3); + expect(integTests[0].fileName).toEqual(expect.stringMatching(/integ.integ-test1.ts/)); + }); }); }); diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/cdk.out b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/cdk.out new file mode 100644 index 0000000000000..2efc89439fab8 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"18.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/integ.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/integ.json new file mode 100644 index 0000000000000..25baeac5899fd --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "v1.0.0", + "testCases": { + "xxxxx.test-with-snapshot": { + "stacks": ["test-stack"], + "diffAssets": true, + "allowDestroy": [ + "AWS::IAM::Role" + ] + } + } +} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/manifest.json new file mode 100644 index 0000000000000..5c9fd61ecec9f --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/manifest.json @@ -0,0 +1,58 @@ +{ + "version": "21.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + }, + "metadata": {} + }, + "test-stack-do-not-diff": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "test-stack-do-not-diff.template.json", + "validateOnSynth": false + }, + "metadata": { + "/test-stack-do-not-diff/MyFunction1/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunction1ServiceRole9852B06B" + } + ], + "/test-stack-do-not-diff/MyFunction1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunction12A744C2E" + } + ] + }, + "displayName": "test-stack-do-not-diff" + }, + "test-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "test-stack.template.json", + "validateOnSynth": false + }, + "metadata": { + "/test-stack/MyFunction1/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunction1ServiceRole9852B06B" + } + ], + "/test-stack/MyFunction1/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunction12A744C2E" + } + ] + }, + "displayName": "test-stack" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack-do-not-diff.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack-do-not-diff.template.json new file mode 100644 index 0000000000000..efed158f80851 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack-do-not-diff.template.json @@ -0,0 +1,75 @@ +{ + "Resources": { + "MyFunction1ServiceRole9852B06B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "MyLambdaFuncServiceRoleDefaultPolicyBEB0E748": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyLambdaFuncServiceRoleDefaultPolicyBEB0E748", + "Roles": [ + { + "Ref": "MyFunction1ServiceRole9852B06B" + } + ] + } + }, + "MyFunction12A744C2E": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunction1ServiceRole9852B06B", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyFunction1ServiceRole9852B06B" + ] + } + } +} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack.template.json new file mode 100644 index 0000000000000..efed158f80851 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack.template.json @@ -0,0 +1,75 @@ +{ + "Resources": { + "MyFunction1ServiceRole9852B06B": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "MyLambdaFuncServiceRoleDefaultPolicyBEB0E748": { + "Type": "AWS::IAM::Policy", + "Properties": { + "PolicyDocument": { + "Statement": [ + { + "Action": "*", + "Effect": "Allow", + "Resource": "*" + } + ], + "Version": "2012-10-17" + }, + "PolicyName": "MyLambdaFuncServiceRoleDefaultPolicyBEB0E748", + "Roles": [ + { + "Ref": "MyFunction1ServiceRole9852B06B" + } + ] + } + }, + "MyFunction12A744C2E": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunction1ServiceRole9852B06B", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyFunction1ServiceRole9852B06B" + ] + } + } +} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/tree.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/tree.json new file mode 100644 index 0000000000000..b664bec74b37c --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/tree.json @@ -0,0 +1,114 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "@aws-cdk/core.Construct", + "version": "0.0.0" + } + }, + "test-stack": { + "id": "test-stack", + "path": "test-stack", + "children": { + "MyFunction1": { + "id": "MyFunction1", + "path": "test-stack/MyFunction1", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "test-stack/MyFunction1/ServiceRole", + "children": { + "Resource": { + "id": "Resource", + "path": "test-stack/MyFunction1/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/MyFunction1/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "MyFunction1ServiceRole9852B06B", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file From d2b89f6568f2d8f7bc7398c3cb10f23ab09ddbaa Mon Sep 17 00:00:00 2001 From: karakter98 <37190268+karakter98@users.noreply.github.com> Date: Wed, 16 Nov 2022 13:34:08 +0200 Subject: [PATCH 2/2] Moved typescript test files to a separate folder for better separation. Added CLI test for typescript files. --- packages/@aws-cdk/integ-runner/package.json | 9 +- .../@aws-cdk/integ-runner/test/cli.test.ts | 11 ++ .../test/runner/integ-test-runner.test.ts | 14 +-- .../xxxxx.typescript-test.ts | 9 ++ ...efaultTestDeployAssert4E6713E1.assets.json | 19 +++ ...aultTestDeployAssert4E6713E1.template.json | 36 ++++++ .../xxxxx.typescript-test.ts.snapshot/cdk.out | 1 + .../integ.json | 12 ++ .../manifest.json | 58 +++++++++ .../tree.json | 57 +++++++++ .../cdk.out | 1 - .../integ.json | 12 -- .../manifest.json | 58 --------- .../test-stack-do-not-diff.template.json | 75 ------------ .../test-stack.template.json | 75 ------------ .../tree.json | 114 ------------------ 16 files changed, 216 insertions(+), 345 deletions(-) create mode 100644 packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts create mode 100644 packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/cdk.out create mode 100644 packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/integ.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/manifest.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/tree.json delete mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/cdk.out delete mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/integ.json delete mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/manifest.json delete mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack-do-not-diff.template.json delete mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack.template.json delete mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/tree.json diff --git a/packages/@aws-cdk/integ-runner/package.json b/packages/@aws-cdk/integ-runner/package.json index 2f9199680f427..392234d15e5bb 100644 --- a/packages/@aws-cdk/integ-runner/package.json +++ b/packages/@aws-cdk/integ-runner/package.json @@ -52,15 +52,18 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/cdk-build-tools": "0.0.0", - "@types/mock-fs": "^4.13.1", - "mock-fs": "^4.14.0", + "@aws-cdk/core": "^0.0.0", + "@aws-cdk/integ-tests": "^0.0.0", "@aws-cdk/pkglint": "0.0.0", "@types/fs-extra": "^8.1.2", "@types/jest": "^27.5.2", + "@types/mock-fs": "^4.13.1", "@types/node": "^14.18.33", "@types/workerpool": "^6.1.0", "@types/yargs": "^15.0.14", - "jest": "^27.5.1" + "constructs": "^10.0.0", + "jest": "^27.5.1", + "mock-fs": "^4.14.0" }, "dependencies": { "@aws-cdk/cloud-assembly-schema": "0.0.0", diff --git a/packages/@aws-cdk/integ-runner/test/cli.test.ts b/packages/@aws-cdk/integ-runner/test/cli.test.ts index bf61aa7633aac..1c3eea7961809 100644 --- a/packages/@aws-cdk/integ-runner/test/cli.test.ts +++ b/packages/@aws-cdk/integ-runner/test/cli.test.ts @@ -41,4 +41,15 @@ describe('CLI', () => { ].join('\n'), ]]); }); + + test('find only TypeScript files', async () => { + await main(['--list', '--language', 'typescript', '--directory=test/test-data-typescript', '--test-regex="^xxxxx\\..*(? { const integTest = new IntegTestRunner({ cdk: cdkMock.cdk, test: new IntegTest({ - fileName: 'test/test-data/xxxxx.test-with-snapshot.ts', - discoveryRoot: 'test/test-data', + fileName: 'test/test-data-typescript/xxxxx.typescript-test.ts', + discoveryRoot: 'test/test-data-typescript', }), }); integTest.runIntegTestCase({ - testCaseName: 'xxxxx.test-with-snapshot', + testCaseName: 'xxxxx.typescript-test', }); // THEN - expect(deployMock).toHaveBeenCalledTimes(2); + expect(deployMock).toHaveBeenCalledTimes(1); expect(destroyMock).toHaveBeenCalledTimes(1); expect(synthFastMock).toHaveBeenCalledTimes(1); expect(deployMock).toHaveBeenCalledWith(expect.objectContaining({ - app: 'node -r ts-node/register xxxxx.test-with-snapshot.ts', + app: 'node -r ts-node/register xxxxx.typescript-test.ts', })); expect(synthFastMock).toHaveBeenCalledWith(expect.objectContaining({ - execCmd: ['node', '-r', 'ts-node/register', 'xxxxx.test-with-snapshot.ts'], + execCmd: ['node', '-r', 'ts-node/register', 'xxxxx.typescript-test.ts'], })); expect(destroyMock).toHaveBeenCalledWith(expect.objectContaining({ - app: 'node -r ts-node/register xxxxx.test-with-snapshot.ts', + app: 'node -r ts-node/register xxxxx.typescript-test.ts', })); }); }); diff --git a/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts new file mode 100644 index 0000000000000..ede7d2f4f7c62 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts @@ -0,0 +1,9 @@ +import { App, Stack } from '@aws-cdk/core'; +import { IntegTest } from '@aws-cdk/integ-tests'; + +const app = new App(); +const stack = new Stack(); + +new IntegTest(app, 'Integ', { testCases: [stack] }); + +app.synth(); diff --git a/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json new file mode 100644 index 0000000000000..1c86a68a43509 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/IntegDefaultTestDeployAssert4E6713E1.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "IntegDefaultTestDeployAssert4E6713E1.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/IntegDefaultTestDeployAssert4E6713E1.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/cdk.out b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/integ.json b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/integ.json new file mode 100644 index 0000000000000..eed35fe9a60d7 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "21.0.0", + "testCases": { + "Integ/DefaultTest": { + "stacks": [ + "Default" + ], + "assertionStack": "Integ/DefaultTest/DeployAssert", + "assertionStackName": "IntegDefaultTestDeployAssert4E6713E1" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/manifest.json new file mode 100644 index 0000000000000..7a077e8868885 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/manifest.json @@ -0,0 +1,58 @@ +{ + "version": "21.0.0", + "artifacts": { + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + }, + "IntegDefaultTestDeployAssert4E6713E1.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "IntegDefaultTestDeployAssert4E6713E1.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "IntegDefaultTestDeployAssert4E6713E1": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "IntegDefaultTestDeployAssert4E6713E1.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "IntegDefaultTestDeployAssert4E6713E1.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "IntegDefaultTestDeployAssert4E6713E1.assets" + ], + "metadata": { + "/Integ/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/Integ/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "Integ/DefaultTest/DeployAssert" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/tree.json b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/tree.json new file mode 100644 index 0000000000000..94fac291ce167 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data-typescript/xxxxx.typescript-test.ts.snapshot/tree.json @@ -0,0 +1,57 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.161" + } + }, + "Integ": { + "id": "Integ", + "path": "Integ", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "Integ/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "Integ/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.161" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "Integ/DefaultTest/DeployAssert", + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/cdk.out b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/cdk.out deleted file mode 100644 index 2efc89439fab8..0000000000000 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/cdk.out +++ /dev/null @@ -1 +0,0 @@ -{"version":"18.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/integ.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/integ.json deleted file mode 100644 index 25baeac5899fd..0000000000000 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/integ.json +++ /dev/null @@ -1,12 +0,0 @@ -{ - "version": "v1.0.0", - "testCases": { - "xxxxx.test-with-snapshot": { - "stacks": ["test-stack"], - "diffAssets": true, - "allowDestroy": [ - "AWS::IAM::Role" - ] - } - } -} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/manifest.json deleted file mode 100644 index 5c9fd61ecec9f..0000000000000 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/manifest.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "version": "21.0.0", - "artifacts": { - "Tree": { - "type": "cdk:tree", - "properties": { - "file": "tree.json" - }, - "metadata": {} - }, - "test-stack-do-not-diff": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "test-stack-do-not-diff.template.json", - "validateOnSynth": false - }, - "metadata": { - "/test-stack-do-not-diff/MyFunction1/ServiceRole/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyFunction1ServiceRole9852B06B" - } - ], - "/test-stack-do-not-diff/MyFunction1/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyFunction12A744C2E" - } - ] - }, - "displayName": "test-stack-do-not-diff" - }, - "test-stack": { - "type": "aws:cloudformation:stack", - "environment": "aws://unknown-account/unknown-region", - "properties": { - "templateFile": "test-stack.template.json", - "validateOnSynth": false - }, - "metadata": { - "/test-stack/MyFunction1/ServiceRole/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyFunction1ServiceRole9852B06B" - } - ], - "/test-stack/MyFunction1/Resource": [ - { - "type": "aws:cdk:logicalId", - "data": "MyFunction12A744C2E" - } - ] - }, - "displayName": "test-stack" - } - } -} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack-do-not-diff.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack-do-not-diff.template.json deleted file mode 100644 index efed158f80851..0000000000000 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack-do-not-diff.template.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "Resources": { - "MyFunction1ServiceRole9852B06B": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "MyLambdaFuncServiceRoleDefaultPolicyBEB0E748": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "*", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "MyLambdaFuncServiceRoleDefaultPolicyBEB0E748", - "Roles": [ - { - "Ref": "MyFunction1ServiceRole9852B06B" - } - ] - } - }, - "MyFunction12A744C2E": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "foo" - }, - "Role": { - "Fn::GetAtt": [ - "MyFunction1ServiceRole9852B06B", - "Arn" - ] - }, - "Handler": "index.handler", - "Runtime": "nodejs14.x" - }, - "DependsOn": [ - "MyFunction1ServiceRole9852B06B" - ] - } - } -} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack.template.json deleted file mode 100644 index efed158f80851..0000000000000 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/test-stack.template.json +++ /dev/null @@ -1,75 +0,0 @@ -{ - "Resources": { - "MyFunction1ServiceRole9852B06B": { - "Type": "AWS::IAM::Role", - "Properties": { - "AssumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "ManagedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "MyLambdaFuncServiceRoleDefaultPolicyBEB0E748": { - "Type": "AWS::IAM::Policy", - "Properties": { - "PolicyDocument": { - "Statement": [ - { - "Action": "*", - "Effect": "Allow", - "Resource": "*" - } - ], - "Version": "2012-10-17" - }, - "PolicyName": "MyLambdaFuncServiceRoleDefaultPolicyBEB0E748", - "Roles": [ - { - "Ref": "MyFunction1ServiceRole9852B06B" - } - ] - } - }, - "MyFunction12A744C2E": { - "Type": "AWS::Lambda::Function", - "Properties": { - "Code": { - "ZipFile": "foo" - }, - "Role": { - "Fn::GetAtt": [ - "MyFunction1ServiceRole9852B06B", - "Arn" - ] - }, - "Handler": "index.handler", - "Runtime": "nodejs14.x" - }, - "DependsOn": [ - "MyFunction1ServiceRole9852B06B" - ] - } - } -} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/tree.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/tree.json deleted file mode 100644 index b664bec74b37c..0000000000000 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-snapshot.ts.snapshot/tree.json +++ /dev/null @@ -1,114 +0,0 @@ -{ - "version": "tree-0.1", - "tree": { - "id": "App", - "path": "", - "children": { - "Tree": { - "id": "Tree", - "path": "Tree", - "constructInfo": { - "fqn": "@aws-cdk/core.Construct", - "version": "0.0.0" - } - }, - "test-stack": { - "id": "test-stack", - "path": "test-stack", - "children": { - "MyFunction1": { - "id": "MyFunction1", - "path": "test-stack/MyFunction1", - "children": { - "ServiceRole": { - "id": "ServiceRole", - "path": "test-stack/MyFunction1/ServiceRole", - "children": { - "Resource": { - "id": "Resource", - "path": "test-stack/MyFunction1/ServiceRole/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::IAM::Role", - "aws:cdk:cloudformation:props": { - "assumeRolePolicyDocument": { - "Statement": [ - { - "Action": "sts:AssumeRole", - "Effect": "Allow", - "Principal": { - "Service": "lambda.amazonaws.com" - } - } - ], - "Version": "2012-10-17" - }, - "managedPolicyArns": [ - { - "Fn::Join": [ - "", - [ - "arn:", - { - "Ref": "AWS::Partition" - }, - ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" - ] - ] - } - ] - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-iam.CfnRole", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-iam.Role", - "version": "0.0.0" - } - }, - "Resource": { - "id": "Resource", - "path": "test-stack/MyFunction1/Resource", - "attributes": { - "aws:cdk:cloudformation:type": "AWS::Lambda::Function", - "aws:cdk:cloudformation:props": { - "code": { - "zipFile": "foo" - }, - "role": { - "Fn::GetAtt": [ - "MyFunction1ServiceRole9852B06B", - "Arn" - ] - }, - "handler": "index.handler", - "runtime": "nodejs14.x" - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.CfnFunction", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/aws-lambda.Function", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/core.Stack", - "version": "0.0.0" - } - } - }, - "constructInfo": { - "fqn": "@aws-cdk/core.App", - "version": "0.0.0" - } - } -} \ No newline at end of file