UNPKG

@aws-cdk/core

Version:

AWS Cloud Development Kit Core Library

276 lines 39.3 kB
"use strict"; const cxapi = require("@aws-cdk/cx-api"); const lib_1 = require("../lib"); const app_1 = require("../lib/app"); function withApp(props, block) { const app = new app_1.App({ runtimeInfo: false, stackTraces: false, ...props, }); block(app); return app.synth(); } function synth(context) { return withApp({ context }, app => { const stack1 = new lib_1.Stack(app, 'stack1', { env: { account: '12345', region: 'us-east-1' } }); new lib_1.CfnResource(stack1, 's1c1', { type: 'DummyResource', properties: { Prop1: 'Prop1' } }); const r2 = new lib_1.CfnResource(stack1, 's1c2', { type: 'DummyResource', properties: { Foo: 123 } }); const stack2 = new lib_1.Stack(app, 'stack2'); new lib_1.CfnResource(stack2, 's2c1', { type: 'DummyResource', properties: { Prog2: 'Prog2' } }); const c1 = new MyConstruct(stack2, 's1c2'); // add some metadata stack1.node.addMetadata('meta', 111); r2.node.addWarning('warning1'); r2.node.addWarning('warning2'); c1.node.addMetadata('meta', { key: 'value' }); app.node.addMetadata('applevel', 123); // apps can also have metadata }); } function synthStack(name, includeMetadata = false, context) { const response = synth(context); const stack = response.getStackByName(name); if (!includeMetadata) { delete stack.metadata; } return stack; } class MyConstruct extends lib_1.Construct { constructor(scope, id) { super(scope, id); new lib_1.CfnResource(this, 'r1', { type: 'ResourceType1' }); new lib_1.CfnResource(this, 'r2', { type: 'ResourceType2', properties: { FromContext: this.node.tryGetContext('ctx1') } }); } } module.exports = { 'synthesizes all stacks and returns synthesis result'(test) { const response = synth(); delete response.dir; test.deepEqual(response.stacks.length, 2); const stack1 = response.stacks[0]; test.deepEqual(stack1.stackName, 'stack1'); test.deepEqual(stack1.id, 'stack1'); test.deepEqual(stack1.environment.account, 12345); test.deepEqual(stack1.environment.region, 'us-east-1'); test.deepEqual(stack1.environment.name, 'aws://12345/us-east-1'); test.deepEqual(stack1.template, { Resources: { s1c1: { Type: 'DummyResource', Properties: { Prop1: 'Prop1' } }, s1c2: { Type: 'DummyResource', Properties: { Foo: 123 } } } }); test.deepEqual(stack1.manifest.metadata, { '/stack1': [{ type: 'meta', data: 111 }], '/stack1/s1c1': [{ type: 'aws:cdk:logicalId', data: 's1c1' }], '/stack1/s1c2': [{ type: 'aws:cdk:logicalId', data: 's1c2' }, { type: 'aws:cdk:warning', data: 'warning1' }, { type: 'aws:cdk:warning', data: 'warning2' }], }); const stack2 = response.stacks[1]; test.deepEqual(stack2.stackName, 'stack2'); test.deepEqual(stack2.id, 'stack2'); test.deepEqual(stack2.environment.name, 'aws://unknown-account/unknown-region'); test.deepEqual(stack2.template, { Resources: { s2c1: { Type: 'DummyResource', Properties: { Prog2: 'Prog2' } }, s1c2r1D1791C01: { Type: 'ResourceType1' }, s1c2r25F685FFF: { Type: 'ResourceType2' } } }); test.deepEqual(stack2.manifest.metadata, { '/stack2/s2c1': [{ type: 'aws:cdk:logicalId', data: 's2c1' }], '/stack2/s1c2': [{ type: 'meta', data: { key: 'value' } }], '/stack2/s1c2/r1': [{ type: 'aws:cdk:logicalId', data: 's1c2r1D1791C01' }], '/stack2/s1c2/r2': [{ type: 'aws:cdk:logicalId', data: 's1c2r25F685FFF' }], }); test.done(); }, 'context can be passed through CDK_CONTEXT'(test) { process.env[cxapi.CONTEXT_ENV] = JSON.stringify({ key1: 'val1', key2: 'val2' }); const prog = new app_1.App(); test.deepEqual(prog.node.tryGetContext('key1'), 'val1'); test.deepEqual(prog.node.tryGetContext('key2'), 'val2'); test.done(); }, 'context passed through CDK_CONTEXT has precedence'(test) { process.env[cxapi.CONTEXT_ENV] = JSON.stringify({ key1: 'val1', key2: 'val2' }); const prog = new app_1.App({ context: { key1: 'val3', key2: 'val4' } }); test.deepEqual(prog.node.tryGetContext('key1'), 'val1'); test.deepEqual(prog.node.tryGetContext('key2'), 'val2'); test.done(); }, 'context from the command line can be used when creating the stack'(test) { const output = synthStack('stack2', false, { ctx1: 'HELLO' }); test.deepEqual(output.template, { Resources: { s2c1: { Type: "DummyResource", Properties: { Prog2: "Prog2" } }, s1c2r1D1791C01: { Type: "ResourceType1" }, s1c2r25F685FFF: { Type: "ResourceType2", Properties: { FromContext: "HELLO" } } } }); test.done(); }, 'setContext(k,v) can be used to set context programmatically'(test) { const prog = new app_1.App({ context: { foo: 'bar' } }); test.deepEqual(prog.node.tryGetContext('foo'), 'bar'); test.done(); }, 'setContext(k,v) cannot be called after stacks have been added because stacks may use the context'(test) { const prog = new app_1.App(); new lib_1.Stack(prog, 's1'); test.throws(() => prog.node.setContext('foo', 'bar')); test.done(); }, 'app.synth() performs validation first and if there are errors, it returns the errors'(test) { class Child extends lib_1.Construct { validate() { return [`Error from ${this.node.id}`]; } } class Parent extends lib_1.Stack { } const app = new app_1.App(); const parent = new Parent(app, 'Parent'); new Child(parent, 'C1'); new Child(parent, 'C2'); test.throws(() => app.synth(), /Validation failed with the following errors/); test.done(); }, 'app.synthesizeStack(stack) will return a list of missing contextual information'(test) { class MyStack extends lib_1.Stack { constructor(scope, id, props) { super(scope, id, props); this.reportMissingContext({ key: 'missing-context-key', provider: 'fake', props: { account: '12345689012', region: 'ab-north-1', }, }); this.reportMissingContext({ key: 'missing-context-key-2', provider: 'fake2', props: { foo: 'bar', account: '12345689012', region: 'ab-south-1', }, }); } } const assembly = withApp({}, app => { new MyStack(app, 'MyStack'); }); test.deepEqual(assembly.manifest.missing, [ { key: "missing-context-key", provider: 'fake', props: { account: '12345689012', region: 'ab-north-1', }, }, { key: "missing-context-key-2", provider: 'fake2', props: { account: '12345689012', region: 'ab-south-1', foo: 'bar', }, } ]); test.done(); }, 'runtime library versions disabled'(test) { const context = {}; context[cxapi.DISABLE_VERSION_REPORTING] = true; const assembly = withApp(context, app => { const stack = new lib_1.Stack(app, 'stack1'); new lib_1.CfnResource(stack, 'MyResource', { type: 'Resource::Type' }); }); test.deepEqual(assembly.runtime, { libraries: {} }); test.done(); }, 'runtime library versions'(test) { const response = withApp({ runtimeInfo: true }, app => { const stack = new lib_1.Stack(app, 'stack1'); new lib_1.CfnResource(stack, 'MyResource', { type: 'Resource::Type' }); }); const libs = (response.runtime && response.runtime.libraries) || {}; // eslint-disable-next-line @typescript-eslint/no-require-imports const version = require('../package.json').version; test.deepEqual(libs['@aws-cdk/core'], version); test.deepEqual(libs['@aws-cdk/cx-api'], version); test.deepEqual(libs['jsii-runtime'], `node.js/${process.version}`); test.done(); }, 'jsii-runtime version loaded from JSII_AGENT'(test) { process.env.JSII_AGENT = 'Java/1.2.3.4'; const response = withApp({ runtimeInfo: true }, app => { const stack = new lib_1.Stack(app, 'stack1'); new lib_1.CfnResource(stack, 'MyResource', { type: 'Resource::Type' }); }); const libs = (response.runtime && response.runtime.libraries) || {}; test.deepEqual(libs['jsii-runtime'], `Java/1.2.3.4`); delete process.env.JSII_AGENT; test.done(); }, 'version reporting includes only @aws-cdk, aws-cdk and jsii libraries'(test) { const response = withApp({ runtimeInfo: true }, app => { const stack = new lib_1.Stack(app, 'stack1'); new lib_1.CfnResource(stack, 'MyResource', { type: 'Resource::Type' }); }); const libs = (response.runtime && response.runtime.libraries) || {}; // eslint-disable-next-line @typescript-eslint/no-require-imports const version = require('../package.json').version; test.deepEqual(libs, { '@aws-cdk/core': version, '@aws-cdk/cx-api': version, 'jsii-runtime': `node.js/${process.version}` }); test.done(); }, 'deep stack is shown and synthesized properly'(test) { // WHEN const response = withApp({}, (app) => { const topStack = new lib_1.Stack(app, 'Stack'); const topResource = new lib_1.CfnResource(topStack, 'Res', { type: 'CDK::TopStack::Resource' }); const bottomStack = new lib_1.Stack(topResource, 'Stack'); new lib_1.CfnResource(bottomStack, 'Res', { type: 'CDK::BottomStack::Resource' }); }); // THEN test.deepEqual(response.stacks.map(s => ({ name: s.stackName, template: s.template })), [ { name: 'Stack', template: { Resources: { Res: { Type: 'CDK::TopStack::Resource' } } }, }, { name: 'StackResStack7E4AFA86', template: { Resources: { Res: { Type: 'CDK::BottomStack::Resource' } } }, }, ]); test.done(); }, }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5hcHAuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJ0ZXN0LmFwcC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUEseUNBQXlDO0FBRXpDLGdDQUFtRTtBQUNuRSxvQ0FBMkM7QUFFM0MsU0FBUyxPQUFPLENBQUMsS0FBZSxFQUFFLEtBQXlCO0lBQ3pELE1BQU0sR0FBRyxHQUFHLElBQUksU0FBRyxDQUFDO1FBQ2xCLFdBQVcsRUFBRSxLQUFLO1FBQ2xCLFdBQVcsRUFBRSxLQUFLO1FBQ2xCLEdBQUcsS0FBSztLQUNULENBQUMsQ0FBQztJQUVILEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUVYLE9BQU8sR0FBRyxDQUFDLEtBQUssRUFBRSxDQUFDO0FBQ3JCLENBQUM7QUFFRCxTQUFTLEtBQUssQ0FBQyxPQUFnQztJQUM3QyxPQUFPLE9BQU8sQ0FBQyxFQUFFLE9BQU8sRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFO1FBQ2hDLE1BQU0sTUFBTSxHQUFHLElBQUksV0FBSyxDQUFDLEdBQUcsRUFBRSxRQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDNUYsSUFBSSxpQkFBVyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxFQUFFLEtBQUssRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0YsTUFBTSxFQUFFLEdBQUcsSUFBSSxpQkFBVyxDQUFDLE1BQU0sRUFBRSxNQUFNLEVBQUUsRUFBRSxJQUFJLEVBQUUsZUFBZSxFQUFFLFVBQVUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFFaEcsTUFBTSxNQUFNLEdBQUcsSUFBSSxXQUFLLENBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQ3hDLElBQUksaUJBQVcs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LEVBQUUsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsQ0FBQyxDQUFDO1lBRTFGLE1BQU0sV0FBVyxHQUFHLElBQUksV0FBSyxDQUFDLFdBQVcsRUFBRSxPQUFPLENBQUMsQ0FBQztZQUNwRCxJQUFJLGlCQUFXLENBQUMsV0FBVyxFQUFFLEtBQUssRUFBRSxFQUFFLElBQUksRUFBRSw0QkFBNEIsRUFBRSxDQUFDLENBQUM7UUFDOUUsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPO1FBQ1AsSUFBSSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLFNBQVMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDLENBQUMsRUFBRTtZQUN0RjtnQkFDRSxJQUFJLEVBQUUsT0FBTztnQkFDYixRQUFRLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxHQUFHLEVBQUUsRUFBRSxJQUFJLEVBQUUseUJBQXlCLEVBQUUsRUFBRSxFQUFFO2FBQ3RFO1lBQ0Q7Z0JBQ0UsSUFBSSxFQUFFLHVCQUF1QjtnQkFDN0IsUUFBUSxFQUFFLEVBQUUsU0FBUyxFQUFFLEVBQUUsR0FBRyxFQUFFLEVBQUUsSUFBSSxFQUFFLDRCQUE0QixFQUFFLEVBQUUsRUFBRTthQUN6RTtTQUNGLENBQUMsQ0FBQztRQUVILElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUNkLENBQUM7Q0FDQSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgY3hhcGkgZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCB7IFRlc3QgfSBmcm9tICdub2RldW5pdCc7XG5pbXBvcnQgeyBDZm5SZXNvdXJjZSwgQ29uc3RydWN0LCBTdGFjaywgU3RhY2tQcm9wcyB9IGZyb20gJy4uL2xpYic7XG5pbXBvcnQgeyBBcHAsIEFwcFByb3BzIH0gZnJvbSAnLi4vbGliL2FwcCc7XG5cbmZ1bmN0aW9uIHdpdGhBcHAocHJvcHM6IEFwcFByb3BzLCBibG9jazogKGFwcDogQXBwKSA9PiB2b2lkKTogY3hhcGkuQ2xvdWRBc3NlbWJseSB7XG4gIGNvbnN0IGFwcCA9IG5ldyBBcHAoe1xuICAgIHJ1bnRpbWVJbmZvOiBmYWxzZSxcbiAgICBzdGFja1RyYWNlczogZmFsc2UsXG4gICAgLi4ucHJvcHMsXG4gIH0pO1xuXG4gIGJsb2NrKGFwcCk7XG5cbiAgcmV0dXJuIGFwcC5zeW50aCgpO1xufVxuXG5mdW5jdGlvbiBzeW50aChjb250ZXh0PzogeyBba2V5OiBzdHJpbmddOiBhbnkgfSk6IGN4YXBpLkNsb3VkQXNzZW1ibHkge1xuICByZXR1cm4gd2l0aEFwcCh7IGNvbnRleHQgfSwgYXBwID0+IHtcbiAgICBjb25zdCBzdGFjazEgPSBuZXcgU3RhY2soYXBwLCAnc3RhY2sxJywgeyBlbnY6IHsgYWNjb3VudDogJzEyMzQ1JywgcmVnaW9uOiAndXMtZWFzdC0xJyB9IH0pO1xuICAgIG5ldyBDZm5SZXNvdXJjZShzdGFjazEsICdzMWMxJywgeyB0eXBlOiAnRHVtbXlSZXNvdXJjZScsIHByb3BlcnRpZXM6IHsgUHJvcDE6ICdQcm9wMScgfSB9KTtcbiAgICBjb25zdCByMiA9IG5ldyBDZm5SZXNvdXJjZShzdGFjazEsICdzMWMyJywgeyB0eXBlOiAnRHVtbXlSZXNvdXJjZScsIHByb3BlcnRpZXM6IHsgRm9vOiAxMjMgfSB9KTtcblxuICAgIGNvbnN0IHN0YWNrMiA9IG5ldyBTdGFjayhhcHAsICdzdGFjazInKTtcbiAgICBuZXcgQ2ZuUmVzb3VyY2Uoc3RhY2syLCAnczJjMScsIHsgdHlwZTogJ0R1bW15UmVzb3VyY2UnLCBwcm9wZXJ0aWVzOiB7IFByb2cyOiAnUHJvZzInIH0gfSk7XG4gICAgY29uc3QgYzEgPSBuZXcgTXlDb25zdHJ1Y3Qoc3RhY2syLCAnczFjMicpO1xuXG4gICAgLy8gYWRkIHNvbWUgbWV0YWRhdGFcbiAgICBzdGFjazEubm9kZS5hZGRNZXRhZGF0YSgnbWV0YScsIDExMSk7XG4gICAgcjIubm9kZS5hZGRXYXJuaW5nKCd3YXJuaW5nMScpO1xuICAgIHIyLm5vZGUuYWRkV2FybmluZygnd2FybmluZzInKTtcbiAgICBjMS5ub2RlLmFkZE1ldGFkYXRhKCdtZXRhJywgeyBrZXk6ICd2YWx1ZScgfSk7XG4gICAgYXBwLm5vZGUuYWRkTWV0YWRhdGEoJ2FwcGxldmVsJywgMTIzKTsgLy8gYXBwcyBjYW4gYWxzbyBoYXZlIG1ldGFkYXRhXG4gIH0pO1xufVxuXG5mdW5jdGlvbiBzeW50aFN0YWNrKG5hbWU6IHN0cmluZywgaW5jbHVkZU1ldGFkYXRhOiBib29sZWFuID0gZmFsc2UsIGNvbnRleHQ/OiBhbnkpOiBjeGFwaS5DbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3Qge1xuICBjb25zdCByZXNwb25zZSA9IHN5bnRoKGNvbnRleHQpO1xuICBjb25zdCBzdGFjayA9IHJlc3BvbnNlLmdldFN0YWNrQnlOYW1lKG5hbWUpO1xuXG4gIGlmICghaW5jbHVkZU1ldGFkYXRhKSB7XG4gICAgZGVsZXRlIChzdGFjayBhcyBhbnkpLm1ldGFkYXRhO1xuICB9XG5cbiAgcmV0dXJuIHN0YWNrO1xufVxuXG5leHBvcnQgPSB7XG4gICdzeW50aGVzaXplcyBhbGwgc3RhY2tzIGFuZCByZXR1cm5zIHN5bnRoZXNpcyByZXN1bHQnKHRlc3Q6IFRlc3QpIHtcbiAgICBjb25zdCByZXNwb25zZSA9IHN5bnRoKCk7XG4gICAgZGVsZXRlIChyZXNwb25zZSBhcyBhbnkpLmRpcjtcblxuICAgIHRlc3QuZGVlcEVxdWFsKHJlc3BvbnNlLnN0YWNrcy5sZW5ndGgsIDIpO1xuXG4gICAgY29uc3Qgc3RhY2sxID0gcmVzcG9uc2Uuc3RhY2tzWzBdO1xuICAgIHRlc3QuZGVlcEVxdWFsKHN0YWNrMS5zdGFja05hbWUsICdzdGFjazEnKTtcbiAgICB0ZXN0LmRlZXBFcXVhbChzdGFjazEuaWQsICdzdGFjazEnKTtcbiAgICB0ZXN0LmRlZXBFcXVhbChzdGFjazEuZW52aXJvbm1lbnQuYWNjb3VudCwgMTIzNDUpO1xuICAgIHRlc3QuZGVlcEVxdWFsKHN0YWNrMS5lbnZpcm9ubWVudC5yZWdpb24sICd1cy1lYXN0LTEnKTtcbiAgICB0ZXN0LmRlZXBFcXVhbChzdGFjazEuZW52aXJvbm1lbnQubmFtZSwgJ2F3czovLzEyMzQ1L3VzLWVhc3QtMScpO1xuICAgIHRlc3QuZGVlcEVxdWFsKHN0YWNrMS50ZW1wbGF0ZSwgeyBSZXNvdXJjZXM6XG4gICAgICB7IHMxYzE6IHsgVHlwZTogJ0R1bW15UmVzb3VyY2UnLCBQcm9wZXJ0aWVzOiB7IFByb3AxOiAnUHJvcDEnIH0gfSxcbiAgICAgICAgczFjMjogeyBUeXBlOiAnRHVtbXlSZXNvdXJjZScsIFByb3BlcnRpZXM6IHsgRm9vOiAxMjMgfSB9IH0gfSk7XG4gICAgdGVzdC5kZWVwRXF1YWwoc3RhY2sxLm1hbmlmZXN0Lm1ldGFkYXRhLCB7XG4gICAgICAnL3N0YWNrMSc6IFt7IHR5cGU6ICdtZXRhJywgZGF0YTogMTExIH1dLFxuICAgICAgJy9zdGFjazEvczFjMSc6IFt7IHR5cGU6ICdhd3M6Y2RrOmxvZ2ljYWxJZCcsIGRhdGE6ICdzMWMxJyB9XSxcbiAgICAgICcvc3RhY2sxL3MxYzInOlxuICAgICAgICBbeyB0eXBlOiAnYXdzOmNkazpsb2dpY2FsSWQnLCBkYXRhOiAnczFjMicgfSxcbiAgICAgICAgeyB0eXBlOiAnYXdzOmNkazp3YXJuaW5nJywgZGF0YTogJ3dhcm5pbmcxJyB9LFxuICAgICAgICB7IHR5cGU6ICdhd3M6Y2RrOndhcm5pbmcnLCBkYXRhOiAnd2FybmluZzInIH1dLFxuICAgIH0pO1xuXG4gICAgY29uc3Qgc3RhY2syID0gcmVzcG9uc2Uuc3RhY2tzWzFdO1xuICAgIHRlc3QuZGVlcEVxdWFsKHN0YWNrMi5zdGFja05hbWUsICdzdGFjazInKTtcbiAgICB0ZXN0LmRlZXBFcXVhbChzdGFjazIuaWQsICdzdGFjazInKTtcbiAgICB0ZXN0LmRlZXBFcXVhbChzdGFjazIuZW52aXJvbm1lbnQubmFtZSwgJ2F3czovL3Vua25vd24tYWNjb3VudC91bmtub3duLXJlZ2lvbicpO1xuICAgIHRlc3QuZGVlcEVxdWFsKHN0YWNrMi50ZW1wbGF0ZSwgeyBSZXNvdXJjZXM6XG4gICAgICB7IHMyYzE6IHsgVHlwZTogJ0R1bW15UmVzb3VyY2UnLCBQcm9wZXJ0aWVzOiB7IFByb2cyOiAnUHJvZzInIH0gfSxcbiAgICAgICAgczFjMnIxRDE3OTFDMDE6IHsgVHlwZTogJ1Jlc291cmNlVHlwZTEnIH0sXG4gICAgICAgIHMxYzJyMjVGNjg1RkZGOiB7IFR5cGU6ICdSZXNvdXJjZVR5cGUyJyB9IH0gfSk7XG4gICAgdGVzdC5kZWVwRXF1YWwoc3RhY2syLm1hbmlmZXN0Lm1ldGFkYXRhLCB7XG4gICAgICAnL3N0YWNrMi9zMmMxJzogW3sgdHlwZTogJ2F3czpjZGs6bG9naWNhbElkJywgZGF0YTogJ3MyYzEnIH1dLFxuICAgICAgJy9zdGFjazIvczFjMic6IFt7IHR5cGU6ICdtZXRhJywgZGF0YTogeyBrZXk6ICd2YWx1ZScgfSB9XSxcbiAgICAgICcvc3RhY2syL3MxYzIvcjEnOlxuICAgICAgICBbeyB0eXBlOiAnYXdzOmNkazpsb2dpY2FsSWQnLCBkYXRhOiAnczFjMnIxRDE3OTFDMDEnIH1dLFxuICAgICAgJy9zdGFjazIvczFjMi9yMic6XG4gICAgICAgIFt7IHR5cGU6ICdhd3M6Y2RrOmxvZ2ljYWxJZCcsIGRhdGE6ICdzMWMycjI1RjY4NUZGRicgfV0sXG4gICAgfSk7XG5cbiAgICB0ZXN0LmRvbmUoKTtcbn0sXG5cbidjb250ZXh0IGNhbiBiZSBwYXNzZWQgdGhyb3VnaCBDREtfQ09OVEVYVCcodGVzdDogVGVzdCkge1xuICBwcm9jZXNzLmVudltjeGFwaS5DT05URVhUX0VOVl0gPSBKU09OLnN0cmluZ2lmeSh7XG4gICAga2V5MTogJ3ZhbDEnLFxuICAgIGtleTI6ICd2YWwyJ1xuICB9KTtcbiAgY29uc3QgcHJvZyA9IG5ldyBBcHAoKTtcbiAgdGVzdC5kZWVwRXF1YWwocHJvZy5ub2RlLnRyeUdldENvbnRleHQoJ2tleTEnKSwgJ3ZhbDEnKTtcbiAgdGVzdC5kZWVwRXF1YWwocHJvZy5ub2RlLnRyeUdldENvbnRleHQoJ2tleTInKSwgJ3ZhbDInKTtcbiAgdGVzdC5kb25lKCk7XG59LFxuXG4nY29udGV4dCBwYXNzZWQgdGhyb3VnaCBDREtfQ09OVEVYVCBoYXMgcHJlY2VkZW5jZScodGVzdDogVGVzdCkge1xuICBwcm9jZXNzLmVudltjeGFwaS5DT05URVhUX0VOVl0gPSBKU09OLnN0cmluZ2lmeSh7XG4gICAga2V5MTogJ3ZhbDEnLFxuICAgIGtleTI6ICd2YWwyJ1xuICB9KTtcbiAgY29uc3QgcHJvZyA9IG5ldyBBcHAoe1xuICAgIGNvbnRleHQ6IHtcbiAgICAgIGtleTE6ICd2YWwzJyxcbiAgICAgIGtleTI6ICd2YWw0J1xuICAgIH1cbiAgfSk7XG4gIHRlc3QuZGVlcEVxdWFsKHByb2cubm9kZS50cnlHZXRDb250ZXh0KCdrZXkxJyksICd2YWwxJyk7XG4gIHRlc3QuZGVlcEVxdWFsKHByb2cubm9kZS50cnlHZXRDb250ZXh0KCdrZXkyJyksICd2YWwyJyk7XG4gIHRlc3QuZG9uZSgpO1xufSxcblxuJ2NvbnRleHQgZnJvbSB0aGUgY29tbWFuZCBsaW5lIGNhbiBiZSB1c2VkIHdoZW4gY3JlYXRpbmcgdGhlIHN0YWNrJyh0ZXN0OiBUZXN0KSB7XG4gIGNvbnN0IG91dHB1dCA9IHN5bnRoU3RhY2soJ3N0YWNrMicsIGZhbHNlLCB7IGN0eDE6ICdIRUxMTycgfSk7XG5cbiAgdGVzdC5kZWVwRXF1YWwob3V0cHV0LnRlbXBsYXRlLCB7XG4gICAgUmVzb3VyY2VzOiB7XG4gICAgICBzMmMxOiB7XG4gICAgICAgIFR5cGU6IFwiRHVtbXlSZXNvdXJjZVwiLFxuICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgUHJvZzI6IFwiUHJvZzJcIlxuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgczFjMnIxRDE3OTFDMDE6IHtcbiAgICAgICAgVHlwZTogXCJSZXNvdXJjZVR5cGUxXCJcbiAgICAgIH0sXG4gICAgICBzMWMycjI1RjY4NUZGRjoge1xuICAgICAgICBUeXBlOiBcIlJlc291cmNlVHlwZTJcIixcbiAgICAgICAgUHJvcGVydGllczoge1xuICAgICAgICAgIEZyb21Db250ZXh0OiBcIkhFTExPXCJcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHRlc3QuZG9uZSgpO1xufSxcblxuJ3NldENvbnRleHQoayx2KSBjYW4gYmUgdXNlZCB0byBzZXQgY29udGV4dCBwcm9ncmFtbWF0aWNhbGx5Jyh0ZXN0OiBUZXN0KSB7XG4gIGNvbnN0IHByb2cgPSBuZXcgQXBwKHtcbiAgICBjb250ZXh0OiB7XG4gICAgICBmb286ICdiYXInXG4gICAgfVxuICB9KTtcbiAgdGVzdC5kZWVwRXF1YWwocHJvZy5ub2RlLnRyeUdldENvbnRleHQoJ2ZvbycpLCAnYmFyJyk7XG4gIHRlc3QuZG9uZSgpO1xufSxcblxuJ3NldENvbnRleHQoayx2KSBjYW5ub3QgYmUgY2FsbGVkIGFmdGVyIHN0YWNrcyBoYXZlIGJlZW4gYWRkZWQgYmVjYXVzZSBzdGFja3MgbWF5IHVzZSB0aGUgY29udGV4dCcodGVzdDogVGVzdCkge1xuICBjb25zdCBwcm9nID0gbmV3IEFwcCgpO1xuICBuZXcgU3RhY2socHJvZywgJ3MxJyk7XG4gIHRlc3QudGhyb3dzKCgpID0+IHByb2cubm9kZS5zZXRDb250ZXh0KCdmb28nLCAnYmFyJykpO1xuICB0ZXN0LmRvbmUoKTtcbn0sXG5cbidhcHAuc3ludGgoKSBwZXJmb3JtcyB2YWxpZGF0aW9uIGZpcnN0IGFuZCBpZiB0aGVyZSBhcmUgZXJyb3JzLCBpdCByZXR1cm5zIHRoZSBlcnJvcnMnKHRlc3Q6IFRlc3QpIHtcblxuICBjbGFzcyBDaGlsZCBleHRlbmRzIENvbnN0cnVjdCB7XG4gICAgcHJvdGVjdGVkIHZhbGlkYXRlKCkge1xuICAgICAgcmV0dXJuIFtgRXJyb3IgZnJvbSAke3RoaXMubm9kZS5pZH1gXTtcbiAgICB9XG4gIH1cblxuICBjbGFzcyBQYXJlbnQgZXh0ZW5kcyBTdGFjayB7XG5cbiAgfVxuXG4gIGNvbnN0IGFwcCA9IG5ldyBBcHAoKTtcblxuICBjb25zdCBwYXJlbnQgPSBuZXcgUGFyZW50KGFwcCwgJ1BhcmVudCcpO1xuICBuZXcgQ2hpbGQocGFyZW50LCAnQzEnKTtcbiAgbmV3IENoaWxkKHBhcmVudCwgJ0MyJyk7XG5cbiAgdGVzdC50aHJvd3MoKCkgPT4gYXBwLnN5bnRoKCksIC9WYWxpZGF0aW9uIGZhaWxlZCB3aXRoIHRoZSBmb2xsb3dpbmcgZXJyb3JzLyk7XG5cbiAgdGVzdC5kb25lKCk7XG59LFxuXG4nYXBwLnN5bnRoZXNpemVTdGFjayhzdGFjaykgd2lsbCByZXR1cm4gYSBsaXN0IG9mIG1pc3NpbmcgY29udGV4dHVhbCBpbmZvcm1hdGlvbicodGVzdDogVGVzdCkge1xuICBjbGFzcyBNeVN0YWNrIGV4dGVuZHMgU3RhY2sge1xuICAgIGNvbnN0cnVjdG9yKHNjb3BlOiBBcHAsIGlkOiBzdHJpbmcsIHByb3BzPzogU3RhY2tQcm9wcykge1xuICAgICAgc3VwZXIoc2NvcGUsIGlkLCBwcm9wcyk7XG5cbiAgICAgIHRoaXMucmVwb3J0TWlzc2luZ0NvbnRleHQoe1xuICAgICAgICBrZXk6ICdtaXNzaW5nLWNvbnRleHQta2V5JyxcbiAgICAgICAgcHJvdmlkZXI6ICdmYWtlJyxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBhY2NvdW50OiAnMTIzNDU2ODkwMTInLFxuICAgICAgICAgIHJlZ2lvbjogJ2FiLW5vcnRoLTEnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMucmVwb3J0TWlzc2luZ0NvbnRleHQoe1xuICAgICAgICBrZXk6ICdtaXNzaW5nLWNvbnRleHQta2V5LTInLFxuICAgICAgICBwcm92aWRlcjogJ2Zha2UyJyxcbiAgICAgICAgcHJvcHM6IHtcbiAgICAgICAgICBmb286ICdiYXInLFxuICAgICAgICAgIGFjY291bnQ6ICcxMjM0NTY4OTAxMicsXG4gICAgICAgICAgcmVnaW9uOiAnYWItc291dGgtMScsXG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBjb25zdCBhc3NlbWJseSA9IHdpdGhBcHAoe30sIGFwcCA9PiB7XG4gICAgbmV3IE15U3RhY2soYXBwLCAnTXlTdGFjaycpO1xuICB9KTtcblxuICB0ZXN0LmRlZXBFcXVhbChhc3NlbWJseS5tYW5pZmVzdC5taXNzaW5nLCBbXG4gICAge1xuICAgICAga2V5OiBcIm1pc3NpbmctY29udGV4dC1rZXlcIixcbiAgICAgIHByb3ZpZGVyOiAnZmFrZScsXG4gICAgICBwcm9wczoge1xuICAgICAgICBhY2NvdW50OiAnMTIzNDU2ODkwMTInLFxuICAgICAgICByZWdpb246ICdhYi1ub3J0aC0xJyxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBrZXk6IFwibWlzc2luZy1jb250ZXh0LWtleS0yXCIsXG4gICAgICBwcm92aWRlcjogJ2Zha2UyJyxcbiAgICAgIHByb3BzOiB7XG4gICAgICAgIGFjY291bnQ6ICcxMjM0NTY4OTAxMicsXG4gICAgICAgIHJlZ2lvbjogJ2FiLXNvdXRoLTEnLFxuICAgICAgICBmb286ICdiYXInLFxuICAgICAgfSxcbiAgICB9XG4gIF0pO1xuXG4gIHRlc3QuZG9uZSgpO1xufSxcblxuJ3J1bnRpbWUgbGlicmFyeSB2ZXJzaW9ucyBkaXNhYmxlZCcodGVzdDogVGVzdCkge1xuICBjb25zdCBjb250ZXh0OiBhbnkgPSB7fTtcbiAgY29udGV4dFtjeGFwaS5ESVNBQkxFX1ZFUlNJT05fUkVQT1JUSU5HXSA9IHRydWU7XG5cbiAgY29uc3QgYXNzZW1ibHkgPSB3aXRoQXBwKGNvbnRleHQsIGFwcCA9PiB7XG4gICAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soYXBwLCAnc3RhY2sxJyk7XG4gICAgbmV3IENmblJlc291cmNlKHN0YWNrLCAnTXlSZXNvdXJjZScsIHsgdHlwZTogJ1Jlc291cmNlOjpUeXBlJyB9KTtcbiAgfSk7XG5cbiAgdGVzdC5kZWVwRXF1YWwoYXNzZW1ibHkucnVudGltZSwgeyBsaWJyYXJpZXM6IHt9IH0pO1xuICB0ZXN0LmRvbmUoKTtcbn0sXG5cbidydW50aW1lIGxpYnJhcnkgdmVyc2lvbnMnKHRlc3Q6IFRlc3QpIHtcbiAgY29uc3QgcmVzcG9uc2UgPSB3aXRoQXBwKHsgcnVudGltZUluZm86IHRydWUgfSwgYXBwID0+IHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayhhcHAsICdzdGFjazEnKTtcbiAgICBuZXcgQ2ZuUmVzb3VyY2Uoc3RhY2ssICdNeVJlc291cmNlJywgeyB0eXBlOiAnUmVzb3VyY2U6OlR5cGUnIH0pO1xuICB9KTtcblxuICBjb25zdCBsaWJzID0gKHJlc3BvbnNlLnJ1bnRpbWUgJiYgcmVzcG9uc2UucnVudGltZS5saWJyYXJpZXMpIHx8IHt9O1xuXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG4gIGNvbnN0IHZlcnNpb24gPSByZXF1aXJlKCcuLi9wYWNrYWdlLmpzb24nKS52ZXJzaW9uO1xuICB0ZXN0LmRlZXBFcXVhbChsaWJzWydAYXdzLWNkay9jb3JlJ10sIHZlcnNpb24pO1xuICB0ZXN0LmRlZXBFcXVhbChsaWJzWydAYXdzLWNkay9jeC1hcGknXSwgdmVyc2lvbik7XG4gIHRlc3QuZGVlcEVxdWFsKGxpYnNbJ2pzaWktcnVudGltZSddLCBgbm9kZS5qcy8ke3Byb2Nlc3MudmVyc2lvbn1gKTtcbiAgdGVzdC5kb25lKCk7XG59LFxuXG4nanNpaS1ydW50aW1lIHZlcnNpb24gbG9hZGVkIGZyb20gSlNJSV9BR0VOVCcodGVzdDogVGVzdCkge1xuICBwcm9jZXNzLmVudi5KU0lJX0FHRU5UID0gJ0phdmEvMS4yLjMuNCc7XG5cbiAgY29uc3QgcmVzcG9uc2UgPSB3aXRoQXBwKHsgcnVudGltZUluZm86IHRydWUgfSwgYXBwID0+IHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayhhcHAsICdzdGFjazEnKTtcbiAgICBuZXcgQ2ZuUmVzb3VyY2Uoc3RhY2ssICdNeVJlc291cmNlJywgeyB0eXBlOiAnUmVzb3VyY2U6OlR5cGUnIH0pO1xuICB9KTtcblxuICBjb25zdCBsaWJzID0gKHJlc3BvbnNlLnJ1bnRpbWUgJiYgcmVzcG9uc2UucnVudGltZS5saWJyYXJpZXMpIHx8IHt9O1xuICB0ZXN0LmRlZXBFcXVhbChsaWJzWydqc2lpLXJ1bnRpbWUnXSwgYEphdmEvMS4yLjMuNGApO1xuXG4gIGRlbGV0ZSBwcm9jZXNzLmVudi5KU0lJX0FHRU5UO1xuICB0ZXN0LmRvbmUoKTtcbn0sXG5cbid2ZXJzaW9uIHJlcG9ydGluZyBpbmNsdWRlcyBvbmx5IEBhd3MtY2RrLCBhd3MtY2RrIGFuZCBqc2lpIGxpYnJhcmllcycodGVzdDogVGVzdCkge1xuICBjb25zdCByZXNwb25zZSA9IHdpdGhBcHAoeyBydW50aW1lSW5mbzogdHJ1ZSB9LCBhcHAgPT4ge1xuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKGFwcCwgJ3N0YWNrMScpO1xuICAgIG5ldyBDZm5SZXNvdXJjZShzdGFjaywgJ015UmVzb3VyY2UnLCB7IHR5cGU6ICdSZXNvdXJjZTo6VHlwZScgfSk7XG4gIH0pO1xuXG4gIGNvbnN0IGxpYnMgPSAocmVzcG9uc2UucnVudGltZSAmJiByZXNwb25zZS5ydW50aW1lLmxpYnJhcmllcykgfHwge307XG5cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcbiAgY29uc3QgdmVyc2lvbiA9IHJlcXVpcmUoJy4uL3BhY2thZ2UuanNvbicpLnZlcnNpb247XG4gIHRlc3QuZGVlcEVxdWFsKGxpYnMsIHtcbiAgICAnQGF3cy1jZGsvY29yZSc6IHZlcnNpb24sXG4gICAgJ0Bhd3MtY2RrL2N4LWFwaSc6IHZlcnNpb24sXG4gICAgJ2pzaWktcnVudGltZSc6IGBub2RlLmpzLyR7cHJvY2Vzcy52ZXJzaW9ufWBcbiAgfSk7XG5cbiAgdGVzdC5kb25lKCk7XG59LFxuXG4nZGVlcCBzdGFjayBpcyBzaG93biBhbmQgc3ludGhlc2l6ZWQgcHJvcGVybHknKHRlc3Q6IFRlc3QpIHtcbiAgLy8gV0hFTlxuICBjb25zdCByZXNwb25zZSA9IHdpdGhBcHAoe30sIChhcHApID0+IHtcbiAgICBjb25zdCB0b3BTdGFjayA9IG5ldyBTdGFjayhhcHAsICdTdGFjaycpO1xuICAgIGNvbnN0IHRvcFJlc291cmNlID0gbmV3IENmblJlc291cmNlKHRvcFN0YWNrLCAnUmVzJywgeyB0eXBlOiAnQ0RLOjpUb3BTdGFjazo6UmVzb3VyY2UnIH0pO1xuXG4gICAgY29uc3QgYm90dG9tU3RhY2sgPSBuZXcgU3RhY2sodG9wUmVzb3VyY2UsICdTdGFjaycpO1xuICAgIG5ldyBDZm5SZXNvdXJjZShib3R0b21TdGFjaywgJ1JlcycsIHsgdHlwZTogJ0NESzo6Qm90dG9tU3RhY2s6OlJlc291cmNlJyB9KTtcbiAgfSk7XG5cbiAgLy8gVEhFTlxuICB0ZXN0LmRlZXBFcXVhbChyZXNwb25zZS5zdGFja3MubWFwKHMgPT4gKHsgbmFtZTogcy5zdGFja05hbWUsIHRlbXBsYXRlOiBzLnRlbXBsYXRlIH0pKSwgW1xuICAgIHtcbiAgICAgIG5hbWU6ICdTdGFjaycsXG4gICAgICB0ZW1wbGF0ZTogeyBSZXNvdXJjZXM6IHsgUmVzOiB7IFR5cGU6ICdDREs6OlRvcFN0YWNrOjpSZXNvdXJjZScgfSB9IH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBuYW1lOiAnU3RhY2tSZXNTdGFjazdFNEFGQTg2JyxcbiAgICAgIHRlbXBsYXRlOiB7IFJlc291cmNlczogeyBSZXM6IHsgVHlwZTogJ0NESzo6Qm90dG9tU3RhY2s6OlJlc291cmNlJyB9IH0gfSxcbiAgICB9LFxuICBdKTtcblxuICB0ZXN0LmRvbmUoKTtcbn0sXG59O1xuXG5jbGFzcyBNeUNvbnN0cnVjdCBleHRlbmRzIENvbnN0cnVjdCB7XG4gIGNvbnN0cnVjdG9yKHNjb3BlOiBDb25zdHJ1Y3QsIGlkOiBzdHJpbmcpIHtcbiAgICBzdXBlcihzY29wZSwgaWQpO1xuXG4gICAgbmV3IENmblJlc291cmNlKHRoaXMsICdyMScsIHsgdHlwZTogJ1Jlc291cmNlVHlwZTEnIH0pO1xuICAgIG5ldyBDZm5SZXNvdXJjZSh0aGlzLCAncjInLCB7IHR5cGU6ICdSZXNvdXJjZVR5cGUyJywgcHJvcGVydGllczogeyBGcm9tQ29udGV4dDogdGhpcy5ub2RlLnRyeUdldENvbnRleHQoJ2N0eDEnKSB9IH0pO1xuICB9XG59XG4iXX0=