UNPKG

@aws-cdk-testing/cli-integ

Version:

Integration tests for the AWS CDK CLI

215 lines 28.7 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"); 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==