@aws-cdk-testing/cli-integ 2.61.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (165) hide show
  1. package/LICENSE +201 -0
  2. package/NOTICE +16 -0
  3. package/README.md +151 -0
  4. package/bin/apply-patches +19 -0
  5. package/bin/download-and-run-old-tests +52 -0
  6. package/bin/query-github +2 -0
  7. package/bin/query-github.d.ts +1 -0
  8. package/bin/query-github.js +55 -0
  9. package/bin/run-suite +2 -0
  10. package/bin/run-suite.d.ts +1 -0
  11. package/bin/run-suite.js +126 -0
  12. package/bin/stage-distribution +2 -0
  13. package/bin/stage-distribution.d.ts +1 -0
  14. package/bin/stage-distribution.js +209 -0
  15. package/bin/test-root +2 -0
  16. package/bin/test-root.d.ts +1 -0
  17. package/bin/test-root.js +6 -0
  18. package/entrypoints/test-cli-regression-against-current-code.sh +11 -0
  19. package/entrypoints/test-cli-regression-against-latest-release.sh +11 -0
  20. package/entrypoints/test-cli-regression.bash +83 -0
  21. package/entrypoints/test.sh +12 -0
  22. package/lib/aws.d.ts +55 -0
  23. package/lib/aws.js +243 -0
  24. package/lib/corking.d.ts +13 -0
  25. package/lib/corking.js +34 -0
  26. package/lib/files.d.ts +15 -0
  27. package/lib/files.js +80 -0
  28. package/lib/github.d.ts +4 -0
  29. package/lib/github.js +43 -0
  30. package/lib/index.d.ts +12 -0
  31. package/lib/index.js +25 -0
  32. package/lib/integ-test.d.ts +11 -0
  33. package/lib/integ-test.js +55 -0
  34. package/lib/lists.d.ts +1 -0
  35. package/lib/lists.js +12 -0
  36. package/lib/memoize.d.ts +6 -0
  37. package/lib/memoize.js +19 -0
  38. package/lib/npm.d.ts +4 -0
  39. package/lib/npm.js +15 -0
  40. package/lib/package-sources/release-source.d.ts +22 -0
  41. package/lib/package-sources/release-source.js +67 -0
  42. package/lib/package-sources/repo-source.d.ts +23 -0
  43. package/lib/package-sources/repo-source.js +92 -0
  44. package/lib/package-sources/repo-tools/npm +2 -0
  45. package/lib/package-sources/repo-tools/npm.d.ts +1 -0
  46. package/lib/package-sources/repo-tools/npm.js +42 -0
  47. package/lib/package-sources/source.d.ts +24 -0
  48. package/lib/package-sources/source.js +3 -0
  49. package/lib/package-sources/subprocess.d.ts +3 -0
  50. package/lib/package-sources/subprocess.js +18 -0
  51. package/lib/resource-pool.d.ts +54 -0
  52. package/lib/resource-pool.js +120 -0
  53. package/lib/resources.d.ts +1 -0
  54. package/lib/resources.js +6 -0
  55. package/lib/shell.d.ts +59 -0
  56. package/lib/shell.js +118 -0
  57. package/lib/staging/codeartifact.d.ts +44 -0
  58. package/lib/staging/codeartifact.js +258 -0
  59. package/lib/staging/maven.d.ts +5 -0
  60. package/lib/staging/maven.js +83 -0
  61. package/lib/staging/npm.d.ts +4 -0
  62. package/lib/staging/npm.js +56 -0
  63. package/lib/staging/nuget.d.ts +4 -0
  64. package/lib/staging/nuget.js +71 -0
  65. package/lib/staging/parallel-shell.d.ts +6 -0
  66. package/lib/staging/parallel-shell.js +46 -0
  67. package/lib/staging/pypi.d.ts +4 -0
  68. package/lib/staging/pypi.js +49 -0
  69. package/lib/staging/usage-dir.d.ts +31 -0
  70. package/lib/staging/usage-dir.js +87 -0
  71. package/lib/with-aws.d.ts +13 -0
  72. package/lib/with-aws.js +60 -0
  73. package/lib/with-cdk-app.d.ts +146 -0
  74. package/lib/with-cdk-app.js +398 -0
  75. package/lib/with-packages.d.ts +5 -0
  76. package/lib/with-packages.js +14 -0
  77. package/lib/with-sam.d.ts +33 -0
  78. package/lib/with-sam.js +240 -0
  79. package/lib/with-temporary-directory.d.ts +5 -0
  80. package/lib/with-temporary-directory.js +32 -0
  81. package/lib/xpmutex.d.ts +43 -0
  82. package/lib/xpmutex.js +207 -0
  83. package/package.json +73 -0
  84. package/resources/cdk-apps/app/app.js +463 -0
  85. package/resources/cdk-apps/app/cdk.json +7 -0
  86. package/resources/cdk-apps/app/docker/Dockerfile +2 -0
  87. package/resources/cdk-apps/app/docker/Dockerfile.Custom +2 -0
  88. package/resources/cdk-apps/app/lambda/index.js +4 -0
  89. package/resources/cdk-apps/app/lambda/response.json +3 -0
  90. package/resources/cdk-apps/app/nested-stack.js +49 -0
  91. package/resources/cdk-apps/cfn-include-app/.gitignore +1 -0
  92. package/resources/cdk-apps/cfn-include-app/cdk.json +4 -0
  93. package/resources/cdk-apps/cfn-include-app/cfn-include-app.js +21 -0
  94. package/resources/cdk-apps/cfn-include-app/example-template.json +13 -0
  95. package/resources/cdk-apps/sam_cdk_integ_app/bin/test-app.js +11 -0
  96. package/resources/cdk-apps/sam_cdk_integ_app/cdk.json +6 -0
  97. package/resources/cdk-apps/sam_cdk_integ_app/lib/nested-stack.js +19 -0
  98. package/resources/cdk-apps/sam_cdk_integ_app/lib/test-stack.js +134 -0
  99. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/.no-packagejson-validator +0 -0
  100. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/Dockerfile +9 -0
  101. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/app.js +22 -0
  102. package/resources/cdk-apps/sam_cdk_integ_app/src/docker/DockerImageFunctionConstruct/package.json +18 -0
  103. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.mod +5 -0
  104. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/go.sum +17 -0
  105. package/resources/cdk-apps/sam_cdk_integ_app/src/go/GoFunctionConstruct/main.go +17 -0
  106. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/.no-packagejson-validator +0 -0
  107. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/app.ts +16 -0
  108. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package-lock.json +12 -0
  109. package/resources/cdk-apps/sam_cdk_integ_app/src/nodejs/NodeJsFunctionConstruct/package.json +5 -0
  110. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/app.py +15 -0
  111. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Function/requirements.txt +1 -0
  112. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/layer_version_dependency.py +5 -0
  113. package/resources/cdk-apps/sam_cdk_integ_app/src/python/Layer/requirements.txt +1 -0
  114. package/resources/cdk-apps/sam_cdk_integ_app/src/rest-api-definition.yaml +12 -0
  115. package/resources/cli-regression-patches/v1.119.0/NOTES.md +5 -0
  116. package/resources/cli-regression-patches/v1.119.0/cli.integtest.js +659 -0
  117. package/resources/cli-regression-patches/v1.130.0/NOTES.md +12 -0
  118. package/resources/cli-regression-patches/v1.130.0/app/app.js +378 -0
  119. package/resources/cli-regression-patches/v1.130.0/bootstrapping.integtest.js +220 -0
  120. package/resources/cli-regression-patches/v1.44.0/NOTES.md +18 -0
  121. package/resources/cli-regression-patches/v1.44.0/bootstrapping.integtest.js +126 -0
  122. package/resources/cli-regression-patches/v1.44.0/test.sh +26 -0
  123. package/resources/cli-regression-patches/v1.61.1/NOTES.md +2 -0
  124. package/resources/cli-regression-patches/v1.61.1/skip-tests.txt +16 -0
  125. package/resources/cli-regression-patches/v1.62.0/NOTES.md +2 -0
  126. package/resources/cli-regression-patches/v1.62.0/aws-helpers.js +245 -0
  127. package/resources/cli-regression-patches/v1.63.0/NOTES.md +1 -0
  128. package/resources/cli-regression-patches/v1.63.0/skip-tests.txt +7 -0
  129. package/resources/cli-regression-patches/v1.64.0/NOTES.md +3 -0
  130. package/resources/cli-regression-patches/v1.64.0/cdk-helpers.js +325 -0
  131. package/resources/cli-regression-patches/v1.64.0/cli.integtest.js +599 -0
  132. package/resources/cli-regression-patches/v1.64.1/NOTES.md +3 -0
  133. package/resources/cli-regression-patches/v1.64.1/cdk-helpers.js +324 -0
  134. package/resources/cli-regression-patches/v1.64.1/cli.integtest.js +599 -0
  135. package/resources/cli-regression-patches/v1.67.0/NOTES.md +2 -0
  136. package/resources/cli-regression-patches/v1.67.0/cdk-helpers.js +331 -0
  137. package/resources/cloud-assemblies/0.36.0/InitStack.template.json +1 -0
  138. package/resources/cloud-assemblies/0.36.0/manifest.json +19 -0
  139. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/InitStack.template.json +2 -0
  140. package/resources/cloud-assemblies/1.10.0-lookup-default-vpc/manifest.json.js +37 -0
  141. package/resources/cloud-assemblies/1.10.0-request-azs/InitStack.template.json +2 -0
  142. package/resources/cloud-assemblies/1.10.0-request-azs/manifest.json.js +34 -0
  143. package/resources/integ.jest.config.js +25 -0
  144. package/skip-tests.txt +8 -0
  145. package/tests/cli-integ-tests/README.md +47 -0
  146. package/tests/cli-integ-tests/bootstrapping.integtest.d.ts +1 -0
  147. package/tests/cli-integ-tests/bootstrapping.integtest.js +271 -0
  148. package/tests/cli-integ-tests/cli.integtest.d.ts +1 -0
  149. package/tests/cli-integ-tests/cli.integtest.js +1029 -0
  150. package/tests/init-csharp/init-csharp.integtest.d.ts +1 -0
  151. package/tests/init-csharp/init-csharp.integtest.js +14 -0
  152. package/tests/init-fsharp/init-fsharp.integtest.d.ts +1 -0
  153. package/tests/init-fsharp/init-fsharp.integtest.js +14 -0
  154. package/tests/init-java/init-java.integtest.d.ts +1 -0
  155. package/tests/init-java/init-java.integtest.js +14 -0
  156. package/tests/init-javascript/init-javascript.integtest.d.ts +1 -0
  157. package/tests/init-javascript/init-javascript.integtest.js +15 -0
  158. package/tests/init-python/init-python.integtest.d.ts +1 -0
  159. package/tests/init-python/init-python.integtest.js +19 -0
  160. package/tests/init-typescript-app/init-typescript-app.integtest.d.ts +1 -0
  161. package/tests/init-typescript-app/init-typescript-app.integtest.js +49 -0
  162. package/tests/init-typescript-lib/init-typescript-lib.integtest.d.ts +1 -0
  163. package/tests/init-typescript-lib/init-typescript-lib.integtest.js +13 -0
  164. package/tests/uberpackage/uberpackage.integtest.d.ts +1 -0
  165. package/tests/uberpackage/uberpackage.integtest.js +11 -0
@@ -0,0 +1,2 @@
1
+ Integration tests are now injected with environment variable that specifies which framework
2
+ version they should install and use. This patch includes the cdk-helpers.js file that is responsible for that.
@@ -0,0 +1,331 @@
1
+ "use strict";
2
+ var _a, _b;
3
+ Object.defineProperty(exports, "__esModule", { value: true });
4
+ exports.randomString = exports.rimraf = exports.shell = exports.TestFixture = exports.cloneDirectory = exports.withDefaultFixture = exports.withCdkApp = exports.withAws = void 0;
5
+ const child_process = require("child_process");
6
+ const fs = require("fs");
7
+ const os = require("os");
8
+ const path = require("path");
9
+ const aws_helpers_1 = require("./aws-helpers");
10
+ const resource_pool_1 = require("./resource-pool");
11
+ const REGIONS = process.env.AWS_REGIONS
12
+ ? process.env.AWS_REGIONS.split(',')
13
+ : [(_b = (_a = process.env.AWS_REGION) !== null && _a !== void 0 ? _a : process.env.AWS_DEFAULT_REGION) !== null && _b !== void 0 ? _b : 'us-east-1'];
14
+ const FRAMEWORK_VERSION = process.env.FRAMEWORK_VERSION;
15
+ process.stdout.write(`Using regions: ${REGIONS}\n`);
16
+ process.stdout.write(`Using framework version: ${FRAMEWORK_VERSION}\n`);
17
+ const REGION_POOL = new resource_pool_1.ResourcePool(REGIONS);
18
+ /**
19
+ * Higher order function to execute a block with an AWS client setup
20
+ *
21
+ * Allocate the next region from the REGION pool and dispose it afterwards.
22
+ */
23
+ function withAws(block) {
24
+ return (context) => REGION_POOL.using(async (region) => {
25
+ const aws = await aws_helpers_1.AwsClients.forRegion(region, context.output);
26
+ await sanityCheck(aws);
27
+ return block({ ...context, aws });
28
+ });
29
+ }
30
+ exports.withAws = withAws;
31
+ /**
32
+ * Higher order function to execute a block with a CDK app fixture
33
+ *
34
+ * Requires an AWS client to be passed in.
35
+ *
36
+ * For backwards compatibility with existing tests (so we don't have to change
37
+ * too much) the inner block is expected to take a `TestFixture` object.
38
+ */
39
+ function withCdkApp(block) {
40
+ return async (context) => {
41
+ const randy = randomString();
42
+ const stackNamePrefix = `cdktest-${randy}`;
43
+ const integTestDir = path.join(os.tmpdir(), `cdk-integ-${randy}`);
44
+ context.output.write(` Stack prefix: ${stackNamePrefix}\n`);
45
+ context.output.write(` Test directory: ${integTestDir}\n`);
46
+ context.output.write(` Region: ${context.aws.region}\n`);
47
+ await cloneDirectory(path.join(__dirname, 'app'), integTestDir, context.output);
48
+ const fixture = new TestFixture(integTestDir, stackNamePrefix, context.output, context.aws);
49
+ let success = true;
50
+ try {
51
+ let modules = [
52
+ '@aws-cdk/core',
53
+ '@aws-cdk/aws-sns',
54
+ '@aws-cdk/aws-iam',
55
+ '@aws-cdk/aws-lambda',
56
+ '@aws-cdk/aws-ssm',
57
+ '@aws-cdk/aws-ecr-assets',
58
+ '@aws-cdk/aws-cloudformation',
59
+ '@aws-cdk/aws-ec2',
60
+ ];
61
+ if (FRAMEWORK_VERSION) {
62
+ modules = modules.map(module => `${module}@${FRAMEWORK_VERSION}`);
63
+ }
64
+ await fixture.shell(['npm', 'install', ...modules]);
65
+ await ensureBootstrapped(fixture);
66
+ await block(fixture);
67
+ }
68
+ catch (e) {
69
+ success = false;
70
+ throw e;
71
+ }
72
+ finally {
73
+ await fixture.dispose(success);
74
+ }
75
+ };
76
+ }
77
+ exports.withCdkApp = withCdkApp;
78
+ /**
79
+ * Default test fixture for most (all?) integ tests
80
+ *
81
+ * It's a composition of withAws/withCdkApp, expecting the test block to take a `TestFixture`
82
+ * object.
83
+ *
84
+ * We could have put `withAws(withCdkApp(fixture => { /... actual test here.../ }))` in every
85
+ * test declaration but centralizing it is going to make it convenient to modify in the future.
86
+ */
87
+ function withDefaultFixture(block) {
88
+ return withAws(withCdkApp(block));
89
+ // ^~~~~~ this is disappointing TypeScript! Feels like you should have been able to derive this.
90
+ }
91
+ exports.withDefaultFixture = withDefaultFixture;
92
+ /**
93
+ * Prepare a target dir byreplicating a source directory
94
+ */
95
+ async function cloneDirectory(source, target, output) {
96
+ await shell(['rm', '-rf', target], { output });
97
+ await shell(['mkdir', '-p', target], { output });
98
+ await shell(['cp', '-R', source + '/*', target], { output });
99
+ }
100
+ exports.cloneDirectory = cloneDirectory;
101
+ class TestFixture {
102
+ constructor(integTestDir, stackNamePrefix, output, aws) {
103
+ this.integTestDir = integTestDir;
104
+ this.stackNamePrefix = stackNamePrefix;
105
+ this.output = output;
106
+ this.aws = aws;
107
+ this.qualifier = randomString().slice(0, 10);
108
+ this.bucketsToDelete = new Array();
109
+ }
110
+ log(s) {
111
+ this.output.write(`${s}\n`);
112
+ }
113
+ async shell(command, options = {}) {
114
+ return shell(command, {
115
+ output: this.output,
116
+ cwd: this.integTestDir,
117
+ ...options,
118
+ });
119
+ }
120
+ async cdkDeploy(stackNames, options = {}) {
121
+ var _a, _b;
122
+ stackNames = typeof stackNames === 'string' ? [stackNames] : stackNames;
123
+ const neverRequireApproval = (_a = options.neverRequireApproval) !== null && _a !== void 0 ? _a : true;
124
+ return this.cdk(['deploy',
125
+ ...(neverRequireApproval ? ['--require-approval=never'] : []), // Default to no approval in an unattended test
126
+ ...((_b = options.options) !== null && _b !== void 0 ? _b : []), ...this.fullStackName(stackNames)], options);
127
+ }
128
+ async cdkDestroy(stackNames, options = {}) {
129
+ var _a;
130
+ stackNames = typeof stackNames === 'string' ? [stackNames] : stackNames;
131
+ return this.cdk(['destroy',
132
+ '-f', // We never want a prompt in an unattended test
133
+ ...((_a = options.options) !== null && _a !== void 0 ? _a : []), ...this.fullStackName(stackNames)], options);
134
+ }
135
+ async cdk(args, options = {}) {
136
+ var _a;
137
+ const verbose = (_a = options.verbose) !== null && _a !== void 0 ? _a : true;
138
+ return this.shell(['cdk', ...(verbose ? ['-v'] : []), ...args], {
139
+ ...options,
140
+ modEnv: {
141
+ AWS_REGION: this.aws.region,
142
+ AWS_DEFAULT_REGION: this.aws.region,
143
+ STACK_NAME_PREFIX: this.stackNamePrefix,
144
+ ...options.modEnv,
145
+ },
146
+ });
147
+ }
148
+ fullStackName(stackNames) {
149
+ if (typeof stackNames === 'string') {
150
+ return `${this.stackNamePrefix}-${stackNames}`;
151
+ }
152
+ else {
153
+ return stackNames.map(s => `${this.stackNamePrefix}-${s}`);
154
+ }
155
+ }
156
+ /**
157
+ * Append this to the list of buckets to potentially delete
158
+ *
159
+ * At the end of a test, we clean up buckets that may not have gotten destroyed
160
+ * (for whatever reason).
161
+ */
162
+ rememberToDeleteBucket(bucketName) {
163
+ this.bucketsToDelete.push(bucketName);
164
+ }
165
+ /**
166
+ * Cleanup leftover stacks and buckets
167
+ */
168
+ async dispose(success) {
169
+ const stacksToDelete = await this.deleteableStacks(this.stackNamePrefix);
170
+ // Bootstrap stacks have buckets that need to be cleaned
171
+ const bucketNames = stacksToDelete.map(stack => aws_helpers_1.outputFromStack('BucketName', stack)).filter(defined);
172
+ await Promise.all(bucketNames.map(b => this.aws.emptyBucket(b)));
173
+ // Bootstrap stacks have ECR repositories with images which should be deleted
174
+ const imageRepositoryNames = stacksToDelete.map(stack => aws_helpers_1.outputFromStack('ImageRepositoryName', stack)).filter(defined);
175
+ await Promise.all(imageRepositoryNames.map(r => this.aws.deleteImageRepository(r)));
176
+ await this.aws.deleteStacks(...stacksToDelete.map(s => s.StackName));
177
+ // We might have leaked some buckets by upgrading the bootstrap stack. Be
178
+ // sure to clean everything.
179
+ for (const bucket of this.bucketsToDelete) {
180
+ await this.aws.deleteBucket(bucket);
181
+ }
182
+ // If the tests completed successfully, happily delete the fixture
183
+ // (otherwise leave it for humans to inspect)
184
+ if (success) {
185
+ rimraf(this.integTestDir);
186
+ }
187
+ }
188
+ /**
189
+ * Return the stacks starting with our testing prefix that should be deleted
190
+ */
191
+ async deleteableStacks(prefix) {
192
+ var _a;
193
+ const statusFilter = [
194
+ 'CREATE_IN_PROGRESS', 'CREATE_FAILED', 'CREATE_COMPLETE',
195
+ 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'ROLLBACK_COMPLETE',
196
+ 'DELETE_FAILED',
197
+ 'UPDATE_IN_PROGRESS', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS',
198
+ 'UPDATE_COMPLETE', 'UPDATE_ROLLBACK_IN_PROGRESS',
199
+ 'UPDATE_ROLLBACK_FAILED',
200
+ 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS',
201
+ 'UPDATE_ROLLBACK_COMPLETE', 'REVIEW_IN_PROGRESS',
202
+ 'IMPORT_IN_PROGRESS', 'IMPORT_COMPLETE',
203
+ 'IMPORT_ROLLBACK_IN_PROGRESS', 'IMPORT_ROLLBACK_FAILED',
204
+ 'IMPORT_ROLLBACK_COMPLETE',
205
+ ];
206
+ const response = await this.aws.cloudFormation('describeStacks', {});
207
+ return ((_a = response.Stacks) !== null && _a !== void 0 ? _a : [])
208
+ .filter(s => s.StackName.startsWith(prefix))
209
+ .filter(s => statusFilter.includes(s.StackStatus))
210
+ .filter(s => s.RootId === undefined); // Only delete parent stacks. Nested stacks are deleted in the process
211
+ }
212
+ }
213
+ exports.TestFixture = TestFixture;
214
+ /**
215
+ * Perform a one-time quick sanity check that the AWS clients has properly configured credentials
216
+ *
217
+ * If we don't do this, calls are going to fail and they'll be retried and everything will take
218
+ * forever before the user notices a simple misconfiguration.
219
+ *
220
+ * We can't check for the presence of environment variables since credentials could come from
221
+ * anywhere, so do simple account retrieval.
222
+ *
223
+ * Only do it once per process.
224
+ */
225
+ async function sanityCheck(aws) {
226
+ if (sanityChecked === undefined) {
227
+ try {
228
+ await aws.account();
229
+ sanityChecked = true;
230
+ }
231
+ catch (e) {
232
+ sanityChecked = false;
233
+ throw new Error(`AWS credentials probably not configured, got error: ${e.message}`);
234
+ }
235
+ }
236
+ if (!sanityChecked) {
237
+ throw new Error('AWS credentials probably not configured, see previous error');
238
+ }
239
+ }
240
+ let sanityChecked;
241
+ /**
242
+ * Make sure that the given environment is bootstrapped
243
+ *
244
+ * Since we go striping across regions, it's going to suck doing this
245
+ * by hand so let's just mass-automate it.
246
+ */
247
+ async function ensureBootstrapped(fixture) {
248
+ // Old-style bootstrap stack with default name
249
+ if (await fixture.aws.stackStatus('CDKToolkit') === undefined) {
250
+ await fixture.cdk(['bootstrap', `aws://${await fixture.aws.account()}/${fixture.aws.region}`]);
251
+ }
252
+ }
253
+ /**
254
+ * A shell command that does what you want
255
+ *
256
+ * Is platform-aware, handles errors nicely.
257
+ */
258
+ async function shell(command, options = {}) {
259
+ var _a, _b;
260
+ if (options.modEnv && options.env) {
261
+ throw new Error('Use either env or modEnv but not both');
262
+ }
263
+ (_a = options.output) === null || _a === void 0 ? void 0 : _a.write(`💻 ${command.join(' ')}\n`);
264
+ const env = (_b = options.env) !== null && _b !== void 0 ? _b : (options.modEnv ? { ...process.env, ...options.modEnv } : undefined);
265
+ const child = child_process.spawn(command[0], command.slice(1), {
266
+ ...options,
267
+ env,
268
+ // Need this for Windows where we want .cmd and .bat to be found as well.
269
+ shell: true,
270
+ stdio: ['ignore', 'pipe', 'pipe'],
271
+ });
272
+ return new Promise((resolve, reject) => {
273
+ const stdout = new Array();
274
+ const stderr = new Array();
275
+ child.stdout.on('data', chunk => {
276
+ var _a;
277
+ (_a = options.output) === null || _a === void 0 ? void 0 : _a.write(chunk);
278
+ stdout.push(chunk);
279
+ });
280
+ child.stderr.on('data', chunk => {
281
+ var _a, _b;
282
+ (_a = options.output) === null || _a === void 0 ? void 0 : _a.write(chunk);
283
+ if ((_b = options.captureStderr) !== null && _b !== void 0 ? _b : true) {
284
+ stderr.push(chunk);
285
+ }
286
+ });
287
+ child.once('error', reject);
288
+ child.once('close', code => {
289
+ if (code === 0 || options.allowErrExit) {
290
+ resolve((Buffer.concat(stdout).toString('utf-8') + Buffer.concat(stderr).toString('utf-8')).trim());
291
+ }
292
+ else {
293
+ reject(new Error(`'${command.join(' ')}' exited with error code ${code}`));
294
+ }
295
+ });
296
+ });
297
+ }
298
+ exports.shell = shell;
299
+ function defined(x) {
300
+ return x !== undefined;
301
+ }
302
+ /**
303
+ * rm -rf reimplementation, don't want to depend on an NPM package for this
304
+ */
305
+ function rimraf(fsPath) {
306
+ try {
307
+ const isDir = fs.lstatSync(fsPath).isDirectory();
308
+ if (isDir) {
309
+ for (const file of fs.readdirSync(fsPath)) {
310
+ rimraf(path.join(fsPath, file));
311
+ }
312
+ fs.rmdirSync(fsPath);
313
+ }
314
+ else {
315
+ fs.unlinkSync(fsPath);
316
+ }
317
+ }
318
+ catch (e) {
319
+ // We will survive ENOENT
320
+ if (e.code !== 'ENOENT') {
321
+ throw e;
322
+ }
323
+ }
324
+ }
325
+ exports.rimraf = rimraf;
326
+ function randomString() {
327
+ // Crazy
328
+ return Math.random().toString(36).replace(/[^a-z0-9]+/g, '');
329
+ }
330
+ exports.randomString = randomString;
331
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJjZGstaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7O0FBQUEsK0NBQStDO0FBQy9DLHlCQUF5QjtBQUN6Qix5QkFBeUI7QUFDekIsNkJBQTZCO0FBQzdCLCtDQUE0RDtBQUM1RCxtREFBK0M7QUFHL0MsTUFBTSxPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxXQUFXO0lBQ3JDLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDO0lBQ3BDLENBQUMsQ0FBQyxhQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxtQ0FBSSxPQUFPLENBQUMsR0FBRyxDQUFDLGtCQUFrQixtQ0FBSSxXQUFXLENBQUMsQ0FBQztBQUU5RSxNQUFNLGlCQUFpQixHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsaUJBQWlCLENBQUM7QUFFeEQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLE9BQU8sSUFBSSxDQUFDLENBQUM7QUFDcEQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLGlCQUFpQixJQUFJLENBQUMsQ0FBQztBQUV4RSxNQUFNLFdBQVcsR0FBRyxJQUFJLDRCQUFZLENBQUMsT0FBTyxDQUFDLENBQUM7QUFLOUM7Ozs7R0FJRztBQUNILFNBQWdCLE9BQU8sQ0FBd0IsS0FBaUQ7SUFDOUYsT0FBTyxDQUFDLE9BQVUsRUFBRSxFQUFFLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEVBQUU7UUFDeEQsTUFBTSxHQUFHLEdBQUcsTUFBTSx3QkFBVSxDQUFDLFNBQVMsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQy9ELE1BQU0sV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBRXZCLE9BQU8sS0FBSyxDQUFDLEVBQUUs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QUFDekIsQ0FBQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IsTUFBTSxDQUFDLE1BQWM7SUFDbkMsSUFBSTtRQUNGLE1BQU0sS0FBSyxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsV0FBVyxFQUFFLENBQUM7UUFFakQsSUFBSSxLQUFLLEVBQUU7WUFDVCxLQUFLLE1BQU0sSUFBSSxJQUFJLEVBQUUsQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLEVBQUU7Z0JBQ3pDLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO2FBQ2pDO1lBQ0QsRUFBRSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN0QjthQUFNO1lBQ0wsRUFBRSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztTQUN2QjtLQUNGO0lBQUMsT0FBTyxDQUFDLEVBQUU7UUFDVix5QkFBeUI7UUFDekIsSUFBSSxDQUFDLENBQUMsSUFBSSxLQUFLLFFBQVEsRUFBRTtZQUFFLE1BQU0sQ0FBQyxDQUFDO1NBQUU7S0FDdEM7QUFDSCxDQUFDO0FBaEJELHdCQWdCQztBQUVELFNBQWdCLFlBQVk7SUFDMUIsUUFBUTtJQUNSLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsYUFBYSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0FBQy9ELENBQUM7QUFIRCxvQ0FHQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCAqIGFzIGNoaWxkX3Byb2Nlc3MgZnJvbSAnY2hpbGRfcHJvY2Vzcyc7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcyc7XG5pbXBvcnQgKiBhcyBvcyBmcm9tICdvcyc7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHsgb3V0cHV0RnJvbVN0YWNrLCBBd3NDbGllbnRzIH0gZnJvbSAnLi9hd3MtaGVscGVycyc7XG5pbXBvcnQgeyBSZXNvdXJjZVBvb2wgfSBmcm9tICcuL3Jlc291cmNlLXBvb2wnO1xuaW1wb3J0IHsgVGVzdENvbnRleHQgfSBmcm9tICcuL3Rlc3QtaGVscGVycyc7XG5cbmNvbnN0IFJFR0lPTlMgPSBwcm9jZXNzLmVudi5BV1NfUkVHSU9OU1xuICA/IHByb2Nlc3MuZW52LkFXU19SRUdJT05TLnNwbGl0KCcsJylcbiAgOiBbcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiA/PyBwcm9jZXNzLmVudi5BV1NfREVGQVVMVF9SRUdJT04gPz8gJ3VzLWVhc3QtMSddO1xuXG5jb25zdCBGUkFNRVdPUktfVkVSU0lPTiA9IHByb2Nlc3MuZW52LkZSQU1FV09SS19WRVJTSU9OO1xuXG5wcm9jZXNzLnN0ZG91dC53cml0ZShgVXNpbmcgcmVnaW9uczogJHtSRUdJT05TfVxcbmApO1xucHJvY2Vzcy5zdGRvdXQud3JpdGUoYFVzaW5nIGZyYW1ld29yayB2ZXJzaW9uOiAke0ZSQU1FV09SS19WRVJTSU9OfVxcbmApO1xuXG5jb25zdCBSRUdJT05fUE9PTCA9IG5ldyBSZXNvdXJjZVBvb2woUkVHSU9OUyk7XG5cblxuZXhwb3J0IHR5cGUgQXdzQ29udGV4dCA9IHsgcmVhZG9ubHkgYXdzOiBBd3NDbGllbnRzIH07XG5cbi8qKlxuICogSGlnaGVyIG9yZGVyIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgYSBibG9jayB3aXRoIGFuIEFXUyBjbGllbnQgc2V0dXBcbiAqXG4gKiBBbGxvY2F0ZSB0aGUgbmV4dCByZWdpb24gZnJvbSB0aGUgUkVHSU9OIHBvb2wgYW5kIGRpc3Bvc2UgaXQgYWZ0ZXJ3YXJkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhBd3M8QSBleHRlbmRzIFRlc3RDb250ZXh0PihibG9jazogKGNvbnRleHQ6IEEgJiBBd3NDb250ZXh0KSA9PiBQcm9taXNlPHZvaWQ+KSB7XG4gIHJldHVybiAoY29udGV4dDogQSkgPT4gUkVHSU9OX1BPT0wudXNpbmcoYXN5bmMgKHJlZ2lvbikgPT4ge1xuICAgIGNvbnN0IGF3cyA9IGF3YWl0IEF3c0NsaWVudHMuZm9yUmVnaW9uKHJlZ2lvbiwgY29udGV4dC5vdXRwdXQpO1xuICAgIGF3YWl0IHNhbml0eUNoZWNrKGF3cyk7XG5cbiAgICByZXR1cm4gYmxvY2soeyAuLi5jb250ZXh0LCBhd3MgfSk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEhpZ2hlciBvcmRlciBmdW5jdGlvbiB0byBleGVjdXRlIGEgYmxvY2sgd2l0aCBhIENESyBhcHAgZml4dHVyZVxuICpcbiAqIFJlcXVpcmVzIGFuIEFXUyBjbGllbnQgdG8gYmUgcGFzc2VkIGluLlxuICpcbiAqIEZvciBiYWNrd2FyZHMgY29tcGF0aWJpbGl0eSB3aXRoIGV4aXN0aW5nIHRlc3RzIChzbyB3ZSBkb24ndCBoYXZlIHRvIGNoYW5nZVxuICogdG9vIG11Y2gpIHRoZSBpbm5lciBibG9jayBpcyBleHBlY3RlZCB0byB0YWtlIGEgYFRlc3RGaXh0dXJlYCBvYmplY3QuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoQ2RrQXBwPEEgZXh0ZW5kcyBUZXN0Q29udGV4dCAmIEF3c0NvbnRleHQ+KGJsb2NrOiAoY29udGV4dDogVGVzdEZpeHR1cmUpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgcmV0dXJuIGFzeW5jIChjb250ZXh0OiBBKSA9PiB7XG4gICAgY29uc3QgcmFuZHkgPSByYW5kb21TdHJpbmcoKTtcbiAgICBjb25zdCBzdGFja05hbWVQcmVmaXggPSBgY2RrdGVzdC0ke3JhbmR5fWA7XG4gICAgY29uc3QgaW50ZWdUZXN0RGlyID0gcGF0aC5qb2luKG9zLnRtcGRpcigpLCBgY2RrLWludGVnLSR7cmFuZHl9YCk7XG5cbiAgICBjb250ZXh0Lm91dHB1dC53cml0ZShgIFN0YWNrIHByZWZpeDogICAke3N0YWNrTmFtZVByZWZpeH1cXG5gKTtcbiAgICBjb250ZXh0Lm91dHB1dC53cml0ZShgIFRlc3QgZGlyZWN0b3J5OiAke2ludGVnVGVzdERpcn1cXG5gKTtcbiAgICBjb250ZXh0Lm91dHB1dC53cml0ZShgIFJlZ2lvbjogICAgICAgICAke2NvbnRleHQuYXdzLnJlZ2lvbn1cXG5gKTtcblxuICAgIGF3YWl0IGNsb25lRGlyZWN0b3J5KHBhdGguam9pbihfX2Rpcm5hbWUsICdhcHAnKSwgaW50ZWdUZXN0RGlyLCBjb250ZXh0Lm91dHB1dCk7XG4gICAgY29uc3QgZml4dHVyZSA9IG5ldyBUZXN0Rml4dHVyZShcbiAgICAgIGludGVnVGVzdERpcixcbiAgICAgIHN0YWNrTmFtZVByZWZpeCxcbiAgICAgIGNvbnRleHQub3V0cHV0LFxuICAgICAgY29udGV4dC5hd3MpO1xuXG4gICAgbGV0IHN1Y2Nlc3MgPSB0cnVlO1xuICAgIHRyeSB7XG4gICAgICBsZXQgbW9kdWxlcyA9IFtcbiAgICAgICAgJ0Bhd3MtY2RrL2NvcmUnLFxuICAgICAgICAnQGF3cy1jZGsvYXdzLXNucycsXG4gICAgICAgICdAYXdzLWNkay9hd3MtaWFtJyxcbiAgICAgICAgJ0Bhd3MtY2RrL2F3cy1sYW1iZGEnLFxuICAgICAgICAnQGF3cy1jZGsvYXdzLXNzbScsXG4gICAgICAgICdAYXdzLWNkay9hd3MtZWNyLWFzc2V0cycsXG4gICAgICAgICdAYXdzLWNkay9hd3MtY2xvdWRmb3JtYXRpb24nLFxuICAgICAgICAnQGF3cy1jZGsvYXdzLWVjMicsXG4gICAgICBdO1xuICAgICAgaWYgKEZSQU1FV09SS19WRVJTSU9OKSB7XG4gICAgICAgIG1vZHVsZXMgPSBtb2R1bGVzLm1hcChtb2R1bGUgPT4gYCR7bW9kdWxlfUAke0ZSQU1FV09SS19WRVJTSU9OfWApO1xuICAgICAgfVxuICAgICAgYXdhaXQgZml4dHVyZS5zaGVsbChbJ25wbScsICdpbnN0YWxsJywgLi4ubW9kdWxlc10pO1xuXG4gICAgICBhd2FpdCBlbnN1cmVCb290c3RyYXBwZWQoZml4dHVyZSk7XG5cbiAgICAgIGF3YWl0IGJsb2NrKGZpeHR1cmUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHN1Y2Nlc3MgPSBmYWxzZTtcbiAgICAgIHRocm93IGU7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGF3YWl0IGZpeHR1cmUuZGlzcG9zZShzdWNjZXNzKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogRGVmYXVsdCB0ZXN0IGZpeHR1cmUgZm9yIG1vc3QgKGFsbD8pIGludGVnIHRlc3RzXG4gKlxuICogSXQncyBhIGNvbXBvc2l0aW9uIG9mIHdpdGhBd3Mvd2l0aENka0FwcCwgZXhwZWN0aW5nIHRoZSB0ZXN0IGJsb2NrIHRvIHRha2UgYSBgVGVzdEZpeHR1cmVgXG4gKiBvYmplY3QuXG4gKlxuICogV2UgY291bGQgaGF2ZSBwdXQgYHdpdGhBd3Mod2l0aENka0FwcChmaXh0dXJlID0+IHsgLy4uLiBhY3R1YWwgdGVzdCBoZXJlLi4uLyB9KSlgIGluIGV2ZXJ5XG4gKiB0ZXN0IGRlY2xhcmF0aW9uIGJ1dCBjZW50cmFsaXppbmcgaXQgaXMgZ29pbmcgdG8gbWFrZSBpdCBjb252ZW5pZW50IHRvIG1vZGlmeSBpbiB0aGUgZnV0dXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gd2l0aERlZmF1bHRGaXh0dXJlKGJsb2NrOiAoY29udGV4dDogVGVzdEZpeHR1cmUpID0+IFByb21pc2U8dm9pZD4pIHtcbiAgcmV0dXJuIHdpdGhBd3M8VGVzdENvbnRleHQ+KHdpdGhDZGtBcHAoYmxvY2spKTtcbiAgLy8gICAgICAgICAgICAgIF5+fn5+fiB0aGlzIGlzIGRpc2FwcG9pbnRpbmcgVHlwZVNjcmlwdCEgRmVlbHMgbGlrZSB5b3Ugc2hvdWxkIGhhdmUgYmVlbiBhYmxlIHRvIGRlcml2ZSB0aGlzLlxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFNoZWxsT3B0aW9ucyBleHRlbmRzIGNoaWxkX3Byb2Nlc3MuU3Bhd25PcHRpb25zIHtcbiAgLyoqXG4gICAqIFByb3BlcnRpZXMgdG8gYWRkIHRvICdlbnYnXG4gICAqL1xuICBtb2RFbnY/OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+O1xuXG4gIC8qKlxuICAgKiBEb24ndCBmYWlsIHdoZW4gZXhpdGluZyB3aXRoIGFuIGVycm9yXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBhbGxvd0VyckV4aXQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGNhcHR1cmUgc3RkZXJyXG4gICAqXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIGNhcHR1cmVTdGRlcnI/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBQYXNzIG91dHB1dCBoZXJlXG4gICAqL1xuICBvdXRwdXQ/OiBOb2RlSlMuV3JpdGFibGVTdHJlYW07XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2RrQ2xpT3B0aW9ucyBleHRlbmRzIFNoZWxsT3B0aW9ucyB7XG4gIG9wdGlvbnM/OiBzdHJpbmdbXTtcbiAgbmV2ZXJSZXF1aXJlQXBwcm92YWw/OiBib29sZWFuO1xuICB2ZXJib3NlPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQcmVwYXJlIGEgdGFyZ2V0IGRpciBieXJlcGxpY2F0aW5nIGEgc291cmNlIGRpcmVjdG9yeVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xvbmVEaXJlY3Rvcnkoc291cmNlOiBzdHJpbmcsIHRhcmdldDogc3RyaW5nLCBvdXRwdXQ/OiBOb2RlSlMuV3JpdGFibGVTdHJlYW0pIHtcbiAgYXdhaXQgc2hlbGwoWydybScsICctcmYnLCB0YXJnZXRdLCB7IG91dHB1dCB9KTtcbiAgYXdhaXQgc2hlbGwoWydta2RpcicsICctcCcsIHRhcmdldF0sIHsgb3V0cHV0IH0pO1xuICBhd2FpdCBzaGVsbChbJ2NwJywgJy1SJywgc291cmNlICsgJy8qJywgdGFyZ2V0XSwgeyBvdXRwdXQgfSk7XG59XG5cbmV4cG9ydCBjbGFzcyBUZXN0Rml4dHVyZSB7XG4gIHB1YmxpYyByZWFkb25seSBxdWFsaWZpZXIgPSByYW5kb21TdHJpbmcoKS5zdWJzdHIoMCwgMTApO1xuICBwcml2YXRlIHJlYWRvbmx5IGJ1Y2tldHNUb0RlbGV0ZSA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGludGVnVGVzdERpcjogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBzdGFja05hbWVQcmVmaXg6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgb3V0cHV0OiBOb2RlSlMuV3JpdGFibGVTdHJlYW0sXG4gICAgcHVibGljIHJlYWRvbmx5IGF3czogQXdzQ2xpZW50cykge1xuICB9XG5cbiAgcHVibGljIGxvZyhzOiBzdHJpbmcpIHtcbiAgICB0aGlzLm91dHB1dC53cml0ZShgJHtzfVxcbmApO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHNoZWxsKGNvbW1hbmQ6IHN0cmluZ1tdLCBvcHRpb25zOiBPbWl0PFNoZWxsT3B0aW9ucywgJ2N3ZCd8J291dHB1dCc+ID0ge30pOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBzaGVsbChjb21tYW5kLCB7XG4gICAgICBvdXRwdXQ6IHRoaXMub3V0cHV0LFxuICAgICAgY3dkOiB0aGlzLmludGVnVGVzdERpcixcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY2RrRGVwbG95KHN0YWNrTmFtZXM6IHN0cmluZyB8IHN0cmluZ1tdLCBvcHRpb25zOiBDZGtDbGlPcHRpb25zID0ge30pIHtcbiAgICBzdGFja05hbWVzID0gdHlwZW9mIHN0YWNrTmFtZXMgPT09ICdzdHJpbmcnID8gW3N0YWNrTmFtZXNdIDogc3RhY2tOYW1lcztcblxuICAgIGNvbnN0IG5ldmVyUmVxdWlyZUFwcHJvdmFsID0gb3B0aW9ucy5uZXZlclJlcXVpcmVBcHByb3ZhbCA/PyB0cnVlO1xuXG4gICAgcmV0dXJuIHRoaXMuY2RrKFsnZGVwbG95JyxcbiAgICAgIC4uLihuZXZlclJlcXVpcmVBcHByb3ZhbCA/IFsnLS1yZXF1aXJlLWFwcHJvdmFsPW5ldmVyJ10gOiBbXSksIC8vIERlZmF1bHQgdG8gbm8gYXBwcm92YWwgaW4gYW4gdW5hdHRlbmRlZCB0ZXN0XG4gICAgICAuLi4ob3B0aW9ucy5vcHRpb25zID8/IFtdKSxcbiAgICAgIC4uLnRoaXMuZnVsbFN0YWNrTmFtZShzdGFja05hbWVzKV0sIG9wdGlvbnMpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNka0Rlc3Ryb3koc3RhY2tOYW1lczogc3RyaW5nIHwgc3RyaW5nW10sIG9wdGlvbnM6IENka0NsaU9wdGlvbnMgPSB7fSkge1xuICAgIHN0YWNrTmFtZXMgPSB0eXBlb2Ygc3RhY2tOYW1lcyA9PT0gJ3N0cmluZycgPyBbc3RhY2tOYW1lc10gOiBzdGFja05hbWVzO1xuXG4gICAgcmV0dXJuIHRoaXMuY2RrKFsnZGVzdHJveScsXG4gICAgICAnLWYnLCAvLyBXZSBuZXZlciB3YW50IGEgcHJvbXB0IGluIGFuIHVuYXR0ZW5kZWQgdGVzdFxuICAgICAgLi4uKG9wdGlvbnMub3B0aW9ucyA/PyBbXSksXG4gICAgICAuLi50aGlzLmZ1bGxTdGFja05hbWUoc3RhY2tOYW1lcyldLCBvcHRpb25zKTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjZGsoYXJnczogc3RyaW5nW10sIG9wdGlvbnM6IENka0NsaU9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IHZlcmJvc2UgPSBvcHRpb25zLnZlcmJvc2UgPz8gdHJ1ZTtcblxuICAgIHJldHVybiB0aGlzLnNoZWxsKFsnY2RrJywgLi4uKHZlcmJvc2UgPyBbJy12J10gOiBbXSksIC4uLmFyZ3NdLCB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgbW9kRW52OiB7XG4gICAgICAgIEFXU19SRUdJT046IHRoaXMuYXdzLnJlZ2lvbixcbiAgICAgICAgQVdTX0RFRkFVTFRfUkVHSU9OOiB0aGlzLmF3cy5yZWdpb24sXG4gICAgICAgIFNUQUNLX05BTUVfUFJFRklYOiB0aGlzLnN0YWNrTmFtZVByZWZpeCxcbiAgICAgICAgLi4ub3B0aW9ucy5tb2RFbnYsXG4gICAgICB9LFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIGZ1bGxTdGFja05hbWUoc3RhY2tOYW1lOiBzdHJpbmcpOiBzdHJpbmc7XG4gIHB1YmxpYyBmdWxsU3RhY2tOYW1lKHN0YWNrTmFtZXM6IHN0cmluZ1tdKTogc3RyaW5nW107XG4gIHB1YmxpYyBmdWxsU3RhY2tOYW1lKHN0YWNrTmFtZXM6IHN0cmluZyB8IHN0cmluZ1tdKTogc3RyaW5nIHwgc3RyaW5nW10ge1xuICAgIGlmICh0eXBlb2Ygc3RhY2tOYW1lcyA9PT0gJ3N0cmluZycpIHtcbiAgICAgIHJldHVybiBgJHt0aGlzLnN0YWNrTmFtZVByZWZpeH0tJHtzdGFja05hbWVzfWA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzdGFja05hbWVzLm1hcChzID0+IGAke3RoaXMuc3RhY2tOYW1lUHJlZml4fS0ke3N9YCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGVuZCB0aGlzIHRvIHRoZSBsaXN0IG9mIGJ1Y2tldHMgdG8gcG90ZW50aWFsbHkgZGVsZXRlXG4gICAqXG4gICAqIEF0IHRoZSBlbmQgb2YgYSB0ZXN0LCB3ZSBjbGVhbiB1cCBidWNrZXRzIHRoYXQgbWF5IG5vdCBoYXZlIGdvdHRlbiBkZXN0cm95ZWRcbiAgICogKGZvciB3aGF0ZXZlciByZWFzb24pLlxuICAgKi9cbiAgcHVibGljIHJlbWVtYmVyVG9EZWxldGVCdWNrZXQoYnVja2V0TmFtZTogc3RyaW5nKSB7XG4gICAgdGhpcy5idWNrZXRzVG9EZWxldGUucHVzaChidWNrZXROYW1lKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhbnVwIGxlZnRvdmVyIHN0YWNrcyBhbmQgYnVja2V0c1xuICAgKi9cbiAgcHVibGljIGFzeW5jIGRpc3Bvc2Uoc3VjY2VzczogYm9vbGVhbikge1xuICAgIGNvbnN0IHN0YWNrc1RvRGVsZXRlID0gYXdhaXQgdGhpcy5kZWxldGVhYmxlU3RhY2tzKHRoaXMuc3RhY2tOYW1lUHJlZml4KTtcblxuICAgIC8vIEJvb3RzdHJhcCBzdGFja3MgaGF2ZSBidWNrZXRzIHRoYXQgbmVlZCB0byBiZSBjbGVhbmVkXG4gICAgY29uc3QgYnVja2V0TmFtZXMgPSBzdGFja3NUb0RlbGV0ZS5tYXAoc3RhY2sgPT4gb3V0cHV0RnJvbVN0YWNrKCdCdWNrZXROYW1lJywgc3RhY2spKS5maWx0ZXIoZGVmaW5lZCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoYnVja2V0TmFtZXMubWFwKGIgPT4gdGhpcy5hd3MuZW1wdHlCdWNrZXQoYikpKTtcblxuICAgIC8vIEJvb3RzdHJhcCBzdGFja3MgaGF2ZSBFQ1IgcmVwb3NpdG9yaWVzIHdpdGggaW1hZ2VzIHdoaWNoIHNob3VsZCBiZSBkZWxldGVkXG4gICAgY29uc3QgaW1hZ2VSZXBvc2l0b3J5TmFtZXMgPSBzdGFja3NUb0RlbGV0ZS5tYXAoc3RhY2sgPT4gb3V0cHV0RnJvbVN0YWNrKCdJbWFnZVJlcG9zaXRvcnlOYW1lJywgc3RhY2spKS5maWx0ZXIoZGVmaW5lZCk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoaW1hZ2VSZXBvc2l0b3J5TmFtZXMubWFwKHIgPT4gdGhpcy5hd3MuZGVsZXRlSW1hZ2VSZXBvc2l0b3J5KHIpKSk7XG5cbiAgICBhd2FpdCB0aGlzLmF3cy5kZWxldGVTdGFja3MoLi4uc3RhY2tzVG9EZWxldGUubWFwKHMgPT4gcy5TdGFja05hbWUpKTtcblxuICAgIC8vIFdlIG1pZ2h0IGhhdmUgbGVha2VkIHNvbWUgYnVja2V0cyBieSB1cGdyYWRpbmcgdGhlIGJvb3RzdHJhcCBzdGFjay4gQmVcbiAgICAvLyBzdXJlIHRvIGNsZWFuIGV2ZXJ5dGhpbmcuXG4gICAgZm9yIChjb25zdCBidWNrZXQgb2YgdGhpcy5idWNrZXRzVG9EZWxldGUpIHtcbiAgICAgIGF3YWl0IHRoaXMuYXdzLmRlbGV0ZUJ1Y2tldChidWNrZXQpO1xuICAgIH1cblxuICAgIC8vIElmIHRoZSB0ZXN0cyBjb21wbGV0ZWQgc3VjY2Vzc2Z1bGx5LCBoYXBwaWx5IGRlbGV0ZSB0aGUgZml4dHVyZVxuICAgIC8vIChvdGhlcndpc2UgbGVhdmUgaXQgZm9yIGh1bWFucyB0byBpbnNwZWN0KVxuICAgIGlmIChzdWNjZXNzKSB7XG4gICAgICByaW1yYWYodGhpcy5pbnRlZ1Rlc3REaXIpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIHN0YWNrcyBzdGFydGluZyB3aXRoIG91ciB0ZXN0aW5nIHByZWZpeCB0aGF0IHNob3VsZCBiZSBkZWxldGVkXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGRlbGV0ZWFibGVTdGFja3MocHJlZml4OiBzdHJpbmcpOiBQcm9taXNlPEFXUy5DbG91ZEZvcm1hdGlvbi5TdGFja1tdPiB7XG4gICAgY29uc3Qgc3RhdHVzRmlsdGVyID0gW1xuICAgICAgJ0NSRUFURV9JTl9QUk9HUkVTUycsICdDUkVBVEVfRkFJTEVEJywgJ0NSRUFURV9DT01QTEVURScsXG4gICAgICAnUk9MTEJBQ0tfSU5fUFJPR1JFU1MnLCAnUk9MTEJBQ0tfRkFJTEVEJywgJ1JPTExCQUNLX0NPTVBMRVRFJyxcbiAgICAgICdERUxFVEVfRkFJTEVEJyxcbiAgICAgICdVUERBVEVfSU5fUFJPR1JFU1MnLCAnVVBEQVRFX0NPTVBMRVRFX0NMRUFOVVBfSU5fUFJPR1JFU1MnLFxuICAgICAgJ1VQREFURV9DT01QTEVURScsICdVUERBVEVfUk9MTEJBQ0tfSU5fUFJPR1JFU1MnLFxuICAgICAgJ1VQREFURV9ST0xMQkFDS19GQUlMRUQnLFxuICAgICAgJ1VQREFURV9ST0xMQkFDS19DT01QTEVURV9DTEVBTlVQX0lOX1BST0dSRVNTJyxcbiAgICAgICdVUERBVEVfUk9MTEJBQ0tfQ09NUExFVEUnLCAnUkVWSUVXX0lOX1BST0dSRVNTJyxcbiAgICAgICdJTVBPUlRfSU5fUFJPR1JFU1MnLCAnSU1QT1JUX0NPTVBMRVRFJyxcbiAgICAgICdJTVBPUlRfUk9MTEJBQ0tfSU5fUFJPR1JFU1MnLCAnSU1QT1JUX1JPTExCQUNLX0ZBSUxFRCcsXG4gICAgICAnSU1QT1JUX1JPTExCQUNLX0NPTVBMRVRFJyxcbiAgICBdO1xuXG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmF3cy5jbG91ZEZvcm1hdGlvbignZGVzY3JpYmVTdGFja3MnLCB7fSk7XG5cbiAgICByZXR1cm4gKHJlc3BvbnNlLlN0YWNrcyA/PyBbXSlcbiAgICAgIC5maWx0ZXIocyA9PiBzLlN0YWNrTmFtZS5zdGFydHNXaXRoKHByZWZpeCkpXG4gICAgICAuZmlsdGVyKHMgPT4gc3RhdHVzRmlsdGVyLmluY2x1ZGVzKHMuU3RhY2tTdGF0dXMpKVxuICAgICAgLmZpbHRlcihzID0+IHMuUm9vdElkID09PSB1bmRlZmluZWQpOyAvLyBPbmx5IGRlbGV0ZSBwYXJlbnQgc3RhY2tzLiBOZXN0ZWQgc3RhY2tzIGFyZSBkZWxldGVkIGluIHRoZSBwcm9jZXNzXG4gIH1cbn1cblxuLyoqXG4gKiBQZXJmb3JtIGEgb25lLXRpbWUgcXVpY2sgc2FuaXR5IGNoZWNrIHRoYXQgdGhlIEFXUyBjbGllbnRzIGhhcyBwcm9wZXJseSBjb25maWd1cmVkIGNyZWRlbnRpYWxzXG4gKlxuICogSWYgd2UgZG9uJ3QgZG8gdGhpcywgY2FsbHMgYXJlIGdvaW5nIHRvIGZhaWwgYW5kIHRoZXknbGwgYmUgcmV0cmllZCBhbmQgZXZlcnl0aGluZyB3aWxsIHRha2VcbiAqIGZvcmV2ZXIgYmVmb3JlIHRoZSB1c2VyIG5vdGljZXMgYSBzaW1wbGUgbWlzY29uZmlndXJhdGlvbi5cbiAqXG4gKiBXZSBjYW4ndCBjaGVjayBmb3IgdGhlIHByZXNlbmNlIG9mIGVudmlyb25tZW50IHZhcmlhYmxlcyBzaW5jZSBjcmVkZW50aWFscyBjb3VsZCBjb21lIGZyb21cbiAqIGFueXdoZXJlLCBzbyBkbyBzaW1wbGUgYWNjb3VudCByZXRyaWV2YWwuXG4gKlxuICogT25seSBkbyBpdCBvbmNlIHBlciBwcm9jZXNzLlxuICovXG5hc3luYyBmdW5jdGlvbiBzYW5pdHlDaGVjayhhd3M6IEF3c0NsaWVudHMpIHtcbiAgaWYgKHNhbml0eUNoZWNrZWQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCBhd3MuYWNjb3VudCgpO1xuICAgICAgc2FuaXR5Q2hlY2tlZCA9IHRydWU7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc2FuaXR5Q2hlY2tlZCA9IGZhbHNlO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBBV1MgY3JlZGVudGlhbHMgcHJvYmFibHkgbm90IGNvbmZpZ3VyZWQsIGdvdCBlcnJvcjogJHtlLm1lc3NhZ2V9YCk7XG4gICAgfVxuICB9XG4gIGlmICghc2FuaXR5Q2hlY2tlZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignQVdTIGNyZWRlbnRpYWxzIHByb2JhYmx5IG5vdCBjb25maWd1cmVkLCBzZWUgcHJldmlvdXMgZXJyb3InKTtcbiAgfVxufVxubGV0IHNhbml0eUNoZWNrZWQ6IGJvb2xlYW4gfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogTWFrZSBzdXJlIHRoYXQgdGhlIGdpdmVuIGVudmlyb25tZW50IGlzIGJvb3RzdHJhcHBlZFxuICpcbiAqIFNpbmNlIHdlIGdvIHN0cmlwaW5nIGFjcm9zcyByZWdpb25zLCBpdCdzIGdvaW5nIHRvIHN1Y2sgZG9pbmcgdGhpc1xuICogYnkgaGFuZCBzbyBsZXQncyBqdXN0IG1hc3MtYXV0b21hdGUgaXQuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGVuc3VyZUJvb3RzdHJhcHBlZChmaXh0dXJlOiBUZXN0Rml4dHVyZSkge1xuICAvLyBPbGQtc3R5bGUgYm9vdHN0cmFwIHN0YWNrIHdpdGggZGVmYXVsdCBuYW1lXG4gIGlmIChhd2FpdCBmaXh0dXJlLmF3cy5zdGFja1N0YXR1cygnQ0RLVG9vbGtpdCcpID09PSB1bmRlZmluZWQpIHtcbiAgICBhd2FpdCBmaXh0dXJlLmNkayhbJ2Jvb3RzdHJhcCcsIGBhd3M6Ly8ke2F3YWl0IGZpeHR1cmUuYXdzLmFjY291bnQoKX0vJHtmaXh0dXJlLmF3cy5yZWdpb259YF0pO1xuICB9XG59XG5cbi8qKlxuICogQSBzaGVsbCBjb21tYW5kIHRoYXQgZG9lcyB3aGF0IHlvdSB3YW50XG4gKlxuICogSXMgcGxhdGZvcm0tYXdhcmUsIGhhbmRsZXMgZXJyb3JzIG5pY2VseS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNoZWxsKGNvbW1hbmQ6IHN0cmluZ1tdLCBvcHRpb25zOiBTaGVsbE9wdGlvbnMgPSB7fSk6IFByb21pc2U8c3RyaW5nPiB7XG4gIGlmIChvcHRpb25zLm1vZEVudiAmJiBvcHRpb25zLmVudikge1xuICAgIHRocm93IG5ldyBFcnJvcignVXNlIGVpdGhlciBlbnYgb3IgbW9kRW52IGJ1dCBub3QgYm90aCcpO1xuICB9XG5cbiAgb3B0aW9ucy5vdXRwdXQ/LndyaXRlKGDwn5K7ICR7Y29tbWFuZC5qb2luKCcgJyl9XFxuYCk7XG5cbiAgY29uc3QgZW52ID0gb3B0aW9ucy5lbnYgPz8gKG9wdGlvbnMubW9kRW52ID8geyAuLi5wcm9jZXNzLmVudiwgLi4ub3B0aW9ucy5tb2RFbnYgfSA6IHVuZGVmaW5lZCk7XG5cbiAgY29uc3QgY2hpbGQgPSBjaGlsZF9wcm9jZXNzLnNwYXduKGNvbW1hbmRbMF0sIGNvbW1hbmQuc2xpY2UoMSksIHtcbiAgICAuLi5vcHRpb25zLFxuICAgIGVudixcbiAgICAvLyBOZWVkIHRoaXMgZm9yIFdpbmRvd3Mgd2hlcmUgd2Ugd2FudCAuY21kIGFuZCAuYmF0IHRvIGJlIGZvdW5kIGFzIHdlbGwuXG4gICAgc2hlbGw6IHRydWUsXG4gICAgc3RkaW86IFsnaWdub3JlJywgJ3BpcGUnLCAncGlwZSddLFxuICB9KTtcblxuICByZXR1cm4gbmV3IFByb21pc2U8c3RyaW5nPigocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgY29uc3Qgc3Rkb3V0ID0gbmV3IEFycmF5PEJ1ZmZlcj4oKTtcbiAgICBjb25zdCBzdGRlcnIgPSBuZXcgQXJyYXk8QnVmZmVyPigpO1xuXG4gICAgY2hpbGQuc3Rkb3V0IS5vbignZGF0YScsIGNodW5rID0+IHtcbiAgICAgIG9wdGlvbnMub3V0cHV0Py53cml0ZShjaHVuayk7XG4gICAgICBzdGRvdXQucHVzaChjaHVuayk7XG4gICAgfSk7XG5cbiAgICBjaGlsZC5zdGRlcnIhLm9uKCdkYXRhJywgY2h1bmsgPT4ge1xuICAgICAgb3B0aW9ucy5vdXRwdXQ/LndyaXRlKGNodW5rKTtcbiAgICAgIGlmIChvcHRpb25zLmNhcHR1cmVTdGRlcnIgPz8gdHJ1ZSkge1xuICAgICAgICBzdGRlcnIucHVzaChjaHVuayk7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICBjaGlsZC5vbmNlKCdlcnJvcicsIHJlamVjdCk7XG5cbiAgICBjaGlsZC5vbmNlKCdjbG9zZScsIGNvZGUgPT4ge1xuICAgICAgaWYgKGNvZGUgPT09IDAgfHwgb3B0aW9ucy5hbGxvd0VyckV4aXQpIHtcbiAgICAgICAgcmVzb2x2ZSgoQnVmZmVyLmNvbmNhdChzdGRvdXQpLnRvU3RyaW5nKCd1dGYtOCcpICsgQnVmZmVyLmNvbmNhdChzdGRlcnIpLnRvU3RyaW5nKCd1dGYtOCcpKS50cmltKCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVqZWN0KG5ldyBFcnJvcihgJyR7Y29tbWFuZC5qb2luKCcgJyl9JyBleGl0ZWQgd2l0aCBlcnJvciBjb2RlICR7Y29kZX1gKSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBkZWZpbmVkPEE+KHg6IEEpOiB4IGlzIE5vbk51bGxhYmxlPEE+IHtcbiAgcmV0dXJuIHggIT09IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBybSAtcmYgcmVpbXBsZW1lbnRhdGlvbiwgZG9uJ3Qgd2FudCB0byBkZXBlbmQgb24gYW4gTlBNIHBhY2thZ2UgZm9yIHRoaXNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJpbXJhZihmc1BhdGg6IHN0cmluZykge1xuICB0cnkge1xuICAgIGNvbnN0IGlzRGlyID0gZnMubHN0YXRTeW5jKGZzUGF0aCkuaXNEaXJlY3RvcnkoKTtcblxuICAgIGlmIChpc0Rpcikge1xuICAgICAgZm9yIChjb25zdCBmaWxlIG9mIGZzLnJlYWRkaXJTeW5jKGZzUGF0aCkpIHtcbiAgICAgICAgcmltcmFmKHBhdGguam9pbihmc1BhdGgsIGZpbGUpKTtcbiAgICAgIH1cbiAgICAgIGZzLnJtZGlyU3luYyhmc1BhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBmcy51bmxpbmtTeW5jKGZzUGF0aCk7XG4gICAgfVxuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gV2Ugd2lsbCBzdXJ2aXZlIEVOT0VOVFxuICAgIGlmIChlLmNvZGUgIT09ICdFTk9FTlQnKSB7IHRocm93IGU7IH1cbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gcmFuZG9tU3RyaW5nKCkge1xuICAvLyBDcmF6eVxuICByZXR1cm4gTWF0aC5yYW5kb20oKS50b1N0cmluZygzNikucmVwbGFjZSgvW15hLXowLTldKy9nLCAnJyk7XG59Il19
@@ -0,0 +1,19 @@
1
+ {
2
+ "version": "0.36.0",
3
+ "artifacts": {
4
+ "InitStack": {
5
+ "type": "aws:cloudformation:stack",
6
+ "environment": "aws://unknown-account/unknown-region",
7
+ "properties": {
8
+ "templateFile": "InitStack.template.json"
9
+ }
10
+ }
11
+ },
12
+ "runtime": {
13
+ "libraries": {
14
+ "@aws-cdk/core": "1.12.0",
15
+ "@aws-cdk/cx-api": "1.12.0",
16
+ "jsii-runtime": "node.js/v8.11.4"
17
+ }
18
+ }
19
+ }
@@ -0,0 +1,37 @@
1
+ process.stdout.write(JSON.stringify({
2
+ "version": "1.10.0",
3
+ "artifacts": {
4
+ "InitStack": {
5
+ "type": "aws:cloudformation:stack",
6
+ "environment": `aws://${process.env.TEST_ACCOUNT}/${process.env.TEST_REGION}`,
7
+ "properties": {
8
+ "templateFile": "InitStack.template.json"
9
+ }
10
+ }
11
+ },
12
+ "runtime": {
13
+ "libraries": {
14
+ "@aws-cdk/core": "1.14.0",
15
+ "@aws-cdk/cx-api": "1.14.0",
16
+ "@aws-cdk/aws-ec2": "1.14.0",
17
+ "@aws-cdk/aws-iam": "1.14.0",
18
+ "@aws-cdk/region-info": "1.14.0",
19
+ "@aws-cdk/aws-ssm": "1.14.0",
20
+ "@aws-cdk/aws-cloudwatch": "1.14.0",
21
+ "jsii-runtime": "node.js/v8.11.4"
22
+ }
23
+ },
24
+ "missing": [
25
+ {
26
+ "key": `vpc-provider:account=${process.env.TEST_ACCOUNT}:filter.isDefault=true:region=${process.env.TEST_REGION}`,
27
+ "props": {
28
+ "account": process.env.TEST_ACCOUNT,
29
+ "region": process.env.TEST_REGION,
30
+ "filter": {
31
+ "isDefault": "true"
32
+ }
33
+ },
34
+ "provider": "vpc-provider"
35
+ }
36
+ ]
37
+ }, undefined, 2));
@@ -0,0 +1,34 @@
1
+ process.stdout.write(JSON.stringify({
2
+ "version": "1.10.0",
3
+ "artifacts": {
4
+ "InitStack": {
5
+ "type": "aws:cloudformation:stack",
6
+ "environment": `aws://${process.env.TEST_ACCOUNT}/${process.env.TEST_REGION}`,
7
+ "properties": {
8
+ "templateFile": "InitStack.template.json"
9
+ }
10
+ }
11
+ },
12
+ "runtime": {
13
+ "libraries": {
14
+ "@aws-cdk/core": "1.14.0",
15
+ "@aws-cdk/cx-api": "1.14.0",
16
+ "@aws-cdk/aws-ec2": "1.14.0",
17
+ "@aws-cdk/aws-iam": "1.14.0",
18
+ "@aws-cdk/region-info": "1.14.0",
19
+ "@aws-cdk/aws-ssm": "1.14.0",
20
+ "@aws-cdk/aws-cloudwatch": "1.14.0",
21
+ "jsii-runtime": "node.js/v8.11.4"
22
+ }
23
+ },
24
+ "missing": [
25
+ {
26
+ "key": `availability-zones:account=${process.env.TEST_ACCOUNT}:region=${process.env.TEST_REGION}`,
27
+ "props": {
28
+ "account": process.env.TEST_ACCOUNT,
29
+ "region": process.env.TEST_REGION,
30
+ },
31
+ "provider": "availability-zones"
32
+ }
33
+ ]
34
+ }, undefined, 2));
@@ -0,0 +1,25 @@
1
+ const path = require('path');
2
+
3
+ const rootDir = path.resolve(__dirname, '..', 'tests', process.env.TEST_SUITE_NAME);
4
+
5
+ if (rootDir.includes('node_modules')) {
6
+ // Jest < 28 under no circumstances supports loading test if there's node_modules anywhere in the path,
7
+ // and Jest >= 28 requires a newer TypeScript version than the one we support.
8
+ throw new Error(`This package must not be 'npm install'ed (found node_modules in dir: ${rootDir})`);
9
+ }
10
+
11
+ module.exports = {
12
+ rootDir,
13
+ testMatch: [`**/*.integtest.js`],
14
+ moduleFileExtensions: ["js"],
15
+
16
+ testEnvironment: "node",
17
+ testTimeout: 300000,
18
+
19
+ // Affects test.concurrent(), these are self-limiting anyway
20
+ maxConcurrency: 10,
21
+ reporters: [
22
+ "default",
23
+ [ "jest-junit", { suiteName: "jest tests", outputDirectory: "coverage" } ]
24
+ ]
25
+ };
package/skip-tests.txt ADDED
@@ -0,0 +1,8 @@
1
+ # This file is empty on purpose. Leave it here as documentation
2
+ # and an example.
3
+ #
4
+ # Copy this file to cli-regression-patches/vX.Y.Z/skip-tests.txt
5
+ # and edit it there if you want to exclude certain tests from running
6
+ # when performing a certain version's regression tests.
7
+ #
8
+ # Put a test name on a line by itself to skip it.
@@ -0,0 +1,47 @@
1
+ # CDK CLI Integration Tests
2
+
3
+ These tests require AWS credentials, and exercise various aspects of the
4
+ CLI on a simple JavaScript CDK app (stored in `app/`).
5
+
6
+ ## Entry point
7
+
8
+ ```
9
+ ../run-against-repo ./test.sh
10
+ ```
11
+
12
+ Running against a failing dist build:
13
+
14
+ ```
15
+ # Download and unpack the zip
16
+ .../CMkBR4V$ tar xzvf js/aws-cdk-[0-9]*.tgz
17
+ .../CMkBR4V$ package/test/integ/run-against-dist package/test/integ/cli/test.sh
18
+ ```
19
+
20
+ ## Adding tests
21
+
22
+ Even though tests are now written in TypeScript, this does not
23
+ conceptually change their SUT! They are still testing the CLI via
24
+ running it as a subprocess, they are NOT reaching directly into the CLI
25
+ code to test its private methods. It's just that setup/teardown/error
26
+ handling/assertions/AWS calls are much more convenient to do in a real
27
+ programming language.
28
+
29
+ Compilation of the tests is done as part of the normal package build, at
30
+ which point it is using the dependencies brought in by the containing
31
+ `aws-cdk` package's `package.json`.
32
+
33
+ When run in a non-development repo (as done during integ tests or canary runs),
34
+ the required dependencies are brought in just-in-time via `test.sh`. Any
35
+ new dependencies added for the tests should be added there as well. But, better
36
+ yet, don't add any dependencies at all. You shouldn't need to, these tests
37
+ are simple.
38
+
39
+ ## Configuration
40
+
41
+ AWS credentials must be configured.
42
+
43
+ Optional configuration:
44
+
45
+ * `AWS_DEFAULT_REGION`, what region to deploy the stacks in.
46
+ * `IS_CANARY`, true or false. Affects the default stack name prefix to make
47
+ integration test and canary runs unique.
@@ -0,0 +1 @@
1
+ export {};