diff --git a/packages/@aws-cdk/cloud-assembly-schema/lib/integ-tests/test-case.ts b/packages/@aws-cdk/cloud-assembly-schema/lib/integ-tests/test-case.ts index 6d3ecc05c626e..d04ffad502c67 100644 --- a/packages/@aws-cdk/cloud-assembly-schema/lib/integ-tests/test-case.ts +++ b/packages/@aws-cdk/cloud-assembly-schema/lib/integ-tests/test-case.ts @@ -1,17 +1,9 @@ import { DeployOptions, DestroyOptions } from './commands'; /** - * Represents an integration test test case + * The set of options to control the workflow of the test runner */ -export interface TestCase { - /** - * Stacks that should be tested as part of this test case - * The stackNames will be passed as args to the cdk commands - * so dependent stacks will be automatically deployed unless - * `exclusively` is passed - */ - readonly stacks: string[]; - +export interface TestOptions { /** * Run update workflow on this test case * This should only be set to false to test scenarios @@ -22,54 +14,67 @@ export interface TestCase { readonly stackUpdateWorkflow?: boolean; /** - * Additional options to use for each CDK command - * - * @default - runner default options - */ + * Additional options to use for each CDK command + * + * @default - runner default options + */ readonly cdkCommandOptions?: CdkCommands; /** - * Additional commands to run at predefined points in the test workflow - * - * e.g. { postDeploy: ['yarn', 'test'] } - * - * @default - no hooks - */ + * Additional commands to run at predefined points in the test workflow + * + * e.g. { postDeploy: ['yarn', 'test'] } + * + * @default - no hooks + */ readonly hooks?: Hooks; /** - * Whether or not to include asset hashes in the diff - * Asset hashes can introduces a lot of unneccessary noise into tests, - * but there are some cases where asset hashes _should_ be included. For example - * any tests involving custom resources or bundling - * - * @default false - */ + * Whether or not to include asset hashes in the diff + * Asset hashes can introduces a lot of unneccessary noise into tests, + * but there are some cases where asset hashes _should_ be included. For example + * any tests involving custom resources or bundling + * + * @default false + */ readonly diffAssets?: boolean; /** - * List of CloudFormation resource types in this stack that can - * be destroyed as part of an update without failing the test. - * - * This list should only include resources that for this specific - * integration test we are sure will not cause errors or an outage if - * destroyed. For example, maybe we know that a new resource will be created - * first before the old resource is destroyed which prevents any outage. - * - * e.g. ['AWS::IAM::Role'] - * - * @default - do not allow destruction of any resources on update - */ + * List of CloudFormation resource types in this stack that can + * be destroyed as part of an update without failing the test. + * + * This list should only include resources that for this specific + * integration test we are sure will not cause errors or an outage if + * destroyed. For example, maybe we know that a new resource will be created + * first before the old resource is destroyed which prevents any outage. + * + * e.g. ['AWS::IAM::Role'] + * + * @default - do not allow destruction of any resources on update + */ readonly allowDestroy?: string[]; /** - * Limit deployment to these regions - * - * @default - can run in any region - */ + * Limit deployment to these regions + * + * @default - can run in any region + */ readonly regions?: string[]; } +/** + * Represents an integration test case + */ +export interface TestCase extends TestOptions { + /** + * Stacks that should be tested as part of this test case + * The stackNames will be passed as args to the cdk commands + * so dependent stacks will be automatically deployed unless + * `exclusively` is passed + */ + readonly stacks: string[]; +} + /** * Commands to run at predefined points during the * integration test workflow diff --git a/packages/@aws-cdk/integ-runner/README.md b/packages/@aws-cdk/integ-runner/README.md index 9fd2b667346ae..ab641d6fb337e 100644 --- a/packages/@aws-cdk/integ-runner/README.md +++ b/packages/@aws-cdk/integ-runner/README.md @@ -146,98 +146,11 @@ Test Results: Tests: 1 passed, 1 total ``` - ### integ.json schema See [@aws-cdk/cloud-assembly-schema/lib/integ-tests/schema.ts](../cloud-assembly-schema/lib/integ-tests/schema.ts) -### defining an integration test - -In most cases an integration test will be an instance of a stack - -```ts -import { Function, FunctionOptions } from '../lib'; - -interface MyIntegTestProps extends StackOptions { - functionProps?: FunctionOptions; -} -class MyIntegTest extends Stack { - constructor(scope: Construct, id: string, props: MyIntegTestProps) { - super(scope, id, props); - - new Function(this, 'Handler', { - runtime: Runtime.NODEJS_12_X, - handler: 'index.handler', - code: Code.fromAsset(path.join(__dirname, 'lambda-handler')), - ...props.functionProps, - }); - } -} -``` +### Defining an integration test -You would then use the `IntegTest` construct to create your test cases - -```ts -new IntegTeset(app, 'ArmTest', { - stacks: [ - new MyIntegTest(app, 'Stack1', { - functionProps: { - architecture: lambda.Architecture.ARM_64, - }, - }), - ], - diffAssets: true, - update: true, - cdkCommandOptions: { - deploy: { - args: { - requireApproval: RequireApproval.NEVER, - json: true, - }, - }, - destroy: { - args: { - force: true, - }, - }, - }, -}); - -new IntegTeset(app, 'AmdTest', { - stacks: [ - new MyIntegTest(app, 'Stack2', { - functionProps: { - architecture: lambda.Architecture.X86_64, - }, - }), - ], -}); -``` - -This will synthesize an `integ.json` file with the following contents - -```json -{ - "ArmTest": { - "stacks": ["Stack1"], - "diffAssets": true, - "update": true, - "cdkCommands": { - "deploy": { - "args": { - "requireApproval": "never", - "json": true - } - }, - "destroy": { - "args": { - "force": true - } - } - } - }, - "AmdTest": { - "stacks": ["Stack2"] - } -} -``` +See the `@aws-cdk/integ-tests` module for information on how to define +integration tests for the runner to exercise. diff --git a/packages/@aws-cdk/integ-tests/.eslintrc.js b/packages/@aws-cdk/integ-tests/.eslintrc.js new file mode 100644 index 0000000000000..2658ee8727166 --- /dev/null +++ b/packages/@aws-cdk/integ-tests/.eslintrc.js @@ -0,0 +1,3 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/eslintrc'); +baseConfig.parserOptions.project = __dirname + '/tsconfig.json'; +module.exports = baseConfig; diff --git a/packages/@aws-cdk/integ-tests/.gitignore b/packages/@aws-cdk/integ-tests/.gitignore new file mode 100644 index 0000000000000..17a41566f0002 --- /dev/null +++ b/packages/@aws-cdk/integ-tests/.gitignore @@ -0,0 +1,19 @@ +*.js +tsconfig.json +*.js.map +*.d.ts +*.generated.ts +dist +lib/generated/resources.ts +.jsii + +.LAST_BUILD +.nyc_output +coverage +nyc.config.js +.LAST_PACKAGE +*.snk +!.eslintrc.js + +junit.xml +!jest.config.js \ No newline at end of file diff --git a/packages/@aws-cdk/integ-tests/.npmignore b/packages/@aws-cdk/integ-tests/.npmignore new file mode 100644 index 0000000000000..52ca12195912c --- /dev/null +++ b/packages/@aws-cdk/integ-tests/.npmignore @@ -0,0 +1,28 @@ +# Don't include original .ts files when doing `npm pack` +*.ts +!*.d.ts +coverage +.nyc_output +*.tgz + +dist +.LAST_PACKAGE +.LAST_BUILD +!*.js + +# Include .jsii +!.jsii + +*.snk + +*.tsbuildinfo + +tsconfig.json +.eslintrc.js + +# exclude cdk artifacts +**/cdk.out +junit.xml +test/ +jest.config.js +!*.lit.ts \ No newline at end of file diff --git a/packages/@aws-cdk/integ-tests/LICENSE b/packages/@aws-cdk/integ-tests/LICENSE new file mode 100644 index 0000000000000..82ad00bb02d0b --- /dev/null +++ b/packages/@aws-cdk/integ-tests/LICENSE @@ -0,0 +1,201 @@ + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. + + END OF TERMS AND CONDITIONS + + APPENDIX: How to apply the Apache License to your work. + + To apply the Apache License to your work, attach the following + boilerplate notice, with the fields enclosed by brackets "[]" + replaced with your own identifying information. (Don't include + the brackets!) The text should be enclosed in the appropriate + comment syntax for the file format. We also recommend that a + file or class name and description of purpose be included on the + same "printed page" as the copyright notice for easier + identification within third-party archives. + + Copyright 2018-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. diff --git a/packages/@aws-cdk/integ-tests/NOTICE b/packages/@aws-cdk/integ-tests/NOTICE new file mode 100644 index 0000000000000..1b7adbb891265 --- /dev/null +++ b/packages/@aws-cdk/integ-tests/NOTICE @@ -0,0 +1,2 @@ +AWS Cloud Development Kit (AWS CDK) +Copyright 2018-2022 Amazon.com, Inc. or its affiliates. All Rights Reserved. diff --git a/packages/@aws-cdk/integ-tests/README.md b/packages/@aws-cdk/integ-tests/README.md new file mode 100644 index 0000000000000..d8ae02bd93d7a --- /dev/null +++ b/packages/@aws-cdk/integ-tests/README.md @@ -0,0 +1,112 @@ +# integ-runner + + + +--- + +![cdk-constructs: Experimental](https://img.shields.io/badge/cdk--constructs-experimental-important.svg?style=for-the-badge) + +> The APIs of higher level constructs in this module are experimental and under active development. +> They are subject to non-backward compatible changes or removal in any future version. These are +> not subject to the [Semantic Versioning](https://semver.org/) model and breaking changes will be +> announced in the release notes. This means that while you may use them, you may need to update +> your source code when upgrading to a newer version of this package. + +--- + + + +## Usage + +Suppose you have a simple stack, that only encapsulates a Lambda function with a +certain handler: + +```ts +interface StackUnderTestProps extends StackProps { + functionProps?: lambda.FunctionProps; +} + +class StackUnderTest extends Stack { + constructor(scope: Construct, id: string, props: StackUnderTestProps) { + super(scope, id, props); + + new lambda.Function(this, 'Handler', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + ...props.functionProps, + }); + } +} +``` + +You may want to test this stack under different conditions. For example, we want +this stack to be deployed correctly, regardless of the architecture we choose +for the Lambda function. In particular, it should work for both `ARM_64` and +`X86_64`. So you can create an `IntegTestCase` that exercises both scenarios: + +```ts +interface StackUnderTestProps extends StackProps { + architecture?: lambda.Architecture; +} + +class StackUnderTest extends Stack { + constructor(scope: Construct, id: string, props: StackUnderTestProps) { + super(scope, id, props); + + new lambda.Function(this, 'Handler', { + runtime: lambda.Runtime.NODEJS_12_X, + handler: 'index.handler', + code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')), + architecture: props.architecture, + }); + } +} + +// Beginning of the test suite +const app = new App(); + +const stack = new Stack(app, 'stack'); +new IntegTestCase(stack, 'DifferentArchitectures', { + stacks: [ + new StackUnderTest(app, 'Stack1', { + architecture: lambda.Architecture.ARM_64, + }), + new StackUnderTest(app, 'Stack2', { + architecture: lambda.Architecture.X86_64, + }), + ], +}); +``` + +This is all the instruction you need for the integration test runner to know +which stacks to synthesize, deploy and destroy. But you may also need to +customize the behavior of the runner by changing its parameters. For example: + +```ts +const app = new App(); + +const stackUnderTest = new Stack(app, 'StackUnderTest', /* ... */); + +const stack = new Stack(app, 'stack'); + +new IntegTestCase(stack, 'CustomizedDeploymentWorkflow', { + stacks: [stackUnderTest], + diffAssets: true, + stackUpdateWorkflow: true, + cdkCommandOptions: { + deploy: { + args: { + requireApproval: RequireApproval.NEVER, + json: true, + }, + }, + destroy: { + args: { + force: true, + }, + }, + }, +}); +``` + diff --git a/packages/@aws-cdk/integ-tests/jest.config.js b/packages/@aws-cdk/integ-tests/jest.config.js new file mode 100644 index 0000000000000..d052cbb29f05d --- /dev/null +++ b/packages/@aws-cdk/integ-tests/jest.config.js @@ -0,0 +1,10 @@ +const baseConfig = require('@aws-cdk/cdk-build-tools/config/jest.config'); +module.exports = { + ...baseConfig, + coverageThreshold: { + global: { + ...baseConfig.coverageThreshold.global, + branches: 60, + }, + }, +}; diff --git a/packages/@aws-cdk/integ-tests/lib/index.ts b/packages/@aws-cdk/integ-tests/lib/index.ts new file mode 100644 index 0000000000000..0553319f009fb --- /dev/null +++ b/packages/@aws-cdk/integ-tests/lib/index.ts @@ -0,0 +1 @@ +export * from './test-case'; \ No newline at end of file diff --git a/packages/@aws-cdk/integ-tests/lib/manifest-writer.ts b/packages/@aws-cdk/integ-tests/lib/manifest-writer.ts new file mode 100644 index 0000000000000..12c39609c9763 --- /dev/null +++ b/packages/@aws-cdk/integ-tests/lib/manifest-writer.ts @@ -0,0 +1,25 @@ +import * as fs from 'fs'; +import * as path from 'path'; +import { IntegManifest, Manifest } from '@aws-cdk/cloud-assembly-schema'; + +export class IntegManifestWriter { + public static readonly DEFAULT_FILENAME = 'integ.json'; + + public static write(manifest: IntegManifest, filePath: string) { + Manifest.saveIntegManifest(manifest, getFinalLocation(filePath)); + } +} + +function getFinalLocation(filePath: string): string { + try { + const st = fs.statSync(filePath); + return st.isDirectory() + ? path.join(filePath, IntegManifestWriter.DEFAULT_FILENAME) + : filePath; + } catch (e) { + if (e.code === 'ENOENT') { + return filePath; + } + throw new Error(`Cannot write integ manifest to '${filePath}': ${e.message}`); + } +} diff --git a/packages/@aws-cdk/integ-tests/lib/test-case.ts b/packages/@aws-cdk/integ-tests/lib/test-case.ts new file mode 100644 index 0000000000000..b57fe9ce03643 --- /dev/null +++ b/packages/@aws-cdk/integ-tests/lib/test-case.ts @@ -0,0 +1,46 @@ +import { IntegManifest, TestCase, TestOptions } from '@aws-cdk/cloud-assembly-schema'; +import { attachCustomSynthesis, ISynthesisSession, Stack } from '@aws-cdk/core'; +import { IntegManifestWriter } from './manifest-writer'; + +// keep this import separate from other imports to reduce chance for merge conflicts with v2-main +// eslint-disable-next-line no-duplicate-imports, import/order +import { Construct } from '@aws-cdk/core'; + +/** + * Properties of an integration test case + */ +export interface IntegTestCaseProps extends TestOptions { + /** + * Stacks to be deployed during the test + */ + readonly stacks: Stack[]; +} + +/** + * An integration test case. Allows the definition of test properties that + * apply to all stacks under this case. + */ +export class IntegTestCase extends Construct { + constructor(scope: Construct, id: string, props: IntegTestCaseProps) { + super(scope, id); + + attachCustomSynthesis(this, { + onSynthesize: (session: ISynthesisSession) => { + const snapshotDir = session.assembly.outdir; + const manifest: IntegManifest = { + version: '', + testCases: { [id]: toTestCase(props) }, + }; + + IntegManifestWriter.write(manifest, snapshotDir); + }, + }); + } +} + +function toTestCase(props: IntegTestCaseProps): TestCase { + return { + ...props, + stacks: props.stacks.map(s => s.artifactId), + }; +} diff --git a/packages/@aws-cdk/integ-tests/package.json b/packages/@aws-cdk/integ-tests/package.json new file mode 100644 index 0000000000000..e82bbad41516c --- /dev/null +++ b/packages/@aws-cdk/integ-tests/package.json @@ -0,0 +1,108 @@ +{ + "name": "@aws-cdk/integ-tests", + "description": "CDK Integration Testing Constructs", + "version": "0.0.0", + "private": false, + "main": "lib/index.js", + "types": "lib/index.d.ts", + "jsii": { + "outdir": "dist", + "targets": { + "java": { + "package": "software.amazon.awscdk.integtests", + "maven": { + "groupId": "software.amazon.awscdk", + "artifactId": "cdk-integ-tests" + } + }, + "dotnet": { + "namespace": "Amazon.CDK.IntegTests", + "packageId": "Amazon.CDK.IntegTests", + "iconUrl": "https://raw.githubusercontent.com/aws/aws-cdk/master/logo/default-256-dark.png" + }, + "python": { + "distName": "aws-cdk.integ-tests", + "module": "aws_cdk.integ_tests", + "classifiers": [ + "Framework :: AWS CDK", + "Framework :: AWS CDK :: 1" + ] + } + }, + "projectReferences": true, + "metadata": { + "jsii": { + "rosetta": { + "strict": true + } + } + } + }, + "scripts": { + "build": "cdk-build", + "lint": "cdk-lint", + "package": "cdk-package", + "awslint": "cdk-awslint", + "pkglint": "pkglint -f", + "test": "cdk-test", + "watch": "cdk-watch", + "build+test": "yarn build && yarn test", + "build+test+package": "yarn build+test && yarn package", + "compat": "cdk-compat", + "rosetta:extract": "yarn --silent jsii-rosetta extract", + "build+extract": "yarn build && yarn rosetta:extract", + "build+test+extract": "yarn build+test && yarn rosetta:extract" + }, + "author": { + "name": "Amazon Web Services", + "url": "https://aws.amazon.com", + "organization": true + }, + "license": "Apache-2.0", + "devDependencies": { + "@aws-cdk/cdk-build-tools": "0.0.0", + "@aws-cdk/pkglint": "0.0.0", + "@types/fs-extra": "^8.1.2", + "@types/jest": "^27.4.1", + "@types/node": "^10.17.60", + "jest": "^27.5.1" + }, + "dependencies": { + "@aws-cdk/cloud-assembly-schema": "0.0.0", + "@aws-cdk/core": "0.0.0", + "constructs": "^3.3.69" + }, + "repository": { + "url": "https://github.com/aws/aws-cdk.git", + "type": "git", + "directory": "packages/@aws-cdk/integ-tests" + }, + "keywords": [ + "aws", + "cdk" + ], + "homepage": "https://github.com/aws/aws-cdk", + "engines": { + "node": ">= 10.13.0 <13 || >=13.7.0" + }, + "nozem": { + "ostools": [ + "unzip", + "diff", + "rm" + ] + }, + "stability": "experimental", + "maturity": "experimental", + "publishConfig": { + "tag": "latest" + }, + "peerDependencies": { + "@aws-cdk/cloud-assembly-schema": "0.0.0", + "@aws-cdk/core": "0.0.0", + "constructs": "^3.3.69" + }, + "awscdkio": { + "announce": false + } +} diff --git a/packages/@aws-cdk/integ-tests/rosetta/default.ts-fixture b/packages/@aws-cdk/integ-tests/rosetta/default.ts-fixture new file mode 100644 index 0000000000000..83fe423064206 --- /dev/null +++ b/packages/@aws-cdk/integ-tests/rosetta/default.ts-fixture @@ -0,0 +1,12 @@ +import * as lambda from '@aws-cdk/aws-lambda'; +import { IntegTestCase } from '@aws-cdk/integ-tests'; +import { + App, + Construct, + Stack, + StackProps, +} from '@aws-cdk/core'; +import * as path from 'path'; +import { RequireApproval } from '@aws-cdk/cloud-assembly-schema'; + +/// here diff --git a/packages/@aws-cdk/integ-tests/test/manifest-writer.test.ts b/packages/@aws-cdk/integ-tests/test/manifest-writer.test.ts new file mode 100644 index 0000000000000..e0e43ae9563d9 --- /dev/null +++ b/packages/@aws-cdk/integ-tests/test/manifest-writer.test.ts @@ -0,0 +1,62 @@ +import * as fs from 'fs'; +import * as os from 'os'; +import * as path from 'path'; +import { IntegManifest, Manifest } from '@aws-cdk/cloud-assembly-schema'; +import { IntegManifestWriter } from '../lib/manifest-writer'; + +describe(IntegManifestWriter, () => { + let tmpDir: string; + const manifest: IntegManifest = { + version: 'does not matter', + testCases: { + test1: { + stacks: ['MyStack'], + diffAssets: false, + }, + test2: { + stacks: ['MyOtherStack'], + diffAssets: true, + }, + }, + }; + + beforeEach(() => { + tmpDir = fs.mkdtempSync(os.tmpdir()); + }); + + afterEach(() => { + deleteFolderRecursive(tmpDir); + }); + + it('writes manifests to default location in the specified directory', () => { + IntegManifestWriter.write(manifest, tmpDir); + + const loaded = Manifest.loadIntegManifest(`${tmpDir}/integ.json`); + + expect(loaded).toEqual({ ...manifest, version: Manifest.version() }); + }); + + it('writes manifests to the chosen location', () => { + IntegManifestWriter.write(manifest, `${tmpDir}/custom-name.json`); + + const loaded = Manifest.loadIntegManifest(`${tmpDir}/custom-name.json`); + + expect(loaded).toEqual({ ...manifest, version: Manifest.version() }); + }); +}); + +function deleteFolderRecursive(directoryPath: string) { + if (fs.existsSync(directoryPath)) { + fs.readdirSync(directoryPath).forEach((file) => { + const curPath = path.join(directoryPath, file); + if (fs.lstatSync(curPath).isDirectory()) { + // recurse + deleteFolderRecursive(curPath); + } else { + // delete file + fs.unlinkSync(curPath); + } + }); + fs.rmdirSync(directoryPath); + } +}; diff --git a/packages/aws-cdk-lib/package.json b/packages/aws-cdk-lib/package.json index eaa07d41a22c4..2fe4d8a6dbfb2 100644 --- a/packages/aws-cdk-lib/package.json +++ b/packages/aws-cdk-lib/package.json @@ -346,6 +346,7 @@ "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", "@aws-cdk/cx-api": "0.0.0", + "@aws-cdk/integ-tests": "0.0.0", "@aws-cdk/lambda-layer-awscli": "0.0.0", "@aws-cdk/lambda-layer-kubectl": "0.0.0", "@aws-cdk/lambda-layer-node-proxy-agent": "0.0.0", diff --git a/packages/monocdk/package.json b/packages/monocdk/package.json index 58258c064e12f..ea69bcce74f59 100644 --- a/packages/monocdk/package.json +++ b/packages/monocdk/package.json @@ -343,6 +343,7 @@ "@aws-cdk/core": "0.0.0", "@aws-cdk/custom-resources": "0.0.0", "@aws-cdk/cx-api": "0.0.0", + "@aws-cdk/integ-tests": "0.0.0", "@aws-cdk/lambda-layer-awscli": "0.0.0", "@aws-cdk/lambda-layer-kubectl": "0.0.0", "@aws-cdk/lambda-layer-node-proxy-agent": "0.0.0",