exec.test.js
1 "use strict"; 2 Object.defineProperty(exports, "__esModule", { value: true }); 3 jest.mock('child_process'); 4 const cxschema = require("@aws-cdk/cloud-assembly-schema"); 5 const cdk = require("@aws-cdk/core"); 6 const semver = require("semver"); 7 const sinon = require("sinon"); 8 const ts_mock_imports_1 = require("ts-mock-imports"); 9 const exec_1 = require("../../lib/api/cxapp/exec"); 10 const logging_1 = require("../../lib/logging"); 11 const settings_1 = require("../../lib/settings"); 12 const bockfs = require("../bockfs"); 13 const util_1 = require("../util"); 14 const mock_child_process_1 = require("../util/mock-child_process"); 15 const mock_sdk_1 = require("../util/mock-sdk"); 16 let sdkProvider; 17 let config; 18 beforeEach(() => { 19 logging_1.setLogLevel(1 /* DEBUG */); 20 sdkProvider = new mock_sdk_1.MockSdkProvider(); 21 config = new settings_1.Configuration(); 22 config.settings.set(['output'], 'cdk.out'); 23 // insert contents in fake filesystem 24 bockfs({ 25 '/home/project/cloud-executable': 'ARBITRARY', 26 '/home/project/windows.js': 'ARBITRARY', 27 'home/project/executable-app.js': 'ARBITRARY', 28 }); 29 bockfs.workingDirectory('/home/project'); 30 bockfs.executable('/home/project/cloud-executable'); 31 bockfs.executable('/home/project/executable-app.js'); 32 }); 33 afterEach(() => { 34 logging_1.setLogLevel(0 /* DEFAULT */); 35 sinon.restore(); 36 bockfs.restore(); 37 }); 38 // We need to increase the default 5s jest 39 // timeout for async tests because the 'execProgram' invocation 40 // might take a while :\ 41 const TEN_SECOND_TIMEOUT = 10000; 42 function createApp() { 43 const app = new cdk.App({ outdir: 'cdk.out' }); 44 const stack = new cdk.Stack(app, 'Stack'); 45 new cdk.CfnResource(stack, 'Role', { 46 type: 'AWS::IAM::Role', 47 properties: { 48 RoleName: 'Role', 49 }, 50 }); 51 return app; 52 } 53 test('cli throws when manifest version > schema version', async () => { 54 const app = createApp(); 55 const currentSchemaVersion = cxschema.Manifest.version(); 56 const mockManifestVersion = semver.inc(currentSchemaVersion, 'major'); 57 // this mock will cause the framework to use a greater schema version than the real one, 58 // and should cause the CLI to fail. 59 const mockVersionNumber = ts_mock_imports_1.ImportMock.mockFunction(cxschema.Manifest, 'version', mockManifestVersion); 60 try { 61 app.synth(); 62 } 63 finally { 64 mockVersionNumber.restore(); 65 } 66 const expectedError = 'This CDK CLI is not compatible with the CDK library used by your application. Please upgrade the CLI to the latest version.' 67 + `\n(Cloud assembly schema version mismatch: Maximum schema version supported is ${currentSchemaVersion}, but found ${mockManifestVersion})`; 68 config.settings.set(['app'], 'cdk.out'); 69 await expect(exec_1.execProgram(sdkProvider, config)).rejects.toEqual(new Error(expectedError)); 70 }, TEN_SECOND_TIMEOUT); 71 test('cli does not throw when manifest version = schema version', async () => { 72 const app = createApp(); 73 app.synth(); 74 config.settings.set(['app'], 'cdk.out'); 75 await exec_1.execProgram(sdkProvider, config); 76 }, TEN_SECOND_TIMEOUT); 77 test('cli does not throw when manifest version < schema version', async () => { 78 const app = createApp(); 79 const currentSchemaVersion = cxschema.Manifest.version(); 80 app.synth(); 81 config.settings.set(['app'], 'cdk.out'); 82 // this mock will cause the cli to think its exepcted schema version is 83 // greater that the version created in the manifest, which is what we are testing for. 84 const mockVersionNumber = ts_mock_imports_1.ImportMock.mockFunction(cxschema.Manifest, 'version', semver.inc(currentSchemaVersion, 'major')); 85 try { 86 await exec_1.execProgram(sdkProvider, config); 87 } 88 finally { 89 mockVersionNumber.restore(); 90 } 91 }, TEN_SECOND_TIMEOUT); 92 test('validates --app key is present', async () => { 93 // GIVEN no config key for `app` 94 await expect(exec_1.execProgram(sdkProvider, config)).rejects.toThrow('--app is required either in command-line, in cdk.json or in ~/.cdk.json'); 95 }); 96 test('bypasses synth when app points to a cloud assembly', async () => { 97 // GIVEN 98 config.settings.set(['app'], 'cdk.out'); 99 writeOutputAssembly(); 100 // WHEN 101 const cloudAssembly = await exec_1.execProgram(sdkProvider, config); 102 expect(cloudAssembly.artifacts).toEqual([]); 103 expect(cloudAssembly.directory).toEqual('cdk.out'); 104 }); 105 test('the application set in --app is executed', async () => { 106 // GIVEN 107 config.settings.set(['app'], 'cloud-executable'); 108 mock_child_process_1.mockSpawn({ 109 commandLine: ['cloud-executable'], 110 sideEffect: () => writeOutputAssembly(), 111 }); 112 // WHEN 113 await exec_1.execProgram(sdkProvider, config); 114 }); 115 test('the application set in --app is executed as-is if it contains a filename that does not exist', async () => { 116 // GIVEN 117 config.settings.set(['app'], 'does-not-exist'); 118 mock_child_process_1.mockSpawn({ 119 commandLine: ['does-not-exist'], 120 sideEffect: () => writeOutputAssembly(), 121 }); 122 // WHEN 123 await exec_1.execProgram(sdkProvider, config); 124 }); 125 test('the application set in --app is executed with arguments', async () => { 126 // GIVEN 127 config.settings.set(['app'], 'cloud-executable an-arg'); 128 mock_child_process_1.mockSpawn({ 129 commandLine: ['cloud-executable', 'an-arg'], 130 sideEffect: () => writeOutputAssembly(), 131 }); 132 // WHEN 133 await exec_1.execProgram(sdkProvider, config); 134 }); 135 test('application set in --app as `*.js` always uses handler on windows', async () => { 136 // GIVEN 137 sinon.stub(process, 'platform').value('win32'); 138 config.settings.set(['app'], 'windows.js'); 139 mock_child_process_1.mockSpawn({ 140 commandLine: [process.execPath, 'windows.js'], 141 sideEffect: () => writeOutputAssembly(), 142 }); 143 // WHEN 144 await exec_1.execProgram(sdkProvider, config); 145 }); 146 test('application set in --app is `*.js` and executable', async () => { 147 // GIVEN 148 config.settings.set(['app'], 'executable-app.js'); 149 mock_child_process_1.mockSpawn({ 150 commandLine: ['executable-app.js'], 151 sideEffect: () => writeOutputAssembly(), 152 }); 153 // WHEN 154 await exec_1.execProgram(sdkProvider, config); 155 }); 156 function writeOutputAssembly() { 157 const asm = util_1.testAssembly({ 158 stacks: [], 159 }); 160 bockfs.write('/home/project/cdk.out/manifest.json', JSON.stringify(asm.manifest)); 161 } 162 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhlYy50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZXhlYy50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsSUFBSSxDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUMzQiwyREFBMkQ7QUFDM0QscUNBQXFDO0FBQ3JDLGlDQUFpQztBQUNqQywrQkFBK0I7QUFDL0IscURBQTZDO0FBQzdDLG1EQUF1RDtBQUN2RCwrQ0FBMEQ7QUFDMUQsaURBQW1EO0FBQ25ELG9DQUFvQztBQUNwQyxrQ0FBdUM7QUFDdkMsbUVBQXVEO0FBQ3ZELCtDQUFtRDtBQUVuRCxJQUFJLFdBQTRCLENBQUM7QUFDakMsSUFBSSxNQUFxQixDQUFDO0FBQzFCLFVBQVUsQ0FBQyxHQUFHLEVBQUU7SUFDZCxxQkFBVyxlQUFnQixDQUFDO0lBRTVCLFdBQVcsR0FBRyxJQUFJLDBCQUFlLEVBQUUsQ0FBQztJQUNwQyxNQUFNLEdBQUcsSUFBSSx3QkFBYSxFQUFFLENBQUM7SUFFN0IsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxRQUFRLENBQUMsRUFBRSxTQUFTLENBQUMsQ0FBQztJQUUzQyxxQ0FBcUM7SUFDckMsTUFBTSxDQUFDO1FBQ0wsZ0NBQWdDLEVBQUUsV0FBVztRQUM3QywwQkFBMEIsRUFBRSxXQUFXO1FBQ3ZDLGdDQUFnQyxFQUFFLFdBQVc7S0FDOUMsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLGdCQUFnQixDQUFDLGVBQWUsQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sQ0FBQyxVQUFVLENBQUMsZ0NBQWdDLENBQUMsQ0FBQztJQUNwRCxNQUFNLENBQUMsVUFBVSxDQUFDLGlDQUFpQyxDQUFDLENBQUM7QUFDdkQsQ0FBQyxDQUFDLENBQUM7QUFFSCxTQUFTLENBQUMsR0FBRyxFQUFFO0lBQ2IscUJBQVcsaUJBQWtCLENBQUM7SUFFOUIsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO0lBQ2hCLE1BQU0sQ0FBQyxPQUFPLEVB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LENBQUM7SUFDM0MsOEJBQVMsQ0FBQztRQUNSLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxRQUFRLEVBQUUsWUFBWSxDQUFDO1FBQzdDLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxtQkFBbUIsRUFBRTtLQUN4QyxDQUFDLENBQUM7SUFFSCxPQUFPO0lBQ1AsTUFBTSxrQkFBVyxDQUFDLFdBQVcsRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN6QyxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQyxtREFBbUQsRUFBRSxLQUFLLElBQUksRUFBRTtJQUNuRSxRQUFRO0lBQ1IsTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0lBQ2xELDhCQUFTLENBQUM7UUFDUixXQUFXLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQztRQUNsQyxVQUFVLEVBQUUsR0FBRyxFQUFFLENBQUMsbUJBQW1CLEVBQUU7S0FDeEMsQ0FBQyxDQUFDO0lBRUgsT0FBTztJQUNQLE1BQU0sa0JBQVcsQ0FBQyxXQUFXLEVBQUUsTUFBTSxDQUFDLENBQUM7QUFDekMsQ0FBQyxDQUFDLENBQUM7QUFFSCxTQUFTLG1CQUFtQjtJQUMxQixNQUFNLEdBQUcsR0FBRyxtQkFBWSxDQUFDO1FBQ3ZCLE1BQU0sRUFBRSxFQUFFO0tBQ1gsQ0FBQyxDQUFDO0lBQ0gsTUFBTSxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsRUFBRSxJQUFJLENBQUMsU0FBUyxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ3BGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJqZXN0Lm1vY2soJ2NoaWxkX3Byb2Nlc3MnKTtcbmltcG9ydCAqIGFzIGN4c2NoZW1hIGZyb20gJ0Bhd3MtY2RrL2Nsb3VkLWFzc2VtYmx5LXNjaGVtYSc7XG5pbXBvcnQgKiBhcyBjZGsgZnJvbSAnQGF3cy1jZGsvY29yZSc7XG5pbXBvcnQgKiBhcyBzZW12ZXIgZnJvbSAnc2VtdmVyJztcbmltcG9ydCAqIGFzIHNpbm9uIGZyb20gJ3Npbm9uJztcbmltcG9ydCB7IEltcG9ydE1vY2sgfSBmcm9tICd0cy1tb2NrLWltcG9ydHMnO1xuaW1wb3J0IHsgZXhlY1Byb2dyYW0gfSBmcm9tICcuLi8uLi9saWIvYXBpL2N4YXBwL2V4ZWMnO1xuaW1wb3J0IHsgTG9nTGV2ZWwsIHNldExvZ0xldmVsIH0gZnJvbSAnLi4vLi4vbGliL2xvZ2dpbmcnO1xuaW1wb3J0IHsgQ29uZmlndXJhdGlvbiB9IGZyb20gJy4uLy4uL2xpYi9zZXR0aW5ncyc7XG5pbXBvcnQgKiBhcyBib2NrZnMgZnJvbSAnLi4vYm9ja2ZzJztcbmltcG9ydCB7IHRlc3RBc3NlbWJseSB9IGZyb20gJy4uL3V0aWwnO1xuaW1wb3J0IHsgbW9ja1NwYXduIH0gZnJvbSAnLi4vdXRpbC9tb2NrLWNoaWxkX3Byb2Nlc3MnO1xuaW1wb3J0IHsgTW9ja1Nka1Byb3ZpZGVyIH0gZnJvbSAnLi4vdXRpbC9tb2NrLXNkayc7XG5cbmxldCBzZGtQcm92aWRlcjogTW9ja1Nka1Byb3ZpZGVyO1xubGV0IGNvbmZpZzogQ29uZmlndXJhdGlvbjtcbmJlZm9yZUVhY2goKCkgPT4ge1xuICBzZXRMb2dMZXZlbChMb2dMZXZlbC5ERUJVRyk7XG5cbiAgc2RrUHJvdmlkZXIgPSBuZXcgTW9ja1Nka1Byb3ZpZGVyKCk7XG4gIGNvbmZpZyA9IG5ldyBDb25maWd1cmF0aW9uKCk7XG5cbiAgY29uZmlnLnNldHRpbmdzLnNldChbJ291dHB1dCddLCAnY2RrLm91dCcpO1xuXG4gIC8vIGluc2VydCBjb250ZW50cyBpbiBmYWtlIGZpbGVzeXN0ZW1cbiAgYm9ja2ZzKHtcbiAgICAnL2hvbWUvcHJvamVjdC9jbG91ZC1leGVjdXRhYmxlJzogJ0FSQklUUkFSWScsXG4gICAgJy9ob21lL3Byb2plY3Qvd2luZG93cy5qcyc6ICdBUkJJVFJBUlknLFxuICAgICdob21lL3Byb2plY3QvZXhlY3V0YWJsZS1hcHAuanMnOiAnQVJCSVRSQVJZJyxcbiAgfSk7XG4gIGJvY2tmcy53b3JraW5nRGlyZWN0b3J5KCcvaG9tZS9wcm9qZWN0Jyk7XG4gIGJvY2tmcy5leGVjdXRhYmxlKCcvaG9tZS9wcm9qZWN0L2Nsb3VkLWV4ZWN1dGFibGUnKTtcbiAgYm9ja2ZzLmV4ZWN1dGFibGUoJy9ob21lL3Byb2plY3QvZXhlY3V0YWJsZS1hcHAuanMnKTtcbn0pO1xuXG5hZnRlckVhY2goKCkgPT4ge1xuICBzZXRMb2dMZXZlbChMb2dMZXZlbC5ERUZBVUxUKTtcblxuICBzaW5vbi5yZXN0b3JlKCk7XG4gIGJvY2tmcy5yZXN0b3JlKCk7XG59KTtcblxuLy8gV2UgbmVlZCB0byBpbmNyZWFzZSB0aGUgZGVmYXVsdCA1cyBqZXN0XG4vLyB0aW1lb3V0IGZvciBhc3luYyB0ZXN0cyBiZWNhdXNlIHRoZSAnZXhlY1Byb2dyYW0nIGludm9jYXRpb25cbi8vIG1pZ2h0IHRha2UgYSB3aGlsZSA6XFxcbmNvbnN0IFRFTl9TRUNPTkRfVElNRU9VVCA9IDEwMDAwO1xuXG5mdW5jdGlvbiBjcmVhdGVBcHAoKTogY2RrLkFwcCB7XG4gIGNvbnN0IGFwcCA9IG5ldyBjZGsuQXBwKHsgb3V0ZGlyOiAnY2RrLm91dCcgfSk7XG4gIGNvbnN0IHN0YWNrID0gbmV3IGNkay5TdGFjayhhcHAsICdTdGFjaycpO1xuXG4gIG5ldyBjZGsuQ2ZuUmVzb3VyY2Uoc3RhY2ssICdSb2xlJywge1xuICAgIHR5cGU6ICdBV1M6OklBTTo6Um9sZScsXG4gICAgcHJvcGVydGllczoge1xuICAgICAgUm9sZU5hbWU6ICdSb2xlJyxcbiAgICB9LFxuICB9KTtcblxuICByZXR1cm4gYXBwO1xufVxuXG50ZXN0KCdjbGkgdGhyb3dzIHdoZW4gbWFuaWZlc3QgdmVyc2lvbiA+IHNjaGVtYSB2ZXJzaW9uJywgYXN5bmMgKCkgPT4ge1xuXG4gIGNvbnN0IGFwcCA9IGNyZWF0ZUFwcCgpO1xuICBjb25zdCBjdXJyZW50U2NoZW1hVmVyc2lvbiA9IGN4c2NoZW1hLk1hbmlmZXN0LnZlcnNpb24oKTtcbiAgY29uc3QgbW9ja01hbmlmZXN0VmVyc2lvbiA9IHNlbXZlci5pbmMoY3VycmVudFNjaGVtYVZlcnNpb24sICdtYWpvcicpO1xuXG4gIC8vIHRoaXMgbW9jayB3aWxsIGNhdXNlIHRoZSBmcmFtZXdvcmsgdG8gdXNlIGEgZ3JlYXRlciBzY2hlbWEgdmVyc2lvbiB0aGFuIHRoZSByZWFsIG9uZSxcbiAgLy8gYW5kIHNob3VsZCBjYXVzZSB0aGUgQ0xJIHRvIGZhaWwuXG4gIGNvbnN0IG1vY2tWZXJzaW9uTnVtYmVyID0gSW1wb3J0TW9jay5tb2NrRnVuY3Rpb24oY3hzY2hlbWEuTWFuaWZlc3QsICd2ZXJzaW9uJywgbW9ja01hbmlmZXN0VmVyc2lvbik7XG4gIHRyeSB7XG4gICAgYXBwLnN5bnRoKCk7XG4gIH0gZmluYWxseSB7XG4gICAgbW9ja1ZlcnNpb25OdW1iZXIucmVzdG9yZSgpO1xuICB9XG5cbiAgY29uc3QgZXhwZWN0ZWRFcnJvciA9ICdUaGlzIENESyBDTEkgaXMgbm90IGNvbXBhdGlibGUgd2l0aCB0aGUgQ0RLIGxpYnJhcnkgdXNlZCBieSB5b3VyIGFwcGxpY2F0aW9uLiBQbGVhc2UgdXBncmFkZSB0aGUgQ0xJIHRvIHRoZSBsYXRlc3QgdmVyc2lvbi4nXG4gICAgKyBgXFxuKENsb3VkIGFzc2VtYmx5IHNjaGVtYSB2ZXJzaW9uIG1pc21hdGNoOiBNYXhpbXVtIHNjaGVtYSB2ZXJzaW9uIHN1cHBvcnRlZCBpcyAke2N1cnJlbnRTY2hlbWFWZXJzaW9ufSwgYnV0IGZvdW5kICR7bW9ja01hbmlmZXN0VmVyc2lvbn0pYDtcblxuICBjb25maWcuc2V0dGluZ3Muc2V0KFsnYXBwJ10sICdjZGsub3V0Jyk7XG5cbiAgYXdhaXQgZXhwZWN0KGV4ZWNQcm9ncmFtKHNka1Byb3ZpZGVyLCBjb25maWcpKS5yZWplY3RzLnRvRXF1YWwobmV3IEVycm9yKGV4cGVjdGVkRXJyb3IpKTtcblxufSwgVEVOX1NFQ09ORF9USU1FT1VUKTtcblxudGVzdCgnY2xpIGRvZXMgbm90IHRocm93IHdoZW4gbWFuaWZlc3QgdmVyc2lvbiA9IHNjaGVtYSB2ZXJzaW9uJywgYXN5bmMgKCkgPT4ge1xuXG4gIGNvbnN0IGFwcCA9IGNyZWF0ZUFwcCgpO1xuICBhcHAuc3ludGgoKTtcblxuICBjb25maWcuc2V0dGluZ3Muc2V0KFsnYXBwJ10sICdjZGsub3V0Jyk7XG5cbiAgYXdhaXQgZXhlY1Byb2dyYW0oc2RrUHJvdmlkZXIsIGNvbmZpZyk7XG5cbn0sIFRFTl9TRUNPTkRfVElNRU9VVCk7XG5cbnRlc3QoJ2NsaSBkb2VzIG5vdCB0aHJvdyB3aGVuIG1hbmlmZXN0IHZlcnNpb24gPCBzY2hlbWEgdmVyc2lvbicsIGFzeW5jICgpID0+IHtcblxuICBjb25zdCBhcHAgPSBjcmVhdGVBcHAoKTtcbiAgY29uc3QgY3VycmVudFNjaGVtYVZlcnNpb24gPSBjeHNjaGVtYS5NYW5pZmVzdC52ZXJzaW9uKCk7XG5cbiAgYXBwLnN5bnRoKCk7XG5cbiAgY29uZmlnLnNldHRpbmdzLnNldChbJ2FwcCddLCAnY2RrLm91dCcpO1xuXG4gIC8vIHRoaXMgbW9jayB3aWxsIGNhdXNlIHRoZSBjbGkgdG8gdGhpbmsgaXRzIGV4ZXBjdGVkIHNjaGVtYSB2ZXJzaW9uIGlzXG4gIC8vIGdyZWF0ZXIgdGhhdCB0aGUgdmVyc2lvbiBjcmVhdGVkIGluIHRoZSBtYW5pZmVzdCwgd2hpY2ggaXMgd2hhdCB3ZSBhcmUgdGVzdGluZyBmb3IuXG4gIGNvbnN0IG1vY2tWZXJzaW9uTnVtYmVyID0gSW1wb3J0TW9jay5tb2NrRnVuY3Rpb24oY3hzY2hlbWEuTWFuaWZlc3QsICd2ZXJzaW9uJywgc2VtdmVyLmluYyhjdXJyZW50U2NoZW1hVmVyc2lvbiwgJ21ham9yJykpO1xuICB0cnkge1xuICAgIGF3YWl0IGV4ZWNQcm9ncmFtKHNka1Byb3ZpZGVyLCBjb25maWcpO1xuICB9IGZpbmFsbHkge1xuICAgIG1vY2tWZXJzaW9uTnVtYmVyLnJlc3RvcmUoKTtcbiAgfVxuXG59LCBURU5fU0VDT05EX1RJTUVPVVQpO1xuXG50ZXN0KCd2YWxpZGF0ZXMgLS1hcHAga2V5IGlzIHByZXNlbnQnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOIG5vIGNvbmZpZyBrZXkgZm9yIGBhcHBgXG4gIGF3YWl0IGV4cGVjdChleGVjUHJvZ3JhbShzZGtQcm92aWRlciwgY29uZmlnKSkucmVqZWN0cy50b1Rocm93KFxuICAgICctLWFwcCBpcyByZXF1aXJlZCBlaXRoZXIgaW4gY29tbWFuZC1saW5lLCBpbiBjZGsuanNvbiBvciBpbiB+Ly5jZGsuanNvbicsXG4gICk7XG5cbn0pO1xuXG50ZXN0KCdieXBhc3NlcyBzeW50aCB3aGVuIGFwcCBwb2ludHMgdG8gYSBjbG91ZCBhc3NlbWJseScsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uZmlnLnNldHRpbmdzLnNldChbJ2FwcCddLCAnY2RrLm91dCcpO1xuICB3cml0ZU91dHB1dEFzc2VtYmx5KCk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCBjbG91ZEFzc2VtYmx5ID0gYXdhaXQgZXhlY1Byb2dyYW0oc2RrUHJvdmlkZXIsIGNvbmZpZyk7XG4gIGV4cGVjdChjbG91ZEFzc2VtYmx5LmFydGlmYWN0cykudG9FcXVhbChbXSk7XG4gIGV4cGVjdChjbG91ZEFzc2VtYmx5LmRpcmVjdG9yeSkudG9FcXVhbCgnY2RrLm91dCcpO1xufSk7XG5cbnRlc3QoJ3RoZSBhcHBsaWNhdGlvbiBzZXQgaW4gLS1hcHAgaXMgZXhlY3V0ZWQnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbmZpZy5zZXR0aW5ncy5zZXQoWydhcHAnXSwgJ2Nsb3VkLWV4ZWN1dGFibGUnKTtcbiAgbW9ja1NwYXduKHtcbiAgICBjb21tYW5kTGluZTogWydjbG91ZC1leGVjdXRhYmxlJ10sXG4gICAgc2lkZUVmZmVjdDogKCkgPT4gd3JpdGVPdXRwdXRBc3NlbWJseSgpLFxuICB9KTtcblxuICAvLyBXSEVOXG4gIGF3YWl0IGV4ZWNQcm9ncmFtKHNka1Byb3ZpZGVyLCBjb25maWcpO1xufSk7XG5cbnRlc3QoJ3RoZSBhcHBsaWNhdGlvbiBzZXQgaW4gLS1hcHAgaXMgZXhlY3V0ZWQgYXMtaXMgaWYgaXQgY29udGFpbnMgYSBmaWxlbmFtZSB0aGF0IGRvZXMgbm90IGV4aXN0JywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25maWcuc2V0dGluZ3Muc2V0KFsnYXBwJ10sICdkb2VzLW5vdC1leGlzdCcpO1xuICBtb2NrU3Bhd24oe1xuICAgIGNvbW1hbmRMaW5lOiBbJ2RvZXMtbm90LWV4aXN0J10sXG4gICAgc2lkZUVmZmVjdDogKCkgPT4gd3JpdGVPdXRwdXRBc3NlbWJseSgpLFxuICB9KTtcblxuICAvLyBXSEVOXG4gIGF3YWl0IGV4ZWNQcm9ncmFtKHNka1Byb3ZpZGVyLCBjb25maWcpO1xufSk7XG5cbnRlc3QoJ3RoZSBhcHBsaWNhdGlvbiBzZXQgaW4gLS1hcHAgaXMgZXhlY3V0ZWQgd2l0aCBhcmd1bWVudHMnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbmZpZy5zZXR0aW5ncy5zZXQoWydhcHAnXSwgJ2Nsb3VkLWV4ZWN1dGFibGUgYW4tYXJnJyk7XG4gIG1vY2tTcGF3bih7XG4gICAgY29tbWFuZExpbmU6IFsnY2xvdWQtZXhlY3V0YWJsZScsICdhbi1hcmcnXSxcbiAgICBzaWRlRWZmZWN0OiAoKSA9PiB3cml0ZU91dHB1dEFzc2VtYmx5KCksXG4gIH0pO1xuXG4gIC8vIFdIRU5cbiAgYXdhaXQgZXhlY1Byb2dyYW0oc2RrUHJvdmlkZXIsIGNvbmZpZyk7XG59KTtcblxudGVzdCgnYXBwbGljYXRpb24gc2V0IGluIC0tYXBwIGFzIGAqLmpzYCBhbHdheXMgdXNlcyBoYW5kbGVyIG9uIHdpbmRvd3MnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIHNpbm9uLnN0dWIocHJvY2VzcywgJ3BsYXRmb3JtJykudmFsdWUoJ3dpbjMyJyk7XG4gIGNvbmZpZy5zZXR0aW5ncy5zZXQoWydhcHAnXSwgJ3dpbmRvd3MuanMnKTtcbiAgbW9ja1NwYXduKHtcbiAgICBjb21tYW5kTGluZTogW3Byb2Nlc3MuZXhlY1BhdGgsICd3aW5kb3dzLmpzJ10sXG4gICAgc2lkZUVmZmVjdDogKCkgPT4gd3JpdGVPdXRwdXRBc3NlbWJseSgpLFxuICB9KTtcblxuICAvLyBXSEVOXG4gIGF3YWl0IGV4ZWNQcm9ncmFtKHNka1Byb3ZpZGVyLCBjb25maWcpO1xufSk7XG5cbnRlc3QoJ2FwcGxpY2F0aW9uIHNldCBpbiAtLWFwcCBpcyBgKi5qc2AgYW5kIGV4ZWN1dGFibGUnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbmZpZy5zZXR0aW5ncy5zZXQoWydhcHAnXSwgJ2V4ZWN1dGFibGUtYXBwLmpzJyk7XG4gIG1vY2tTcGF3bih7XG4gICAgY29tbWFuZExpbmU6IFsnZXhlY3V0YWJsZS1hcHAuanMnXSxcbiAgICBzaWRlRWZmZWN0OiAoKSA9PiB3cml0ZU91dHB1dEFzc2VtYmx5KCksXG4gIH0pO1xuXG4gIC8vIFdIRU5cbiAgYXdhaXQgZXhlY1Byb2dyYW0oc2RrUHJvdmlkZXIsIGNvbmZpZyk7XG59KTtcblxuZnVuY3Rpb24gd3JpdGVPdXRwdXRBc3NlbWJseSgpIHtcbiAgY29uc3QgYXNtID0gdGVzdEFzc2VtYmx5KHtcbiAgICBzdGFja3M6IFtdLFxuICB9KTtcbiAgYm9ja2ZzLndyaXRlKCcvaG9tZS9wcm9qZWN0L2Nkay5vdXQvbWFuaWZlc3QuanNvbicsIEpTT04uc3RyaW5naWZ5KGFzbS5tYW5pZmVzdCkpO1xufVxuIl19