@aws-cdk/integ-runner 2.202.2 → 2.202.3

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 (38) hide show
  1. package/lib/cli.d.ts.map +1 -1
  2. package/lib/cli.js +3 -2
  3. package/lib/engines/toolkit-lib.d.ts +1 -1
  4. package/lib/engines/toolkit-lib.d.ts.map +1 -1
  5. package/lib/engines/toolkit-lib.js +11 -11
  6. package/lib/files.d.ts +9 -0
  7. package/lib/files.d.ts.map +1 -0
  8. package/lib/files.js +51 -0
  9. package/lib/index.js +218 -182
  10. package/lib/runner/{cdk-integ-helper.d.ts → cdk-test-app.d.ts} +90 -114
  11. package/lib/runner/cdk-test-app.d.ts.map +1 -0
  12. package/lib/runner/cdk-test-app.js +584 -0
  13. package/lib/runner/engine.d.ts +2 -2
  14. package/lib/runner/engine.d.ts.map +1 -1
  15. package/lib/runner/engine.js +2 -2
  16. package/lib/runner/index.d.ts +1 -1
  17. package/lib/runner/index.d.ts.map +1 -1
  18. package/lib/runner/index.js +2 -2
  19. package/lib/runner/integ-test-runner.d.ts +36 -36
  20. package/lib/runner/integ-test-runner.d.ts.map +1 -1
  21. package/lib/runner/integ-test-runner.js +172 -235
  22. package/lib/runner/integ-test-suite.d.ts +6 -11
  23. package/lib/runner/integ-test-suite.d.ts.map +1 -1
  24. package/lib/runner/integ-test-suite.js +14 -20
  25. package/lib/runner/integration-tests.d.ts +12 -3
  26. package/lib/runner/integration-tests.d.ts.map +1 -1
  27. package/lib/runner/integration-tests.js +32 -8
  28. package/lib/runner/snapshot-test-runner.d.ts +19 -22
  29. package/lib/runner/snapshot-test-runner.d.ts.map +1 -1
  30. package/lib/runner/snapshot-test-runner.js +47 -75
  31. package/lib/workers/extract/extract_worker.d.ts.map +1 -1
  32. package/lib/workers/extract/extract_worker.js +65 -78
  33. package/lib/workers/extract/index.js +226955 -226979
  34. package/lib/workers/integ-test-worker.d.ts.map +1 -1
  35. package/lib/workers/integ-test-worker.js +3 -2
  36. package/package.json +3 -3
  37. package/lib/runner/cdk-integ-helper.d.ts.map +0 -1
  38. package/lib/runner/cdk-integ-helper.js +0 -525
@@ -0,0 +1,584 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.DEFAULT_ARGS = exports.DEFAULT_SYNTH_OPTIONS = exports.CdkTestApp = void 0;
37
+ exports.currentlyRecommendedAwsCdkLibFlags = currentlyRecommendedAwsCdkLibFlags;
38
+ /* eslint-disable @cdklabs/no-literal-partition */
39
+ const path = __importStar(require("path"));
40
+ const cloud_assembly_api_1 = require("@aws-cdk/cloud-assembly-api");
41
+ const cloud_assembly_schema_1 = require("@aws-cdk/cloud-assembly-schema");
42
+ const fs = __importStar(require("fs-extra"));
43
+ const integ_test_suite_1 = require("./integ-test-suite");
44
+ const logger = __importStar(require("../logger"));
45
+ const recommendedFlagsFile = __importStar(require("../recommended-feature-flags.json"));
46
+ const utils_1 = require("../utils");
47
+ const cloud_assembly_1 = require("./private/cloud-assembly");
48
+ const integ_manifest_1 = require("./private/integ-manifest");
49
+ const test_specific_context_1 = require("./private/test-specific-context");
50
+ const toolkit_lib_1 = require("../engines/toolkit-lib");
51
+ const files_1 = require("../files");
52
+ const DESTRUCTIVE_CHANGES = '!!DESTRUCTIVE_CHANGES:';
53
+ /**
54
+ * Class with some helper routines for running CDK snapshots and integration tests.
55
+ *
56
+ * A "golden snapshot" is the snapshot that is stored permanently in version
57
+ * control, that new runs are compared against (stored in a directory named
58
+ * `<test-name>.snapshot`).
59
+ *
60
+ * This is as opposed to other snapshots, which can be generated for example
61
+ * temporarily in a temporary directory, to compare agains the golden snapshot.
62
+ */
63
+ class CdkTestApp {
64
+ options;
65
+ testSpecificContext;
66
+ static async forGoldenSnapshot(options) {
67
+ return CdkTestApp.create({
68
+ ...options,
69
+ outputDirectoryNameTemplate: '{testBaseName}.snapshot',
70
+ });
71
+ }
72
+ static async forComparison(options) {
73
+ return CdkTestApp.create({
74
+ ...options,
75
+ outputDirectoryNameTemplate: 'cdk-integ.out.{testBaseName}.snapshot',
76
+ });
77
+ }
78
+ static async forSpecificDirectory(options) {
79
+ return CdkTestApp.create(options);
80
+ }
81
+ static async forDeployment(options) {
82
+ return CdkTestApp.create({
83
+ ...options,
84
+ outputDirectoryNameTemplate: 'cdk-integ.out.deploy.{testBaseName}.snapshot',
85
+ });
86
+ }
87
+ static async create(options) {
88
+ const ctx = await (0, test_specific_context_1.findTestSpecificContext)(options.test.absoluteFileName);
89
+ const app = new CdkTestApp(options, ctx);
90
+ return app;
91
+ }
92
+ /**
93
+ * An instance of the CDK CLI
94
+ */
95
+ cdk;
96
+ outputDirectory;
97
+ /**
98
+ * Default options to pass to the CDK CLI
99
+ */
100
+ defaultArgs = {
101
+ pathMetadata: false,
102
+ assetMetadata: false,
103
+ versionReporting: false,
104
+ };
105
+ /**
106
+ * The profile to use for the CDK CLI calls
107
+ */
108
+ profile;
109
+ /**
110
+ * Show output from the integ test run.
111
+ */
112
+ showOutput;
113
+ test;
114
+ synthReproCommand = '';
115
+ _destructiveChanges;
116
+ legacyContext;
117
+ _testSuite;
118
+ _legacyEnableLookups;
119
+ appCommand;
120
+ hasValidRegion;
121
+ constructor(options, testSpecificContext) {
122
+ this.options = options;
123
+ this.testSpecificContext = testSpecificContext;
124
+ this.hasValidRegion = options.region !== cloud_assembly_api_1.UNKNOWN_REGION;
125
+ this.test = options.test;
126
+ const outputDirectoryNameTemplate = options.outputDirectoryNameTemplate;
127
+ this.outputDirectory = (0, files_1.absAwareJoin)(this.test.testDirectory, this.test.specializeTemplate(outputDirectoryNameTemplate));
128
+ this.profile = options.profile;
129
+ this.showOutput = options.showOutput ?? false;
130
+ this.cdk = options.cdk ?? new toolkit_lib_1.ToolkitLibRunnerEngine({
131
+ workingDirectory: this.test.workingDirectory,
132
+ showOutput: options.showOutput,
133
+ env: options.env,
134
+ region: options.region,
135
+ profile: options.profile,
136
+ proxy: options.proxy,
137
+ caBundlePath: options.caBundlePath,
138
+ });
139
+ this.appCommand = this.test.specializeTemplate(this.test.appCommandTemplate);
140
+ }
141
+ /**
142
+ * Configure the legacy enableLookups value to use when generating the actual snapshot.
143
+ *
144
+ * Must be set before using snapshot methods.
145
+ */
146
+ configureLegacyEnableLookups(enableLookups) {
147
+ this._legacyEnableLookups = enableLookups;
148
+ }
149
+ async hasOutput() {
150
+ return (await fs.pathExists(this.outputDirectory)) && (await fs.pathExists(path.join(this.outputDirectory, 'manifest.json')));
151
+ }
152
+ /**
153
+ * Return the test cases inside the output
154
+ */
155
+ testCases() {
156
+ return this.testSuite.testSuite;
157
+ }
158
+ /**
159
+ * The test suite from the output
160
+ */
161
+ get testSuite() {
162
+ if (!this._testSuite) {
163
+ throw new Error('Synthesize first!');
164
+ }
165
+ return this._testSuite;
166
+ }
167
+ /**
168
+ * If the snapshot already exists, load it
169
+ */
170
+ async loadExistingSuite() {
171
+ if (this._testSuite) {
172
+ return this._testSuite;
173
+ }
174
+ if (await this.hasOutput()) {
175
+ this._testSuite = await this._loadManifest();
176
+ return this._testSuite;
177
+ }
178
+ if (this.options.TESTING_forceReadLegacyTestSuite) {
179
+ return this._loadLegacyTestSuite();
180
+ }
181
+ return undefined;
182
+ }
183
+ async synthForSnapshotComparison(enableLookupsGuess) {
184
+ this.configureLegacyEnableLookups(enableLookupsGuess);
185
+ const suite = await this.synth(this.getContext('snapshot'), exports.DEFAULT_SYNTH_OPTIONS.env);
186
+ // Check if the enableLookups value has changed between the golden
187
+ // snapshot and the actual snapshot. If it has, we need to re-synth the
188
+ // actual snapshot with the new enableLookups value.
189
+ //
190
+ // See `synthActualSnapshot` for a description of why this is necessary.
191
+ const actualEnableLookups = suite.enableLookups ?? false;
192
+ if (actualEnableLookups !== this._legacyEnableLookups && this._legacyEnableLookups !== 'dont-care') {
193
+ this.configureLegacyEnableLookups(actualEnableLookups);
194
+ return this.synth(this.getContext('snapshot'), exports.DEFAULT_SYNTH_OPTIONS.env);
195
+ }
196
+ return suite;
197
+ }
198
+ async synthForGoldenSnapshot(destructiveChanges, enableLookups) {
199
+ this.configureLegacyEnableLookups(enableLookups);
200
+ await this.synth(this.getContext('snapshot'), exports.DEFAULT_SYNTH_OPTIONS.env);
201
+ await this.cleanupGoldenSnapshot(destructiveChanges);
202
+ return this.testSuite;
203
+ }
204
+ async synthForDeployment() {
205
+ this.configureLegacyEnableLookups('dont-care');
206
+ await this.synth(this.getContext('deployment'), {});
207
+ return this.testSuite;
208
+ }
209
+ /**
210
+ * For a given cloud assembly return a collection of all templates
211
+ * that should be part of the snapshot and any required meta data.
212
+ *
213
+ * @param cloudAssemblyDir - The directory of the cloud assembly to look for snapshots
214
+ * @param pickStacks - Pick only these stacks from the cloud assembly
215
+ * @returns A SnapshotAssembly, the collection of all templates in this snapshot and required meta data
216
+ */
217
+ snapshotAssembly(pickStacks = []) {
218
+ const assembly = this.readAssembly(this.outputDirectory);
219
+ const stacks = assembly.stacks;
220
+ const snapshots = {};
221
+ for (const [stackName, stackTemplate] of Object.entries(stacks)) {
222
+ if (pickStacks.includes(stackName)) {
223
+ const manifest = cloud_assembly_1.AssemblyManifestReader.fromPath(this.outputDirectory);
224
+ const assets = manifest.getAssetIdsForStack(stackName);
225
+ snapshots[stackName] = {
226
+ templates: {
227
+ [stackName]: stackTemplate,
228
+ ...assembly.getNestedStacksForStack(stackName),
229
+ },
230
+ assets,
231
+ };
232
+ }
233
+ }
234
+ return snapshots;
235
+ }
236
+ readAssembly(dir) {
237
+ return cloud_assembly_1.AssemblyManifestReader.fromPath(dir);
238
+ }
239
+ /**
240
+ * Synth the actual application to the given directory, for purposes of generating/validating a snapshot
241
+ *
242
+ * `legacyEnableLookups` is to preserve historical behavior for a while:
243
+ * traditionally, the application would only be seeded with context if
244
+ * `enableLookups` was true, and this information would come from the test
245
+ * definition.
246
+ *
247
+ * - Since the test definition comes from inside the app, this requires a
248
+ * synth just to get the test definition, and then another synth to generate
249
+ * the actual snapshot with the correct context, which is time consuming.
250
+ * - Given that the context is fixed and fake, it could always have been passed.
251
+ *
252
+ * However, the snapshot contents themselves depend on the context flag, and changing
253
+ * this behavior now invalidates all snapshots everywhere, which is annoying for upgrading.
254
+ *
255
+ * So we will use the behavior from the GOLDEN SNAPSHOT's test definition to
256
+ * determine whether to pass the context, and if the new actual snapshot has a
257
+ * different value for `enableLookups`, we will throw away the old snapshot and synth again.
258
+ */
259
+ async synth(context, env) {
260
+ const output = this.outputDirectory;
261
+ // Remove the target directory, so that we don't have stale files from
262
+ // previous synths. Also, the runner will re-use a directory that already
263
+ // exists and we want force recreation (unless we are unit testing).
264
+ if (!this.options.TESTING_usingMocks) {
265
+ await fs.rm(output, { recursive: true, force: true });
266
+ }
267
+ await this.cdk.synth({
268
+ app: this.appCommand,
269
+ context,
270
+ env,
271
+ output,
272
+ });
273
+ this.setReproCommand(context, env);
274
+ this._testSuite = await this._loadManifest();
275
+ return this._testSuite;
276
+ }
277
+ async deploy(deployArgs) {
278
+ if (!this.hasValidRegion) {
279
+ throw new Error('CdkTestApp.deploy: not initialized with a valid region');
280
+ }
281
+ return this.cdk.deploy({
282
+ ...exports.DEFAULT_ARGS,
283
+ ...deployArgs,
284
+ output: this.outputDirectory,
285
+ profile: this.profile,
286
+ requireApproval: cloud_assembly_schema_1.RequireApproval.NEVER,
287
+ app: this.appCommand,
288
+ context: {
289
+ ...this.getContext('deployment'),
290
+ ...deployArgs?.context,
291
+ },
292
+ });
293
+ }
294
+ async destroy(destroyArgs) {
295
+ if (!this.hasValidRegion) {
296
+ throw new Error('CdkTestApp.destroy: not initialized with a valid region');
297
+ }
298
+ await this.cdk.destroy({
299
+ ...exports.DEFAULT_ARGS,
300
+ ...destroyArgs,
301
+ app: this.appCommand,
302
+ output: this.outputDirectory,
303
+ profile: this.profile,
304
+ force: true,
305
+ context: {
306
+ ...this.getContext('deployment'),
307
+ ...destroyArgs?.context,
308
+ },
309
+ });
310
+ }
311
+ async watch(watchArgs, watchEvents) {
312
+ if (!this.hasValidRegion) {
313
+ throw new Error('CdkTestApp.watch: not initialized with a valid region');
314
+ }
315
+ await this.cdk.watch({
316
+ ...exports.DEFAULT_ARGS,
317
+ ...watchArgs,
318
+ output: this.outputDirectory,
319
+ profile: this.profile,
320
+ requireApproval: cloud_assembly_schema_1.RequireApproval.NEVER,
321
+ app: this.appCommand,
322
+ context: {
323
+ ...this.getContext('deployment'),
324
+ ...watchArgs?.context,
325
+ },
326
+ }, watchEvents);
327
+ }
328
+ setReproCommand(context, env) {
329
+ // Show the command necessary to repro this
330
+ const envSet = Object.entries(env).map(([k, v]) => `${k}='${v}'`);
331
+ const envCmd = envSet.length > 0 ? ['env', ...envSet] : [];
332
+ this.synthReproCommand = [
333
+ ...envCmd,
334
+ 'cdk',
335
+ 'synth',
336
+ '-a',
337
+ `'${this.appCommand}'`,
338
+ '-o',
339
+ `'${this.outputDirectory}'`,
340
+ ...Object.entries(context).flatMap(([k, v]) => typeof v !== 'object' ? [`-c '${k}=${v}'`] : []),
341
+ ].join(' ');
342
+ }
343
+ /**
344
+ * Load the integ manifest which contains information
345
+ * on how to execute the tests
346
+ * First we try and load the manifest from the integ manifest (i.e. integ.json)
347
+ * from the cloud assembly. If it doesn't exist, then we fallback to the
348
+ * "legacy mode" and create a manifest from pragma
349
+ *
350
+ * @internal
351
+ */
352
+ async _loadManifest() {
353
+ if (!await this.hasOutput() && !this.options.TESTING_usingMocks) {
354
+ throw new Error(`Synth did not produce output directory: ${this.outputDirectory}`);
355
+ }
356
+ const manifestDir = this.outputDirectory;
357
+ try {
358
+ const testSuite = integ_test_suite_1.IntegTestSuite.fromPath(manifestDir);
359
+ return testSuite;
360
+ }
361
+ catch (modernError) {
362
+ // Only attempt legacy test case if the integ test manifest was not found
363
+ // For any other errors, e.g. when parsing the manifest fails, we abort.
364
+ if (!(modernError instanceof integ_manifest_1.NoManifestError)) {
365
+ throw modernError;
366
+ }
367
+ if (this.showOutput) {
368
+ logger.trace("Failed to load integ test manifest for '%s'. Attempting as deprecated legacy test instead. Error was: %s", manifestDir, modernError.message ?? String(modernError));
369
+ }
370
+ return this._loadLegacyTestSuite();
371
+ }
372
+ }
373
+ async _loadLegacyTestSuite() {
374
+ const testCases = await integ_test_suite_1.LegacyIntegTestSuite.fromLegacy({
375
+ cdk: this.cdk,
376
+ testName: this.test.normalizedTestName,
377
+ integSourceFilePath: this.test.fileName,
378
+ listOptions: {
379
+ ...this.defaultArgs,
380
+ all: true,
381
+ app: this.appCommand,
382
+ profile: this.profile,
383
+ output: this.outputDirectory,
384
+ },
385
+ });
386
+ this.legacyContext = integ_test_suite_1.LegacyIntegTestSuite.getPragmaContext(this.test.fileName);
387
+ return testCases;
388
+ }
389
+ cleanup() {
390
+ const cdkOutPath = this.outputDirectory;
391
+ if (fs.existsSync(cdkOutPath)) {
392
+ fs.removeSync(cdkOutPath);
393
+ }
394
+ // Clear cache
395
+ this._testSuite = undefined;
396
+ }
397
+ /**
398
+ * If there are any destructive changes to a stack then this will record
399
+ * those in the manifest.json file
400
+ */
401
+ renderTraceData(destructiveChanges) {
402
+ const traceData = new Map();
403
+ destructiveChanges.forEach(change => {
404
+ const trace = traceData.get(change.stackName);
405
+ if (trace) {
406
+ trace.set(change.logicalId, `${DESTRUCTIVE_CHANGES} ${change.impact}`);
407
+ }
408
+ else {
409
+ traceData.set(change.stackName, new Map([
410
+ [change.logicalId, `${DESTRUCTIVE_CHANGES} ${change.impact}`],
411
+ ]));
412
+ }
413
+ });
414
+ return traceData;
415
+ }
416
+ /**
417
+ * In cases where we do not want to retain the assets,
418
+ * for example, if the assets are very large.
419
+ *
420
+ * Since it is possible to disable the update workflow for individual test
421
+ * cases, this needs to first get a list of stacks that have the update workflow
422
+ * disabled and then delete assets that relate to that stack. It does that
423
+ * by reading the asset manifest for the stack and deleting the asset source
424
+ */
425
+ async removeAssetsFromSnapshot() {
426
+ const stacks = this.testSuite.getStacksWithoutUpdateWorkflow() ?? [];
427
+ const manifest = cloud_assembly_1.AssemblyManifestReader.fromPath(this.outputDirectory);
428
+ const assets = (0, utils_1.flatten)(stacks.map(stack => {
429
+ return manifest.getAssetLocationsForStack(stack) ?? [];
430
+ }));
431
+ assets.forEach(asset => {
432
+ const fileName = path.join(this.outputDirectory, asset);
433
+ if (fs.existsSync(fileName)) {
434
+ if (fs.lstatSync(fileName).isDirectory()) {
435
+ fs.removeSync(fileName);
436
+ }
437
+ else {
438
+ fs.unlinkSync(fileName);
439
+ }
440
+ }
441
+ });
442
+ }
443
+ /**
444
+ * Remove the asset cache (.cache/) files from the snapshot.
445
+ * These are a cache of the asset zips, but we are fine with
446
+ * re-zipping on deploy
447
+ */
448
+ removeAssetsCacheFromSnapshot() {
449
+ const files = fs.readdirSync(this.outputDirectory);
450
+ files.forEach(file => {
451
+ const fileName = path.join(this.outputDirectory, file);
452
+ if (fs.lstatSync(fileName).isDirectory() && file === '.cache') {
453
+ fs.emptyDirSync(fileName);
454
+ fs.rmdirSync(fileName);
455
+ }
456
+ });
457
+ }
458
+ /**
459
+ * Perform some cleanup steps after the snapshot is created
460
+ * Anytime the snapshot needs to be modified after creation
461
+ * the logic should live here.
462
+ */
463
+ async cleanupGoldenSnapshot(destructiveChanges) {
464
+ if (!await this.hasOutput()) {
465
+ // This should not be possible, but a lot of the tests depend on this being a no-op
466
+ // if no output directory got produced.
467
+ return;
468
+ }
469
+ await this.removeAssetsFromSnapshot();
470
+ this.removeAssetsCacheFromSnapshot();
471
+ const assembly = cloud_assembly_1.AssemblyManifestReader.fromPath(this.outputDirectory);
472
+ assembly.cleanManifest();
473
+ assembly.recordTrace(this.renderTraceData(destructiveChanges));
474
+ // if this is a legacy test then create an integ manifest
475
+ // in the snapshot directory which can be used for the
476
+ // update workflow. Save any legacyContext as well so that it can be read
477
+ // the next time
478
+ const actualTestSuite = this.testSuite;
479
+ actualTestSuite.enableLookups = true;
480
+ if (actualTestSuite instanceof integ_test_suite_1.LegacyIntegTestSuite) {
481
+ actualTestSuite.saveManifest(this.outputDirectory, this.legacyContext);
482
+ }
483
+ else if (actualTestSuite instanceof integ_test_suite_1.IntegTestSuite) {
484
+ actualTestSuite.saveManifest(this.outputDirectory);
485
+ }
486
+ }
487
+ getContext(forSnapshot) {
488
+ if (this._legacyEnableLookups === undefined) {
489
+ throw new Error('Must call configureLegacyEnableLookups before synthing');
490
+ }
491
+ // Load the test-specific context (from `integ.context.json` or `cdk.json#context`), if any.
492
+ // If not found, use the built-in current feature flags (at the risk of newer feature flags changing
493
+ // the snapshots).
494
+ const featureFlags = this.testSpecificContext ?? currentlyRecommendedAwsCdkLibFlags();
495
+ return {
496
+ ...featureFlags,
497
+ ...this.legacyContext,
498
+ // The _legacyEnableLookups flag is crazy but is only there to not disturb existing snapshots too much.
499
+ ...(forSnapshot === 'snapshot' && this._legacyEnableLookups !== false ? exports.DEFAULT_SYNTH_OPTIONS.context : {}),
500
+ // Don't record creation stack traces in the snapshot, since they just take up space and are never deterministic.
501
+ 'aws:cdk:disable-creation-stack-traces': true,
502
+ // We originally had PLANNED to set this to ['aws', 'aws-cn'], but due to a programming mistake
503
+ // it was set to everything. In this PR, set it to everything to not mess up all the snapshots.
504
+ '@aws-cdk/core:target-partitions': undefined,
505
+ /* ---------------- THE FUTURE LIVES BELOW----------------------------
506
+ // Restricting to these target partitions makes most service principals synthesize to
507
+ // `service.${URL_SUFFIX}`, which is technically *incorrect* (it's only `amazonaws.com`
508
+ // or `amazonaws.com.cn`, never UrlSuffix for any of the restricted regions) but it's what
509
+ // most existing integ tests contain, and we want to disturb as few as possible.
510
+ // [TARGET_PARTITIONS]: ['aws', 'aws-cn'],
511
+ /* ---------------- END OF THE FUTURE ------------------------------- */
512
+ };
513
+ }
514
+ }
515
+ exports.CdkTestApp = CdkTestApp;
516
+ // Default context we run all integ tests with, so they don't depend on the
517
+ // account of the exercising user.
518
+ exports.DEFAULT_SYNTH_OPTIONS = {
519
+ context: {
520
+ // We have traditionally set this, but it's quite a bad idea. It makes region-agnostic stacks undeployable, and there's really no reason for that.
521
+ // However, if we unset this, we will break many existing snapshots so we keep it for now.
522
+ [cloud_assembly_api_1.AVAILABILITY_ZONE_FALLBACK_CONTEXT_KEY]: ['test-region-1a', 'test-region-1b', 'test-region-1c'],
523
+ 'availability-zones:account=12345678:region=test-region': ['test-region-1a', 'test-region-1b', 'test-region-1c'],
524
+ 'ssm:account=12345678:parameterName=/aws/service/ami-amazon-linux-latest/amzn-ami-hvm-x86_64-gp2:region=test-region': 'ami-1234',
525
+ 'ssm:account=12345678:parameterName=/aws/service/ami-amazon-linux-latest/amzn2-ami-hvm-x86_64-gp2:region=test-region': 'ami-1234',
526
+ 'ssm:account=12345678:parameterName=/aws/service/ecs/optimized-ami/amazon-linux/recommended:region=test-region': '{"image_id": "ami-1234"}',
527
+ // eslint-disable-next-line @stylistic/max-len
528
+ 'ami:account=12345678:filters.image-type.0=machine:filters.name.0=amzn-ami-vpc-nat-*:filters.state.0=available:owners.0=amazon:region=test-region': 'ami-1234',
529
+ 'vpc-provider:account=12345678:filter.isDefault=true:region=test-region:returnAsymmetricSubnets=true': {
530
+ vpcId: 'vpc-60900905',
531
+ subnetGroups: [
532
+ {
533
+ type: 'Public',
534
+ name: 'Public',
535
+ subnets: [
536
+ {
537
+ subnetId: 'subnet-e19455ca',
538
+ availabilityZone: 'us-east-1a',
539
+ routeTableId: 'rtb-e19455ca',
540
+ },
541
+ {
542
+ subnetId: 'subnet-e0c24797',
543
+ availabilityZone: 'us-east-1b',
544
+ routeTableId: 'rtb-e0c24797',
545
+ },
546
+ {
547
+ subnetId: 'subnet-ccd77395',
548
+ availabilityZone: 'us-east-1c',
549
+ routeTableId: 'rtb-ccd77395',
550
+ },
551
+ ],
552
+ },
553
+ ],
554
+ },
555
+ },
556
+ env: {
557
+ CDK_INTEG_ACCOUNT: '12345678',
558
+ CDK_INTEG_REGION: 'test-region',
559
+ CDK_INTEG_HOSTED_ZONE_ID: 'Z23ABC4XYZL05B',
560
+ CDK_INTEG_HOSTED_ZONE_NAME: 'example.com',
561
+ CDK_INTEG_DOMAIN_NAME: '*.example.com',
562
+ CDK_INTEG_CERT_ARN: 'arn:aws:acm:test-region:12345678:certificate/86468209-a272-595d-b831-0efb6421265z',
563
+ CDK_INTEG_SUBNET_ID: 'subnet-0dff1a399d8f6f92c',
564
+ },
565
+ };
566
+ /**
567
+ * Return the currently recommended flags for `aws-cdk-lib`.
568
+ *
569
+ * These have been built into the CLI at build time. If this ever gets changed
570
+ * back to a dynamic load, remember that this source file may be bundled into
571
+ * a JavaScript bundle, and `__dirname` might not point where you think it does.
572
+ */
573
+ function currentlyRecommendedAwsCdkLibFlags() {
574
+ return recommendedFlagsFile;
575
+ }
576
+ /**
577
+ * Default options to pass to the CDK CLI
578
+ */
579
+ exports.DEFAULT_ARGS = {
580
+ pathMetadata: false,
581
+ assetMetadata: false,
582
+ versionReporting: false,
583
+ };
584
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2RrLXRlc3QtYXBwLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiY2RrLXRlc3QtYXBwLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQTJyQkEsZ0ZBRUM7QUE3ckJELGtEQUFrRDtBQUNsRCwyQ0FBNkI7QUFDN0Isb0VBQXFHO0FBQ3JHLDBFQUF3RztBQUN4Ryw2Q0FBK0I7QUFDL0IseURBQTBFO0FBRTFFLGtEQUFvQztBQUNwQyx3RkFBMEU7QUFDMUUsb0NBQW1DO0FBR25DLDZEQUFrRTtBQUVsRSw2REFBMkQ7QUFDM0QsMkVBQTJGO0FBQzNGLHdEQUFnRTtBQUNoRSxvQ0FBd0M7QUFFeEMsTUFBTSxtQkFBbUIsR0FBRyx3QkFBd0IsQ0FBQztBQStGckQ7Ozs7Ozs7OztHQVNHO0FBQ0gsTUFBYSxVQUFVO0lBc0VnQjtJQUE2QztJQXJFM0UsTUFBTSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsQ0FBQyxPQUErRDtRQUNuRyxPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFDdkIsR0FBRyxPQUFPO1lBQ1YsMkJBQTJCLEVBQUUseUJBQXlCO1NBQ3ZELENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLGFBQWEsQ0FBQyxPQUErRDtRQUMvRixPQUFPLFVBQVUsQ0FBQyxNQUFNLENBQUM7WUFDdkIsR0FBRyxPQUFPO1lBQ1YsMkJBQTJCLEVBQUUsdUNBQXVDO1NBQ3JFLENBQUMsQ0FBQztJQUNMLENBQUM7SUFFTSxNQUFNLENBQUMsS0FBSyxDQUFDLG9CQUFvQixDQUFDLE9BQTBCO1FBQ2pFLE9BQU8sVUFBVSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNwQyxDQUFDO0lBRU0sTUFBTSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsT0FBK0Q7UUFDL0YsT0FBTyxVQUFVLENBQUMsTUFBTSxDQUFDO1lBQ3ZCLEdBQUcsT0FBTztZQUNWLDJCQUEy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QkFBaUI7NEJBQzNCLGdCQUFnQixFQUFFLFlBQVk7NEJBQzlCLFlBQVksRUFBRSxjQUFjO3lCQUM3QjtxQkFDRjtpQkFDRjthQUNGO1NBQ0Y7S0FDRjtJQUNELEdBQUcsRUFBRTtRQUNILGlCQUFpQixFQUFFLFVBQVU7UUFDN0IsZ0JBQWdCLEVBQUUsYUFBYTtRQUMvQix3QkFBd0IsRUFBRSxnQkFBZ0I7UUFDMUMsMEJBQTBCLEVBQUUsYUFBYTtRQUN6QyxxQkFBcUIsRUFBRSxlQUFlO1FBQ3RDLGtCQUFrQixFQUFFLG1GQUFtRjtRQUN2RyxtQkFBbUIsRUFBRSwwQkFBMEI7S0FDaEQ7Q0FDRixDQUFDO0FBRUY7Ozs7OztHQU1HO0FBQ0gsU0FBZ0Isa0NBQWtDO0lBQ2hELE9BQU8sb0JBQW9CLENBQUM7QUFDOUIsQ0FBQztBQXFCRDs7R0FFRztBQUNVLFFBQUEsWUFBWSxHQUFzQjtJQUM3QyxZQUFZLEVBQUUsS0FBSztJQUNuQixhQUFhLEVBQUUsS0FBSztJQUNwQixnQkFBZ0IsRUFBRSxLQUFLO0NBQ3hCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBAY2RrbGFicy9uby1saXRlcmFsLXBhcnRpdGlvbiAqL1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7IEFWQUlMQUJJTElUWV9aT05FX0ZBTExCQUNLX0NPTlRFWFRfS0VZLCBVTktOT1dOX1JFR0lPTiB9IGZyb20gJ0Bhd3MtY2RrL2Nsb3VkLWFzc2VtYmx5LWFwaSc7XG5pbXBvcnQgeyB0eXBlIFRlc3RDYXNlLCB0eXBlIERlZmF1bHRDZGtPcHRpb25zLCBSZXF1aXJlQXBwcm92YWwgfSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0ICogYXMgZnMgZnJvbSAnZnMtZXh0cmEnO1xuaW1wb3J0IHsgSW50ZWdUZXN0U3VpdGUsIExlZ2FjeUludGVnVGVzdFN1aXRlIH0gZnJvbSAnLi9pbnRlZy10ZXN0LXN1aXRlJztcbmltcG9ydCB0eXBlIHsgRGVwbG95T3B0aW9ucywgRGVzdHJveU9wdGlvbnMsIElDZGssIFdhdGNoRXZlbnRzIH0gZnJvbSAnLi4vZW5naW5lcy9jZGstaW50ZXJmYWNlJztcbmltcG9ydCAqIGFzIGxvZ2dlciBmcm9tICcuLi9sb2dnZXInO1xuaW1wb3J0ICogYXMgcmVjb21tZW5kZWRGbGFnc0ZpbGUgZnJvbSAnLi4vcmVjb21tZW5kZWQtZmVhdHVyZS1mbGFncy5qc29uJztcbmltcG9ydCB7IGZsYXR0ZW4gfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgdHlwZSB7IEludGVnVGVzdCB9IGZyb20gJy4vaW50ZWdyYXRpb24tdGVzdHMnO1xuaW1wb3J0IHR5cGUgeyBNYW5pZmVzdFRyYWNlIH0gZnJvbSAnLi9wcml2YXRlL2Nsb3VkLWFzc2VtYmx5JztcbmltcG9ydCB7IEFzc2VtYmx5TWFuaWZlc3RSZWFkZXIgfSBmcm9tICcuL3ByaXZhdGUvY2xvdWQtYXNzZW1ibHknO1xuaW1wb3J0IHR5cGUgeyBEZXN0cnVjdGl2ZUNoYW5nZSB9IGZyb20gJy4uL3dvcmtlcnMvY29tbW9uJztcbmltcG9ydCB7IE5vTWFuaWZlc3RFcnJvciB9IGZyb20gJy4vcHJpdmF0ZS9pbnRlZy1tYW5pZmVzdCc7XG5pbXBvcnQgeyBmaW5kVGVzdFNwZWNpZmljQ29udGV4dCwgdHlwZSBDZGtDb250ZXh0IH0gZnJvbSAnLi9wcml2YXRlL3Rlc3Qtc3BlY2lmaWMtY29udGV4dCc7XG5pbXBvcnQgeyBUb29sa2l0TGliUnVubmVyRW5naW5lIH0gZnJvbSAnLi4vZW5naW5lcy90b29sa2l0LWxpYic7XG5pbXBvcnQgeyBhYnNBd2FyZUpvaW4gfSBmcm9tICcuLi9maWxlcyc7XG5cbmNvbnN0IERFU1RSVUNUSVZFX0NIQU5HRVMgPSAnISFERVNUUlVDVElWRV9DSEFOR0VTOic7XG5cbi8qKlxuICogT3B0aW9ucyBmb3IgY3JlYXRpbmcgYSBDREsgQ2xvdWQgQXNzZW1ibHlcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBDZGtUZXN0QXBwT3B0aW9ucyB7XG4gIHJlYWRvbmx5IHRlc3Q6IEludGVnVGVzdDtcblxuICAvKipcbiAgICogVGhlIHJlZ2lvbiB3aGVyZSB0aGUgdGVzdCBzaG91bGQgYmUgZGVwbG95ZWRcbiAgICovXG4gIHJlYWRvbmx5IHJlZ2lvbj86IHN0cmluZztcblxuICAvKipcbiAgICogVGhlIEFXUyBwcm9maWxlIHRvIHVzZSB3aGVuIGludm9raW5nIHRoZSBDREsgQ0xJXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gcHJvZmlsZSBpcyBwYXNzZWQsIHRoZSBkZWZhdWx0IHByb2ZpbGUgaXMgdXNlZFxuICAgKi9cbiAgcmVhZG9ubHkgcHJvZmlsZT86IHN0cmluZztcblxuICAvKipcbiAgICogQWRkaXRpb25hbCBlbnZpcm9ubWVudCB2YXJpYWJsZXMgdGhhdCB3aWxsIGJlIGF2YWlsYWJsZVxuICAgKiB0byB0aGUgQ0RLIENMSVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIGFkZGl0aW9uYWwgZW52aXJvbm1lbnQgdmFyaWFibGVzXG4gICAqL1xuICByZWFkb25seSBlbnY/OiB7IFtuYW1lOiBzdHJpbmddOiBzdHJpbmcgfTtcblxuICAvKipcbiAgICogV2hlcmUgd2Ugd2lsbCB3cml0ZSB0aGUgb3V0cHV0IG9mIHRoZSBDREsgQ0xJLCBpbmNsdWRpbmcgdGhlIGNsb3VkIGFzc2VtYmx5IGFuZCB0aGUgc25hcHNob3RcbiAgICpcbiAgICogU2hvdWxkIGJlIGEgc3RyaW5nIGNvbnRhaW5pbmcgYHt0ZXN0TmFtZX1gLCB3aWxsIGJlIHVzZWQgdG8gZ2VuZXJhdGUgYSBkaXJlY3RvcnkgbmFtZSBpbiB0aGUgc2FtZVxuICAgKiBkaXJlY3RvcnkgYXMgdGhlIHRlc3QgaXRzZWxmLlxuICAgKlxuICAgKiBAZGVmYXVsdCAnY2RrLWludGVnLm91dC57dGVzdE5hbWV9LnNuYXBzaG90J1xuICAgKi9cbiAgcmVhZG9ubHkgb3V0cHV0RGlyZWN0b3J5TmFtZVRlbXBsYXRlOiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEluc3RhbmNlIG9mIHRoZSBDREsgVG9vbGtpdCBFbmdpbmUgdG8gdXNlXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gYmFzZWQgb24gYGVuZ2luZWAgb3B0aW9uXG4gICAqL1xuICByZWFkb25seSBjZGs/OiBJQ2RrO1xuXG4gIC8qKlxuICAgKiBTaG93IG91dHB1dCBmcm9tIHJ1bm5pbmcgaW50ZWdyYXRpb24gdGVzdHNcbiAgICpcbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIHJlYWRvbmx5IHNob3dPdXRwdXQ/OiBib29sZWFuO1xuXG4gIC8qKlxuICAgKiBVc2UgdGhlIGluZGljYXRlZCBwcm94eVxuICAgKlxuICAgKiBAZGVmYXVsdCAtIG5vIHByb3h5XG4gICAqL1xuICByZWFkb25seSBwcm94eT86IHN0cmluZztcblxuICAvKipcbiAgICogUGF0aCB0byBDQSBjZXJ0aWZpY2F0ZSB0byB1c2Ugd2hlbiB2YWxpZGF0aW5nIEhUVFBTIHJlcXVlc3RzXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gbm8gYWRkaXRpb25hbCBDQSBidW5kbGVcbiAgICovXG4gIHJlYWRvbmx5IGNhQnVuZGxlUGF0aD86IHN0cmluZztcblxuICAvKipcbiAgICogSW4gdW5pdCB0ZXN0IG1vZGUsIHdlIGFyZSB1c2luZyBtb2NrcyBmb3IgYSBsb3Qgb2YgY2FsbHNcbiAgICpcbiAgICogRG9uJ3QgZGVsZXRlIGRpcmVjdG9yaWVzLCBhbmQgZG9uJ3QgZG8gY2hlY2tzIHdoZXRoZXIgZmlsZXMgYWN0dWFsbHkgZXhpc3Q7IHRoZVxuICAgKiBtb2NrcyB3aWxsIGJlIHRoZXJlIHRvIHByb2R1Y2UgdGhlIGNvbnRlbnRzIGZvciBmaWxlcyB0aGF0IGFyZSBiZWluZyByZWFkIChhbHRob3VnaFxuICAgKiB0aGV5IGFyZSBub3QgdGhlcmUgdG8gcHJldGVuZCB0byBoYXZlIGZpbGVzIHRoZW1zZWx2ZXMpLlxuICAgKi9cbiAgcmVhZG9ubHkgVEVTVElOR191c2luZ01vY2tzPzogYm9vbGVhbjtcblxuICAvKipcbiAgICogV2Ugd2lsbCBvbmx5IHJlYWQgdGhlIGxlZ2FjeSB0ZXN0IGluZm9ybWF0aW9uIGlmIHRoZSB0ZXN0IGFjdHVhbGx5IHByb2R1Y2VkIGFuIG91dHB1dCBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEZvciBoaXN0b3JpY2FsIHJlYXNvbnMgdGhlIHRlc3RzIGhhdmUgYmVlbiB3cml0dGVuIHNvIHRoYXQgdGhleSB3aWxsIGV4cGVjdCB0byByZWFkXG4gICAqIGxlZ2FjeSB0ZXN0IGluZm9ybWF0aW9uIGFsd2F5cy4gRm9yY2UgdGhhdCBiZWhhdmlvciBiYWNrIGZvciB0ZXN0cy5cbiAgICovXG4gIHJlYWRvbmx5IFRFU1RJTkdfZm9yY2VSZWFkTGVnYWN5VGVzdFN1aXRlPzogYm9vbGVhbjtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIHRvIHN5bnRoZXNpemUgdGhlIGFjdHVhbCBzbmFwc2hvdCB3aXRoIGxvb2t1cHMgZW5hYmxlZCBvciBub3QuXG4gKlxuICogSWYgZWl0aGVyIGB0cnVlYCBvciBgZmFsc2VgLCB3ZSBzZW5kIGNvbnRleHQgaW4gb3Igbm90IHdoaWxlIHN5bnRoZXNpemluZyxcbiAqIGFuZCBpZiB0aGUgZ2VuZXJhdGVkIHNuYXBzaG90IHRlc3QgZGVmaW5pdGlvbiByZXF1ZXN0cyBhIGRpZmZlcmVudCB2YWx1ZSB3ZVxuICogd2lsbCBzeW50aCBhZ2Fpbi5cbiAqXG4gKiBGb3IgYGRvbnQtY2FyZWAsIHdlIGRvIHNlbmQgaW4gdGhlIGNvbnRleHQgYnV0IHdlIG5ldmVyIHJlc3ludGguXG4gKi9cbmV4cG9ydCB0eXBlIExlZ2FjeUVuYWJsZUxvb2t1cHMgPSB0cnVlIHwgZmFsc2UgfCAnZG9udC1jYXJlJztcblxuLyoqXG4gKiBDbGFzcyB3aXRoIHNvbWUgaGVscGVyIHJvdXRpbmVzIGZvciBydW5uaW5nIENESyBzbmFwc2hvdHMgYW5kIGludGVncmF0aW9uIHRlc3RzLlxuICpcbiAqIEEgXCJnb2xkZW4gc25hcHNob3RcIiBpcyB0aGUgc25hcHNob3QgdGhhdCBpcyBzdG9yZWQgcGVybWFuZW50bHkgaW4gdmVyc2lvblxuICogY29udHJvbCwgdGhhdCBuZXcgcnVucyBhcmUgY29tcGFyZWQgYWdhaW5zdCAoc3RvcmVkIGluIGEgZGlyZWN0b3J5IG5hbWVkXG4gKiBgPHRlc3QtbmFtZT4uc25hcHNob3RgKS5cbiAqXG4gKiBUaGlzIGlzIGFzIG9wcG9zZWQgdG8gb3RoZXIgc25hcHNob3RzLCB3aGljaCBjYW4gYmUgZ2VuZXJhdGVkIGZvciBleGFtcGxlXG4gKiB0ZW1wb3JhcmlseSBpbiBhIHRlbXBvcmFyeSBkaXJlY3RvcnksIHRvIGNvbXBhcmUgYWdhaW5zIHRoZSBnb2xkZW4gc25hcHNob3QuXG4gKi9cbmV4cG9ydCBjbGFzcyBDZGtUZXN0QXBwIHtcbiAgcHVibGljIHN0YXRpYyBhc3luYyBmb3JHb2xkZW5TbmFwc2hvdChvcHRpb25zOiBPbWl0PENka1Rlc3RBcHBPcHRpb25zLCAnb3V0cHV0RGlyZWN0b3J5TmFtZVRlbXBsYXRlJz4pOiBQcm9taXNlPENka1Rlc3RBcHA+IHtcbiAgICByZXR1cm4gQ2RrVGVzdEFwcC5jcmVhdGUoe1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIG91dHB1dERpcmVjdG9yeU5hbWVUZW1wbGF0ZTogJ3t0ZXN0QmFzZU5hbWV9LnNuYXBzaG90JyxcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZm9yQ29tcGFyaXNvbihvcHRpb25zOiBPbWl0PENka1Rlc3RBcHBPcHRpb25zLCAnb3V0cHV0RGlyZWN0b3J5TmFtZVRlbXBsYXRlJz4pOiBQcm9taXNlPENka1Rlc3RBcHA+IHtcbiAgICByZXR1cm4gQ2RrVGVzdEFwcC5jcmVhdGUoe1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIG91dHB1dERpcmVjdG9yeU5hbWVUZW1wbGF0ZTogJ2Nkay1pbnRlZy5vdXQue3Rlc3RCYXNlTmFtZX0uc25hcHNob3QnLFxuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHN0YXRpYyBhc3luYyBmb3JTcGVjaWZpY0RpcmVjdG9yeShvcHRpb25zOiBDZGtUZXN0QXBwT3B0aW9ucyk6IFByb21pc2U8Q2RrVGVzdEFwcD4ge1xuICAgIHJldHVybiBDZGtUZXN0QXBwLmNyZWF0ZShvcHRpb25zKTtcbiAgfVxuXG4gIHB1YmxpYyBzdGF0aWMgYXN5bmMgZm9yRGVwbG95bWVudChvcHRpb25zOiBPbWl0PENka1Rlc3RBcHBPcHRpb25zLCAnb3V0cHV0RGlyZWN0b3J5TmFtZVRlbXBsYXRlJz4pOiBQcm9taXNlPENka1Rlc3RBcHA+IHtcbiAgICByZXR1cm4gQ2RrVGVzdEFwcC5jcmVhdGUoe1xuICAgICAgLi4ub3B0aW9ucyxcbiAgICAgIG91dHB1dERpcmVjdG9yeU5hbWVUZW1wbGF0ZTogJ2Nkay1pbnRlZy5vdXQuZGVwbG95Lnt0ZXN0QmFzZU5hbWV9LnNuYXBzaG90JyxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGFzeW5jIGNyZWF0ZShvcHRpb25zOiBDZGtUZXN0QXBwT3B0aW9ucyk6IFByb21pc2U8Q2RrVGVzdEFwcD4ge1xuICAgIGNvbnN0IGN0eCA9IGF3YWl0IGZpbmRUZXN0U3BlY2lmaWNDb250ZXh0KG9wdGlvbnMudGVzdC5hYnNvbHV0ZUZpbGVOYW1lKTtcbiAgICBjb25zdCBhcHAgPSBuZXcgQ2RrVGVzdEFwcChvcHRpb25zLCBjdHgpO1xuICAgIHJldHVybiBhcHA7XG4gIH1cblxuICAvKipcbiAgICogQW4gaW5zdGFuY2Ugb2YgdGhlIENESyAgQ0xJXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGNkazogSUNkaztcblxuICBwdWJsaWMgcmVhZG9ubHkgb3V0cHV0RGlyZWN0b3J5OiBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgb3B0aW9ucyB0byBwYXNzIHRvIHRoZSBDREsgQ0xJXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGRlZmF1bHRBcmdzOiBEZWZhdWx0Q2RrT3B0aW9ucyA9IHtcbiAgICBwYXRoTWV0YWRhdGE6IGZhbHNlLFxuICAgIGFzc2V0TWV0YWRhdGE6IGZhbHNlLFxuICAgIHZlcnNpb25SZXBvcnRpbmc6IGZhbHNlLFxuICB9O1xuXG4gIC8qKlxuICAgKiBUaGUgcHJvZmlsZSB0byB1c2UgZm9yIHRoZSBDREsgQ0xJIGNhbGxzXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgcHJvZmlsZT86IHN0cmluZztcblxuICAvKipcbiAgICogU2hvdyBvdXRwdXQgZnJvbSB0aGUgaW50ZWcgdGVzdCBydW4uXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHNob3dPdXRwdXQ6IGJvb2xlYW47XG5cbiAgcHVibGljIHJlYWRvbmx5IHRlc3Q6IEludGVnVGVzdDtcblxuICBwdWJsaWMgc3ludGhSZXByb0NvbW1hbmQ6IHN0cmluZyA9ICcnO1xuXG4gIHB1YmxpYyBfZGVzdHJ1Y3RpdmVDaGFuZ2VzPzogRGVzdHJ1Y3RpdmVDaGFuZ2VbXTtcbiAgcHJpdmF0ZSBsZWdhY3lDb250ZXh0PzogUmVjb3JkPHN0cmluZywgYW55PjtcbiAgcHJpdmF0ZSBfdGVzdFN1aXRlPzogSW50ZWdUZXN0U3VpdGUgfCBMZWdhY3lJbnRlZ1Rlc3RTdWl0ZTtcbiAgcHJpdmF0ZSBfbGVnYWN5RW5hYmxlTG9va3Vwcz86IExlZ2FjeUVuYWJsZUxvb2t1cHM7XG5cbiAgcHVibGljIHJlYWRvbmx5IGFwcENvbW1hbmQ6IHN0cmluZztcbiAgcHJpdmF0ZSBoYXNWYWxpZFJlZ2lvbjogYm9vbGVhbjtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKHByaXZhdGUgcmVhZG9ubHkgb3B0aW9uczogQ2RrVGVzdEFwcE9wdGlvbnMsIHByaXZhdGUgcmVhZG9ubHkgdGVzdFNwZWNpZmljQ29udGV4dD86IENka0NvbnRleHQpIHtcbiAgICB0aGlzLmhhc1ZhbGlkUmVnaW9uID0gb3B0aW9ucy5yZWdpb24gIT09IFVOS05PV05fUkVHSU9OO1xuXG4gICAgdGhpcy50ZXN0ID0gb3B0aW9ucy50ZXN0O1xuXG4gICAgY29uc3Qgb3V0cHV0RGlyZWN0b3J5TmFtZVRlbXBsYXRlID0gb3B0aW9ucy5vdXRwdXREaXJlY3RvcnlOYW1lVGVtcGxhdGU7XG4gICAgdGhpcy5vdXRwdXREaXJlY3RvcnkgPSBhYnNBd2FyZUpvaW4odGhpcy50ZXN0LnRlc3REaXJlY3RvcnksIHRoaXMudGVzdC5zcGVjaWFsaXplVGVtcGxhdGUob3V0cHV0RGlyZWN0b3J5TmFtZVRlbXBsYXRlKSk7XG5cbiAgICB0aGlzLnByb2ZpbGUgPSBvcHRpb25zLnByb2ZpbGU7XG4gICAgdGhpcy5zaG93T3V0cHV0ID0gb3B0aW9ucy5zaG93T3V0cHV0ID8/IGZhbHNlO1xuXG4gICAgdGhpcy5jZGsgPSBvcHRpb25zLmNkayA/PyBuZXcgVG9vbGtpdExpYlJ1bm5lckVuZ2luZSh7XG4gICAgICB3b3JraW5nRGlyZWN0b3J5OiB0aGlzLnRlc3Qud29ya2luZ0RpcmVjdG9yeSxcbiAgICAgIHNob3dPdXRwdXQ6IG9wdGlvbnMuc2hvd091dHB1dCxcbiAgICAgIGVudjogb3B0aW9ucy5lbnYsXG4gICAgICByZWdpb246IG9wdGlvbnMucmVnaW9uLFxuICAgICAgcHJvZmlsZTogb3B0aW9ucy5wcm9maWxlLFxuICAgICAgcHJveHk6IG9wdGlvbnMucHJveHksXG4gICAgICBjYUJ1bmRsZVBhdGg6IG9wdGlvbnMuY2FCdW5kbGVQYXRoLFxuICAgIH0pO1xuXG4gICAgdGhpcy5hcHBDb21tYW5kID0gdGhpcy50ZXN0LnNwZWNpYWxpemVUZW1wbGF0ZSh0aGlzLnRlc3QuYXBwQ29tbWFuZFRlbXBsYXRlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmUgdGhlIGxlZ2FjeSBlbmFibGVMb29rdXBzIHZhbHVlIHRvIHVzZSB3aGVuIGdlbmVyYXRpbmcgdGhlIGFjdHVhbCBzbmFwc2hvdC5cbiAgICpcbiAgICogTXVzdCBiZSBzZXQgYmVmb3JlIHVzaW5nIHNuYXBzaG90IG1ldGhvZHMuXG4gICAqL1xuICBwdWJsaWMgY29uZmlndXJlTGVnYWN5RW5hYmxlTG9va3VwcyhlbmFibGVMb29rdXBzOiBMZWdhY3lFbmFibGVMb29rdXBzKTogdm9pZCB7XG4gICAgdGhpcy5fbGVnYWN5RW5hYmxlTG9va3VwcyA9IGVuYWJsZUxvb2t1cHM7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgaGFzT3V0cHV0KCkge1xuICAgIHJldHVybiAoYXdhaXQgZnMucGF0aEV4aXN0cyh0aGlzLm91dHB1dERpcmVjdG9yeSkpICYmIChhd2FpdCBmcy5wYXRoRXhpc3RzKHBhdGguam9pbih0aGlzLm91dHB1dERpcmVjdG9yeSwgJ21hbmlmZXN0Lmpzb24nKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgdGVzdCBjYXNlcyBpbnNpZGUgdGhlIG91dHB1dFxuICAgKi9cbiAgcHVibGljIHRlc3RDYXNlcygpOiB7IFt0ZXN0TmFtZTogc3RyaW5nXTogVGVzdENhc2UgfSB7XG4gICAgcmV0dXJuIHRoaXMudGVzdFN1aXRlLnRlc3RTdWl0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGVzdCBzdWl0ZSBmcm9tIHRoZSBvdXRwdXRcbiAgICovXG4gIHB1YmxpYyBnZXQgdGVzdFN1aXRlKCk6IEludGVnVGVzdFN1aXRlIHwgTGVnYWN5SW50ZWdUZXN0U3VpdGUge1xuICAgIGlmICghdGhpcy5fdGVzdFN1aXRlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1N5bnRoZXNpemUgZmlyc3QhJyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuX3Rlc3RTdWl0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiB0aGUgc25hcHNob3QgYWxyZWFkeSBleGlzdHMsIGxvYWQgaXRcbiAgICovXG4gIHB1YmxpYyBhc3luYyBsb2FkRXhpc3RpbmdTdWl0ZSgpOiBQcm9taXNlPEludGVnVGVzdFN1aXRlIHwgTGVnYWN5SW50ZWdUZXN0U3VpdGUgfCB1bmRlZmluZWQ+IHtcbiAgICBpZiAodGhpcy5fdGVzdFN1aXRlKSB7XG4gICAgICByZXR1cm4gdGhpcy5fdGVzdFN1aXRlO1xuICAgIH1cblxuICAgIGlmIChhd2FpdCB0aGlzLmhhc091dHB1dCgpKSB7XG4gICAgICB0aGlzLl90ZXN0U3VpdGUgPSBhd2FpdCB0aGlzLl9sb2FkTWFuaWZlc3QoKTtcbiAgICAgIHJldHVybiB0aGlzLl90ZXN0U3VpdGU7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMub3B0aW9ucy5URVNUSU5HX2ZvcmNlUmVhZExlZ2FjeVRlc3RTdWl0ZSkge1xuICAgICAgcmV0dXJuIHRoaXMuX2xvYWRMZWdhY3lUZXN0U3VpdGUoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHN5bnRoRm9yU25hcHNob3RDb21wYXJpc29uKGVuYWJsZUxvb2t1cHNHdWVzczogTGVnYWN5RW5hYmxlTG9va3Vwcykge1xuICAgIHRoaXMuY29uZmlndXJlTGVnYWN5RW5hYmxlTG9va3VwcyhlbmFibGVMb29rdXBzR3Vlc3MpO1xuICAgIGNvbnN0IHN1aXRlID0gYXdhaXQgdGhpcy5zeW50aCh0aGlzLmdldENvbnRleHQoJ3NuYXBzaG90JyksIERFRkFVTFRfU1lOVEhfT1BUSU9OUy5lbnYpO1xuXG4gICAgLy8gQ2hlY2sgaWYgdGhlIGVuYWJsZUxvb2t1cHMgdmFsdWUgaGFzIGNoYW5nZWQgYmV0d2VlbiB0aGUgZ29sZGVuXG4gICAgLy8gc25hcHNob3QgYW5kIHRoZSBhY3R1YWwgc25hcHNob3QuIElmIGl0IGhhcywgd2UgbmVlZCB0byByZS1zeW50aCB0aGVcbiAgICAvLyBhY3R1YWwgc25hcHNob3Qgd2l0aCB0aGUgbmV3IGVuYWJsZUxvb2t1cHMgdmFsdWUuXG4gICAgLy9cbiAgICAvLyBTZWUgYHN5bnRoQWN0dWFsU25hcHNob3RgIGZvciBhIGRlc2NyaXB0aW9uIG9mIHdoeSB0aGlzIGlzIG5lY2Vzc2FyeS5cbiAgICBjb25zdCBhY3R1YWxFbmFibGVMb29rdXBzID0gc3VpdGUuZW5hYmxlTG9va3VwcyA/PyBmYWxzZTtcbiAgICBpZiAoYWN0dWFsRW5hYmxlTG9va3VwcyAhPT0gdGhpcy5fbGVnYWN5RW5hYmxlTG9va3VwcyAmJiB0aGlzLl9sZWdhY3lFbmFibGVMb29rdXBzICE9PSAnZG9udC1jYXJlJykge1xuICAgICAgdGhpcy5jb25maWd1cmVMZWdhY3lFbmFibGVMb29rdXBzKGFjdHVhbEVuYWJsZUxvb2t1cHMpO1xuICAgICAgcmV0dXJuIHRoaXMuc3ludGgodGhpcy5nZXRDb250ZXh0KCdzbmFwc2hvdCcpLCBERUZBVUxUX1NZTlRIX09QVElPTlMuZW52KTtcbiAgICB9XG4gICAgcmV0dXJuIHN1aXRlO1xuICB9XG5cbiAgcHVibGljIGFzeW5jIHN5bnRoRm9yR29sZGVuU25hcHNob3QoZGVzdHJ1Y3RpdmVDaGFuZ2VzOiBEZXN0cnVjdGl2ZUNoYW5nZVtdLCBlbmFibGVMb29rdXBzOiBMZWdhY3lFbmFibGVMb29rdXBzKSB7XG4gICAgdGhpcy5jb25maWd1cmVMZWdhY3lFbmFibGVMb29rdXBzKGVuYWJsZUxvb2t1cHMpO1xuICAgIGF3YWl0IHRoaXMuc3ludGgodGhpcy5nZXRDb250ZXh0KCdzbmFwc2hvdCcpLCBERUZBVUxUX1NZTlRIX09QVElPTlMuZW52KTtcbiAgICBhd2FpdCB0aGlzLmNsZWFudXBHb2xkZW5TbmFwc2hvdChkZXN0cnVjdGl2ZUNoYW5nZXMpO1xuICAgIHJldHVybiB0aGlzLnRlc3RTdWl0ZTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBzeW50aEZvckRlcGxveW1lbnQoKSB7XG4gICAgdGhpcy5jb25maWd1cmVMZWdhY3lFbmFibGVMb29rdXBzKCdkb250LWNhcmUnKTtcbiAgICBhd2FpdCB0aGlzLnN5bnRoKHRoaXMuZ2V0Q29udGV4dCgnZGVwbG95bWVudCcpLCB7fSk7XG4gICAgcmV0dXJuIHRoaXMudGVzdFN1aXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvciBhIGdpdmVuIGNsb3VkIGFzc2VtYmx5IHJldHVybiBhIGNvbGxlY3Rpb24gb2YgYWxsIHRlbXBsYXRlc1xuICAgKiB0aGF0IHNob3VsZCBiZSBwYXJ0IG9mIHRoZSBzbmFwc2hvdCBhbmQgYW55IHJlcXVpcmVkIG1ldGEgZGF0YS5cbiAgICpcbiAgICogQHBhcmFtIGNsb3VkQXNzZW1ibHlEaXIgLSBUaGUgZGlyZWN0b3J5IG9mIHRoZSBjbG91ZCBhc3NlbWJseSB0byBsb29rIGZvciBzbmFwc2hvdHNcbiAgICogQHBhcmFtIHBpY2tTdGFja3MgLSBQaWNrIG9ubHkgdGhlc2Ugc3RhY2tzIGZyb20gdGhlIGNsb3VkIGFzc2VtYmx5XG4gICAqIEByZXR1cm5zIEEgU25hcHNob3RBc3NlbWJseSwgdGhlIGNvbGxlY3Rpb24gb2YgYWxsIHRlbXBsYXRlcyBpbiB0aGlzIHNuYXBzaG90IGFuZCByZXF1aXJlZCBtZXRhIGRhdGFcbiAgICovXG4gIHB1YmxpYyBzbmFwc2hvdEFzc2VtYmx5KHBpY2tTdGFja3M6IHN0cmluZ1tdID0gW10pOiBTbmFwc2hvdEFzc2VtYmx5IHtcbiAgICBjb25zdCBhc3NlbWJseSA9IHRoaXMucmVhZEFzc2VtYmx5KHRoaXMub3V0cHV0RGlyZWN0b3J5KTtcbiAgICBjb25zdCBzdGFja3MgPSBhc3NlbWJseS5zdGFja3M7XG4gICAgY29uc3Qgc25hcHNob3RzOiBTbmFwc2hvdEFzc2VtYmx5ID0ge307XG4gICAgZm9yIChjb25zdCBbc3RhY2tOYW1lLCBzdGFja1RlbXBsYXRlXSBvZiBPYmplY3QuZW50cmllcyhzdGFja3MpKSB7XG4gICAgICBpZiAocGlja1N0YWNrcy5pbmNsdWRlcyhzdGFja05hbWUpKSB7XG4gICAgICAgIGNvbnN0IG1hbmlmZXN0ID0gQXNzZW1ibHlNYW5pZmVzdFJlYWRlci5mcm9tUGF0aCh0aGlzLm91dHB1dERpcmVjdG9yeSk7XG4gICAgICAgIGNvbnN0IGFzc2V0cyA9IG1hbmlmZXN0LmdldEFzc2V0SWRzRm9yU3RhY2soc3RhY2tOYW1lKTtcblxuICAgICAgICBzbmFwc2hvdHNbc3RhY2tOYW1lXSA9IHtcbiAgICAgICAgICB0ZW1wbGF0ZXM6IHtcbiAgICAgICAgICAgIFtzdGFja05hbWVdOiBzdGFja1RlbXBsYXRlLFxuICAgICAgICAgICAgLi4uYXNzZW1ibHkuZ2V0TmVzdGVkU3RhY2tzRm9yU3RhY2soc3RhY2tOYW1lKSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIGFzc2V0cyxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gc25hcHNob3RzO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkQXNzZW1ibHkoZGlyOiBzdHJpbmcpOiBBc3NlbWJseU1hbmlmZXN0UmVhZGVyIHtcbiAgICByZXR1cm4gQXNzZW1ibHlNYW5pZmVzdFJlYWRlci5mcm9tUGF0aChkaXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN5bnRoIHRoZSBhY3R1YWwgYXBwbGljYXRpb24gdG8gdGhlIGdpdmVuIGRpcmVjdG9yeSwgZm9yIHB1cnBvc2VzIG9mIGdlbmVyYXRpbmcvdmFsaWRhdGluZyBhIHNuYXBzaG90XG4gICAqXG4gICAqIGBsZWdhY3lFbmFibGVMb29rdXBzYCBpcyB0byBwcmVzZXJ2ZSBoaXN0b3JpY2FsIGJlaGF2aW9yIGZvciBhIHdoaWxlOlxuICAgKiB0cmFkaXRpb25hbGx5LCB0aGUgYXBwbGljYXRpb24gd291bGQgb25seSBiZSBzZWVkZWQgd2l0aCBjb250ZXh0IGlmXG4gICAqIGBlbmFibGVMb29rdXBzYCB3YXMgdHJ1ZSwgYW5kIHRoaXMgaW5mb3JtYXRpb24gd291bGQgY29tZSBmcm9tIHRoZSB0ZXN0XG4gICAqIGRlZmluaXRpb24uXG4gICAqXG4gICAqIC0gU2luY2UgdGhlIHRlc3QgZGVmaW5pdGlvbiBjb21lcyBmcm9tIGluc2lkZSB0aGUgYXBwLCB0aGlzIHJlcXVpcmVzIGFcbiAgICogICBzeW50aCBqdXN0IHRvIGdldCB0aGUgdGVzdCBkZWZpbml0aW9uLCBhbmQgdGhlbiBhbm90aGVyIHN5bnRoIHRvIGdlbmVyYXRlXG4gICAqICAgdGhlIGFjdHVhbCBzbmFwc2hvdCB3aXRoIHRoZSBjb3JyZWN0IGNvbnRleHQsIHdoaWNoIGlzIHRpbWUgY29uc3VtaW5nLlxuICAgKiAtIEdpdmVuIHRoYXQgdGhlIGNvbnRleHQgaXMgZml4ZWQgYW5kIGZha2UsIGl0IGNvdWxkIGFsd2F5cyBoYXZlIGJlZW4gcGFzc2VkLlxuICAgKlxuICAgKiBIb3dldmVyLCB0aGUgc25hcHNob3QgY29udGVudHMgdGhlbXNlbHZlcyBkZXBlbmQgb24gdGhlIGNvbnRleHQgZmxhZywgYW5kIGNoYW5naW5nXG4gICAqIHRoaXMgYmVoYXZpb3Igbm93IGludmFsaWRhdGVzIGFsbCBzbmFwc2hvdHMgZXZlcnl3aGVyZSwgd2hpY2ggaXMgYW5ub3lpbmcgZm9yIHVwZ3JhZGluZy5cbiAgICpcbiAgICogU28gd2Ugd2lsbCB1c2UgdGhlIGJlaGF2aW9yIGZyb20gdGhlIEdPTERFTiBTTkFQU0hPVCdzIHRlc3QgZGVmaW5pdGlvbiB0b1xuICAgKiBkZXRlcm1pbmUgd2hldGhlciB0byBwYXNzIHRoZSBjb250ZXh0LCBhbmQgaWYgdGhlIG5ldyBhY3R1YWwgc25hcHNob3QgaGFzIGFcbiAgICogZGlmZmVyZW50IHZhbHVlIGZvciBgZW5hYmxlTG9va3Vwc2AsIHdlIHdpbGwgdGhyb3cgYXdheSB0aGUgb2xkIHNuYXBzaG90IGFuZCBzeW50aCBhZ2Fpbi5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgc3ludGgoY29udGV4dDogUmVjb3JkPHN0cmluZywgYW55PiwgZW52OiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+KTogUHJvbWlzZTxJbnRlZ1Rlc3RTdWl0ZSB8IExlZ2FjeUludGVnVGVzdFN1aXRlPiB7XG4gICAgY29uc3Qgb3V0cHV0ID0gdGhpcy5vdXRwdXREaXJlY3Rvcnk7XG5cbiAgICAvLyBSZW1vdmUgdGhlIHRhcmdldCBkaXJlY3RvcnksIHNvIHRoYXQgd2UgZG9uJ3QgaGF2ZSBzdGFsZSBmaWxlcyBmcm9tXG4gICAgLy8gcHJldmlvdXMgc3ludGhzLiBBbHNvLCB0aGUgcnVubmVyIHdpbGwgcmUtdXNlIGEgZGlyZWN0b3J5IHRoYXQgYWxyZWFkeVxuICAgIC8vIGV4aXN0cyBhbmQgd2Ugd2FudCBmb3JjZSByZWNyZWF0aW9uICh1bmxlc3Mgd2UgYXJlIHVuaXQgdGVzdGluZykuXG4gICAgaWYgKCF0aGlzLm9wdGlvbnMuVEVTVElOR191c2luZ01vY2tzKSB7XG4gICAgICBhd2FpdCBmcy5ybShvdXRwdXQsIHsgcmVjdXJzaXZlOiB0cnVlLCBmb3JjZTogdHJ1ZSB9KTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmNkay5zeW50aCh7XG4gICAgICBhcHA6IHRoaXMuYXBwQ29tbWFuZCxcbiAgICAgIGNvbnRleHQsXG4gICAgICBlbnYsXG4gICAgICBvdXRwdXQsXG4gICAgfSk7XG5cbiAgICB0aGlzLnNldFJlcHJvQ29tbWFuZChjb250ZXh0LCBlbnYpO1xuXG4gICAgdGhpcy5fdGVzdFN1aXRlID0gYXdhaXQgdGhpcy5fbG9hZE1hbmlmZXN0KCk7XG4gICAgcmV0dXJuIHRoaXMuX3Rlc3RTdWl0ZTtcbiAgfVxuXG4gIHB1YmxpYyBhc3luYyBkZXBsb3koZGVwbG95QXJnczogT21pdDxEZXBsb3lPcHRpb25zLCAnYXBwJyB8ICdyZXF1aXJlQXBwcm92YWwnIHwgJ3Byb2ZpbGUnIHwgJ291dHB1dCcgfCAnbG9va3Vwcyc+KSB7XG4gICAgaWYgKCF0aGlzLmhhc1ZhbGlkUmVnaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nka1Rlc3RBcHAuZGVwbG95OiBub3QgaW5pdGlhbGl6ZWQgd2l0aCBhIHZhbGlkIHJlZ2lvbicpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNkay5kZXBsb3koe1xuICAgICAgLi4uREVGQVVMVF9BUkdTLFxuICAgICAgLi4uZGVwbG95QXJncyxcbiAgICAgIG91dHB1dDogdGhpcy5vdXRwdXREaXJlY3RvcnksXG4gICAgICBwcm9maWxlOiB0aGlzLnByb2ZpbGUsXG4gICAgICByZXF1aXJlQXBwcm92YWw6IFJlcXVpcmVBcHByb3ZhbC5ORVZFUixcbiAgICAgIGFwcDogdGhpcy5hcHBDb21tYW5kLFxuICAgICAgY29udGV4dDoge1xuICAgICAgICAuLi50aGlzLmdldENvbnRleHQoJ2RlcGxveW1lbnQnKSxcbiAgICAgICAgLi4uZGVwbG95QXJncz8uY29udGV4dCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgZGVzdHJveShkZXN0cm95QXJnczogT21pdDxEZXN0cm95T3B0aW9ucywgJ2FwcCcgfCAnZm9yY2UnIHwgJ3Byb2ZpbGUnIHwgJ291dHB1dCc+KSB7XG4gICAgaWYgKCF0aGlzLmhhc1ZhbGlkUmVnaW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ0Nka1Rlc3RBcHAuZGVzdHJveTogbm90IGluaXRpYWxpemVkIHdpdGggYSB2YWxpZCByZWdpb24nKTtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLmNkay5kZXN0cm95KHtcbiAgICAgIC4uLkRFRkFVTFRfQVJHUyxcbiAgICAgIC4uLmRlc3Ryb3lBcmdzLFxuICAgICAgYXBwOiB0aGlzLmFwcENvbW1hbmQsXG4gICAgICBvdXRwdXQ6IHRoaXMub3V0cHV0RGlyZWN0b3J5LFxuICAgICAgcHJvZmlsZTogdGhpcy5wcm9maWxlLFxuICAgICAgZm9yY2U6IHRydWUsXG4gICAgICBjb250ZXh0OiB7XG4gICAgICAgIC4uLnRoaXMuZ2V0Q29udGV4dCgnZGVwbG95bWVudCcpLFxuICAgICAgICAuLi5kZXN0cm95QXJncz8uY29udGV4dCxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgYXN5bmMgd2F0Y2god2F0Y2hBcmdzOiBPbWl0PERlcGxveU9wdGlvbnMsICdhcHAnIHwgJ3JlcXVpcmVBcHByb3ZhbCcgfCAncHJvZmlsZScgfCAnb3V0cHV0JyB8ICdsb29rdXBzJz4sIHdhdGNoRXZlbnRzOiBXYXRjaEV2ZW50cykge1xuICAgIGlmICghdGhpcy5oYXNWYWxpZFJlZ2lvbikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdDZGtUZXN0QXBwLndhdGNoOiBub3QgaW5pdGlhbGl6ZWQgd2l0aCBhIHZhbGlkIHJlZ2lvbicpO1xuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuY2RrLndhdGNoKHtcbiAgICAgIC4uLkRFRkFVTFRfQVJHUyxcbiAgICAgIC4uLndhdGNoQXJncyxcbiAgICAgIG91dHB1dDogdGhpcy5vdXRwdXREaXJlY3RvcnksXG4gICAgICBwcm9maWxlOiB0aGlzLnByb2ZpbGUsXG4gICAgICByZXF1aXJlQXBwcm92YWw6IFJlcXVpcmVBcHByb3ZhbC5ORVZFUixcbiAgICAgIGFwcDogdGhpcy5hcHBDb21tYW5kLFxuICAgICAgY29udGV4dDoge1xuICAgICAgICAuLi50aGlzLmdldENvbnRleHQoJ2RlcGxveW1lbnQnKSxcbiAgICAgICAgLi4ud2F0Y2hBcmdzPy5jb250ZXh0LFxuICAgICAgfSxcbiAgICB9LCB3YXRjaEV2ZW50cyk7XG4gIH1cblxuICBwcml2YXRlIHNldFJlcHJvQ29tbWFuZChjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBlbnY6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4pIHtcbiAgICAvLyBTaG93IHRoZSBjb21tYW5kIG5lY2Vzc2FyeSB0byByZXBybyB0aGlzXG4gICAgY29uc3QgZW52U2V0ID0gT2JqZWN0LmVudHJpZXMoZW52KS5tYXAoKFtrLCB2XSkgPT4gYCR7a309JyR7dn0nYCk7XG4gICAgY29uc3QgZW52Q21kID0gZW52U2V0Lmxlbmd0aCA+IDAgPyBbJ2VudicsIC4uLmVudlNldF0gOiBbXTtcblxuICAgIHRoaXMuc3ludGhSZXByb0NvbW1hbmQgPSBbXG4gICAgICAuLi5lbnZDbWQsXG4gICAgICAnY2RrJyxcbiAgICAgICdzeW50aCcsXG4gICAgICAnLWEnLFxuICAgICAgYCcke3RoaXMuYXBwQ29tbWFuZH0nYCxcbiAgICAgICctbycsXG4gICAgICBgJyR7dGhpcy5vdXRwdXREaXJlY3Rvcnl9J2AsXG4gICAgICAuLi5PYmplY3QuZW50cmllcyhjb250ZXh0KS5mbGF0TWFwKChbaywgdl0pID0+IHR5cGVvZiB2ICE9PSAnb2JqZWN0JyA/IFtgLWMgJyR7a309JHt2fSdgXSA6IFtdKSxcbiAgICBdLmpvaW4oJyAnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMb2FkIHRoZSBpbnRlZyBtYW5pZmVzdCB3aGljaCBjb250YWlucyBpbmZvcm1hdGlvblxuICAgKiBvbiBob3cgdG8gZXhlY3V0ZSB0aGUgdGVzdHNcbiAgICogRmlyc3Qgd2UgdHJ5IGFuZCBsb2FkIHRoZSBtYW5pZmVzdCBmcm9tIHRoZSBpbnRlZyBtYW5pZmVzdCAoaS5lLiBpbnRlZy5qc29uKVxuICAgKiBmcm9tIHRoZSBjbG91ZCBhc3NlbWJseS4gSWYgaXQgZG9lc24ndCBleGlzdCwgdGhlbiB3ZSBmYWxsYmFjayB0byB0aGVcbiAgICogXCJsZWdhY3kgbW9kZVwiIGFuZCBjcmVhdGUgYSBtYW5pZmVzdCBmcm9tIHByYWdtYVxuICAgKlxuICAgKiBAaW50ZXJuYWxcbiAgICovXG4gIHByaXZhdGUgYXN5bmMgX2xvYWRNYW5pZmVzdCgpOiBQcm9taXNlPEludGVnVGVzdFN1aXRlIHwgTGVnYWN5SW50ZWdUZXN0U3VpdGU+IHtcbiAgICBpZiAoIWF3YWl0IHRoaXMuaGFzT3V0cHV0KCkgJiYgIXRoaXMub3B0aW9ucy5URVNUSU5HX3VzaW5nTW9ja3MpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU3ludGggZGlkIG5vdCBwcm9kdWNlIG91dHB1dCBkaXJlY3Rvcnk6ICR7dGhpcy5vdXRwdXREaXJlY3Rvcnl9YCk7XG4gICAgfVxuICAgIGNvbnN0IG1hbmlmZXN0RGlyID0gdGhpcy5vdXRwdXREaXJlY3Rvcnk7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHRlc3RTdWl0ZSA9IEludGVnVGVzdFN1aXRlLmZyb21QYXRoKG1hbmlmZXN0RGlyKTtcbiAgICAgIHJldHVybiB0ZXN0U3VpdGU7XG4gICAgfSBjYXRjaCAobW9kZXJuRXJyb3I6IGFueSkge1xuICAgICAgLy8gT25seSBhdHRlbXB0IGxlZ2FjeSB0ZXN0IGNhc2UgaWYgdGhlIGludGVnIHRlc3QgbWFuaWZlc3Qgd2FzIG5vdCBmb3VuZFxuICAgICAgLy8gRm9yIGFueSBvdGhlciBlcnJvcnMsIGUuZy4gd2hlbiBwYXJzaW5nIHRoZSBtYW5pZmVzdCBmYWlscywgd2UgYWJvcnQuXG4gICAgICBpZiAoIShtb2Rlcm5FcnJvciBpbnN0YW5jZW9mIE5vTWFuaWZlc3RFcnJvcikpIHtcbiAgICAgICAgdGhyb3cgbW9kZXJuRXJyb3I7XG4gICAgICB9XG5cbiAgICAgIGlmICh0aGlzLnNob3dPdXRwdXQpIHtcbiAgICAgICAgbG9nZ2VyLnRyYWNlKFxuICAgICAgICAgIFwiRmFpbGVkIHRvIGxvYWQgaW50ZWcgdGVzdCBtYW5pZmVzdCBmb3IgJyVzJy4gQXR0ZW1wdGluZyBhcyBkZXByZWNhdGVkIGxlZ2FjeSB0ZXN0IGluc3RlYWQuIEVycm9yIHdhczogJXNcIixcbiAgICAgICAgICBtYW5pZmVzdERpcixcbiAgICAgICAgICBtb2Rlcm5FcnJvci5tZXNzYWdlID8/IFN0cmluZyhtb2Rlcm5FcnJvciksXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0aGlzLl9sb2FkTGVnYWN5VGVzdFN1aXRlKCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyBfbG9hZExlZ2FjeVRlc3RTdWl0ZSgpOiBQcm9taXNlPExlZ2FjeUludGVnVGVzdFN1aXRlPiB7XG4gICAgY29uc3QgdGVzdENhc2VzID0gYXdhaXQgTGVnYWN5SW50ZWdUZXN0U3VpdGUuZnJvbUxlZ2FjeSh7XG4gICAgICBjZGs6IHRoaXMuY2RrLFxuICAgICAgdGVzdE5hbWU6IHRoaXMudGVzdC5ub3JtYWxpemVkVGVzdE5hbWUsXG4gICAgICBpbnRlZ1NvdXJjZUZpbGVQYXRoOiB0aGlzLnRlc3QuZmlsZU5hbWUsXG4gICAgICBsaXN0T3B0aW9uczoge1xuICAgICAgICAuLi50aGlzLmRlZmF1bHRBcmdzLFxuICAgICAgICBhbGw6IHRydWUsXG4gICAgICAgIGFwcDogdGhpcy5hcHBDb21tYW5kLFxuICAgICAgICBwcm9maWxlOiB0aGlzLnByb2ZpbGUsXG4gICAgICAgIG91dHB1dDogdGhpcy5vdXRwdXREaXJlY3RvcnksXG4gICAgICB9LFxuICAgIH0pO1xuICAgIHRoaXMubGVnYWN5Q29udGV4dCA9IExlZ2FjeUludGVnVGVzdFN1aXRlLmdldFByYWdtYUNvbnRleHQodGhpcy50ZXN0LmZpbGVOYW1lKTtcbiAgICByZXR1cm4gdGVzdENhc2VzO1xuICB9XG5cbiAgcHVibGljIGNsZWFudXAoKTogdm9pZCB7XG4gICAgY29uc3QgY2RrT3V0UGF0aCA9IHRoaXMub3V0cHV0RGlyZWN0b3J5O1xuICAgIGlmIChmcy5leGlzdHNTeW5jKGNka091dFBhdGgpKSB7XG4gICAgICBmcy5yZW1vdmVTeW5jKGNka091dFBhdGgpO1xuICAgIH1cbiAgICAvLyBDbGVhciBjYWNoZVxuICAgIHRoaXMuX3Rlc3RTdWl0ZSA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiB0aGVyZSBhcmUgYW55IGRlc3RydWN0aXZlIGNoYW5nZXMgdG8gYSBzdGFjayB0aGVuIHRoaXMgd2lsbCByZWNvcmRcbiAgICogdGhvc2UgaW4gdGhlIG1hbmlmZXN0Lmpzb24gZmlsZVxuICAgKi9cbiAgcHJpdmF0ZSByZW5kZXJUcmFjZURhdGEoZGVzdHJ1Y3RpdmVDaGFuZ2VzOiBEZXN0cnVjdGl2ZUNoYW5nZVtdKTogTWFuaWZlc3RUcmFjZSB7XG4gICAgY29uc3QgdHJhY2VEYXRhOiBNYW5pZmVzdFRyYWNlID0gbmV3IE1hcCgpO1xuICAgIGRlc3RydWN0aXZlQ2hhbmdlcy5mb3JFYWNoKGNoYW5nZSA9PiB7XG4gICAgICBjb25zdCB0cmFjZSA9IHRyYWNlRGF0YS5nZXQoY2hhbmdlLnN0YWNrTmFtZSk7XG4gICAgICBpZiAodHJhY2UpIHtcbiAgICAgICAgdHJhY2Uuc2V0KGNoYW5nZS5sb2dpY2FsSWQsIGAke0RFU1RSVUNUSVZFX0NIQU5HRVN9ICR7Y2hhbmdlLmltcGFjdH1gKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyYWNlRGF0YS5zZXQoY2hhbmdlLnN0YWNrTmFtZSwgbmV3IE1hcChbXG4gICAgICAgICAgW2NoYW5nZS5sb2dpY2FsSWQsIGAke0RFU1RSVUNUSVZFX0NIQU5HRVN9ICR7Y2hhbmdlLmltcGFjdH1gXSxcbiAgICAgICAgXSkpO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB0cmFjZURhdGE7XG4gIH1cblxuICAvKipcbiAgICogSW4gY2FzZXMgd2hlcmUgd2UgZG8gbm90IHdhbnQgdG8gcmV0YWluIHRoZSBhc3NldHMsXG4gICAqIGZvciBleGFtcGxlLCBpZiB0aGUgYXNzZXRzIGFyZSB2ZXJ5IGxhcmdlLlxuICAgKlxuICAgKiBTaW5jZSBpdCBpcyBwb3NzaWJsZSB0byBkaXNhYmxlIHRoZSB1cGRhdGUgd29ya2Zsb3cgZm9yIGluZGl2aWR1YWwgdGVzdFxuICAgKiBjYXNlcywgdGhpcyBuZWVkcyB0byBmaXJzdCBnZXQgYSBsaXN0IG9mIHN0YWNrcyB0aGF0IGhhdmUgdGhlIHVwZGF0ZSB3b3JrZmxvd1xuICAgKiBkaXNhYmxlZCBhbmQgdGhlbiBkZWxldGUgYXNzZXRzIHRoYXQgcmVsYXRlIHRvIHRoYXQgc3RhY2suIEl0IGRvZXMgdGhhdFxuICAgKiBieSByZWFkaW5nIHRoZSBhc3NldCBtYW5pZmVzdCBmb3IgdGhlIHN0YWNrIGFuZCBkZWxldGluZyB0aGUgYXNzZXQgc291cmNlXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlbW92ZUFzc2V0c0Zyb21TbmFwc2hvdCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBzdGFja3MgPSB0aGlzLnRlc3RTdWl0ZS5nZXRTdGFja3NXaXRob3V0VXBkYXRlV29ya2Zsb3coKSA/PyBbXTtcbiAgICBjb25zdCBtYW5pZmVzdCA9IEFzc2VtYmx5TWFuaWZlc3RSZWFkZXIuZnJvbVBhdGgodGhpcy5vdXRwdXREaXJlY3RvcnkpO1xuICAgIGNvbnN0IGFzc2V0cyA9IGZsYXR0ZW4oc3RhY2tzLm1hcChzdGFjayA9PiB7XG4gICAgICByZXR1cm4gbWFuaWZlc3QuZ2V0QXNzZXRMb2NhdGlvbnNGb3JTdGFjayhzdGFjaykgPz8gW107XG4gICAgfSkpO1xuXG4gICAgYXNzZXRzLmZvckVhY2goYXNzZXQgPT4ge1xuICAgICAgY29uc3QgZmlsZU5hbWUgPSBwYXRoLmpvaW4odGhpcy5vdXRwdXREaXJlY3RvcnksIGFzc2V0KTtcbiAgICAgIGlmIChmcy5leGlzdHNTeW5jKGZpbGVOYW1lKSkge1xuICAgICAgICBpZiAoZnMubHN0YXRTeW5jKGZpbGVOYW1lKS5pc0RpcmVjdG9yeSgpKSB7XG4gICAgICAgICAgZnMucmVtb3ZlU3luYyhmaWxlTmFtZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZnMudW5saW5rU3luYyhmaWxlTmFtZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmUgdGhlIGFzc2V0IGNhY2hlICguY2FjaGUvKSBmaWxlcyBmcm9tIHRoZSBzbmFwc2hvdC5cbiAgICogVGhlc2UgYXJlIGEgY2FjaGUgb2YgdGhlIGFzc2V0IHppcHMsIGJ1dCB3ZSBhcmUgZmluZSB3aXRoXG4gICAqIHJlLXppcHBpbmcgb24gZGVwbG95XG4gICAqL1xuICBwcml2YXRlIHJlbW92ZUFzc2V0c0NhY2hlRnJvbVNuYXBzaG90KCk6IHZvaWQge1xuICAgIGNvbnN0IGZpbGVzID0gZnMucmVhZGRpclN5bmModGhpcy5vdXRwdXREaXJlY3RvcnkpO1xuICAgIGZpbGVzLmZvckVhY2goZmlsZSA9PiB7XG4gICAgICBjb25zdCBmaWxlTmFtZSA9IHBhdGguam9pbih0aGlzLm91dHB1dERpcmVjdG9yeSwgZmlsZSk7XG4gICAgICBpZiAoZnMubHN0YXRTeW5jKGZpbGVOYW1lKS5pc0RpcmVjdG9yeSgpICYmIGZpbGUgPT09ICcuY2FjaGUnKSB7XG4gICAgICAgIGZzLmVtcHR5RGlyU3luYyhmaWxlTmFtZSk7XG4gICAgICAgIGZzLnJtZGlyU3luYyhmaWxlTmFtZSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybSBzb21lIGNsZWFudXAgc3RlcHMgYWZ0ZXIgdGhlIHNuYXBzaG90IGlzIGNyZWF0ZWRcbiAgICogQW55dGltZSB0aGUgc25hcHNob3QgbmVlZHMgdG8gYmUgbW9kaWZpZWQgYWZ0ZXIgY3JlYXRpb25cbiAgICogdGhlIGxvZ2ljIHNob3VsZCBsaXZlIGhlcmUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGNsZWFudXBHb2xkZW5TbmFwc2hvdChkZXN0cnVjdGl2ZUNoYW5nZXM6IERlc3RydWN0aXZlQ2hhbmdlW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIWF3YWl0IHRoaXMuaGFzT3V0cHV0KCkpIHtcbiAgICAgIC8vIFRoaXMgc2hvdWxkIG5vdCBiZSBwb3NzaWJsZSwgYnV0IGEgbG90IG9mIHRoZSB0ZXN0cyBkZXBlbmQgb24gdGhpcyBiZWluZyBhIG5vLW9wXG4gICAgICAvLyBpZiBubyBvdXRwdXQgZGlyZWN0b3J5IGdvdCBwcm9kdWNlZC5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLnJlbW92ZUFzc2V0c0Zyb21TbmFwc2hvdCgpO1xuICAgIHRoaXMucmVtb3ZlQXNzZXRzQ2FjaGVGcm9tU25hcHNob3QoKTtcbiAgICBjb25zdCBhc3NlbWJseSA9IEFzc2VtYmx5TWFuaWZlc3RSZWFkZXIuZnJvbVBhdGgodGhpcy5vdXRwdXREaXJlY3RvcnkpO1xuICAgIGFzc2VtYmx5LmNsZWFuTWFuaWZlc3QoKTtcbiAgICBhc3NlbWJseS5yZWNvcmRUcmFjZSh0aGlzLnJlbmRlclRyYWNlRGF0YShkZXN0cnVjdGl2ZUNoYW5nZXMpKTtcblxuICAgIC8vIGlmIHRoaXMgaXMgYSBsZWdhY3kgdGVzdCB0aGVuIGNyZWF0ZSBhbiBpbnRlZyBtYW5pZmVzdFxuICAgIC8vIGluIHRoZSBzbmFwc2hvdCBkaXJlY3Rvcnkgd2hpY2ggY2FuIGJlIHVzZWQgZm9yIHRoZVxuICAgIC8vIHVwZGF0ZSB3b3JrZmxvdy4gU2F2ZSBhbnkgbGVnYWN5Q29udGV4dCBhcyB3ZWxsIHNvIHRoYXQgaXQgY2FuIGJlIHJlYWRcbiAgICAvLyB0aGUgbmV4dCB0aW1lXG4gICAgY29uc3QgYWN0dWFsVGVzdFN1aXRlID0gdGhpcy50ZXN0U3VpdGU7XG4gICAgYWN0dWFsVGVzdFN1aXRlLmVuYWJsZUxvb2t1cHMgPSB0cnVlO1xuXG4gICAgaWYgKGFjdHVhbFRlc3RTdWl0ZSBpbnN0YW5jZW9mIExlZ2FjeUludGVnVGVzdFN1aXRlKSB7XG4gICAgICBhY3R1YWxUZXN0U3VpdGUuc2F2ZU1hbmlmZXN0KHRoaXMub3V0cHV0RGlyZWN0b3J5LCB0aGlzLmxlZ2FjeUNvbnRleHQpO1xuICAgIH0gZWxzZSBpZiAoYWN0dWFsVGVzdFN1aXRlIGluc3RhbmNlb2YgSW50ZWdUZXN0U3VpdGUpIHtcbiAgICAgIGFjdHVhbFRlc3RTdWl0ZS5zYXZlTWFuaWZlc3QodGhpcy5vdXRwdXREaXJlY3RvcnkpO1xuICAgIH1cbiAgfVxuXG4gIHB1YmxpYyBnZXRDb250ZXh0KGZvclNuYXBzaG90OiAnc25hcHNob3QnIHwgJ2RlcGxveW1lbnQnKTogUmVjb3JkPHN0cmluZywgYW55PiB7XG4gICAgaWYgKHRoaXMuX2xlZ2FjeUVuYWJsZUxvb2t1cHMgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdNdXN0IGNhbGwgY29uZmlndXJlTGVnYWN5RW5hYmxlTG9va3VwcyBiZWZvcmUgc3ludGhpbmcnKTtcbiAgICB9XG4gICAgLy8gTG9hZCB0aGUgdGVzdC1zcGVjaWZpYyBjb250ZXh0IChmcm9tIGBpbnRlZy5jb250ZXh0Lmpzb25gIG9yIGBjZGsuanNvbiNjb250ZXh0YCksIGlmIGFueS5cbiAgICAvLyBJZiBub3QgZm91bmQsIHVzZSB0aGUgYnVpbHQtaW4gY3VycmVudCBmZWF0dXJlIGZsYWdzIChhdCB0aGUgcmlzayBvZiBuZXdlciBmZWF0dXJlIGZsYWdzIGNoYW5naW5nXG4gICAgLy8gdGhlIHNuYXBzaG90cykuXG4gICAgY29uc3QgZmVhdHVyZUZsYWdzID0gdGhpcy50ZXN0U3BlY2lmaWNDb250ZXh0ID8/IGN1cnJlbnRseVJlY29tbWVuZGVkQXdzQ2RrTGliRmxhZ3MoKTtcblxuICAgIHJldHVybiB7XG4gICAgICAuLi5mZWF0dXJlRmxhZ3MsXG4gICAgICAuLi50aGlzLmxlZ2FjeUNvbnRleHQsXG5cbiAgICAgIC8vIFRoZSBfbGVnYWN5RW5hYmxlTG9va3VwcyBmbGFnIGlzIGNyYXp5IGJ1dCBpcyBvbmx5IHRoZXJlIHRvIG5vdCBkaXN0dXJiIGV4aXN0aW5nIHNuYXBzaG90cyB0b28gbXVjaC5cbiAgICAgIC4uLihmb3JTbmFwc2hvdCA9PT0gJ3NuYXBzaG90JyAmJiB0aGlzLl9sZWdhY3lFbmFibGVMb29rdXBzICE9PSBmYWxzZSA/IERFRkFVTFRfU1lOVEhfT1BUSU9OUy5jb250ZXh0IDoge30pLFxuXG4gICAgICAvLyBEb24ndCByZWNvcmQgY3JlYXRpb24gc3RhY2sgdHJhY2VzIGluIHRoZSBzbmFwc2hvdCwgc2luY2UgdGhleSBqdXN0IHRha2UgdXAgc3BhY2UgYW5kIGFyZSBuZXZlciBkZXRlcm1pbmlzdGljLlxuICAgICAgJ2F3czpjZGs6ZGlzYWJsZS1jcmVhdGlvbi1zdGFjay10cmFjZXMnOiB0cnVlLFxuXG4gICAgICAvLyBXZSBvcmlnaW5hbGx5IGhhZCBQTEFOTkVEIHRvIHNldCB0aGlzIHRvIFsnYXdzJywgJ2F3cy1jbiddLCBidXQgZHVlIHRvIGEgcHJvZ3JhbW1pbmcgbWlzdGFrZVxuICAgICAgLy8gaXQgd2FzIHNldCB0byBldmVyeXRoaW5nLiBJbiB0aGlzIFBSLCBzZXQgaXQgdG8gZXZlcnl0aGluZyB0byBub3QgbWVzcyB1cCBhbGwgdGhlIHNuYXBzaG90cy5cbiAgICAgICdAYXdzLWNkay9jb3JlOnRhcmdldC1wYXJ0aXRpb25zJzogdW5kZWZpbmVkLFxuXG4gICAgICAvKiAtLS0tLS0tLS0tLS0tLS0tIFRIRSBGVVRVUkUgTElWRVMgQkVMT1ctLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4gICAgICAvLyBSZXN0cmljdGluZyB0byB0aGVzZSB0YXJnZXQgcGFydGl0aW9ucyBtYWtlcyBtb3N0IHNlcnZpY2UgcHJpbmNpcGFscyBzeW50aGVzaXplIHRvXG4gICAgICAvLyBgc2VydmljZS4ke1VSTF9TVUZGSVh9YCwgd2hpY2ggaXMgdGVjaG5pY2FsbHkgKmluY29ycmVjdCogKGl0J3Mgb25seSBgYW1hem9uYXdzLmNvbWBcbiAgICAgIC8vIG9yIGBhbWF6b25hd3MuY29tLmNuYCwgbmV2ZXIgVXJsU3VmZml4IGZvciBhbnkgb2YgdGhlIHJlc3RyaWN0ZWQgcmVnaW9ucykgYnV0IGl0J3Mgd2hhdFxuICAgICAgLy8gbW9zdCBleGlzdGluZyBpbnRlZyB0ZXN0cyBjb250YWluLCBhbmQgd2Ugd2FudCB0byBkaXN0dXJiIGFzIGZldyBhcyBwb3NzaWJsZS5cbiAgICAgIC8vIFtUQVJHRVRfUEFSVElUSU9OU106IFsnYXdzJywgJ2F3cy1jbiddLFxuICAgICAgLyogLS0tLS0tLS0tLS0tLS0tLSBFTkQgT0YgVEhFIEZVVFVSRSAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tICovXG4gICAgfTtcbiAgfVxufVxuXG4vLyBEZWZhdWx0IGNvbnRleHQgd2UgcnVuIGFsbCBpbnRlZyB0ZXN0cyB3aXRoLCBzbyB0aGV5IGRvbid0IGRlcGVuZCBvbiB0aGVcbi8vIGFjY291bnQgb2YgdGhlIGV4ZXJjaXNpbmcgdXNlci5cbmV4cG9ydCBjb25zdCBERUZBVUxUX1NZTlRIX09QVElPTlMgPSB7XG4gIGNvbnRleHQ6IHtcbiAgICAvLyBXZSBoYXZlIHRyYWRpdGlvbmFsbHkgc2V0IHRoaXMsIGJ1dCBpdCdzIHF1aXRlIGEgYmFkIGlkZWEuIEl0IG1ha2VzIHJlZ2lvbi1hZ25vc3RpYyBzdGFja3MgdW5kZXBsb3lhYmxlLCBhbmQgdGhlcmUncyByZWFsbHkgbm8gcmVhc29uIGZvciB0aGF0LlxuICAgIC8vIEhvd2V2ZXIsIGlmIHdlIHVuc2V0IHRoaXMsIHdlIHdpbGwgYnJlYWsgbWFueSBleGlzdGluZyBzbmFwc2hvdHMgc28gd2Uga2VlcCBpdCBmb3Igbm93LlxuICAgIFtBVkFJTEFCSUxJVFlfWk9ORV9GQUxMQkFDS19DT05URVhUX0tFWV06IFsndGVzdC1yZWdpb24tMWEnLCAndGVzdC1yZWdpb24tMWInLCAndGVzdC1yZWdpb24tMWMnXSxcbiAgICAnYXZhaWxhYmlsaXR5LXpvbmVzOmFjY291bnQ9MTIzNDU2Nzg6cmVnaW9uPXRlc3QtcmVnaW9uJzogWyd0ZXN0LXJlZ2lvbi0xYScsICd0ZXN0LXJlZ2lvbi0xYicsICd0ZXN0LXJlZ2lvbi0xYyddLFxuICAgICdzc206YWNjb3VudD0xMjM0NTY3ODpwYXJhbWV0ZXJOYW1lPS9hd3Mvc2VydmljZS9hbWktYW1hem9uLWxpbnV4LWxhdGVzdC9hbXpuLWFtaS1odm0teDg2XzY0LWdwMjpyZWdpb249dGVzdC1yZWdpb24nOiAnYW1pLTEyMzQnLFxuICAgICdzc206YWNjb3VudD0xMjM0NTY3ODpwYXJhbWV0ZXJOYW1lPS9hd3Mvc2VydmljZS9hbWktYW1hem9uLWxpbnV4LWxhdGVzdC9hbXpuMi1hbWktaHZtLXg4Nl82NC1ncDI6cmVnaW9uPXRlc3QtcmVnaW9uJzogJ2FtaS0xMjM0JyxcbiAgICAnc3NtOmFjY291bnQ9MTIzNDU2Nzg6cGFyYW1ldGVyTmFtZT0vYXdzL3NlcnZpY2UvZWNzL29wdGltaXplZC1hbWkvYW1hem9uLWxpbnV4L3JlY29tbWVuZGVkOnJlZ2lvbj10ZXN0LXJlZ2lvbic6ICd7XCJpbWFnZV9pZFwiOiBcImFtaS0xMjM0XCJ9JyxcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHN0eWxpc3RpYy9tYXgtbGVuXG4gICAgJ2FtaTphY2NvdW50PTEyMzQ1Njc4OmZpbHRlcnMuaW1hZ2UtdHlwZS4wPW1hY2hpbmU6ZmlsdGVycy5uYW1lLjA9YW16bi1hbWktdnBjLW5hdC0qOmZpbHRlcnMuc3RhdGUuMD1hdmFpbGFibGU6b3duZXJzLjA9YW1hem9uOnJlZ2lvbj10ZXN0LXJlZ2lvbic6ICdhbWktMTIzNCcsXG4gICAgJ3ZwYy1wcm92aWRlcjphY2NvdW50PTEyMzQ1Njc4OmZpbHRlci5pc0RlZmF1bHQ9dHJ1ZTpyZWdpb249dGVzdC1yZWdpb246cmV0dXJuQXN5bW1ldHJpY1N1Ym5ldHM9dHJ1ZSc6IHtcbiAgICAgIHZwY0lkOiAndnBjLTYwOTAwOTA1JyxcbiAgICAgIHN1Ym5ldEdyb3VwczogW1xuICAgICAgICB7XG4gICAgICAgICAgdHlwZTogJ1B1YmxpYycsXG4gICAgICAgICAgbmFtZTogJ1B1YmxpYycsXG4gICAgICAgICAgc3VibmV0czogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICBzdWJuZXRJZDogJ3N1Ym5ldC1lMTk0NTVjYScsXG4gICAgICAgICAgICAgIGF2YWlsYWJpbGl0eVpvbmU6ICd1cy1lYXN0LTFhJyxcbiAgICAgICAgICAgICAgcm91dGVUYWJsZUlkOiAncnRiLWUxOTQ1NWNhJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICB7XG4gICAgICAgICAgICAgIHN1Ym5ldElkOiAnc3VibmV0LWUwYzI0Nzk3JyxcbiAgICAgICAgICAgICAgYXZhaWxhYmlsaXR5Wm9uZTogJ3VzLWVhc3QtMWInLFxuICAgICAgICAgICAgICByb3V0ZVRhYmxlSWQ6ICdydGItZTBjMjQ3OTcnLFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgc3VibmV0SWQ6ICdzdWJuZXQtY2NkNzczOTUnLFxuICAgICAgICAgICAgICBhdmFpbGFiaWxpdHlab25lOiAndXMtZWFzdC0xYycsXG4gICAgICAgICAgICAgIHJvdXRlVGFibGVJZDogJ3J0Yi1jY2Q3NzM5NScsXG4gICAgICAgICAgICB9LFxuICAgICAgICAgIF0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0sXG4gIH0sXG4gIGVudjoge1xuICAgIENES19JTlRFR19BQ0NPVU5UOiAnMTIzNDU2NzgnLFxuICAgIENES19JTlRFR19SRUdJT046ICd0ZXN0LXJlZ2lvbicsXG4gICAgQ0RLX0lOVEVHX0hPU1RFRF9aT05FX0lEOiAnWjIzQUJDNFhZWkwwNUInLFxuICAgIENES19JTlRFR19IT1NURURfWk9ORV9OQU1FOiAnZXhhbXBsZS5jb20nLFxuICAgIENES19JTlRFR19ET01BSU5fTkFNRTogJyouZXhhbXBsZS5jb20nLFxuICAgIENES19JTlRFR19DRVJUX0FSTjogJ2Fybjphd3M6YWNtOnRlc3QtcmVnaW9uOjEyMzQ1Njc4OmNlcnRpZmljYXRlLzg2NDY4MjA5LWEyNzItNTk1ZC1iODMxLTBlZmI2NDIxMjY1eicsXG4gICAgQ0RLX0lOVEVHX1NVQk5FVF9JRDogJ3N1Ym5ldC0wZGZmMWEzOTlkOGY2ZjkyYycsXG4gIH0sXG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgY3VycmVudGx5IHJlY29tbWVuZGVkIGZsYWdzIGZvciBgYXdzLWNkay1saWJgLlxuICpcbiAqIFRoZXNlIGhhdmUgYmVlbiBidWlsdCBpbnRvIHRoZSBDTEkgYXQgYnVpbGQgdGltZS4gSWYgdGhpcyBldmVyIGdldHMgY2hhbmdlZFxuICogYmFjayB0byBhIGR5bmFtaWMgbG9hZCwgcmVtZW1iZXIgdGhhdCB0aGlzIHNvdXJjZSBmaWxlIG1heSBiZSBidW5kbGVkIGludG9cbiAqIGEgSmF2YVNjcmlwdCBidW5kbGUsIGFuZCBgX19kaXJuYW1lYCBtaWdodCBub3QgcG9pbnQgd2hlcmUgeW91IHRoaW5rIGl0IGRvZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjdXJyZW50bHlSZWNvbW1lbmRlZEF3c0Nka0xpYkZsYWdzKCkge1xuICByZXR1cm4gcmVjb21tZW5kZWRGbGFnc0ZpbGU7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU25hcHNob3RBc3NlbWJseSB7XG4gIC8qKlxuICAgKiBNYXAgb2Ygc3RhY2tzIHRoYXQgYXJlIHBhcnQgb2YgdGhpcyBhc3NlbWJseVxuICAgKi9cbiAgW3N0YWNrTmFtZTogc3RyaW5nXToge1xuICAgIC8qKlxuICAgICAqIEFsbCB0ZW1wbGF0ZXMgZm9yIHRoaXMgc3RhY2ssIGluY2x1ZGluZyBuZXN0ZWQgc3RhY2tzXG4gICAgICovXG4gICAgdGVtcGxhdGVzOiB7XG4gICAgICBbdGVtcGxhdGVJZDogc3RyaW5nXTogYW55O1xuICAgIH07XG5cbiAgICAvKipcbiAgICAgKiBMaXN0IG9mIGFzc2V0IElkcyB0aGF0IGFyZSB1c2VkIGJ5IHRoaXMgYXNzZW1ibHlcbiAgICAgKi9cbiAgICBhc3NldHM6IHN0cmluZ1tdO1xuICB9O1xufVxuXG4vKipcbiAqIERlZmF1bHQgb3B0aW9ucyB0byBwYXNzIHRvIHRoZSBDREsgQ0xJXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0FSR1M6IERlZmF1bHRDZGtPcHRpb25zID0ge1xuICBwYXRoTWV0YWRhdGE6IGZhbHNlLFxuICBhc3NldE1ldGFkYXRhOiBmYWxzZSxcbiAgdmVyc2lvblJlcG9ydGluZzogZmFsc2UsXG59O1xuIl19