@aws-cdk-testing/cli-integ
Version:
Integration tests for the AWS CDK CLI
215 lines • 28.7 kB
JavaScript
;
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");
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',
})
.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)
const cliSource = new UniqueOption('CLI version');
for (const flagAlias of ['cli-version', 'use-cli-release']) {
if (args[flagAlias]) {
cliSource.set(new cli_npm_source_1.RunnerCliNpmSource(args[flagAlias]), `--${flagAlias}`);
}
}
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(root), `--${flagAlias}`);
}
}
if (args['auto-source'] || !cliSource.isSet()) {
cliSource.set(new cli_repo_source_1.RunnerCliRepoSource(await (0, find_root_1.autoFindRepoRoot)()), '--auto-source');
}
const librarySource = new library_npm_source_1.RunnerLibraryNpmSource('aws-cdk-lib', args['framework-version'] ? args['framework-version'] : '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}`);
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}`);
(0, subprocess_1.serializeSources)({
cli,
library,
toolkitLib,
});
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVuLXN1aXRlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsicnVuLXN1aXRlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsK0JBQStCO0FBQy9CLDZCQUE2QjtBQUM3Qiw2QkFBNkI7QUFDN0IsK0JBQStCO0FBQy9CLHNFQUF1RTtBQUN2RSx3RUFBeUU7QUFDekUsNERBQWdFO0FBQ2hFLGtHQUFtRztBQUNuRyw4RUFBK0U7QUFDL0UsZ0dBQWlHO0FBRWpHLDhEQUFpRTtBQUVqRSxLQUFLLFVBQVUsSUFBSTtJQUNqQixNQUFNLElBQUksR0FBRyxNQUFNLEtBQUs7U0FDckIsT0FBTyxDQUFDLGVBQWUsRUFBRSxpQkFBaUIsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7U0FDaEQsVUFBVSxDQUFDLFdBQVcsRUFBRTtRQUN2QixRQUFRLEVBQUUsK0JBQStCO1FBQ3pDLElBQUksRUFBRSxRQUFRO1FBQ2QsWUFBWSxFQUFFLElBQUk7S0FDbkIsQ0FBQztRQUNGLDZFQUE2RTtRQUM3RSx3QkFBd0I7U0FDdkIsT0FBTyxDQUFDLGFBQWEsRUFBRTtRQUN0QixRQUFRLEVBQUUscUJBQXFCO1FBQy9CLEtBQUssRUFBRSxHQUFHO1FBQ1YsSUFBSSxFQUFFLFFBQVE7S0FDZixDQUFDO1NBQ0QsT0FBTyxDQUFDLFlBQVksRUFBRTtRQUNyQixRQUFRLEVBQUUsNENBQTRDO1FBQ3RELEtBQUssRUFBRSxHQUFHO1FBQ1YsSUFBSSxFQUFFLFFBQVE7S0FDZixDQUFDO1NBQ0QsT0FBTyxDQUFDLG1CQUFtQixFQUFFO1FBQzVCLFFBQVEsRUFBRSwwQkFBMEI7UUFDcEMsS0FBSyxFQUFFLEdBQUc7UUFDVixJQUFJLEVBQUUsUUFBUTtLQUNmLENBQUM7U0FDRCxPQUFPLENBQUMscUJBQXFCLEVBQUU7UUFDOUIsUUFBUSxFQUFFLDRCQUE0QjtRQUN0QyxLQUFLLEVBQUUsR0FBRztRQUNWLElBQUksRUFBRSxRQUFRO0tBQ2YsQ0FBQztTQUNELE1BQU0sQ0FB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QUMsQ0FBQyxDQUFDO0lBQ2pCLE9BQU8sQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO0FBQ3ZCLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogZXNsaW50LWRpc2FibGUgbm8tY29uc29sZSAqL1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIGplc3QgZnJvbSAnamVzdCc7XG5pbXBvcnQgKiBhcyB5YXJncyBmcm9tICd5YXJncyc7XG5pbXBvcnQgeyBSdW5uZXJDbGlOcG1Tb3VyY2UgfSBmcm9tICcuLi9wYWNrYWdlLXNvdXJjZXMvY2xpLW5wbS1zb3VyY2UnO1xuaW1wb3J0IHsgUnVubmVyQ2xpUmVwb1NvdXJjZSB9IGZyb20gJy4uL3BhY2thZ2Utc291cmNlcy9jbGktcmVwby1zb3VyY2UnO1xuaW1wb3J0IHsgYXV0b0ZpbmRSZXBvUm9vdCB9IGZyb20gJy4uL3BhY2thZ2Utc291cmNlcy9maW5kLXJvb3QnO1xuaW1wb3J0IHsgUnVubmVyTGlicmFyeUdsb2JhbEluc3RhbGxTb3VyY2UgfSBmcm9tICcuLi9wYWNrYWdlLXNvdXJjZXMvbGlicmFyeS1nbG9iYWxpbnN0YWxsLXNvdXJjZSc7XG5pbXBvcnQgeyBSdW5uZXJMaWJyYXJ5TnBtU291cmNlIH0gZnJvbSAnLi4vcGFja2FnZS1zb3VyY2VzL2xpYnJhcnktbnBtLXNvdXJjZSc7XG5pbXBvcnQgeyBSdW5uZXJMaWJyYXJ5UHJlaW5zdGFsbGVkU291cmNlIH0gZnJvbSAnLi4vcGFja2FnZS1zb3VyY2VzL2xpYnJhcnktcHJlaW5zdGFsbGVkLXNvdXJjZSc7XG5pbXBvcnQgdHlwZSB7IElSdW5uZXJTb3VyY2UsIElUZXN0Q2xpU291cmNlLCBJVGVzdExpYnJhcnlTb3VyY2UgfSBmcm9tICcuLi9wYWNrYWdlLXNvdXJjZXMvc291cmNlJztcbmltcG9ydCB7IHNlcmlhbGl6ZVNvdXJjZXMgfSBmcm9tICcuLi9wYWNrYWdlLXNvdXJjZXMvc3VicHJvY2Vzcyc7XG5cbmFzeW5jIGZ1bmN0aW9uIG1haW4oKSB7XG4gIGNvbnN0IGFyZ3MgPSBhd2FpdCB5YXJnc1xuICAgIC5jb21tYW5kKCcqIDxTVUlURU5BTUU+JywgJ2RlZmF1bHQgY29tbWFuZCcsIHkgPT4geVxuICAgICAgLnBvc2l0aW9uYWwoJ1NVSVRFTkFNRScsIHtcbiAgICAgICAgZGVzY3JpYmU6ICdOYW1lIG9mIHRoZSB0ZXN0IHN1aXRlIHRvIHJ1bicsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICBkZW1hbmRPcHRpb246IHRydWUsXG4gICAgICB9KVxuICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAgIC8vICBTb3VyY2VzIGFuZCB2ZXJzaW9uc1xuICAgICAgLm9wdGlvbnMoJ2NsaS12ZXJzaW9uJywge1xuICAgICAgICBkZXNjcmliZTogJ0NMSSB2ZXJzaW9uIHRvIHVzZS4nLFxuICAgICAgICBhbGlhczogJ2MnLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIH0pXG4gICAgICAub3B0aW9ucygnY2xpLXNvdXJjZScsIHtcbiAgICAgICAgZGVzY3JpYmU6ICdSb290IG9mIGF3cy1jZGstY2xpIHJlcG9zaXRvcnksIG9yIFwiYXV0b1wiLicsXG4gICAgICAgIGFsaWFzOiAncycsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgfSlcbiAgICAgIC5vcHRpb25zKCdmcmFtZXdvcmstdmVyc2lvbicsIHtcbiAgICAgICAgZGVzY3JpYmU6ICdGcmFtZXdvcmsgdmVyc2lvbiB0byB1c2UnLFxuICAgICAgICBhbGlhczogJ2YnLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgIH0pXG4gICAgICAub3B0aW9ucygndG9vbGtpdC1saWItdmVyc2lvbicsIHtcbiAgICAgICAgZGVzY3JpYmU6ICdUb29sa2l0IGxpYiB2ZXJzaW9uIHRvIHVzZScsXG4gICAgICAgIGFsaWFzOiAnbCcsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgfSlcbiAgICAgIC5vcHRpb24oJ3VzZS1zb3VyY2UnLCB7XG4gICAgICAgIGRlc2NyaXB0b246ICdVc2UgVHlwZVNjcmlwdCBwYWNrYWdlcyBmcm9tIHRoZSBnaXZlbiBzb3VyY2UgcmVwb3NpdG9yeSAob3IgXCJhdXRvXCIpJyxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgIHJlcXVpcmVzQXJnOiB0cnVlLFxuICAgICAgICBkZXByZWNhdGVkOiAnVXNlIC0tY2xpLXNvdXJjZSBpbnN0ZWFkJyxcbiAgICAgIH0pXG4gICAgICAub3B0aW9uKCd1c2UtY2xpLXJlbGVhc2UnLCB7XG4gICAgICAgIGRlc2NyaXB0b246ICdSdW4gdGhlIGN1cnJlbnQgdGVzdHMgYWdhaW5zdCB0aGUgQ0xJIGF0IHRoZSBnaXZlbiB2ZXJzaW9uJyxcbiAgICAgICAgYWxpYXM6ICd1JyxcbiAgICAgICAgdHlwZTogJ3N0cmluZycsXG4gICAgICAgIHJlcXVpcmVzQXJnOiB0cnVlLFxuICAgICAgICBkZXByZWNhdGVkOiAnVXNlIC0tY2xpLXZlcnNpb24gaW5zdGVhZCcsXG4gICAgICB9KVxuICAgICAgLm9wdGlvbignYXV0by1zb3VyY2UnLCB7XG4gICAgICAgIGFsaWFzOiAnYScsXG4gICAgICAgIGRlc2NyaWJlOiAnQXV0b21hdGljYWxseSBmaW5kIHRoZSBzb3VyY2UgdHJlZSBmcm9tIHRoZSBjdXJyZW50IHdvcmtpbmcgZGlyZWN0b3J5JyxcbiAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICAgIGRlcHJlY2F0ZWQ6ICdVc2UgLS11c2Utc291cmNlPWF1dG8gaW5zdGVhZCcsXG4gICAgICB9KVxuICAgICAgLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy8vLy9cbiAgICAgIC8vICBUZXN0IHJ1bm5pbmcgZmxhZ3NcbiAgICAgIC5vcHRpb24oJ3J1bkluQmFuZCcsIHtcbiAgICAgICAgZGVzY3JpcHRvbjogJ1J1biBhbGwgdGVzdHMgaW4gb25lIE5vZGUgcHJvY2VzcycsXG4gICAgICAgIGFsaWFzOiAnaScsXG4gICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgIH0pXG4gICAgICAub3B0aW9uKCd0ZXN0Jywge1xuICAgICAgICBkZXNjcmlwdG9uOiAnVGVzdCBwYXR0ZXJuIHRvIHNlbGVjdGl2ZWx5IHJ1biB0ZXN0cycsXG4gICAgICAgIGFsaWFzOiAndCcsXG4gICAgICAgIHR5cGU6ICdzdHJpbmcnLFxuICAgICAgICByZXF1aXJlc0FyZzogdHJ1ZSxcbiAgICAgIH0pXG4gICAgICAub3B0aW9uKCd0ZXN0LWZpbGUnLCB7XG4gICAgICAgIGRlc2NyaWJlOiAnVGhlIHNwZWNpZmljIHRlc3QgZmlsZSB0byBydW4nLFxuICAgICAgICBhbGlhczogJ0YnLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgcmVxdWlyZXNBcmc6IHRydWUsXG4gICAgICB9KVxuICAgICAgLm9wdGlvbnMoJ3ZlcmJvc2UnLCB7XG4gICAgICAgIGFsaWFzOiAndicsXG4gICAgICAgIGRlc2NyaWJlOiAnUnVuIGluIHZlcmJvc2UgbW9kZScsXG4gICAgICAgIHR5cGU6ICdib29sZWFuJyxcbiAgICAgICAgcmVxdWlyZXNBcmc6IGZhbHNlLFxuICAgICAgfSlcbiAgICAgIC5vcHRpb25zKCdwYXNzV2l0aE5vVGVzdHMnLCB7XG4gICAgICAgIGRlc2NyaWJlOiAnQWxsb3cgcGFzc2luZyBpZiB0aGUgdGVzdCBzdWl0ZSBpcyBub3QgZm91bmQgKGRlZmF1bHQgdHJ1ZSB3aGVuIElTX0NBTkFSWSBtb2RlLCBmYWxzZSBvdGhlcndpc2UpJyxcbiAgICAgICAgdHlwZTogJ2Jvb2xlYW4nLFxuICAgICAgICByZXF1aXJlc0FyZzogZmFsc2UsXG4gICAgICB9KVxuICAgICAgLm9wdGlvbnMoJ21heFdvcmtlcnMnLCB7XG4gICAgICAgIGFsaWFzOiAndycsXG4gICAgICAgIGRlc2NyaWJlOiAnU3BlY2lmaWVzIHRoZSBtYXhpbXVtIG51bWJlciBvZiB3b3JrZXJzIHRoZSB3b3JrZXItcG9vbCB3aWxsIHNwYXduIGZvciBydW5uaW5nIHRlc3RzLiBXZSB1c2UgYSBzZW5zaWJsZSBkZWZhdWx0IGZvciBydW5uaW5nIGNsaSBpbnRlZyB0ZXN0cy4nLFxuICAgICAgICB0eXBlOiAnc3RyaW5nJyxcbiAgICAgICAgcmVxdWlyZXNBcmc6IHRydWUsXG4gICAgICB9KSwgKCkgPT4ge1xuICAgIH0sXG4gICAgKVxuICAgIC5zdHJpY3QoKVxuICAgIC5wYXJzZSgpO1xuXG4gIGNvbnN0IHN1aXRlTmFtZSA9IGFyZ3MuU1VJVEVOQU1FO1xuXG4gIC8vIFNvIG1hbnkgd2F5cyB0byBzcGVjaWZ5IHRoaXMsIGFuZCB3aXRoIHZhcmlvdXMgd2F5cyB0byBzcGVsbCB0aGUgc2FtZSBmbGFnIChvX08pXG4gIGNvbnN0IGNsaVNvdXJjZSA9IG5ldyBVbmlxdWVPcHRpb248SVJ1bm5lclNvdXJjZTxJVGVzdENsaVNvdXJjZT4+KCdDTEkgdmVyc2lvbicpO1xuICBmb3IgKGNvbnN0IGZsYWdBbGlhcyBvZiBbJ2NsaS12ZXJzaW9uJywgJ3VzZS1jbGktcmVsZWFzZSddIGFzIGNvbnN0KSB7XG4gICAgaWYgKGFyZ3NbZmxhZ0FsaWFzXSkge1xuICAgICAgY2xpU291cmNlLnNldChuZXcgUnVubmVyQ2xpTnBtU291cmNlKGFyZ3NbZmxhZ0FsaWFzXSksIGAtLSR7ZmxhZ0FsaWFzfWApO1xuICAgIH1cbiAgfVxuICBmb3IgKGNvbnN0IGZsYWdBbGlhcyBvZiBbJ2NsaS1zb3VyY2UnLCAndXNlLXNvdXJjZSddIGFzIGNvbnN0KSB7XG4gICAgaWYgKGFyZ3NbZmxhZ0FsaWFzXSkge1xuICAgICAgY29uc3Qgcm9vdCA9IGFyZ3NbZmxhZ0FsaWFzXSA9PT0gJ2F1dG8nID8gYXdhaXQgYXV0b0ZpbmRSZXBvUm9vdCgpIDogYXJnc1tmbGFnQWxpYXNdO1xuICAgICAgY2xpU291cmNlLnNldChuZXcgUnVubmVyQ2xpUmVwb1NvdXJjZShyb290KSwgYC0tJHtmbGFnQWxpYXN9YCk7XG4gICAgfVxuICB9XG4gIGlmIChhcmdzWydhdXRvLXNvdXJjZSddIHx8ICFjbGlTb3VyY2UuaXNTZXQoKSkge1xuICAgIGNsaVNvdXJjZS5zZXQobmV3IFJ1bm5lckNsaVJlcG9Tb3VyY2UoYXdhaXQgYXV0b0ZpbmRSZXBvUm9vdCgpKSwgJy0tYXV0by1zb3VyY2UnKTtcbiAgfVxuXG4gIGNvbnN0IGxpYnJhcnlTb3VyY2U6IElSdW5uZXJTb3VyY2U8SVRlc3RMaWJyYXJ5U291cmNlPlxuICAgID0gbmV3IFJ1bm5lckxpYnJhcnlOcG1Tb3VyY2UoJ2F3cy1jZGstbGliJywgYXJnc1snZnJhbWV3b3JrLXZlcnNpb24nXSA/IGFyZ3NbJ2ZyYW1ld29yay12ZXJzaW9uJ10gOiAnbGF0ZXN0Jyk7XG5cbiAgY29uc3QgdG9vbGtpdExpYlBhY2thZ2UgPSAnQGF3cy1jZGsvdG9vbGtpdC1saWInO1xuICBsZXQgdG9vbGtpdFNvdXJjZTogSVJ1bm5lclNvdXJjZTxJVGVzdExpYnJhcnlTb3VyY2U+IHwgdW5kZWZpbmVkO1xuICBpZiAoYXJnc1sndG9vbGtpdC1saWItdmVyc2lvbiddKSB7XG4gICAgdG9vbGtpdFNvdXJjZSA9IG5ldyBSdW5uZXJMaWJyYXJ5R2xvYmFsSW5zdGFsbFNvdXJjZSh0b29sa2l0TGliUGFja2FnZSwgYXJnc1sndG9vbGtpdC1saWItdmVyc2lvbiddKTtcbiAgfVxuICBpZiAoIXRvb2xraXRTb3VyY2UpIHtcbiAgICB0b29sa2l0U291cmNlID0gYXdhaXQgUnVubmVyTGlicmFyeVByZWluc3RhbGxlZFNvdXJjZS5pc1ByZWluc3RhbGxlZCh0b29sa2l0TGliUGFja2FnZSlcbiAgICAgID8gbmV3IFJ1bm5lckxpYnJhcnlQcmVpbnN0YWxsZWRTb3VyY2UodG9vbGtpdExpYlBhY2thZ2UpXG4gICAgICA6IG5ldyBSdW5uZXJMaWJyYXJ5R2xvYmFsSW5zdGFsbFNvdXJjZSh0b29sa2l0TGliUGFja2FnZSwgJ2xhdGVzdCcpO1xuICB9XG5cbiAgY29uc29sZS5sb2coJy0tLS0tLT4gQ29uZmlndXJhdGlvbicpO1xuICBjb25zb2xlLmxvZyhgICAgICAgICBUZXN0IHN1aXRlOiAgICAgICAgICR7c3VpdGVOYW1lfWApO1xuICBjb25zb2xlLmxvZyhgICAgICAgICBUZXN0IHZlcnNpb246ICAgICAgICR7dGhpc1BhY2thZ2VWZXJzaW9uKCl9YCk7XG4gIGNvbnNvbGUubG9nKGAgICAgICAgIENMSSBzb3VyY2U6ICAgICAgICAgJHtjbGlTb3VyY2UuYXNzZXJ0KCkuc291cmNlRGVzY3JpcHRpb259YCk7XG4gIGNvbnNvbGUubG9nKGAgICAgICAgIExpYnJhcnkgc291cmNlOiAgICAgJHtsaWJyYXJ5U291cmNlLnNvdXJjZURlc2NyaXB0aW9ufWApO1xuICBjb25zb2xlLmxvZyhgICAgICAgICBUb29sa2l0IGxpYiBzb3VyY2U6ICR7dG9vbGtpdFNvdXJjZS5zb3VyY2VEZXNjcmlwdGlvbn1gKTtcblxuICBpZiAoYXJncy52ZXJib3NlKSB7XG4gICAgcHJvY2Vzcy5lbnYuVkVSQk9TRSA9ICcxJztcbiAgfVxuXG4gIC8vIE1vdGl2YXRpb24gYmVoaW5kIHRoaXMgYmVoYXZpb3I6IHdoZW4gYWRkaW5nIGEgbmV3IHRlc3Qgc3VpdGUgdG8gdGhlIHBpcGVsaW5lLCBiZWNhdXNlIG9mIHRoZSB3YXkgb3VyXG4gIC8vIFBpcGVsaW5lIHBhY2thZ2Ugd29ya3MsIHRoZSBzdWl0ZSB3b3VsZCBiZSBhZGRlZCB0byB0aGUgcGlwZWxpbmUgQU5EIGFzIGEgY2FuYXJ5IGltbWVkaWF0ZWx5LiBUaGUgY2FuYXJ5XG4gIC8vIHdvdWxkIGZhaWwgdW50aWwgdGhlIHBhY2thZ2Ugd2FzIGFjdHVhbGx5IHJlbGVhc2VkLCBzbyBmb3IgY2FuYXJpZXMgd2UgbWFrZSBhbiBleGNlcHRpb24gc28gdGhhdCB0aGUgaW5pdGlhbFxuICAvLyBjYW5hcnkgd291bGQgc3VjY2VlZCBldmVuIGlmIHRoZSBzdWl0ZSB3YXNuJ3QgeWV0IGF2YWlsYWJsZS4gVGhlIGZhY3QgdGhhdCB0aGUgc3VpdGUgaXMgbm90IG9wdGlvbmFsIGluXG4gIC8vIHRoZSBwaXBlbGluZSBwcm90ZWN0cyB1cyBmcm9tIHR5cG9zLlxuICBjb25zdCBwYXNzV2l0aE5vVGVzdHMgPSBhcmdzLnBhc3NXaXRoTm9UZXN0cyA/PyAhIXByb2Nlc3MuZW52LklTX0NBTkFSWTtcblxuICAvLyBDb21tdW5pY2F0ZSB3aXRoIHRoZSBjb25maWcgZmlsZSAoaW50ZWcuamVzdC5jb25maWcuanMpXG4gIHByb2Nlc3MuZW52LlRFU1RfU1VJVEVfTkFNRSA9IHN1aXRlTmFtZTtcblxuICBjb25zdCBkaXNwb3NhYmxlcyA9IG5ldyBBcnJheTx7IGRpc3Bvc2UoKTogUHJvbWlzZTx2b2lkPiB9PigpO1xuICB0cnkge1xuICAgIGNvbnNvbGUubG9nKCctLS0tLS0+IFJlc29sdmVkIHZlcnNpb25zJyk7XG4gICAgY29uc3QgY2xpID0gYXdhaXQgY2xpU291cmNlLmFzc2VydCgpLnJ1bm5lclByZXBhcmUoKTtcbiAgICBkaXNwb3NhYmxlcy5wdXNoKGNsaSk7XG4gICAgY29uc29sZS5sb2coYCAgICAgICAgQ0xJOiAgICAgICAgICAgICAke2NsaS52ZXJzaW9ufWApO1xuXG4gICAgY29uc3QgbGlicmFyeSA9IGF3YWl0IGxpYnJhcnlTb3VyY2UucnVubmVyUHJlcGFyZSgpO1xuICAgIGRpc3Bvc2FibGVzLnB1c2gobGlicmFyeSk7XG4gICAgY29uc29sZS5sb2coYCAgICAgICAgTGlicmFyeTogICAgICAgICAke2xpYnJhcnkudmVyc2lvbn1gKTtcblxuICAgIGNvbnN0IHRvb2xraXRMaWIgPSBhd2FpdCB0b29sa2l0U291cmNlLnJ1bm5lclByZXBhcmUoKTtcbiAgICBkaXNwb3NhYmxlcy5wdXNoKHRvb2xraXRMaWIpO1xuICAgIGNvbnNvbGUubG9nKGAgICAgICAgIFRvb2xraXQgbGlicmFyeTogJHt0b29sa2l0TGliLnZlcnNpb259YCk7XG5cbiAgICBzZXJpYWxpemVTb3VyY2VzKHtcbiAgICAgIGNsaSxcbiAgICAgIGxpYnJhcnksXG4gICAgICB0b29sa2l0TGliLFxuICAgIH0pO1xuXG4gICAgY29uc3QgamVzdENvbmZpZyA9IHBhdGgucmVzb2x2ZShfX2Rpcm5hbWUsICcuLicsICcuLicsICdyZXNvdXJjZXMnLCAnaW50ZWcuamVzdC5jb25maWcuanMnKTtcblxuICAgIGF3YWl0IGplc3QucnVuKFtcbiAgICAgICctLXJhbmRvbWl6ZScsXG4gICAgICAuLi5hcmdzLnJ1bkluQmFuZCA/IFsnLWknXSA6IFtdLFxuICAgICAgLi4uYXJncy50ZXN0ID8gWyctdCcsIGFyZ3MudGVzdF0gOiBbXSxcbiAgICAgIC4uLmFyZ3MudmVyYm9zZSA/IFsnLS12ZXJib3NlJ10gOiBbXSxcbiAgICAgIC4uLmFyZ3MubWF4V29ya2VycyA/IFtgLS1tYXhXb3JrZXJzPSR7YXJncy5tYXhXb3JrZXJzfWBdIDogW10sXG4gICAgICAuLi5wYXNzV2l0aE5vVGVzdHMgPyBbJy0tcGFzc1dpdGhOb1Rlc3RzJ10gOiBbXSxcbiAgICAgIC4uLmFyZ3NbJ3Rlc3QtZmlsZSddID8gW2FyZ3NbJ3Rlc3QtZmlsZSddXSA6IFtdLFxuICAgIF0sIGplc3RDb25maWcpO1xuICB9IGZpbmFsbHkge1xuICAgIGZvciAoY29uc3QgZGlzcCBvZiBkaXNwb3NhYmxlcykge1xuICAgICAgYXdhaXQgZGlzcC5kaXNwb3NlKCk7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIFVuaXF1ZU9wdGlvbjxBPiB7XG4gIHB1YmxpYyB2YWx1ZTogQSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBzb3VyY2U6IHN0cmluZyB8IHVuZGVmaW5lZDtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IHdoYXQ6IHN0cmluZykge1xuICB9XG5cbiAgcHVibGljIGlzU2V0KCkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlICE9PSB1bmRlZmluZWQ7XG4gIH1cblxuICBwdWJsaWMgYXNzZXJ0KCk6IEEge1xuICAgIGlmICghdGhpcy52YWx1ZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3RoaXMud2hhdH0gbm90IGNvbmZpZ3VyZWRgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gIH1cblxuICBwdWJsaWMgc2V0KHg6IEEsIHNvdXJjZTogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMudmFsdWUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHt0aGlzLndoYXR9OiAke3NvdXJjZX0gYWxyZWFkeSBjb25maWd1cmVkIHZpYSAke3RoaXMuc291cmNlfWApO1xuICAgIH1cbiAgICB0aGlzLnZhbHVlID0geDtcbiAgICB0aGlzLnNvdXJjZSA9IHNvdXJjZTtcbiAgfVxufVxuXG5mdW5jdGlvbiB0aGlzUGFja2FnZVZlcnNpb24oKTogc3RyaW5nIHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgcmV0dXJuIHJlcXVpcmUoJy4uLy4uL3BhY2thZ2UuanNvbicpLnZlcnNpb247XG59XG5cbm1haW4oKS5jYXRjaChlID0+IHtcbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG5vLWNvbnNvbGVcbiAgY29uc29sZS5lcnJvcihlKTtcbiAgcHJvY2Vzcy5leGl0Q29kZSA9IDE7XG59KTtcbiJdfQ==