@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,398 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.installNpmPackages = exports.TestFixture = exports.cloneDirectory = exports.withDefaultFixture = exports.withMonolithicCfnIncludeCdkApp = exports.withCdkApp = void 0;
4
+ /* eslint-disable no-console */
5
+ const fs = require("fs");
6
+ const os = require("os");
7
+ const path = require("path");
8
+ const aws_1 = require("./aws");
9
+ const subprocess_1 = require("./package-sources/subprocess");
10
+ const resources_1 = require("./resources");
11
+ const shell_1 = require("./shell");
12
+ const with_aws_1 = require("./with-aws");
13
+ /**
14
+ * Higher order function to execute a block with a CDK app fixture
15
+ *
16
+ * Requires an AWS client to be passed in.
17
+ *
18
+ * For backwards compatibility with existing tests (so we don't have to change
19
+ * too much) the inner block is expected to take a `TestFixture` object.
20
+ */
21
+ function withCdkApp(block) {
22
+ return async (context) => {
23
+ const randy = context.randomString;
24
+ const stackNamePrefix = `cdktest-${randy}`;
25
+ const integTestDir = path.join(os.tmpdir(), `cdk-integ-${randy}`);
26
+ context.output.write(` Stack prefix: ${stackNamePrefix}\n`);
27
+ context.output.write(` Test directory: ${integTestDir}\n`);
28
+ context.output.write(` Region: ${context.aws.region}\n`);
29
+ await cloneDirectory(path.join(resources_1.RESOURCES_DIR, 'cdk-apps', 'app'), integTestDir, context.output);
30
+ const fixture = new TestFixture(integTestDir, stackNamePrefix, context.output, context.aws, context.randomString);
31
+ let success = true;
32
+ try {
33
+ const installationVersion = fixture.packages.requestedFrameworkVersion();
34
+ if (fixture.packages.majorVersion() === '1') {
35
+ await installNpmPackages(fixture, {
36
+ '@aws-cdk/core': installationVersion,
37
+ '@aws-cdk/aws-sns': installationVersion,
38
+ '@aws-cdk/aws-sqs': installationVersion,
39
+ '@aws-cdk/aws-iam': installationVersion,
40
+ '@aws-cdk/aws-lambda': installationVersion,
41
+ '@aws-cdk/aws-ssm': installationVersion,
42
+ '@aws-cdk/aws-ecr-assets': installationVersion,
43
+ '@aws-cdk/aws-cloudformation': installationVersion,
44
+ '@aws-cdk/aws-ec2': installationVersion,
45
+ '@aws-cdk/aws-s3': installationVersion,
46
+ 'constructs': '^3',
47
+ });
48
+ }
49
+ else {
50
+ await installNpmPackages(fixture, {
51
+ 'aws-cdk-lib': installationVersion,
52
+ 'constructs': '^10',
53
+ });
54
+ }
55
+ await ensureBootstrapped(fixture);
56
+ await block(fixture);
57
+ }
58
+ catch (e) {
59
+ success = false;
60
+ throw e;
61
+ }
62
+ finally {
63
+ if (process.env.INTEG_NO_CLEAN) {
64
+ context.log(`Left test directory in '${integTestDir}' ($INTEG_NO_CLEAN)\n`);
65
+ }
66
+ else {
67
+ await fixture.dispose(success);
68
+ }
69
+ }
70
+ };
71
+ }
72
+ exports.withCdkApp = withCdkApp;
73
+ function withMonolithicCfnIncludeCdkApp(block) {
74
+ return async (context) => {
75
+ const uberPackage = process.env.UBERPACKAGE;
76
+ if (!uberPackage) {
77
+ throw new Error('The UBERPACKAGE environment variable is required for running this test!');
78
+ }
79
+ const randy = context.randomString;
80
+ const stackNamePrefix = `cdk-uber-cfn-include-${randy}`;
81
+ const integTestDir = path.join(os.tmpdir(), `cdk-uber-cfn-include-${randy}`);
82
+ context.output.write(` Stack prefix: ${stackNamePrefix}\n`);
83
+ context.output.write(` Test directory: ${integTestDir}\n`);
84
+ const awsClients = await aws_1.AwsClients.default(context.output);
85
+ await cloneDirectory(path.join(resources_1.RESOURCES_DIR, 'cdk-apps', 'cfn-include-app'), integTestDir, context.output);
86
+ const fixture = new TestFixture(integTestDir, stackNamePrefix, context.output, awsClients, context.randomString);
87
+ let success = true;
88
+ try {
89
+ await installNpmPackages(fixture, {
90
+ [uberPackage]: fixture.packages.requestedFrameworkVersion(),
91
+ });
92
+ await block(fixture);
93
+ }
94
+ catch (e) {
95
+ success = false;
96
+ throw e;
97
+ }
98
+ finally {
99
+ if (process.env.INTEG_NO_CLEAN) {
100
+ context.log(`Left test directory in '${integTestDir}' ($INTEG_NO_CLEAN)`);
101
+ }
102
+ else {
103
+ await fixture.dispose(success);
104
+ }
105
+ }
106
+ };
107
+ }
108
+ exports.withMonolithicCfnIncludeCdkApp = withMonolithicCfnIncludeCdkApp;
109
+ /**
110
+ * Default test fixture for most (all?) integ tests
111
+ *
112
+ * It's a composition of withAws/withCdkApp, expecting the test block to take a `TestFixture`
113
+ * object.
114
+ *
115
+ * We could have put `withAws(withCdkApp(fixture => { /... actual test here.../ }))` in every
116
+ * test declaration but centralizing it is going to make it convenient to modify in the future.
117
+ */
118
+ function withDefaultFixture(block) {
119
+ return with_aws_1.withAws(withCdkApp(block));
120
+ // ^~~~~~ this is disappointing TypeScript! Feels like you should have been able to derive this.
121
+ }
122
+ exports.withDefaultFixture = withDefaultFixture;
123
+ /**
124
+ * Prepare a target dir byreplicating a source directory
125
+ */
126
+ async function cloneDirectory(source, target, output) {
127
+ await shell_1.shell(['rm', '-rf', target], { output });
128
+ await shell_1.shell(['mkdir', '-p', target], { output });
129
+ await shell_1.shell(['cp', '-R', source + '/*', target], { output });
130
+ }
131
+ exports.cloneDirectory = cloneDirectory;
132
+ class TestFixture extends shell_1.ShellHelper {
133
+ constructor(integTestDir, stackNamePrefix, output, aws, randomString) {
134
+ super(integTestDir, output);
135
+ this.integTestDir = integTestDir;
136
+ this.stackNamePrefix = stackNamePrefix;
137
+ this.output = output;
138
+ this.aws = aws;
139
+ this.randomString = randomString;
140
+ this.qualifier = this.randomString.slice(0, 10);
141
+ this.bucketsToDelete = new Array();
142
+ this.packages = subprocess_1.packageSourceInSubprocess();
143
+ }
144
+ log(s) {
145
+ this.output.write(`${s}\n`);
146
+ }
147
+ async cdkDeploy(stackNames, options = {}) {
148
+ stackNames = typeof stackNames === 'string' ? [stackNames] : stackNames;
149
+ const neverRequireApproval = options.neverRequireApproval ?? true;
150
+ return this.cdk(['deploy',
151
+ ...(neverRequireApproval ? ['--require-approval=never'] : []),
152
+ ...(options.options ?? []),
153
+ ...this.fullStackName(stackNames)], options);
154
+ }
155
+ async cdkSynth(options = {}) {
156
+ return this.cdk([
157
+ 'synth',
158
+ ...(options.options ?? []),
159
+ ], options);
160
+ }
161
+ async cdkDestroy(stackNames, options = {}) {
162
+ stackNames = typeof stackNames === 'string' ? [stackNames] : stackNames;
163
+ return this.cdk(['destroy',
164
+ '-f',
165
+ ...(options.options ?? []),
166
+ ...this.fullStackName(stackNames)], options);
167
+ }
168
+ async cdkBootstrapLegacy(options) {
169
+ const args = ['bootstrap'];
170
+ if (options.verbose) {
171
+ args.push('-v');
172
+ }
173
+ args.push('--toolkit-stack-name', options.toolkitStackName);
174
+ if (options.bootstrapBucketName) {
175
+ args.push('--bootstrap-bucket-name', options.bootstrapBucketName);
176
+ }
177
+ if (options.noExecute) {
178
+ args.push('--no-execute');
179
+ }
180
+ if (options.publicAccessBlockConfiguration !== undefined) {
181
+ args.push('--public-access-block-configuration', options.publicAccessBlockConfiguration.toString());
182
+ }
183
+ if (options.tags) {
184
+ args.push('--tags', options.tags);
185
+ }
186
+ return this.cdk(args, {
187
+ ...options.cliOptions,
188
+ modEnv: {
189
+ ...options.cliOptions?.modEnv,
190
+ // so that this works for V2,
191
+ // where the "new" bootstrap is the default
192
+ CDK_LEGACY_BOOTSTRAP: '1',
193
+ },
194
+ });
195
+ }
196
+ async cdkBootstrapModern(options) {
197
+ const args = ['bootstrap'];
198
+ if (options.verbose) {
199
+ args.push('-v');
200
+ }
201
+ if (options.showTemplate) {
202
+ args.push('--show-template');
203
+ }
204
+ if (options.template) {
205
+ args.push('--template', options.template);
206
+ }
207
+ args.push('--toolkit-stack-name', options.toolkitStackName);
208
+ if (options.bootstrapBucketName) {
209
+ args.push('--bootstrap-bucket-name', options.bootstrapBucketName);
210
+ }
211
+ args.push('--qualifier', this.qualifier);
212
+ if (options.cfnExecutionPolicy) {
213
+ args.push('--cloudformation-execution-policies', options.cfnExecutionPolicy);
214
+ }
215
+ if (options.terminationProtection !== undefined) {
216
+ args.push('--termination-protection', options.terminationProtection.toString());
217
+ }
218
+ if (options.force) {
219
+ args.push('--force');
220
+ }
221
+ if (options.tags) {
222
+ args.push('--tags', options.tags);
223
+ }
224
+ if (options.customPermissionsBoundary !== undefined) {
225
+ args.push('--custom-permissions-boundary', options.customPermissionsBoundary);
226
+ }
227
+ else if (options.examplePermissionsBoundary !== undefined) {
228
+ args.push('--example-permissions-boundary');
229
+ }
230
+ return this.cdk(args, {
231
+ ...options.cliOptions,
232
+ modEnv: {
233
+ ...options.cliOptions?.modEnv,
234
+ // so that this works for V1,
235
+ // where the "old" bootstrap is the default
236
+ CDK_NEW_BOOTSTRAP: '1',
237
+ },
238
+ });
239
+ }
240
+ async cdk(args, options = {}) {
241
+ const verbose = options.verbose ?? true;
242
+ await this.packages.makeCliAvailable();
243
+ return this.shell(['cdk', ...(verbose ? ['-v'] : []), ...args], {
244
+ ...options,
245
+ modEnv: {
246
+ AWS_REGION: this.aws.region,
247
+ AWS_DEFAULT_REGION: this.aws.region,
248
+ STACK_NAME_PREFIX: this.stackNamePrefix,
249
+ PACKAGE_LAYOUT_VERSION: this.packages.majorVersion(),
250
+ ...options.modEnv,
251
+ },
252
+ });
253
+ }
254
+ template(stackName) {
255
+ const fullStackName = this.fullStackName(stackName);
256
+ const templatePath = path.join(this.integTestDir, 'cdk.out', `${fullStackName}.template.json`);
257
+ return JSON.parse(fs.readFileSync(templatePath, { encoding: 'utf-8' }).toString());
258
+ }
259
+ get bootstrapStackName() {
260
+ return this.fullStackName('bootstrap-stack');
261
+ }
262
+ fullStackName(stackNames) {
263
+ if (typeof stackNames === 'string') {
264
+ return `${this.stackNamePrefix}-${stackNames}`;
265
+ }
266
+ else {
267
+ return stackNames.map(s => `${this.stackNamePrefix}-${s}`);
268
+ }
269
+ }
270
+ /**
271
+ * Append this to the list of buckets to potentially delete
272
+ *
273
+ * At the end of a test, we clean up buckets that may not have gotten destroyed
274
+ * (for whatever reason).
275
+ */
276
+ rememberToDeleteBucket(bucketName) {
277
+ this.bucketsToDelete.push(bucketName);
278
+ }
279
+ /**
280
+ * Cleanup leftover stacks and buckets
281
+ */
282
+ async dispose(success) {
283
+ const stacksToDelete = await this.deleteableStacks(this.stackNamePrefix);
284
+ this.sortBootstrapStacksToTheEnd(stacksToDelete);
285
+ // Bootstrap stacks have buckets that need to be cleaned
286
+ const bucketNames = stacksToDelete.map(stack => aws_1.outputFromStack('BucketName', stack)).filter(defined);
287
+ await Promise.all(bucketNames.map(b => this.aws.emptyBucket(b)));
288
+ // The bootstrap bucket has a removal policy of RETAIN by default, so add it to the buckets to be cleaned up.
289
+ this.bucketsToDelete.push(...bucketNames);
290
+ // Bootstrap stacks have ECR repositories with images which should be deleted
291
+ const imageRepositoryNames = stacksToDelete.map(stack => aws_1.outputFromStack('ImageRepositoryName', stack)).filter(defined);
292
+ await Promise.all(imageRepositoryNames.map(r => this.aws.deleteImageRepository(r)));
293
+ await this.aws.deleteStacks(...stacksToDelete.map(s => s.StackName));
294
+ // We might have leaked some buckets by upgrading the bootstrap stack. Be
295
+ // sure to clean everything.
296
+ for (const bucket of this.bucketsToDelete) {
297
+ await this.aws.deleteBucket(bucket);
298
+ }
299
+ // If the tests completed successfully, happily delete the fixture
300
+ // (otherwise leave it for humans to inspect)
301
+ if (success) {
302
+ shell_1.rimraf(this.integTestDir);
303
+ }
304
+ }
305
+ /**
306
+ * Return the stacks starting with our testing prefix that should be deleted
307
+ */
308
+ async deleteableStacks(prefix) {
309
+ const statusFilter = [
310
+ 'CREATE_IN_PROGRESS', 'CREATE_FAILED', 'CREATE_COMPLETE',
311
+ 'ROLLBACK_IN_PROGRESS', 'ROLLBACK_FAILED', 'ROLLBACK_COMPLETE',
312
+ 'DELETE_FAILED',
313
+ 'UPDATE_IN_PROGRESS', 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS',
314
+ 'UPDATE_COMPLETE', 'UPDATE_ROLLBACK_IN_PROGRESS',
315
+ 'UPDATE_ROLLBACK_FAILED',
316
+ 'UPDATE_ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS',
317
+ 'UPDATE_ROLLBACK_COMPLETE', 'REVIEW_IN_PROGRESS',
318
+ 'IMPORT_IN_PROGRESS', 'IMPORT_COMPLETE',
319
+ 'IMPORT_ROLLBACK_IN_PROGRESS', 'IMPORT_ROLLBACK_FAILED',
320
+ 'IMPORT_ROLLBACK_COMPLETE',
321
+ ];
322
+ const response = await this.aws.cloudFormation('describeStacks', {});
323
+ return (response.Stacks ?? [])
324
+ .filter(s => s.StackName.startsWith(prefix))
325
+ .filter(s => statusFilter.includes(s.StackStatus))
326
+ .filter(s => s.RootId === undefined); // Only delete parent stacks. Nested stacks are deleted in the process
327
+ }
328
+ sortBootstrapStacksToTheEnd(stacks) {
329
+ stacks.sort((a, b) => {
330
+ const aBs = a.StackName.startsWith(this.bootstrapStackName);
331
+ const bBs = b.StackName.startsWith(this.bootstrapStackName);
332
+ return aBs != bBs
333
+ // '+' converts a boolean to 0 or 1
334
+ ? (+aBs) - (+bBs)
335
+ : a.StackName.localeCompare(b.StackName);
336
+ });
337
+ }
338
+ }
339
+ exports.TestFixture = TestFixture;
340
+ /**
341
+ * Make sure that the given environment is bootstrapped
342
+ *
343
+ * Since we go striping across regions, it's going to suck doing this
344
+ * by hand so let's just mass-automate it.
345
+ */
346
+ async function ensureBootstrapped(fixture) {
347
+ // Always use the modern bootstrap stack, otherwise we may get the error
348
+ // "refusing to downgrade from version 7 to version 0" when bootstrapping with default
349
+ // settings using a v1 CLI.
350
+ //
351
+ // It doesn't matter for tests: when they want to test something about an actual legacy
352
+ // bootstrap stack, they'll create a bootstrap stack with a non-default name to test that exact property.
353
+ const envSpecifier = `aws://${await fixture.aws.account()}/${fixture.aws.region}`;
354
+ if (ALREADY_BOOTSTRAPPED_IN_THIS_RUN.has(envSpecifier)) {
355
+ return;
356
+ }
357
+ await fixture.cdk(['bootstrap', envSpecifier], {
358
+ modEnv: {
359
+ // Even for v1, use new bootstrap
360
+ CDK_NEW_BOOTSTRAP: '1',
361
+ },
362
+ });
363
+ ALREADY_BOOTSTRAPPED_IN_THIS_RUN.add(envSpecifier);
364
+ }
365
+ function defined(x) {
366
+ return x !== undefined;
367
+ }
368
+ /**
369
+ * Install the given NPM packages, identified by their names and versions
370
+ *
371
+ * Works by writing the packages to a `package.json` file, and
372
+ * then running NPM7's "install" on it. The use of NPM7 will automatically
373
+ * install required peerDependencies.
374
+ *
375
+ * If we're running in REPO mode and we find the package in the set of local
376
+ * packages in the repository, we'll write the directory name to `package.json`
377
+ * so that NPM will create a symlink (this allows running tests against
378
+ * built-but-unpackaged modules, and saves dev cycle time).
379
+ *
380
+ * Be aware you MUST install all the packages you directly depend upon! In the case
381
+ * of a repo/symlinking install, transitive dependencies WILL NOT be installed in the
382
+ * current directory's `node_modules` directory, because they will already have been
383
+ * symlinked from the TARGET directory's `node_modules` directory (which is sufficient
384
+ * for Node's dependency lookup mechanism).
385
+ */
386
+ async function installNpmPackages(fixture, packages) {
387
+ fs.writeFileSync(path.join(fixture.integTestDir, 'package.json'), JSON.stringify({
388
+ name: 'cdk-integ-tests',
389
+ private: true,
390
+ version: '0.0.1',
391
+ devDependencies: packages,
392
+ }, undefined, 2), { encoding: 'utf-8' });
393
+ // Now install that `package.json` using NPM7
394
+ await fixture.shell(['node', require.resolve('npm'), 'install']);
395
+ }
396
+ exports.installNpmPackages = installNpmPackages;
397
+ const ALREADY_BOOTSTRAPPED_IN_THIS_RUN = new Set();
398
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1jZGstYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsid2l0aC1jZGstYXBwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQUFBLCtCQUErQjtBQUMvQix5QkFBeUI7QUFDekIseUJBQXlCO0FBQ3pCLDZCQUE2QjtBQUM3QiwrQkFBb0Q7QUFHcEQsNkRBQXlFO0FBQ3pFLDJDQUE0QztBQUM1QyxtQ0FBbUU7QUFDbkUseUNBQWlEO0FBRWpEOzs7Ozs7O0dBT0c7QUFDSCxTQUFnQixVQUFVLENBQXFDLEtBQThDO0lBQzNHLE9BQU8sS0FBSyxFQUFFLE9BQVUsRUFBRSxFQUFFO1FBQzFCLE1BQU0sS0FBSyxHQUFHLE9BQU8sQ0FBQyxZQUFZLENBQUM7UUFDbkMsTUFBTSxlQUFlLEdBQUcsV0FBVyxLQUFLLEVBQUUsQ0FBQztRQUMzQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxNQUFNLEVBQUUsRUFBRSxhQUFhLEtBQUssRUFBRSxDQUFDLENBQUM7UUFFbEUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLGVBQWUsSUFBSSxDQUFDLENBQUM7UUFDOUQsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLFlBQVksSUFBSSxDQUFDLENBQUM7UUFDM0QsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsb0JBQW9CLE9BQU8sQ0FBQyxHQUFHLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQztRQUVqRSxNQUFNLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLHlCQUFhLEVBQUUsVUFBVSxFQUFFLEtBQUssQ0FBQyxFQUFFLFlBQVksRUFBRSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDaEcsTUFBTSxPQUFPLEdBQUcsSUFBSSxXQUFXLENBQzdCLFlBQVksRUFDWixlQUFlLEVBQ2YsT0FBTyxDQUFDLE1BQU0sRUFDZCxPQUFPLENBQUMsR0FBRyxFQUNYLE9B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LE1BQU0sRUFBRSxPQUFPLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7QUFDbkUsQ0FBQztBQVZELGdEQVVDO0FBRUQsTUFBTSxnQ0FBZ0MsR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMnO1xuaW1wb3J0ICogYXMgb3MgZnJvbSAnb3MnO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IG91dHB1dEZyb21TdGFjaywgQXdzQ2xpZW50cyB9IGZyb20gJy4vYXdzJztcbmltcG9ydCB7IFRlc3RDb250ZXh0IH0gZnJvbSAnLi9pbnRlZy10ZXN0JztcbmltcG9ydCB7IElQYWNrYWdlU291cmNlIH0gZnJvbSAnLi9wYWNrYWdlLXNvdXJjZXMvc291cmNlJztcbmltcG9ydCB7IHBhY2thZ2VTb3VyY2VJblN1YnByb2Nlc3MgfSBmcm9tICcuL3BhY2thZ2Utc291cmNlcy9zdWJwcm9jZXNzJztcbmltcG9ydCB7IFJFU09VUkNFU19ESVIgfSBmcm9tICcuL3Jlc291cmNlcyc7XG5pbXBvcnQgeyBzaGVsbCwgU2hlbGxPcHRpb25zLCBTaGVsbEhlbHBlciwgcmltcmFmIH0gZnJvbSAnLi9zaGVsbCc7XG5pbXBvcnQgeyBBd3NDb250ZXh0LCB3aXRoQXdzIH0gZnJvbSAnLi93aXRoLWF3cyc7XG5cbi8qKlxuICogSGlnaGVyIG9yZGVyIGZ1bmN0aW9uIHRvIGV4ZWN1dGUgYSBibG9jayB3aXRoIGEgQ0RLIGFwcCBmaXh0dXJlXG4gKlxuICogUmVxdWlyZXMgYW4gQVdTIGNsaWVudCB0byBiZSBwYXNzZWQgaW4uXG4gKlxuICogRm9yIGJhY2t3YXJkcyBjb21wYXRpYmlsaXR5IHdpdGggZXhpc3RpbmcgdGVzdHMgKHNvIHdlIGRvbid0IGhhdmUgdG8gY2hhbmdlXG4gKiB0b28gbXVjaCkgdGhlIGlubmVyIGJsb2NrIGlzIGV4cGVjdGVkIHRvIHRha2UgYSBgVGVzdEZpeHR1cmVgIG9iamVjdC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHdpdGhDZGtBcHA8QSBleHRlbmRzIFRlc3RDb250ZXh0ICYgQXdzQ29udGV4dD4oYmxvY2s6IChjb250ZXh0OiBUZXN0Rml4dHVyZSkgPT4gUHJvbWlzZTx2b2lkPikge1xuICByZXR1cm4gYXN5bmMgKGNvbnRleHQ6IEEpID0+IHtcbiAgICBjb25zdCByYW5keSA9IGNvbnRleHQucmFuZG9tU3RyaW5nO1xuICAgIGNvbnN0IHN0YWNrTmFtZVByZWZpeCA9IGBjZGt0ZXN0LSR7cmFuZHl9YDtcbiAgICBjb25zdCBpbnRlZ1Rlc3REaXIgPSBwYXRoLmpvaW4ob3MudG1wZGlyKCksIGBjZGstaW50ZWctJHtyYW5keX1gKTtcblxuICAgIGNvbnRleHQub3V0cHV0LndyaXRlKGAgU3RhY2sgcHJlZml4OiAgICR7c3RhY2tOYW1lUHJlZml4fVxcbmApO1xuICAgIGNvbnRleHQub3V0cHV0LndyaXRlKGAgVGVzdCBkaXJlY3Rvcnk6ICR7aW50ZWdUZXN0RGlyfVxcbmApO1xuICAgIGNvbnRleHQub3V0cHV0LndyaXRlKGAgUmVnaW9uOiAgICAgICAgICR7Y29udGV4dC5hd3MucmVnaW9ufVxcbmApO1xuXG4gICAgYXdhaXQgY2xvbmVEaXJlY3RvcnkocGF0aC5qb2luKFJFU09VUkNFU19ESVIsICdjZGstYXBwcycsICdhcHAnKSwgaW50ZWdUZXN0RGlyLCBjb250ZXh0Lm91dHB1dCk7XG4gICAgY29uc3QgZml4dHVyZSA9IG5ldyBUZXN0Rml4dHVyZShcbiAgICAgIGludGVnVGVzdERpcixcbiAgICAgIHN0YWNrTmFtZVByZWZpeCxcbiAgICAgIGNvbnRleHQub3V0cHV0LFxuICAgICAgY29udGV4dC5hd3MsXG4gICAgICBjb250ZXh0LnJhbmRvbVN0cmluZyk7XG5cbiAgICBsZXQgc3VjY2VzcyA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IGluc3RhbGxhdGlvblZlcnNpb24gPSBmaXh0dXJlLnBhY2thZ2VzLnJlcXVlc3RlZEZyYW1ld29ya1ZlcnNpb24oKTtcblxuICAgICAgaWYgKGZpeHR1cmUucGFja2FnZXMubWFqb3JWZXJzaW9uKCkgPT09ICcxJykge1xuICAgICAgICBhd2FpdCBpbnN0YWxsTnBtUGFja2FnZXMoZml4dHVyZSwge1xuICAgICAgICAgICdAYXdzLWNkay9jb3JlJzogaW5zdGFsbGF0aW9uVmVyc2lvbixcbiAgICAgICAgICAnQGF3cy1jZGsvYXdzLXNucyc6IGluc3RhbGxhdGlvblZlcnNpb24sXG4gICAgICAgICAgJ0Bhd3MtY2RrL2F3cy1zcXMnOiBpbnN0YWxsYXRpb25WZXJzaW9uLFxuICAgICAgICAgICdAYXdzLWNkay9hd3MtaWFtJzogaW5zdGFsbGF0aW9uVmVyc2lvbixcbiAgICAgICAgICAnQGF3cy1jZGsvYXdzLWxhbWJkYSc6IGluc3RhbGxhdGlvblZlcnNpb24sXG4gICAgICAgICAgJ0Bhd3MtY2RrL2F3cy1zc20nOiBpbnN0YWxsYXRpb25WZXJzaW9uLFxuICAgICAgICAgICdAYXdzLWNkay9hd3MtZWNyLWFzc2V0cyc6IGluc3RhbGxhdGlvblZlcnNpb24sXG4gICAgICAgICAgJ0Bhd3MtY2RrL2F3cy1jbG91ZGZvcm1hdGlvbic6IGluc3RhbGxhdGlvblZlcnNpb24sXG4gICAgICAgICAgJ0Bhd3MtY2RrL2F3cy1lYzInOiBpbnN0YWxsYXRpb25WZXJzaW9uLFxuICAgICAgICAgICdAYXdzLWNkay9hd3MtczMnOiBpbnN0YWxsYXRpb25WZXJzaW9uLFxuICAgICAgICAgICdjb25zdHJ1Y3RzJzogJ14zJyxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBpbnN0YWxsTnBtUGFja2FnZXMoZml4dHVyZSwge1xuICAgICAgICAgICdhd3MtY2RrLWxpYic6IGluc3RhbGxhdGlvblZlcnNpb24sXG4gICAgICAgICAgJ2NvbnN0cnVjdHMnOiAnXjEwJyxcbiAgICAgICAgfSk7XG4gICAgICB9XG5cbiAgICAgIGF3YWl0IGVuc3VyZUJvb3RzdHJhcHBlZChmaXh0dXJlKTtcblxuICAgICAgYXdhaXQgYmxvY2soZml4dHVyZSk7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgc3VjY2VzcyA9IGZhbHNlO1xuICAgICAgdGhyb3cgZTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgaWYgKHByb2Nlc3MuZW52LklOVEVHX05PX0NMRUFOKSB7XG4gICAgICAgIGNvbnRleHQubG9nKGBMZWZ0IHRlc3QgZGlyZWN0b3J5IGluICcke2ludGVnVGVzdERpcn0nICgkSU5URUdfTk9fQ0xFQU4pXFxuYCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBhd2FpdCBmaXh0dXJlLmRpc3Bvc2Uoc3VjY2Vzcyk7XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aE1vbm9saXRoaWNDZm5JbmNsdWRlQ2RrQXBwPEEgZXh0ZW5kcyBUZXN0Q29udGV4dD4oYmxvY2s6IChjb250ZXh0OiBUZXN0Rml4dHVyZSkgPT4gUHJvbWlzZTx2b2lkPikge1xuICByZXR1cm4gYXN5bmMgKGNvbnRleHQ6IEEpID0+IHtcbiAgICBjb25zdCB1YmVyUGFja2FnZSA9IHByb2Nlc3MuZW52LlVCRVJQQUNLQUdFO1xuICAgIGlmICghdWJlclBhY2thZ2UpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVGhlIFVCRVJQQUNLQUdFIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIHJlcXVpcmVkIGZvciBydW5uaW5nIHRoaXMgdGVzdCEnKTtcbiAgICB9XG5cbiAgICBjb25zdCByYW5keSA9IGNvbnRleHQucmFuZG9tU3RyaW5nO1xuICAgIGNvbnN0IHN0YWNrTmFtZVByZWZpeCA9IGBjZGstdWJlci1jZm4taW5jbHVkZS0ke3JhbmR5fWA7XG4gICAgY29uc3QgaW50ZWdUZXN0RGlyID0gcGF0aC5qb2luKG9zLnRtcGRpcigpLCBgY2RrLXViZXItY2ZuLWluY2x1ZGUtJHtyYW5keX1gKTtcblxuICAgIGNvbnRleHQub3V0cHV0LndyaXRlKGAgU3RhY2sgcHJlZml4OiAgICR7c3RhY2tOYW1lUHJlZml4fVxcbmApO1xuICAgIGNvbnRleHQub3V0cHV0LndyaXRlKGAgVGVzdCBkaXJlY3Rvcnk6ICR7aW50ZWdUZXN0RGlyfVxcbmApO1xuXG4gICAgY29uc3QgYXdzQ2xpZW50cyA9IGF3YWl0IEF3c0NsaWVudHMuZGVmYXVsdChjb250ZXh0Lm91dHB1dCk7XG4gICAgYXdhaXQgY2xvbmVEaXJlY3RvcnkocGF0aC5qb2luKFJFU09VUkNFU19ESVIsICdjZGstYXBwcycsICdjZm4taW5jbHVkZS1hcHAnKSwgaW50ZWdUZXN0RGlyLCBjb250ZXh0Lm91dHB1dCk7XG4gICAgY29uc3QgZml4dHVyZSA9IG5ldyBUZXN0Rml4dHVyZShcbiAgICAgIGludGVnVGVzdERpcixcbiAgICAgIHN0YWNrTmFtZVByZWZpeCxcbiAgICAgIGNvbnRleHQub3V0cHV0LFxuICAgICAgYXdzQ2xpZW50cyxcbiAgICAgIGNvbnRleHQucmFuZG9tU3RyaW5nLFxuICAgICk7XG5cbiAgICBsZXQgc3VjY2VzcyA9IHRydWU7XG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGluc3RhbGxOcG1QYWNrYWdlcyhmaXh0dXJlLCB7XG4gICAgICAgIFt1YmVyUGFja2FnZV06IGZpeHR1cmUucGFja2FnZXMucmVxdWVzdGVkRnJhbWV3b3JrVmVyc2lvbigpLFxuICAgICAgfSk7XG5cbiAgICAgIGF3YWl0IGJsb2NrKGZpeHR1cmUpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHN1Y2Nlc3MgPSBmYWxzZTtcbiAgICAgIHRocm93IGU7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIGlmIChwcm9jZXNzLmVudi5JTlRFR19OT19DTEVBTikge1xuICAgICAgICBjb250ZXh0LmxvZyhgTGVmdCB0ZXN0IGRpcmVjdG9yeSBpbiAnJHtpbnRlZ1Rlc3REaXJ9JyAoJElOVEVHX05PX0NMRUFOKWApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYXdhaXQgZml4dHVyZS5kaXNwb3NlKHN1Y2Nlc3MpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IHRlc3QgZml4dHVyZSBmb3IgbW9zdCAoYWxsPykgaW50ZWcgdGVzdHNcbiAqXG4gKiBJdCdzIGEgY29tcG9zaXRpb24gb2Ygd2l0aEF3cy93aXRoQ2RrQXBwLCBleHBlY3RpbmcgdGhlIHRlc3QgYmxvY2sgdG8gdGFrZSBhIGBUZXN0Rml4dHVyZWBcbiAqIG9iamVjdC5cbiAqXG4gKiBXZSBjb3VsZCBoYXZlIHB1dCBgd2l0aEF3cyh3aXRoQ2RrQXBwKGZpeHR1cmUgPT4geyAvLi4uIGFjdHVhbCB0ZXN0IGhlcmUuLi4vIH0pKWAgaW4gZXZlcnlcbiAqIHRlc3QgZGVjbGFyYXRpb24gYnV0IGNlbnRyYWxpemluZyBpdCBpcyBnb2luZyB0byBtYWtlIGl0IGNvbnZlbmllbnQgdG8gbW9kaWZ5IGluIHRoZSBmdXR1cmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3aXRoRGVmYXVsdEZpeHR1cmUoYmxvY2s6IChjb250ZXh0OiBUZXN0Rml4dHVyZSkgPT4gUHJvbWlzZTx2b2lkPikge1xuICByZXR1cm4gd2l0aEF3czxUZXN0Q29udGV4dD4od2l0aENka0FwcChibG9jaykpO1xuICAvLyAgICAgICAgICAgICAgXn5+fn5+IHRoaXMgaXMgZGlzYXBwb2ludGluZyBUeXBlU2NyaXB0ISBGZWVscyBsaWtlIHlvdSBzaG91bGQgaGF2ZSBiZWVuIGFibGUgdG8gZGVyaXZlIHRoaXMuXG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQ2RrQ2xpT3B0aW9ucyBleHRlbmRzIFNoZWxsT3B0aW9ucyB7XG4gIG9wdGlvbnM/OiBzdHJpbmdbXTtcbiAgbmV2ZXJSZXF1aXJlQXBwcm92YWw/OiBib29sZWFuO1xuICB2ZXJib3NlPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBQcmVwYXJlIGEgdGFyZ2V0IGRpciBieXJlcGxpY2F0aW5nIGEgc291cmNlIGRpcmVjdG9yeVxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY2xvbmVEaXJlY3Rvcnkoc291cmNlOiBzdHJpbmcsIHRhcmdldDogc3RyaW5nLCBvdXRwdXQ/OiBOb2RlSlMuV3JpdGFibGVTdHJlYW0pIHtcbiAgYXdhaXQgc2hlbGwoWydybScsICctcmYnLCB0YXJnZXRdLCB7IG91dHB1dCB9KTtcbiAgYXdhaXQgc2hlbGwoWydta2RpcicsICctcCcsIHRhcmdldF0sIHsgb3V0cHV0IH0pO1xuICBhd2FpdCBzaGVsbChbJ2NwJywgJy1SJywgc291cmNlICsgJy8qJywgdGFyZ2V0XSwgeyBvdXRwdXQgfSk7XG59XG5cbmludGVyZmFjZSBDb21tb25DZGtCb290c3RyYXBDb21tYW5kT3B0aW9ucyB7XG4gIHJlYWRvbmx5IHRvb2xraXRTdGFja05hbWU6IHN0cmluZztcblxuICAvKipcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHZlcmJvc2U/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAZGVmYXVsdCAtIGF1dG8tZ2VuZXJhdGVkIENsb3VkRm9ybWF0aW9uIG5hbWVcbiAgICovXG4gIHJlYWRvbmx5IGJvb3RzdHJhcEJ1Y2tldE5hbWU/OiBzdHJpbmc7XG5cbiAgcmVhZG9ubHkgY2xpT3B0aW9ucz86IENka0NsaU9wdGlvbnM7XG5cbiAgLyoqXG4gICAqIEBkZWZhdWx0IC0gbm9uZVxuICAgKi9cbiAgcmVhZG9ubHkgdGFncz86IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBDZGtMZWdhY3lCb290c3RyYXBDb21tYW5kT3B0aW9ucyBleHRlbmRzIENvbW1vbkNka0Jvb3RzdHJhcENvbW1hbmRPcHRpb25zIHtcbiAgLyoqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBub0V4ZWN1dGU/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBAZGVmYXVsdCB0cnVlXG4gICAqL1xuICByZWFkb25seSBwdWJsaWNBY2Nlc3NCbG9ja0NvbmZpZ3VyYXRpb24/OiBib29sZWFuO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIENka01vZGVybkJvb3RzdHJhcENvbW1hbmRPcHRpb25zIGV4dGVuZHMgQ29tbW9uQ2RrQm9vdHN0cmFwQ29tbWFuZE9wdGlvbnMge1xuICAvKipcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IGZvcmNlPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQGRlZmF1bHQgLSBub25lXG4gICAqL1xuICByZWFkb25seSBjZm5FeGVjdXRpb25Qb2xpY3k/OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSBzaG93VGVtcGxhdGU/OiBib29sZWFuO1xuXG4gIHJlYWRvbmx5IHRlbXBsYXRlPzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBAZGVmYXVsdCBmYWxzZVxuICAgKi9cbiAgcmVhZG9ubHkgdGVybWluYXRpb25Qcm90ZWN0aW9uPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogQGRlZmF1bHQgdW5kZWZpbmVkXG4gICAqL1xuICByZWFkb25seSBleGFtcGxlUGVybWlzc2lvbnNCb3VuZGFyeT86IGJvb2xlYW47XG5cbiAgLyoqXG4gICAqIEBkZWZhdWx0IHVuZGVmaW5lZFxuICAgKi9cbiAgcmVhZG9ubHkgY3VzdG9tUGVybWlzc2lvbnNCb3VuZGFyeT86IHN0cmluZztcbn1cblxuZXhwb3J0IGNsYXNzIFRlc3RGaXh0dXJlIGV4dGVuZHMgU2hlbGxIZWxwZXIge1xuICBwdWJsaWMgcmVhZG9ubHkgcXVhbGlmaWVyID0gdGhpcy5yYW5kb21TdHJpbmcuc2xpY2UoMCwgMTApO1xuICBwcml2YXRlIHJlYWRvbmx5IGJ1Y2tldHNUb0RlbGV0ZSA9IG5ldyBBcnJheTxzdHJpbmc+KCk7XG4gIHB1YmxpYyByZWFkb25seSBwYWNrYWdlczogSVBhY2thZ2VTb3VyY2U7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHJlYWRvbmx5IGludGVnVGVzdERpcjogc3RyaW5nLFxuICAgIHB1YmxpYyByZWFkb25seSBzdGFja05hbWVQcmVmaXg6IHN0cmluZyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgb3V0cHV0OiBOb2RlSlMuV3JpdGFibGVTdHJlYW0sXG4gICAgcHVibGljIHJlYWRvbmx5IGF3czogQXdzQ2xpZW50cyxcbiAgICBwdWJsaWMgcmVhZG9ubHkgcmFuZG9tU3RyaW5nOiBzdHJpbmcpIHtcblxuICAgIHN1cGVyKGludGVnVGVzdERpciwgb3V0cHV0KTtcblxuICAgIHRoaXMucGFja2FnZXMgPSBwYWNrYWdlU291cmNlSW5TdWJwcm9jZXNzKCk7XG4gIH1cblxuICBwdWJsaWMgbG9nKHM6IHN0cmluZykge1xuICAgIHRoaXMub3V0cHV0LndyaXRlKGAke3N9XFxuYCk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY2RrRGVwbG95KHN0YWNrTmFtZXM6IHN0cmluZyB8IHN0cmluZ1tdLCBvcHRpb25zOiBDZGtDbGlPcHRpb25zID0ge30pIHtcbiAgICBzdGFja05hbWVzID0gdHlwZW9mIHN0YWNrTmFtZXMgPT09ICdzdHJpbmcnID8gW3N0YWNrTmFtZXNdIDogc3RhY2tOYW1lcztcblxuICAgIGNvbnN0IG5ldmVyUmVxdWlyZUFwcHJvdmFsID0gb3B0aW9ucy5uZXZlclJlcXVpcmVBcHByb3ZhbCA/PyB0cnVlO1xuXG4gICAgcmV0dXJuIHRoaXMuY2RrKFsnZGVwbG95JyxcbiAgICAgIC4uLihuZXZlclJlcXVpcmVBcHByb3ZhbCA/IFsnLS1yZXF1aXJlLWFwcHJvdmFsPW5ldmVyJ10gOiBbXSksIC8vIERlZmF1bHQgdG8gbm8gYXBwcm92YWwgaW4gYW4gdW5hdHRlbmRlZCB0ZXN0XG4gICAgICAuLi4ob3B0aW9ucy5vcHRpb25zID8/IFtdKSxcbiAgICAgIC4uLnRoaXMuZnVsbFN0YWNrTmFtZShzdGFja05hbWVzKV0sIG9wdGlvbnMpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNka1N5bnRoKG9wdGlvbnM6IENka0NsaU9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiB0aGlzLmNkayhbXG4gICAgICAnc3ludGgnLFxuICAgICAgLi4uKG9wdGlvbnMub3B0aW9ucyA/PyBbXSksXG4gICAgXSwgb3B0aW9ucyk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY2RrRGVzdHJveShzdGFja05hbWVzOiBzdHJpbmcgfCBzdHJpbmdbXSwgb3B0aW9uczogQ2RrQ2xpT3B0aW9ucyA9IHt9KSB7XG4gICAgc3RhY2tOYW1lcyA9IHR5cGVvZiBzdGFja05hbWVzID09PSAnc3RyaW5nJyA/IFtzdGFja05hbWVzXSA6IHN0YWNrTmFtZXM7XG5cbiAgICByZXR1cm4gdGhpcy5jZGsoWydkZXN0cm95JyxcbiAgICAgICctZicsIC8vIFdlIG5ldmVyIHdhbnQgYSBwcm9tcHQgaW4gYW4gdW5hdHRlbmRlZCB0ZXN0XG4gICAgICAuLi4ob3B0aW9ucy5vcHRpb25zID8/IFtdKSxcbiAgICAgIC4uLnRoaXMuZnVsbFN0YWNrTmFtZShzdGFja05hbWVzKV0sIG9wdGlvbnMpO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIGNka0Jvb3RzdHJhcExlZ2FjeShvcHRpb25zOiBDZGtMZWdhY3lCb290c3RyYXBDb21tYW5kT3B0aW9ucyk6IFByb21pc2U8c3RyaW5nPiB7XG4gICAgY29uc3QgYXJncyA9IFsnYm9vdHN0cmFwJ107XG5cbiAgICBpZiAob3B0aW9ucy52ZXJib3NlKSB7XG4gICAgICBhcmdzLnB1c2goJy12Jyk7XG4gICAgfVxuICAgIGFyZ3MucHVzaCgnLS10b29sa2l0LXN0YWNrLW5hbWUnLCBvcHRpb25zLnRvb2xraXRTdGFja05hbWUpO1xuICAgIGlmIChvcHRpb25zLmJvb3RzdHJhcEJ1Y2tldE5hbWUpIHtcbiAgICAgIGFyZ3MucHVzaCgnLS1ib290c3RyYXAtYnVja2V0LW5hbWUnLCBvcHRpb25zLmJvb3RzdHJhcEJ1Y2tldE5hbWUpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5ub0V4ZWN1dGUpIHtcbiAgICAgIGFyZ3MucHVzaCgnLS1uby1leGVjdXRlJyk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnB1YmxpY0FjY2Vzc0Jsb2NrQ29uZmlndXJhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhcmdzLnB1c2goJy0tcHVibGljLWFjY2Vzcy1ibG9jay1jb25maWd1cmF0aW9uJywgb3B0aW9ucy5wdWJsaWNBY2Nlc3NCbG9ja0NvbmZpZ3VyYXRpb24udG9TdHJpbmcoKSk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLnRhZ3MpIHtcbiAgICAgIGFyZ3MucHVzaCgnLS10YWdzJywgb3B0aW9ucy50YWdzKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jZGsoYXJncywge1xuICAgICAgLi4ub3B0aW9ucy5jbGlPcHRpb25zLFxuICAgICAgbW9kRW52OiB7XG4gICAgICAgIC4uLm9wdGlvbnMuY2xpT3B0aW9ucz8ubW9kRW52LFxuICAgICAgICAvLyBzbyB0aGF0IHRoaXMgd29ya3MgZm9yIFYyLFxuICAgICAgICAvLyB3aGVyZSB0aGUgXCJuZXdcIiBib290c3RyYXAgaXMgdGhlIGRlZmF1bHRcbiAgICAgICAgQ0RLX0xFR0FDWV9CT09UU1RSQVA6ICcxJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgY2RrQm9vdHN0cmFwTW9kZXJuKG9wdGlvbnM6IENka01vZGVybkJvb3RzdHJhcENvbW1hbmRPcHRpb25zKTogUHJvbWlzZTxzdHJpbmc+IHtcbiAgICBjb25zdCBhcmdzID0gWydib290c3RyYXAnXTtcblxuICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgIGFyZ3MucHVzaCgnLXYnKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMuc2hvd1RlbXBsYXRlKSB7XG4gICAgICBhcmdzLnB1c2goJy0tc2hvdy10ZW1wbGF0ZScpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy50ZW1wbGF0ZSkge1xuICAgICAgYXJncy5wdXNoKCctLXRlbXBsYXRlJywgb3B0aW9ucy50ZW1wbGF0ZSk7XG4gICAgfVxuICAgIGFyZ3MucHVzaCgnLS10b29sa2l0LXN0YWNrLW5hbWUnLCBvcHRpb25zLnRvb2xraXRTdGFja05hbWUpO1xuICAgIGlmIChvcHRpb25zLmJvb3RzdHJhcEJ1Y2tldE5hbWUpIHtcbiAgICAgIGFyZ3MucHVzaCgnLS1ib290c3RyYXAtYnVja2V0LW5hbWUnLCBvcHRpb25zLmJvb3RzdHJhcEJ1Y2tldE5hbWUpO1xuICAgIH1cbiAgICBhcmdzLnB1c2goJy0tcXVhbGlmaWVyJywgdGhpcy5xdWFsaWZpZXIpO1xuICAgIGlmIChvcHRpb25zLmNmbkV4ZWN1dGlvblBvbGljeSkge1xuICAgICAgYXJncy5wdXNoKCctLWNsb3VkZm9ybWF0aW9uLWV4ZWN1dGlvbi1wb2xpY2llcycsIG9wdGlvbnMuY2ZuRXhlY3V0aW9uUG9saWN5KTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMudGVybWluYXRpb25Qcm90ZWN0aW9uICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGFyZ3MucHVzaCgnLS10ZXJtaW5hdGlvbi1wcm90ZWN0aW9uJywgb3B0aW9ucy50ZXJtaW5hdGlvblByb3RlY3Rpb24udG9TdHJpbmcoKSk7XG4gICAgfVxuICAgIGlmIChvcHRpb25zLmZvcmNlKSB7XG4gICAgICBhcmdzLnB1c2goJy0tZm9yY2UnKTtcbiAgICB9XG4gICAgaWYgKG9wdGlvbnMudGFncykge1xuICAgICAgYXJncy5wdXNoKCctLXRhZ3MnLCBvcHRpb25zLnRhZ3MpO1xuICAgIH1cbiAgICBpZiAob3B0aW9ucy5jdXN0b21QZXJtaXNzaW9uc0JvdW5kYXJ5ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGFyZ3MucHVzaCgnLS1jdXN0b20tcGVybWlzc2lvbnMtYm91bmRhcnknLCBvcHRpb25zLmN1c3RvbVBlcm1pc3Npb25zQm91bmRhcnkpO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5leGFtcGxlUGVybWlzc2lvbnNCb3VuZGFyeSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBhcmdzLnB1c2goJy0tZXhhbXBsZS1wZXJtaXNzaW9ucy1ib3VuZGFyeScpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNkayhhcmdzLCB7XG4gICAgICAuLi5vcHRpb25zLmNsaU9wdGlvbnMsXG4gICAgICBtb2RFbnY6IHtcbiAgICAgICAgLi4ub3B0aW9ucy5jbGlPcHRpb25zPy5tb2RFbnYsXG4gICAgICAgIC8vIHNvIHRoYXQgdGhpcyB3b3JrcyBmb3IgVjEsXG4gICAgICAgIC8vIHdoZXJlIHRoZSBcIm9sZFwiIGJvb3RzdHJhcCBpcyB0aGUgZGVmYXVsdFxuICAgICAgICBDREtfTkVXX0JPT1RTVFJBUDogJzEnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBjZGsoYXJnczogc3RyaW5nW10sIG9wdGlvbnM6IENka0NsaU9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IHZlcmJvc2UgPSBvcHRpb25zLnZlcmJvc2UgPz8gdHJ1ZTtcblxuICAgIGF3YWl0IHRoaXMucGFja2FnZXMubWFrZUNsaUF2YWlsYWJsZSgpO1xuXG4gICAgcmV0dXJuIHRoaXMuc2hlbGwoWydjZGsnLCAuLi4odmVyYm9zZSA/IFsnLXYnXSA6IFtdKSwgLi4uYXJnc10sIHtcbiAgICAgIC4uLm9wdGlvbnMsXG4gICAgICBtb2RFbnY6IHtcbiAgICAgICAgQVdTX1JFR0lPTjogdGhpcy5hd3MucmVnaW9uLFxuICAgICAgICBBV1NfREVGQVVMVF9SRUdJT046IHRoaXMuYXdzLnJlZ2lvbixcbiAgICAgICAgU1RBQ0tfTkFNRV9QUkVGSVg6IHRoaXMuc3RhY2tOYW1lUHJlZml4LFxuICAgICAgICBQQUNLQUdFX0xBWU9VVF9WRVJTSU9OOiB0aGlzLnBhY2thZ2VzLm1ham9yVmVyc2lvbigpLFxuICAgICAgICAuLi5vcHRpb25zLm1vZEVudixcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgdGVtcGxhdGUoc3RhY2tOYW1lOiBzdHJpbmcpOiBhbnkge1xuICAgIGNvbnN0IGZ1bGxTdGFja05hbWUgPSB0aGlzLmZ1bGxTdGFja05hbWUoc3RhY2tOYW1lKTtcbiAgICBjb25zdCB0ZW1wbGF0ZVBhdGggPSBwYXRoLmpvaW4odGhpcy5pbnRlZ1Rlc3REaXIsICdjZGsub3V0JywgYCR7ZnVsbFN0YWNrTmFtZX0udGVtcGxhdGUuanNvbmApO1xuICAgIHJldHVybiBKU09OLnBhcnNlKGZzLnJlYWRGaWxlU3luYyh0ZW1wbGF0ZVBhdGgsIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSkudG9TdHJpbmcoKSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGJvb3RzdHJhcFN0YWNrTmFtZSgpIHtcbiAgICByZXR1cm4gdGhpcy5mdWxsU3RhY2tOYW1lKCdib290c3RyYXAtc3RhY2snKTtcbiAgfVxuXG4gIHB1YmxpYyBmdWxsU3RhY2tOYW1lKHN0YWNrTmFtZTogc3RyaW5nKTogc3RyaW5nO1xuICBwdWJsaWMgZnVsbFN0YWNrTmFtZShzdGFja05hbWVzOiBzdHJpbmdbXSk6IHN0cmluZ1tdO1xuICBwdWJsaWMgZnVsbFN0YWNrTmFtZShzdGFja05hbWVzOiBzdHJpbmcgfCBzdHJpbmdbXSk6IHN0cmluZyB8IHN0cmluZ1tdIHtcbiAgICBpZiAodHlwZW9mIHN0YWNrTmFtZXMgPT09ICdzdHJpbmcnKSB7XG4gICAgICByZXR1cm4gYCR7dGhpcy5zdGFja05hbWVQcmVmaXh9LSR7c3RhY2tOYW1lc31gO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc3RhY2tOYW1lcy5tYXAocyA9PiBgJHt0aGlzLnN0YWNrTmFtZVByZWZpeH0tJHtzfWApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBlbmQgdGhpcyB0byB0aGUgbGlzdCBvZiBidWNrZXRzIHRvIHBvdGVudGlhbGx5IGRlbGV0ZVxuICAgKlxuICAgKiBBdCB0aGUgZW5kIG9mIGEgdGVzdCwgd2UgY2xlYW4gdXAgYnVja2V0cyB0aGF0IG1heSBub3QgaGF2ZSBnb3R0ZW4gZGVzdHJveWVkXG4gICAqIChmb3Igd2hhdGV2ZXIgcmVhc29uKS5cbiAgICovXG4gIHB1YmxpYyByZW1lbWJlclRvRGVsZXRlQnVja2V0KGJ1Y2tldE5hbWU6IHN0cmluZykge1xuICAgIHRoaXMuYnVja2V0c1RvRGVsZXRlLnB1c2goYnVja2V0TmFtZSk7XG4gIH1cblxuICAvKipcbiAgICogQ2xlYW51cCBsZWZ0b3ZlciBzdGFja3MgYW5kIGJ1Y2tldHNcbiAgICovXG4gIHB1YmxpYyBhc3luYyBkaXNwb3NlKHN1Y2Nlc3M6IGJvb2xlYW4pIHtcbiAgICBjb25zdCBzdGFja3NUb0RlbGV0ZSA9IGF3YWl0IHRoaXMuZGVsZXRlYWJsZVN0YWNrcyh0aGlzLnN0YWNrTmFtZVByZWZpeCk7XG5cbiAgICB0aGlzLnNvcnRCb290c3RyYXBTdGFja3NUb1RoZUVuZChzdGFja3NUb0RlbGV0ZSk7XG5cbiAgICAvLyBCb290c3RyYXAgc3RhY2tzIGhhdmUgYnVja2V0cyB0aGF0IG5lZWQgdG8gYmUgY2xlYW5lZFxuICAgIGNvbnN0IGJ1Y2tldE5hbWVzID0gc3RhY2tzVG9EZWxldGUubWFwKHN0YWNrID0+IG91dHB1dEZyb21TdGFjaygnQnVja2V0TmFtZScsIHN0YWNrKSkuZmlsdGVyKGRlZmluZWQpO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKGJ1Y2tldE5hbWVzLm1hcChiID0+IHRoaXMuYXdzLmVtcHR5QnVja2V0KGIpKSk7XG4gICAgLy8gVGhlIGJvb3RzdHJhcCBidWNrZXQgaGFzIGEgcmVtb3ZhbCBwb2xpY3kgb2YgUkVUQUlOIGJ5IGRlZmF1bHQsIHNvIGFkZCBpdCB0byB0aGUgYnVja2V0cyB0byBiZSBjbGVhbmVkIHVwLlxuICAgIHRoaXMuYnVja2V0c1RvRGVsZXRlLnB1c2goLi4uYnVja2V0TmFtZXMpO1xuXG4gICAgLy8gQm9vdHN0cmFwIHN0YWNrcyBoYXZlIEVDUiByZXBvc2l0b3JpZXMgd2l0aCBpbWFnZXMgd2hpY2ggc2hvdWxkIGJlIGRlbGV0ZWRcbiAgICBjb25zdCBpbWFnZVJlcG9zaXRvcnlOYW1lcyA9IHN0YWNrc1RvRGVsZXRlLm1hcChzdGFjayA9PiBvdXRwdXRGcm9tU3RhY2soJ0ltYWdlUmVwb3NpdG9yeU5hbWUnLCBzdGFjaykpLmZpbHRlcihkZWZpbmVkKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChpbWFnZVJlcG9zaXRvcnlOYW1lcy5tYXAociA9PiB0aGlzLmF3cy5kZWxldGVJbWFnZVJlcG9zaXRvcnkocikpKTtcblxuICAgIGF3YWl0IHRoaXMuYXdzLmRlbGV0ZVN0YWNrcyguLi5zdGFja3NUb0RlbGV0ZS5tYXAocyA9PiBzLlN0YWNrTmFtZSkpO1xuXG4gICAgLy8gV2UgbWlnaHQgaGF2ZSBsZWFrZWQgc29tZSBidWNrZXRzIGJ5IHVwZ3JhZGluZyB0aGUgYm9vdHN0cmFwIHN0YWNrLiBCZVxuICAgIC8vIHN1cmUgdG8gY2xlYW4gZXZlcnl0aGluZy5cbiAgICBmb3IgKGNvbnN0IGJ1Y2tldCBvZiB0aGlzLmJ1Y2tldHNUb0RlbGV0ZSkge1xuICAgICAgYXdhaXQgdGhpcy5hd3MuZGVsZXRlQnVja2V0KGJ1Y2tldCk7XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHRlc3RzIGNvbXBsZXRlZCBzdWNjZXNzZnVsbHksIGhhcHBpbHkgZGVsZXRlIHRoZSBmaXh0dXJlXG4gICAgLy8gKG90aGVyd2lzZSBsZWF2ZSBpdCBmb3IgaHVtYW5zIHRvIGluc3BlY3QpXG4gICAgaWYgKHN1Y2Nlc3MpIHtcbiAgICAgIHJpbXJhZih0aGlzLmludGVnVGVzdERpcik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgc3RhY2tzIHN0YXJ0aW5nIHdpdGggb3VyIHRlc3RpbmcgcHJlZml4IHRoYXQgc2hvdWxkIGJlIGRlbGV0ZWRcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZGVsZXRlYWJsZVN0YWNrcyhwcmVmaXg6IHN0cmluZyk6IFByb21pc2U8QVdTLkNsb3VkRm9ybWF0aW9uLlN0YWNrW10+IHtcbiAgICBjb25zdCBzdGF0dXNGaWx0ZXIgPSBbXG4gICAgICAnQ1JFQVRFX0lOX1BST0dSRVNTJywgJ0NSRUFURV9GQUlMRUQnLCAnQ1JFQVRFX0NPTVBMRVRFJyxcbiAgICAgICdST0xMQkFDS19JTl9QUk9HUkVTUycsICdST0xMQkFDS19GQUlMRUQnLCAnUk9MTEJBQ0tfQ09NUExFVEUnLFxuICAgICAgJ0RFTEVURV9GQUlMRUQnLFxuICAgICAgJ1VQREFURV9JTl9QUk9HUkVTUycsICdVUERBVEVfQ09NUExFVEVfQ0xFQU5VUF9JTl9QUk9HUkVTUycsXG4gICAgICAnVVBEQVRFX0NPTVBMRVRFJywgJ1VQREFURV9ST0xMQkFDS19JTl9QUk9HUkVTUycsXG4gICAgICAnVVBEQVRFX1JPTExCQUNLX0ZBSUxFRCcsXG4gICAgICAnVVBEQVRFX1JPTExCQUNLX0NPTVBMRVRFX0NMRUFOVVBfSU5fUFJPR1JFU1MnLFxuICAgICAgJ1VQREFURV9ST0xMQkFDS19DT01QTEVURScsICdSRVZJRVdfSU5fUFJPR1JFU1MnLFxuICAgICAgJ0lNUE9SVF9JTl9QUk9HUkVTUycsICdJTVBPUlRfQ09NUExFVEUnLFxuICAgICAgJ0lNUE9SVF9ST0xMQkFDS19JTl9QUk9HUkVTUycsICdJTVBPUlRfUk9MTEJBQ0tfRkFJTEVEJyxcbiAgICAgICdJTVBPUlRfUk9MTEJBQ0tfQ09NUExFVEUnLFxuICAgIF07XG5cbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuYXdzLmNsb3VkRm9ybWF0aW9uKCdkZXNjcmliZVN0YWNrcycsIHt9KTtcblxuICAgIHJldHVybiAocmVzcG9uc2UuU3RhY2tzID8/IFtdKVxuICAgICAgLmZpbHRlcihzID0+IHMuU3RhY2tOYW1lLnN0YXJ0c1dpdGgocHJlZml4KSlcbiAgICAgIC5maWx0ZXIocyA9PiBzdGF0dXNGaWx0ZXIuaW5jbHVkZXMocy5TdGFja1N0YXR1cykpXG4gICAgICAuZmlsdGVyKHMgPT4gcy5Sb290SWQgPT09IHVuZGVmaW5lZCk7IC8vIE9ubHkgZGVsZXRlIHBhcmVudCBzdGFja3MuIE5lc3RlZCBzdGFja3MgYXJlIGRlbGV0ZWQgaW4gdGhlIHByb2Nlc3NcbiAgfVxuXG4gIHByaXZhdGUgc29ydEJvb3RzdHJhcFN0YWNrc1RvVGhlRW5kKHN0YWNrczogQVdTLkNsb3VkRm9ybWF0aW9uLlN0YWNrW10pIHtcbiAgICBzdGFja3Muc29ydCgoYSwgYikgPT4ge1xuICAgICAgY29uc3QgYUJzID0gYS5TdGFja05hbWUuc3RhcnRzV2l0aCh0aGlzLmJvb3RzdHJhcFN0YWNrTmFtZSk7XG4gICAgICBjb25zdCBiQnMgPSBiLlN0YWNrTmFtZS5zdGFydHNXaXRoKHRoaXMuYm9vdHN0cmFwU3RhY2tOYW1lKTtcblxuICAgICAgcmV0dXJuIGFCcyAhPSBiQnNcbiAgICAgICAgLy8gJysnIGNvbnZlcnRzIGEgYm9vbGVhbiB0byAwIG9yIDFcbiAgICAgICAgPyAoK2FCcykgLSAoK2JCcylcbiAgICAgICAgOiBhLlN0YWNrTmFtZS5sb2NhbGVDb21wYXJlKGIuU3RhY2tOYW1lKTtcbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIE1ha2Ugc3VyZSB0aGF0IHRoZSBnaXZlbiBlbnZpcm9ubWVudCBpcyBib290c3RyYXBwZWRcbiAqXG4gKiBTaW5jZSB3ZSBnbyBzdHJpcGluZyBhY3Jvc3MgcmVnaW9ucywgaXQncyBnb2luZyB0byBzdWNrIGRvaW5nIHRoaXNcbiAqIGJ5IGhhbmQgc28gbGV0J3MganVzdCBtYXNzLWF1dG9tYXRlIGl0LlxuICovXG5hc3luYyBmdW5jdGlvbiBlbnN1cmVCb290c3RyYXBwZWQoZml4dHVyZTogVGVzdEZpeHR1cmUpIHtcbiAgLy8gQWx3YXlzIHVzZSB0aGUgbW9kZXJuIGJvb3RzdHJhcCBzdGFjaywgb3RoZXJ3aXNlIHdlIG1heSBnZXQgdGhlIGVycm9yXG4gIC8vIFwicmVmdXNpbmcgdG8gZG93bmdyYWRlIGZyb20gdmVyc2lvbiA3IHRvIHZlcnNpb24gMFwiIHdoZW4gYm9vdHN0cmFwcGluZyB3aXRoIGRlZmF1bHRcbiAgLy8gc2V0dGluZ3MgdXNpbmcgYSB2MSBDTEkuXG4gIC8vXG4gIC8vIEl0IGRvZXNuJ3QgbWF0dGVyIGZvciB0ZXN0czogd2hlbiB0aGV5IHdhbnQgdG8gdGVzdCBzb21ldGhpbmcgYWJvdXQgYW4gYWN0dWFsIGxlZ2FjeVxuICAvLyBib290c3RyYXAgc3RhY2ssIHRoZXknbGwgY3JlYXRlIGEgYm9vdHN0cmFwIHN0YWNrIHdpdGggYSBub24tZGVmYXVsdCBuYW1lIHRvIHRlc3QgdGhhdCBleGFjdCBwcm9wZXJ0eS5cbiAgY29uc3QgZW52U3BlY2lmaWVyID0gYGF3czovLyR7YXdhaXQgZml4dHVyZS5hd3MuYWNjb3VudCgpfS8ke2ZpeHR1cmUuYXdzLnJlZ2lvbn1gO1xuICBpZiAoQUxSRUFEWV9CT09UU1RSQVBQRURfSU5fVEhJU19SVU4uaGFzKGVudlNwZWNpZmllcikpIHsgcmV0dXJuOyB9XG5cbiAgYXdhaXQgZml4dHVyZS5jZGsoWydib290c3RyYXAnLCBlbnZTcGVjaWZpZXJdLCB7XG4gICAgbW9kRW52OiB7XG4gICAgICAvLyBFdmVuIGZvciB2MSwgdXNlIG5ldyBib290c3RyYXBcbiAgICAgIENES19ORVdfQk9PVFNUUkFQOiAnMScsXG4gICAgfSxcbiAgfSk7XG4gIEFMUkVBRFlfQk9PVFNUUkFQUEVEX0lOX1RISVNfUlVOLmFkZChlbnZTcGVjaWZpZXIpO1xufVxuXG5mdW5jdGlvbiBkZWZpbmVkPEE+KHg6IEEpOiB4IGlzIE5vbk51bGxhYmxlPEE+IHtcbiAgcmV0dXJuIHggIT09IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBJbnN0YWxsIHRoZSBnaXZlbiBOUE0gcGFja2FnZXMsIGlkZW50aWZpZWQgYnkgdGhlaXIgbmFtZXMgYW5kIHZlcnNpb25zXG4gKlxuICogV29ya3MgYnkgd3JpdGluZyB0aGUgcGFja2FnZXMgdG8gYSBgcGFja2FnZS5qc29uYCBmaWxlLCBhbmRcbiAqIHRoZW4gcnVubmluZyBOUE03J3MgXCJpbnN0YWxsXCIgb24gaXQuIFRoZSB1c2Ugb2YgTlBNNyB3aWxsIGF1dG9tYXRpY2FsbHlcbiAqIGluc3RhbGwgcmVxdWlyZWQgcGVlckRlcGVuZGVuY2llcy5cbiAqXG4gKiBJZiB3ZSdyZSBydW5uaW5nIGluIFJFUE8gbW9kZSBhbmQgd2UgZmluZCB0aGUgcGFja2FnZSBpbiB0aGUgc2V0IG9mIGxvY2FsXG4gKiBwYWNrYWdlcyBpbiB0aGUgcmVwb3NpdG9yeSwgd2UnbGwgd3JpdGUgdGhlIGRpcmVjdG9yeSBuYW1lIHRvIGBwYWNrYWdlLmpzb25gXG4gKiBzbyB0aGF0IE5QTSB3aWxsIGNyZWF0ZSBhIHN5bWxpbmsgKHRoaXMgYWxsb3dzIHJ1bm5pbmcgdGVzdHMgYWdhaW5zdFxuICogYnVpbHQtYnV0LXVucGFja2FnZWQgbW9kdWxlcywgYW5kIHNhdmVzIGRldiBjeWNsZSB0aW1lKS5cbiAqXG4gKiBCZSBhd2FyZSB5b3UgTVVTVCBpbnN0YWxsIGFsbCB0aGUgcGFja2FnZXMgeW91IGRpcmVjdGx5IGRlcGVuZCB1cG9uISBJbiB0aGUgY2FzZVxuICogb2YgYSByZXBvL3N5bWxpbmtpbmcgaW5zdGFsbCwgdHJhbnNpdGl2ZSBkZXBlbmRlbmNpZXMgV0lMTCBOT1QgYmUgaW5zdGFsbGVkIGluIHRoZVxuICogY3VycmVudCBkaXJlY3RvcnkncyBgbm9kZV9tb2R1bGVzYCBkaXJlY3RvcnksIGJlY2F1c2UgdGhleSB3aWxsIGFscmVhZHkgaGF2ZSBiZWVuXG4gKiBzeW1saW5rZWQgZnJvbSB0aGUgVEFSR0VUIGRpcmVjdG9yeSdzIGBub2RlX21vZHVsZXNgIGRpcmVjdG9yeSAod2hpY2ggaXMgc3VmZmljaWVudFxuICogZm9yIE5vZGUncyBkZXBlbmRlbmN5IGxvb2t1cCBtZWNoYW5pc20pLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gaW5zdGFsbE5wbVBhY2thZ2VzKGZpeHR1cmU6IFRlc3RGaXh0dXJlLCBwYWNrYWdlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPikge1xuICBmcy53cml0ZUZpbGVTeW5jKHBhdGguam9pbihmaXh0dXJlLmludGVnVGVzdERpciwgJ3BhY2thZ2UuanNvbicpLCBKU09OLnN0cmluZ2lmeSh7XG4gICAgbmFtZTogJ2Nkay1pbnRlZy10ZXN0cycsXG4gICAgcHJpdmF0ZTogdHJ1ZSxcbiAgICB2ZXJzaW9uOiAnMC4wLjEnLFxuICAgIGRldkRlcGVuZGVuY2llczogcGFja2FnZXMsXG4gIH0sIHVuZGVmaW5lZCwgMiksIHsgZW5jb2Rpbmc6ICd1dGYtOCcgfSk7XG5cbiAgLy8gTm93IGluc3RhbGwgdGhhdCBgcGFja2FnZS5qc29uYCB1c2luZyBOUE03XG4gIGF3YWl0IGZpeHR1cmUuc2hlbGwoWydub2RlJywgcmVxdWlyZS5yZXNvbHZlKCducG0nKSwgJ2luc3RhbGwnXSk7XG59XG5cbmNvbnN0IEFMUkVBRFlfQk9PVFNUUkFQUEVEX0lOX1RISVNfUlVOID0gbmV3IFNldCgpO1xuIl19
@@ -0,0 +1,5 @@
1
+ import { IPackageSource } from './package-sources/source';
2
+ export interface PackageContext {
3
+ readonly packages: IPackageSource;
4
+ }
5
+ export declare function withPackages<A extends object>(block: (context: A & PackageContext) => Promise<void>): (context: A) => Promise<void>;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.withPackages = void 0;
4
+ const subprocess_1 = require("./package-sources/subprocess");
5
+ function withPackages(block) {
6
+ return async (context) => {
7
+ return block({
8
+ ...context,
9
+ packages: subprocess_1.packageSourceInSubprocess(),
10
+ });
11
+ };
12
+ }
13
+ exports.withPackages = withPackages;
14
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2l0aC1wYWNrYWdlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIndpdGgtcGFja2FnZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQ0EsNkRBQXlFO0FBTXpFLFNBQWdCLFlBQVksQ0FBbUIsS0FBcUQ7SUFDbEcsT0FBTyxLQUFLLEVBQUUsT0FBVSxFQUFFLEVBQUU7UUFDMUIsT0FBTyxLQUFLLENBQUM7WUFDWCxHQUFHLE9BQU87WUFDVixRQUFRLEVBQUUsc0NBQXlCLEVBQUU7U0FDdEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQyxDQUFDO0FBQ0osQ0FBQztBQVBELG9DQU9DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgSVBhY2thZ2VTb3VyY2UgfSBmcm9tICcuL3BhY2thZ2Utc291cmNlcy9zb3VyY2UnO1xuaW1wb3J0IHsgcGFja2FnZVNvdXJjZUluU3VicHJvY2VzcyB9IGZyb20gJy4vcGFja2FnZS1zb3VyY2VzL3N1YnByb2Nlc3MnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFBhY2thZ2VDb250ZXh0IHtcbiAgcmVhZG9ubHkgcGFja2FnZXM6IElQYWNrYWdlU291cmNlO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gd2l0aFBhY2thZ2VzPEEgZXh0ZW5kcyBvYmplY3Q+KGJsb2NrOiAoY29udGV4dDogQSAmIFBhY2thZ2VDb250ZXh0KSA9PiBQcm9taXNlPHZvaWQ+KSB7XG4gIHJldHVybiBhc3luYyAoY29udGV4dDogQSkgPT4ge1xuICAgIHJldHVybiBibG9jayh7XG4gICAgICAuLi5jb250ZXh0LFxuICAgICAgcGFja2FnZXM6IHBhY2thZ2VTb3VyY2VJblN1YnByb2Nlc3MoKSxcbiAgICB9KTtcbiAgfTtcbn0iXX0=
@@ -0,0 +1,33 @@
1
+ import { TestContext } from './integ-test';
2
+ import { ShellOptions } from './shell';
3
+ import { AwsContext } from './with-aws';
4
+ import { TestFixture } from './with-cdk-app';
5
+ export interface ActionOutput {
6
+ actionSucceeded?: boolean;
7
+ actionOutput?: any;
8
+ shellOutput?: string;
9
+ }
10
+ /**
11
+ * Higher order function to execute a block with a SAM Integration CDK app fixture
12
+ */
13
+ export declare function withSamIntegrationCdkApp<A extends TestContext & AwsContext>(block: (context: SamIntegrationTestFixture) => Promise<void>): (context: A) => Promise<void>;
14
+ /**
15
+ * SAM Integration test fixture for CDK - SAM integration test cases
16
+ */
17
+ export declare function withSamIntegrationFixture(block: (context: SamIntegrationTestFixture) => Promise<void>): (context: TestContext) => Promise<void>;
18
+ export declare class SamIntegrationTestFixture extends TestFixture {
19
+ samShell(command: string[], filter?: string, action?: () => any, options?: Omit<ShellOptions, 'cwd' | 'output'>): Promise<ActionOutput>;
20
+ samBuild(stackName: string): Promise<ActionOutput>;
21
+ samLocalStartApi(stackName: string, isBuilt: boolean, port: number, apiPath: string): Promise<ActionOutput>;
22
+ /**
23
+ * Cleanup leftover stacks and buckets
24
+ */
25
+ dispose(success: boolean): Promise<void>;
26
+ }
27
+ export declare function randomInteger(min: number, max: number): number;
28
+ /**
29
+ * A shell command that does what you want
30
+ *
31
+ * Is platform-aware, handles errors nicely.
32
+ */
33
+ export declare function shellWithAction(command: string[], filter?: string, action?: () => Promise<any>, options?: ShellOptions): Promise<ActionOutput>;