UNPKG

@aws-cdk-testing/cli-integ

Version:

Integration tests for the AWS CDK CLI

251 lines 35.5 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); /* eslint-disable no-console */ const path = require("path"); const jest = require("jest"); const yargs = require("yargs"); const cli_npm_source_1 = require("../package-sources/cli-npm-source"); const cli_repo_source_1 = require("../package-sources/cli-repo-source"); const find_root_1 = require("../package-sources/find-root"); const library_globalinstall_source_1 = require("../package-sources/library-globalinstall-source"); const library_npm_source_1 = require("../package-sources/library-npm-source"); const library_preinstalled_source_1 = require("../package-sources/library-preinstalled-source"); const subprocess_1 = require("../package-sources/subprocess"); const CLI_PACKAGE_NAME = 'aws-cdk'; const CDK_ASSETS_PACKAGE_NAME = 'cdk-assets'; async function main() { const args = await yargs .command('* <SUITENAME>', 'default command', y => y .positional('SUITENAME', { describe: 'Name of the test suite to run', type: 'string', demandOption: true, }) ///////////////////////////////////////////////////////////////////////////// // Sources and versions .options('cli-version', { describe: 'CLI version to use.', alias: 'c', type: 'string', }) .options('cli-source', { describe: 'Root of aws-cdk-cli repository, or "auto".', alias: 's', type: 'string', }) .options('framework-version', { describe: 'Framework version to use', alias: 'f', type: 'string', }) .options('toolkit-lib-version', { describe: 'Toolkit lib version to use', alias: 'l', type: 'string', }) .options('cdk-assets-version', { describe: 'cdk-assets version to use.', alias: 'a', type: 'string', }) .option('use-source', { descripton: 'Use TypeScript packages from the given source repository (or "auto")', type: 'string', requiresArg: true, deprecated: 'Use --cli-source instead', }) .option('use-cli-release', { descripton: 'Run the current tests against the CLI at the given version', alias: 'u', type: 'string', requiresArg: true, deprecated: 'Use --cli-version instead', }) .option('auto-source', { alias: 'a', describe: 'Automatically find the source tree from the current working directory', type: 'boolean', requiresArg: false, deprecated: 'Use --use-source=auto instead', }) ///////////////////////////////////////////////////////////////////////////// // Test running flags .option('runInBand', { descripton: 'Run all tests in one Node process', alias: 'i', type: 'boolean', }) .option('test', { descripton: 'Test pattern to selectively run tests', alias: 't', type: 'string', requiresArg: true, }) .option('test-file', { describe: 'The specific test file to run', alias: 'F', type: 'string', requiresArg: true, }) .options('verbose', { alias: 'v', describe: 'Run in verbose mode', type: 'boolean', requiresArg: false, }) .options('passWithNoTests', { describe: 'Allow passing if the test suite is not found (default true when IS_CANARY mode, false otherwise)', type: 'boolean', requiresArg: false, }) .options('maxWorkers', { alias: 'w', describe: 'Specifies the maximum number of workers the worker-pool will spawn for running tests. We use a sensible default for running cli integ tests.', type: 'string', requiresArg: true, }), () => { }) .strict() .parse(); const suiteName = args.SUITENAME; // So many ways to specify this, and with various ways to spell the same flag (o_O) // Also, some of them depend on each other for convenience. const cliSource = new UniqueOption('CLI version'); const cdkAssetsSource = new UniqueOption('cdk-assets version'); // Specific CLI version for (const flagAlias of ['cli-version', 'use-cli-release']) { if (args[flagAlias]) { cliSource.set(new cli_npm_source_1.RunnerCliNpmSource(CLI_PACKAGE_NAME, args[flagAlias]), `--${flagAlias}`); } } // Specific cdk-assets version if (args['cdk-assets-version']) { cdkAssetsSource.set(new cli_npm_source_1.RunnerCliNpmSource(CDK_ASSETS_PACKAGE_NAME, args['cdk-assets-version']), '--cdk-assets-version'); } // Specifically use a source location for (const flagAlias of ['cli-source', 'use-source']) { if (args[flagAlias]) { const root = args[flagAlias] === 'auto' ? await (0, find_root_1.autoFindRepoRoot)() : args[flagAlias]; cliSource.set(new cli_repo_source_1.RunnerCliRepoSource(CLI_PACKAGE_NAME, root), `--${flagAlias}`); cdkAssetsSource.set(new cli_repo_source_1.RunnerCliRepoSource(CDK_ASSETS_PACKAGE_NAME, root), `--${flagAlias}`); } } // Specifically request that a source location is given, or we didn't find a CLI yet. // A CLI source is required, so if this fails that's alright. if (args['auto-source'] || !cliSource.isSet()) { cliSource.set(new cli_repo_source_1.RunnerCliRepoSource(CLI_PACKAGE_NAME, await (0, find_root_1.autoFindRepoRoot)()), '--auto-source'); } // If the CLI is taken from the source, and cdk-assets is not set, we can copy the cdk-assets source from the CLI source. if (!cdkAssetsSource.isSet()) { const cliSrc = cliSource.assert(); if (cliSrc instanceof cli_repo_source_1.RunnerCliRepoSource) { cdkAssetsSource.set(new cli_repo_source_1.RunnerCliRepoSource(CDK_ASSETS_PACKAGE_NAME, cliSrc.repoRoot), 'copied from CLI source'); } } // If cdk-assets is still not configured, fall back to the latest version that is available if (!cdkAssetsSource.isSet()) { cdkAssetsSource.set(new cli_npm_source_1.RunnerCliNpmSource(CDK_ASSETS_PACKAGE_NAME, 'latest'), '--cdk-assets-version not set'); } // Library source is either the given one, or 'latest' (nice and simple) const librarySource = new library_npm_source_1.RunnerLibraryNpmSource('aws-cdk-lib', args['framework-version'] ? args['framework-version'] : 'latest'); // Toolkit lib source is either the given one, or the one that's being brought by 'package.json' already, or 'latest' const toolkitLibPackage = '@aws-cdk/toolkit-lib'; let toolkitSource; if (args['toolkit-lib-version']) { toolkitSource = new library_globalinstall_source_1.RunnerLibraryGlobalInstallSource(toolkitLibPackage, args['toolkit-lib-version']); } if (!toolkitSource) { toolkitSource = await library_preinstalled_source_1.RunnerLibraryPreinstalledSource.isPreinstalled(toolkitLibPackage) ? new library_preinstalled_source_1.RunnerLibraryPreinstalledSource(toolkitLibPackage) : new library_globalinstall_source_1.RunnerLibraryGlobalInstallSource(toolkitLibPackage, 'latest'); } console.log('------> Configuration'); console.log(` Test suite: ${suiteName}`); console.log(` Test version: ${thisPackageVersion()}`); console.log(` CLI source: ${cliSource.assert().sourceDescription}`); console.log(` Library source: ${librarySource.sourceDescription}`); console.log(` Toolkit lib source: ${toolkitSource.sourceDescription}`); console.log(` cdk-assets source: ${cdkAssetsSource.assert().sourceDescription}`); if (args.verbose) { process.env.VERBOSE = '1'; } // Motivation behind this behavior: when adding a new test suite to the pipeline, because of the way our // Pipeline package works, the suite would be added to the pipeline AND as a canary immediately. The canary // would fail until the package was actually released, so for canaries we make an exception so that the initial // canary would succeed even if the suite wasn't yet available. The fact that the suite is not optional in // the pipeline protects us from typos. const passWithNoTests = args.passWithNoTests ?? !!process.env.IS_CANARY; // Communicate with the config file (integ.jest.config.js) process.env.TEST_SUITE_NAME = suiteName; const disposables = new Array(); try { console.log('------> Resolved versions'); const cli = await cliSource.assert().runnerPrepare(); disposables.push(cli); console.log(` CLI: ${cli.version}`); const library = await librarySource.runnerPrepare(); disposables.push(library); console.log(` Library: ${library.version}`); const toolkitLib = await toolkitSource.runnerPrepare(); disposables.push(toolkitLib); console.log(` Toolkit library: ${toolkitLib.version}`); const cdkAssets = await cdkAssetsSource.assert().runnerPrepare(); disposables.push(cdkAssets); console.log(` cdk-assets: ${cdkAssets.version}`); (0, subprocess_1.serializeSources)({ cli, library, toolkitLib, cdkAssets, }); const jestConfig = path.resolve(__dirname, '..', '..', 'resources', 'integ.jest.config.js'); await jest.run([ '--randomize', ...args.runInBand ? ['-i'] : [], ...args.test ? ['-t', args.test] : [], ...args.verbose ? ['--verbose'] : [], ...args.maxWorkers ? [`--maxWorkers=${args.maxWorkers}`] : [], ...passWithNoTests ? ['--passWithNoTests'] : [], ...args['test-file'] ? [args['test-file']] : [], ], jestConfig); } finally { for (const disp of disposables) { await disp.dispose(); } } } class UniqueOption { what; value; source; constructor(what) { this.what = what; } isSet() { return this.value !== undefined; } assert() { if (!this.value) { throw new Error(`${this.what} not configured`); } return this.value; } set(x, source) { if (this.value) { throw new Error(`${this.what}: ${source} already configured via ${this.source}`); } this.value = x; this.source = source; } } function thisPackageVersion() { // eslint-disable-next-line @typescript-eslint/no-require-imports return require('../../package.json').version; } main().catch(e => { // eslint-disable-next-line no-console console.error(e); process.exitCode = 1; }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLXN1aXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicnVuLXN1aXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0JBQStCO0FBQy9CLDZCQUE2QjtBQUM3Qiw2QkFBNkI7QUFDN0IsK0JBQStCO0FBQy9CLHNFQUF1RTtBQUN2RSx3RUFBeUU7QUFDekUsNERBQWdFO0FBQ2hFLGtHQUFtRztBQUNuRyw4RUFBK0U7QUFDL0UsZ0dBQWlHO0FBRWpHLDhEQUFpRTtBQUVqRSxNQUFNLGdCQUFnQixHQUFHLFNBQVMsQ0FBQztBQUNuQyxNQUFNLHVCQUF1QixHQUFHLFlBQVksQ0FBQztBQUU3QyxLQUFLLFVBQVUsSUFBSTtJQUNqQixNQUFNLElBQUksR0FBRyxNQUFNLEtBQUs7U0FDckIsT0FBTyxDQUFDLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDaEQsVUFBVSxDQUFDLFdBQVcsRUFBRTtRQUN2QixRQUFRLEVBQUUsK0JBQStCO1FBQ3pDLElBQUksRUFBRSxRQUFRO1FBQ2QsWUFBWSxFQUFFLElBQUk7S0FDbkIsQ0FBQztRQUNGLDZFQUE2RTtRQUM3RSx3QkFBd0I7U0FDdkIsT0FBTyxDQUFDLGFBQWEsRUFBRTtRQUN0QixRQUFRLEVBQUUscUJBQXFCO1FBQy9CLEtBQUssRUFBRSxHQUFHO1FBQ1YsSUFBSSxFQUFFLFFBQVE7S0FDZixDQUFDO1NBQ0QsT0FBTyxDQUFDLFlBQVksRUFBRTtRQUNyQixRQUFRLEVBQUUsNENBQTRDO1FBQ3RELEtBQUssRUFBRSxHQUFHO1FBQ1YsSUFBSSxFQUFFLFFBQVE7S0FDZixDQUFDO1NBQ0QsT0FBTyxDQUFDLG1CQUFtQixFQUFFO1FBQzVCLFFBQVEsRUFBRSwwQkFBMEI7UUFDcEMsS0FBSyxFQUFFLEdBQUc7UUFDVixJQUFJLEVBQUUsUUFBUTtLQUNmLENBQUM7U0FDRCxPQUFPLENBQUMscUJBQXFCLEVBQUU7UUFDOUIsUUFBUSxFQUFFLDRCQUE0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LElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNmLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxLQUFLLE1BQU0sMkJBQTJCLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBQ25GLENBQUM7UUFDRCxJQUFJLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUNmLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO0lBQ3ZCLENBQUM7Q0FDRjtBQUVELFNBQVMsa0JBQWtCO0lBQ3pCLGlFQUFpRTtJQUNqRSxPQUFPLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDLE9BQU8sQ0FBQztBQUMvQyxDQUFDO0FBRUQsSUFBSSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFO0lBQ2Ysc0NBQXNDO0lBQ3RDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakIsT0FBTyxDQUFDLFFBQVEsR0FBRyxDQUFDLENBQUM7QUFDdkIsQ0FBQyxDQUFDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBuby1jb25zb2xlICovXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0ICogYXMgamVzdCBmcm9tICdqZXN0JztcbmltcG9ydCAqIGFzIHlhcmdzIGZyb20gJ3lhcmdzJztcbmltcG9ydCB7IFJ1bm5lckNsaU5wbVNvdXJjZSB9IGZyb20gJy4uL3BhY2thZ2Utc291cmNlcy9jbGktbnBtLXNvdXJjZSc7XG5pbXBvcnQgeyBSdW5uZXJDbGlSZXBvU291cmNlIH0gZnJvbSAnLi4vcGFja2FnZS1zb3VyY2VzL2NsaS1yZXBvLXNvdXJjZSc7XG5pbXBvcnQgeyBhdXRvRmluZFJlcG9Sb290IH0gZnJvbSAnLi4vcGFja2FnZS1zb3VyY2VzL2ZpbmQtcm9vdCc7XG5pbXBvcnQgeyBSdW5uZXJMaWJyYXJ5R2xvYmFsSW5zdGFsbFNvdXJjZSB9IGZyb20gJy4uL3BhY2thZ2Utc291cmNlcy9saWJyYXJ5LWdsb2JhbGluc3RhbGwtc291cmNlJztcbmltcG9ydCB7IFJ1bm5lckxpYnJhcnlOcG1Tb3VyY2UgfSBmcm9tICcuLi9wYWNrYWdlLXNvdXJjZXMvbGlicmFyeS1ucG0tc291cmNlJztcbmltcG9ydCB7IFJ1bm5lckxpYnJhcnlQcmVpbnN0YWxsZWRTb3VyY2UgfSBmcm9tICcuLi9wYWNrYWdlLXNvdXJjZXMvbGlicmFyeS1wcmVpbnN0YWxsZWQtc291cmNlJztcbmltcG9ydCB0eXBlIHsgSVJ1bm5lclNvdXJjZSwgSVRlc3RDbGlTb3VyY2UsIElUZXN0TGlicmFyeVNvdXJjZSB9IGZyb20gJy4uL3BhY2thZ2Utc291cmNlcy9zb3VyY2UnO1xuaW1wb3J0IHsgc2VyaWFsaXplU291cmNlcyB9IGZyb20gJy4uL3BhY2thZ2Utc291cmNlcy9zdWJwcm9jZXNzJztcblxuY29uc3QgQ0xJX1BBQ0tBR0VfTkFNRSA9ICdhd3MtY2RrJztcbmNvbnN0IENES19BU1NFVFNfUEFDS0FHRV9OQU1FID0gJ2Nkay1hc3NldHMnO1xuXG5hc3luYyBmdW5jdGlvbiBtYWluKCkge1xuICBjb25zdCBhcmdzID0gYXdhaXQgeWFyZ3NcbiAgICAuY29tbWFuZCgnKiA8U1VJVEVOQU1FPicsICdkZWZhdWx0IGNvbW1hbmQnLCB5ID0+IHlcbiAgICAgIC5wb3NpdGlvbmFsKCdTVUlURU5BTUUnLCB7XG4gICAgICAgIGRlc2NyaWJlOiAnTmFtZSBvZiB0aGUgdGVzdCBzdWl0ZSB0byBydW4nLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgZGVtYW5kT3B0aW9uOiB0cnVlLFxuICAgICAgfSlcbiAgICAgIC8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vXG4gICAgICAvLyAgU291cmNlcyBhbmQgdmVyc2lvbnNcbiAgICAgIC5vcHRpb25zKCdjbGktdmVyc2lvbicsIHtcbiAgICAgICAgZGVzY3JpYmU6ICdDTEkgdmVyc2lvbiB0byB1c2UuJyxcbiAgICAgICAgYWxpYXM6ICdjJyxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICB9KVxuICAgICAgLm9wdGlvbnMoJ2NsaS1zb3VyY2UnLCB7XG4gICAgICAgIGRlc2NyaWJlOiAnUm9vdCBvZiBhd3MtY2RrLWNsaSByZXBvc2l0b3J5LCBvciBcImF1dG9cIi4nLFxuICAgICAgICBhbGlhczogJ3MnLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIH0pXG4gICAgICAub3B0aW9ucygnZnJhbWV3b3JrLXZlcnNpb24nLCB7XG4gICAgICAgIGRlc2NyaWJlOiAnRnJhbWV3b3JrIHZlcnNpb24gdG8gdXNlJyxcbiAgICAgICAgYWxpYXM6ICdmJyxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICB9KVxuICAgICAgLm9wdGlvbnMoJ3Rvb2xraXQtbGliLXZlcnNpb24nLCB7XG4gICAgICAgIGRlc2NyaWJlOiAnVG9vbGtpdCBsaWIgdmVyc2lvbiB0byB1c2UnLFxuICAgICAgICBhbGlhczogJ2wnLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIH0pXG4gICAgICAub3B0aW9ucygnY2RrLWFzc2V0cy12ZXJzaW9uJywge1xuICAgICAgICBkZXNjcmliZTogJ2Nkay1hc3NldHMgdmVyc2lvbiB0byB1c2UuJyxcbiAgICAgICAgYWxpYXM6ICdhJyxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICB9KVxuICAgICAgLm9wdGlvbigndXNlLXNvdXJjZScsIHtcbiAgICAgICAgZGVzY3JpcHRvbjogJ1VzZSBUeXBlU2NyaXB0IHBhY2thZ2VzIGZyb20gdGhlIGdpdmVuIHNvdXJjZSByZXBvc2l0b3J5IChvciBcImF1dG9cIiknLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgcmVxdWlyZXNBcmc6IHRydWUsXG4gICAgICAgIGRlcHJlY2F0ZWQ6ICdVc2UgLS1jbGktc291cmNlIGluc3RlYWQnLFxuICAgICAgfSlcbiAgICAgIC5vcHRpb24oJ3VzZS1jbGktcmVsZWFzZScsIHtcbiAgICAgICAgZGVzY3JpcHRvbjogJ1J1biB0aGUgY3VycmVudCB0ZXN0cyBhZ2FpbnN0IHRoZSBDTEkgYXQgdGhlIGdpdmVuIHZlcnNpb24nLFxuICAgICAgICBhbGlhczogJ3UnLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgcmVxdWlyZXNBcmc6IHRydWUsXG4gICAgICAgIGRlcHJlY2F0ZWQ6ICdVc2UgLS1jbGktdmVyc2lvbiBpbnN0ZWFkJyxcbiAgICAgIH0pXG4gICAgICAub3B0aW9uKCdhdXRvLXNvdXJjZScsIHtcbiAgICAgICAgYWxpYXM6ICdhJyxcbiAgICAgICAgZGVzY3JpYmU6ICdBdXRvbWF0aWNhbGx5IGZpbmQgdGhlIHNvdXJjZSB0cmVlIGZyb20gdGhlIGN1cnJlbnQgd29ya2luZyBkaXJlY3RvcnknLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgICAgZGVwcmVjYXRlZDogJ1VzZSAtLXVzZS1zb3VyY2U9YXV0byBpbnN0ZWFkJyxcbiAgICAgIH0pXG4gICAgICAvLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vL1xuICAgICAgLy8gIFRlc3QgcnVubmluZyBmbGFnc1xuICAgICAgLm9wdGlvbigncnVuSW5CYW5kJywge1xuICAgICAgICBkZXNjcmlwdG9uOiAnUnVuIGFsbCB0ZXN0cyBpbiBvbmUgTm9kZSBwcm9jZXNzJyxcbiAgICAgICAgYWxpYXM6ICdpJyxcbiAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgfSlcbiAgICAgIC5vcHRpb24oJ3Rlc3QnLCB7XG4gICAgICAgIGRlc2NyaXB0b246ICdUZXN0IHBhdHRlcm4gdG8gc2VsZWN0aXZlbHkgcnVuIHRlc3RzJyxcbiAgICAgICAgYWxpYXM6ICd0JyxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgIHJlcXVpcmVzQXJnOiB0cnVlLFxuICAgICAgfSlcbiAgICAgIC5vcHRpb24oJ3Rlc3QtZmlsZScsIHtcbiAgICAgICAgZGVzY3JpYmU6ICdUaGUgc3BlY2lmaWMgdGVzdCBmaWxlIHRvIHJ1bicsXG4gICAgICAgIGFsaWFzOiAnRicsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICByZXF1aXJlc0FyZzogdHJ1ZSxcbiAgICAgIH0pXG4gICAgICAub3B0aW9ucygndmVyYm9zZScsIHtcbiAgICAgICAgYWxpYXM6ICd2JyxcbiAgICAgICAgZGVzY3JpYmU6ICdSdW4gaW4gdmVyYm9zZSBtb2RlJyxcbiAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICB9KVxuICAgICAgLm9wdGlvbnMoJ3Bhc3NXaXRoTm9UZXN0cycsIHtcbiAgICAgICAgZGVzY3JpYmU6ICdBbGxvdyBwYXNzaW5nIGlmIHRoZSB0ZXN0IHN1aXRlIGlzIG5vdCBmb3VuZCAoZGVmYXVsdCB0cnVlIHdoZW4gSVNfQ0FOQVJZIG1vZGUsIGZhbHNlIG90aGVyd2lzZSknLFxuICAgICAgICB0eXBlOiAnYm9vbGVhbicsXG4gICAgICAgIHJlcXVpcmVzQXJnOiBmYWxzZSxcbiAgICAgIH0pXG4gICAgICAub3B0aW9ucygnbWF4V29ya2VycycsIHtcbiAgICAgICAgYWxpYXM6ICd3JyxcbiAgICAgICAgZGVzY3JpYmU6ICdTcGVjaWZpZXMgdGhlIG1heGltdW0gbnVtYmVyIG9mIHdvcmtlcnMgdGhlIHdvcmtlci1wb29sIHdpbGwgc3Bhd24gZm9yIHJ1bm5pbmcgdGVzdHMuIFdlIHVzZSBhIHNlbnNpYmxlIGRlZmF1bHQgZm9yIHJ1bm5pbmcgY2xpIGludGVnIHRlc3RzLicsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICByZXF1aXJlc0FyZzogdHJ1ZSxcbiAgICAgIH0pLCAoKSA9PiB7XG4gICAgfSxcbiAgICApXG4gICAgLnN0cmljdCgpXG4gICAgLnBhcnNlKCk7XG5cbiAgY29uc3Qgc3VpdGVOYW1lID0gYXJncy5TVUlURU5BTUU7XG5cbiAgLy8gU28gbWFueSB3YXlzIHRvIHNwZWNpZnkgdGhpcywgYW5kIHdpdGggdmFyaW91cyB3YXlzIHRvIHNwZWxsIHRoZSBzYW1lIGZsYWcgKG9fTylcbiAgLy8gQWxzbywgc29tZSBvZiB0aGVtIGRlcGVuZCBvbiBlYWNoIG90aGVyIGZvciBjb252ZW5pZW5jZS5cbiAgY29uc3QgY2xpU291cmNlID0gbmV3IFVuaXF1ZU9wdGlvbjxJUnVubmVyU291cmNlPElUZXN0Q2xpU291cmNlPj4oJ0NMSSB2ZXJzaW9uJyk7XG4gIGNvbnN0IGNka0Fzc2V0c1NvdXJjZSA9IG5ldyBVbmlxdWVPcHRpb248SVJ1bm5lclNvdXJjZTxJVGVzdENsaVNvdXJjZT4+KCdjZGstYXNzZXRzIHZlcnNpb24nKTtcblxuICAvLyBTcGVjaWZpYyBDTEkgdmVyc2lvblxuICBmb3IgKGNvbnN0IGZsYWdBbGlhcyBvZiBbJ2NsaS12ZXJzaW9uJywgJ3VzZS1jbGktcmVsZWFzZSddIGFzIGNvbnN0KSB7XG4gICAgaWYgKGFyZ3NbZmxhZ0FsaWFzXSkge1xuICAgICAgY2xpU291cmNlLnNldChuZXcgUnVubmVyQ2xpTnBtU291cmNlKENMSV9QQUNLQUdFX05BTUUsIGFyZ3NbZmxhZ0FsaWFzXSksIGAtLSR7ZmxhZ0FsaWFzfWApO1xuICAgIH1cbiAgfVxuXG4gIC8vIFNwZWNpZmljIGNkay1hc3NldHMgdmVyc2lvblxuICBpZiAoYXJnc1snY2RrLWFzc2V0cy12ZXJzaW9uJ10pIHtcbiAgICBjZGtBc3NldHNTb3VyY2Uuc2V0KG5ldyBSdW5uZXJDbGlOcG1Tb3VyY2UoQ0RLX0FTU0VUU19QQUNLQUdFX05BTUUsIGFyZ3NbJ2Nkay1hc3NldHMtdmVyc2lvbiddKSwgJy0tY2RrLWFzc2V0cy12ZXJzaW9uJyk7XG4gIH1cblxuICAvLyBTcGVjaWZpY2FsbHkgdXNlIGEgc291cmNlIGxvY2F0aW9uXG4gIGZvciAoY29uc3QgZmxhZ0FsaWFzIG9mIFsnY2xpLXNvdXJjZScsICd1c2Utc291cmNlJ10gYXMgY29uc3QpIHtcbiAgICBpZiAoYXJnc1tmbGFnQWxpYXNdKSB7XG4gICAgICBjb25zdCByb290ID0gYXJnc1tmbGFnQWxpYXNdID09PSAnYXV0bycgPyBhd2FpdCBhdXRvRmluZFJlcG9Sb290KCkgOiBhcmdzW2ZsYWdBbGlhc107XG4gICAgICBjbGlTb3VyY2Uuc2V0KG5ldyBSdW5uZXJDbGlSZXBvU291cmNlKENMSV9QQUNLQUdFX05BTUUsIHJvb3QpLCBgLS0ke2ZsYWdBbGlhc31gKTtcbiAgICAgIGNka0Fzc2V0c1NvdXJjZS5zZXQobmV3IFJ1bm5lckNsaVJlcG9Tb3VyY2UoQ0RLX0FTU0VUU19QQUNLQUdFX05BTUUsIHJvb3QpLCBgLS0ke2ZsYWdBbGlhc31gKTtcbiAgICB9XG4gIH1cblxuICAvLyBTcGVjaWZpY2FsbHkgcmVxdWVzdCB0aGF0IGEgc291cmNlIGxvY2F0aW9uIGlzIGdpdmVuLCBvciB3ZSBkaWRuJ3QgZmluZCBhIENMSSB5ZXQuXG4gIC8vIEEgQ0xJIHNvdXJjZSBpcyByZXF1aXJlZCwgc28gaWYgdGhpcyBmYWlscyB0aGF0J3MgYWxyaWdodC5cbiAgaWYgKGFyZ3NbJ2F1dG8tc291cmNlJ10gfHwgIWNsaVNvdXJjZS5pc1NldCgpKSB7XG4gICAgY2xpU291cmNlLnNldChuZXcgUnVubmVyQ2xpUmVwb1NvdXJjZShDTElfUEFDS0FHRV9OQU1FLCBhd2FpdCBhdXRvRmluZFJlcG9Sb290KCkpLCAnLS1hdXRvLXNvdXJjZScpO1xuICB9XG5cbiAgLy8gSWYgdGhlIENMSSBpcyB0YWtlbiBmcm9tIHRoZSBzb3VyY2UsIGFuZCBjZGstYXNzZXRzIGlzIG5vdCBzZXQsIHdlIGNhbiBjb3B5IHRoZSBjZGstYXNzZXRzIHNvdXJjZSBmcm9tIHRoZSBDTEkgc291cmNlLlxuICBpZiAoIWNka0Fzc2V0c1NvdXJjZS5pc1NldCgpKSB7XG4gICAgY29uc3QgY2xpU3JjID0gY2xpU291cmNlLmFzc2VydCgpO1xuICAgIGlmIChjbGlTcmMgaW5zdGFuY2VvZiBSdW5uZXJDbGlSZXBvU291cmNlKSB7XG4gICAgICBjZGtBc3NldHNTb3VyY2Uuc2V0KG5ldyBSdW5uZXJDbGlSZXBvU291cmNlKENES19BU1NFVFNfUEFDS0FHRV9OQU1FLCBjbGlTcmMucmVwb1Jvb3QpLCAnY29waWVkIGZyb20gQ0xJIHNvdXJjZScpO1xuICAgIH1cbiAgfVxuXG4gIC8vIElmIGNkay1hc3NldHMgaXMgc3RpbGwgbm90IGNvbmZpZ3VyZWQsIGZhbGwgYmFjayB0byB0aGUgbGF0ZXN0IHZlcnNpb24gdGhhdCBpcyBhdmFpbGFibGVcbiAgaWYgKCFjZGtBc3NldHNTb3VyY2UuaXNTZXQoKSkge1xuICAgIGNka0Fzc2V0c1NvdXJjZS5zZXQobmV3IFJ1bm5lckNsaU5wbVNvdXJjZShDREtfQVNTRVRTX1BBQ0tBR0VfTkFNRSwgJ2xhdGVzdCcpLCAnLS1jZGstYXNzZXRzLXZlcnNpb24gbm90IHNldCcpO1xuICB9XG5cbiAgLy8gTGlicmFyeSBzb3VyY2UgaXMgZWl0aGVyIHRoZSBnaXZlbiBvbmUsIG9yICdsYXRlc3QnIChuaWNlIGFuZCBzaW1wbGUpXG4gIGNvbnN0IGxpYnJhcnlTb3VyY2U6IElSdW5uZXJTb3VyY2U8SVRlc3RMaWJyYXJ5U291cmNlPlxuICAgID0gbmV3IFJ1bm5lckxpYnJhcnlOcG1Tb3VyY2UoJ2F3cy1jZGstbGliJywgYXJnc1snZnJhbWV3b3JrLXZlcnNpb24nXSA/IGFyZ3NbJ2ZyYW1ld29yay12ZXJzaW9uJ10gOiAnbGF0ZXN0Jyk7XG5cbiAgLy8gVG9vbGtpdCBsaWIgc291cmNlIGlzIGVpdGhlciB0aGUgZ2l2ZW4gb25lLCBvciB0aGUgb25lIHRoYXQncyBiZWluZyBicm91Z2h0IGJ5ICdwYWNrYWdlLmpzb24nIGFscmVhZHksIG9yICdsYXRlc3QnXG4gIGNvbnN0IHRvb2xraXRMaWJQYWNrYWdlID0gJ0Bhd3MtY2RrL3Rvb2xraXQtbGliJztcbiAgbGV0IHRvb2xraXRTb3VyY2U6IElSdW5uZXJTb3VyY2U8SVRlc3RMaWJyYXJ5U291cmNlPiB8IHVuZGVmaW5lZDtcbiAgaWYgKGFyZ3NbJ3Rvb2xraXQtbGliLXZlcnNpb24nXSkge1xuICAgIHRvb2xraXRTb3VyY2UgPSBuZXcgUnVubmVyTGlicmFyeUdsb2JhbEluc3RhbGxTb3VyY2UodG9vbGtpdExpYlBhY2thZ2UsIGFyZ3NbJ3Rvb2xraXQtbGliLXZlcnNpb24nXSk7XG4gIH1cbiAgaWYgKCF0b29sa2l0U291cmNlKSB7XG4gICAgdG9vbGtpdFNvdXJjZSA9IGF3YWl0IFJ1bm5lckxpYnJhcnlQcmVpbnN0YWxsZWRTb3VyY2UuaXNQcmVpbnN0YWxsZWQodG9vbGtpdExpYlBhY2thZ2UpXG4gICAgICA/IG5ldyBSdW5uZXJMaWJyYXJ5UHJlaW5zdGFsbGVkU291cmNlKHRvb2xraXRMaWJQYWNrYWdlKVxuICAgICAgOiBuZXcgUnVubmVyTGlicmFyeUdsb2JhbEluc3RhbGxTb3VyY2UodG9vbGtpdExpYlBhY2thZ2UsICdsYXRlc3QnKTtcbiAgfVxuXG4gIGNvbnNvbGUubG9nKCctLS0tLS0+IENvbmZpZ3VyYXRpb24nKTtcbiAgY29uc29sZS5sb2coYCAgICAgICAgVGVzdCBzdWl0ZTogICAgICAgICAke3N1aXRlTmFtZX1gKTtcbiAgY29uc29sZS5sb2coYCAgICAgICAgVGVzdCB2ZXJzaW9uOiAgICAgICAke3RoaXNQYWNrYWdlVmVyc2lvbigpfWApO1xuICBjb25zb2xlLmxvZyhgICAgICAgICBDTEkgc291cmNlOiAgICAgICAgICR7Y2xpU291cmNlLmFzc2VydCgpLnNvdXJjZURlc2NyaXB0aW9ufWApO1xuICBjb25zb2xlLmxvZyhgICAgICAgICBMaWJyYXJ5IHNvdXJjZTogICAgICR7bGlicmFyeVNvdXJjZS5zb3VyY2VEZXNjcmlwdGlvbn1gKTtcbiAgY29uc29sZS5sb2coYCAgICAgICAgVG9vbGtpdCBsaWIgc291cmNlOiAke3Rvb2xraXRTb3VyY2Uuc291cmNlRGVzY3JpcHRpb259YCk7XG4gIGNvbnNvbGUubG9nKGAgICAgICAgIGNkay1hc3NldHMgc291cmNlOiAgJHtjZGtBc3NldHNTb3VyY2UuYXNzZXJ0KCkuc291cmNlRGVzY3JpcHRpb259YCk7XG5cbiAgaWYgKGFyZ3MudmVyYm9zZSkge1xuICAgIHByb2Nlc3MuZW52LlZFUkJPU0UgPSAnMSc7XG4gIH1cblxuICAvLyBNb3RpdmF0aW9uIGJlaGluZCB0aGlzIGJlaGF2aW9yOiB3aGVuIGFkZGluZyBhIG5ldyB0ZXN0IHN1aXRlIHRvIHRoZSBwaXBlbGluZSwgYmVjYXVzZSBvZiB0aGUgd2F5IG91clxuICAvLyBQaXBlbGluZSBwYWNrYWdlIHdvcmtzLCB0aGUgc3VpdGUgd291bGQgYmUgYWRkZWQgdG8gdGhlIHBpcGVsaW5lIEFORCBhcyBhIGNhbmFyeSBpbW1lZGlhdGVseS4gVGhlIGNhbmFyeVxuICAvLyB3b3VsZCBmYWlsIHVudGlsIHRoZSBwYWNrYWdlIHdhcyBhY3R1YWxseSByZWxlYXNlZCwgc28gZm9yIGNhbmFyaWVzIHdlIG1ha2UgYW4gZXhjZXB0aW9uIHNvIHRoYXQgdGhlIGluaXRpYWxcbiAgLy8gY2FuYXJ5IHdvdWxkIHN1Y2NlZWQgZXZlbiBpZiB0aGUgc3VpdGUgd2Fzbid0IHlldCBhdmFpbGFibGUuIFRoZSBmYWN0IHRoYXQgdGhlIHN1aXRlIGlzIG5vdCBvcHRpb25hbCBpblxuICAvLyB0aGUgcGlwZWxpbmUgcHJvdGVjdHMgdXMgZnJvbSB0eXBvcy5cbiAgY29uc3QgcGFzc1dpdGhOb1Rlc3RzID0gYXJncy5wYXNzV2l0aE5vVGVzdHMgPz8gISFwcm9jZXNzLmVudi5JU19DQU5BUlk7XG5cbiAgLy8gQ29tbXVuaWNhdGUgd2l0aCB0aGUgY29uZmlnIGZpbGUgKGludGVnLmplc3QuY29uZmlnLmpzKVxuICBwcm9jZXNzLmVudi5URVNUX1NVSVRFX05BTUUgPSBzdWl0ZU5hbWU7XG5cbiAgY29uc3QgZGlzcG9zYWJsZXMgPSBuZXcgQXJyYXk8eyBkaXNwb3NlKCk6IFByb21pc2U8dm9pZD4gfT4oKTtcbiAgdHJ5IHtcbiAgICBjb25zb2xlLmxvZygnLS0tLS0tPiBSZXNvbHZlZCB2ZXJzaW9ucycpO1xuICAgIGNvbnN0IGNsaSA9IGF3YWl0IGNsaVNvdXJjZS5hc3NlcnQoKS5ydW5uZXJQcmVwYXJlKCk7XG4gICAgZGlzcG9zYWJsZXMucHVzaChjbGkpO1xuICAgIGNvbnNvbGUubG9nKGAgICAgICAgIENMSTogICAgICAgICAgICAgJHtjbGkudmVyc2lvbn1gKTtcblxuICAgIGNvbnN0IGxpYnJhcnkgPSBhd2FpdCBsaWJyYXJ5U291cmNlLnJ1bm5lclByZXBhcmUoKTtcbiAgICBkaXNwb3NhYmxlcy5wdXNoKGxpYnJhcnkpO1xuICAgIGNvbnNvbGUubG9nKGAgICAgICAgIExpYnJhcnk6ICAgICAgICAgJHtsaWJyYXJ5LnZlcnNpb259YCk7XG5cbiAgICBjb25zdCB0b29sa2l0TGliID0gYXdhaXQgdG9vbGtpdFNvdXJjZS5ydW5uZXJQcmVwYXJlKCk7XG4gICAgZGlzcG9zYWJsZXMucHVzaCh0b29sa2l0TGliKTtcbiAgICBjb25zb2xlLmxvZyhgICAgICAgICBUb29sa2l0IGxpYnJhcnk6ICR7dG9vbGtpdExpYi52ZXJzaW9ufWApO1xuXG4gICAgY29uc3QgY2RrQXNzZXRzID0gYXdhaXQgY2RrQXNzZXRzU291cmNlLmFzc2VydCgpLnJ1bm5lclByZXBhcmUoKTtcbiAgICBkaXNwb3NhYmxlcy5wdXNoKGNka0Fzc2V0cyk7XG4gICAgY29uc29sZS5sb2coYCAgICAgICAgY2RrLWFzc2V0czogICAgICAke2Nka0Fzc2V0cy52ZXJzaW9ufWApO1xuXG4gICAgc2VyaWFsaXplU291cmNlcyh7XG4gICAgICBjbGksXG4gICAgICBsaWJyYXJ5LFxuICAgICAgdG9vbGtpdExpYixcbiAgICAgIGNka0Fzc2V0cyxcbiAgICB9KTtcblxuICAgIGNvbnN0IGplc3RDb25maWcgPSBwYXRoLnJlc29sdmUoX19kaXJuYW1lLCAnLi4nLCAnLi4nLCAncmVzb3VyY2VzJywgJ2ludGVnLmplc3QuY29uZmlnLmpzJyk7XG5cbiAgICBhd2FpdCBqZXN0LnJ1bihbXG4gICAgICAnLS1yYW5kb21pemUnLFxuICAgICAgLi4uYXJncy5ydW5JbkJhbmQgPyBbJy1pJ10gOiBbXSxcbiAgICAgIC4uLmFyZ3MudGVzdCA/IFsnLXQnLCBhcmdzLnRlc3RdIDogW10sXG4gICAgICAuLi5hcmdzLnZlcmJvc2UgPyBbJy0tdmVyYm9zZSddIDogW10sXG4gICAgICAuLi5hcmdzLm1heFdvcmtlcnMgPyBbYC0tbWF4V29ya2Vycz0ke2FyZ3MubWF4V29ya2Vyc31gXSA6IFtdLFxuICAgICAgLi4ucGFzc1dpdGhOb1Rlc3RzID8gWyctLXBhc3NXaXRoTm9UZXN0cyddIDogW10sXG4gICAgICAuLi5hcmdzWyd0ZXN0LWZpbGUnXSA/IFthcmdzWyd0ZXN0LWZpbGUnXV0gOiBbXSxcbiAgICBdLCBqZXN0Q29uZmlnKTtcbiAgfSBmaW5hbGx5IHtcbiAgICBmb3IgKGNvbnN0IGRpc3Agb2YgZGlzcG9zYWJsZXMpIHtcbiAgICAgIGF3YWl0IGRpc3AuZGlzcG9zZSgpO1xuICAgIH1cbiAgfVxufVxuXG5jbGFzcyBVbmlxdWVPcHRpb248QT4ge1xuICBwdWJsaWMgdmFsdWU6IEEgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgc291cmNlOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSB3aGF0OiBzdHJpbmcpIHtcbiAgfVxuXG4gIHB1YmxpYyBpc1NldCgpIHtcbiAgICByZXR1cm4gdGhpcy52YWx1ZSAhPT0gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHVibGljIGFzc2VydCgpOiBBIHtcbiAgICBpZiAoIXRoaXMudmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLndoYXR9IG5vdCBjb25maWd1cmVkYCk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICB9XG5cbiAgcHVibGljIHNldCh4OiBBLCBzb3VyY2U6IHN0cmluZykge1xuICAgIGlmICh0aGlzLnZhbHVlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7dGhpcy53aGF0fTogJHtzb3VyY2V9IGFscmVhZHkgY29uZmlndXJlZCB2aWEgJHt0aGlzLnNvdXJjZX1gKTtcbiAgICB9XG4gICAgdGhpcy52YWx1ZSA9IHg7XG4gICAgdGhpcy5zb3VyY2UgPSBzb3VyY2U7XG4gIH1cbn1cblxuZnVuY3Rpb24gdGhpc1BhY2thZ2VWZXJzaW9uKCk6IHN0cmluZyB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gIHJldHVybiByZXF1aXJlKCcuLi8uLi9wYWNrYWdlLmpzb24nKS52ZXJzaW9uO1xufVxuXG5tYWluKCkuY2F0Y2goZSA9PiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBuby1jb25zb2xlXG4gIGNvbnNvbGUuZXJyb3IoZSk7XG4gIHByb2Nlc3MuZXhpdENvZGUgPSAxO1xufSk7XG4iXX0=