@aws-cdk/core
Version:
AWS Cloud Development Kit Core Library
502 lines • 74.7 kB
JavaScript
"use strict";
const lib_1 = require("../lib");
const intrinsic_1 = require("../lib/private/intrinsic");
const util_1 = require("./util");
class StackWithPostProcessor extends lib_1.Stack {
// ...
_toCloudFormation() {
const template = super._toCloudFormation();
// manipulate template (e.g. rename "Key" to "key")
template.Resources.myResource.Properties.Environment.key =
template.Resources.myResource.Properties.Environment.Key;
delete template.Resources.myResource.Properties.Environment.Key;
return template;
}
}
module.exports = {
'a stack can be serialized into a CloudFormation template, initially it\'s empty'(test) {
const stack = new lib_1.Stack();
test.deepEqual(util_1.toCloudFormation(stack), {});
test.done();
},
'stack objects have some template-level propeties, such as Description, Version, Transform'(test) {
const stack = new lib_1.Stack();
stack.templateOptions.templateFormatVersion = 'MyTemplateVersion';
stack.templateOptions.description = 'This is my description';
stack.templateOptions.transform = 'SAMy';
test.deepEqual(util_1.toCloudFormation(stack), {
Description: 'This is my description',
AWSTemplateFormatVersion: 'MyTemplateVersion',
Transform: 'SAMy'
});
test.done();
},
'Stack.isStack indicates that a construct is a stack'(test) {
const stack = new lib_1.Stack();
const c = new lib_1.Construct(stack, 'Construct');
test.ok(lib_1.Stack.isStack(stack));
test.ok(!lib_1.Stack.isStack(c));
test.done();
},
'stack.id is not included in the logical identities of resources within it'(test) {
const stack = new lib_1.Stack(undefined, 'MyStack');
new lib_1.CfnResource(stack, 'MyResource', { type: 'MyResourceType' });
test.deepEqual(util_1.toCloudFormation(stack), { Resources: { MyResource: { Type: 'MyResourceType' } } });
test.done();
},
'stack.templateOptions can be used to set template-level options'(test) {
const stack = new lib_1.Stack();
stack.templateOptions.description = 'StackDescription';
stack.templateOptions.templateFormatVersion = 'TemplateVersion';
stack.templateOptions.transform = 'DeprecatedField';
stack.templateOptions.transforms = ['Transform'];
stack.templateOptions.metadata = {
MetadataKey: 'MetadataValue'
};
test.deepEqual(util_1.toCloudFormation(stack), {
Description: 'StackDescription',
Transform: ['DeprecatedField', 'Transform'],
AWSTemplateFormatVersion: 'TemplateVersion',
Metadata: { MetadataKey: 'MetadataValue' }
});
test.done();
},
// This approach will only apply to TypeScript code, but at least it's a temporary
// workaround for people running into issues caused by SDK-3003.
// We should come up with a proper solution that involved jsii callbacks (when they exist)
// so this can be implemented by jsii languages as well.
'Overriding `Stack._toCloudFormation` allows arbitrary post-processing of the generated template during synthesis'(test) {
const stack = new StackWithPostProcessor();
new lib_1.CfnResource(stack, 'myResource', {
type: 'AWS::MyResource',
properties: {
MyProp1: 'hello',
MyProp2: 'howdy',
Environment: {
Key: 'value'
}
}
});
test.deepEqual(stack._toCloudFormation(), { Resources: { myResource: { Type: 'AWS::MyResource',
Properties: { MyProp1: 'hello',
MyProp2: 'howdy',
Environment: { key: 'value' } } } } });
test.done();
},
'Stack.getByPath can be used to find any CloudFormation element (Parameter, Output, etc)'(test) {
const stack = new lib_1.Stack();
const p = new lib_1.CfnParameter(stack, 'MyParam', { type: 'String' });
const o = new lib_1.CfnOutput(stack, 'MyOutput', { value: 'boom' });
const c = new lib_1.CfnCondition(stack, 'MyCondition');
test.equal(stack.node.findChild(p.node.path), p);
test.equal(stack.node.findChild(o.node.path), o);
test.equal(stack.node.findChild(c.node.path), c);
test.done();
},
'Stack names can have hyphens in them'(test) {
const root = new lib_1.App();
new lib_1.Stack(root, 'Hello-World');
// Did not throw
test.done();
},
'Include should support non-hash top-level template elements like "Description"'(test) {
const stack = new lib_1.Stack();
const template = {
Description: 'hello, world'
};
new lib_1.CfnInclude(stack, 'Include', { template });
const output = util_1.toCloudFormation(stack);
test.equal(typeof output.Description, 'string');
test.done();
},
'Pseudo values attached to one stack can be referenced in another stack'(test) {
// GIVEN
const app = new lib_1.App();
const stack1 = new lib_1.Stack(app, 'Stack1');
const account1 = new lib_1.ScopedAws(stack1).accountId;
const stack2 = new lib_1.Stack(app, 'Stack2');
// WHEN - used in another stack
new lib_1.CfnParameter(stack2, 'SomeParameter', { type: 'String', default: account1 });
// THEN
const assembly = app.synth();
const template1 = assembly.getStack(stack1.stackName).template;
const template2 = assembly.getStack(stack2.stackName).template;
test.deepEqual(template1, {
Outputs: {
ExportsOutputRefAWSAccountIdAD568057: {
Value: { Ref: 'AWS::AccountId' },
Export: { Name: 'Stack1:ExportsOutputRefAWSAccountIdAD568057' }
}
}
});
test.deepEqual(template2, {
Parameters: {
SomeParameter: {
Type: 'String',
Default: { 'Fn::ImportValue': 'Stack1:ExportsOutputRefAWSAccountIdAD568057' }
}
}
});
test.done();
},
'Cross-stack references are detected in resource properties'(test) {
// GIVEN
const app = new lib_1.App();
const stack1 = new lib_1.Stack(app, 'Stack1');
const resource1 = new lib_1.CfnResource(stack1, 'Resource', { type: 'BLA' });
const stack2 = new lib_1.Stack(app, 'Stack2');
// WHEN - used in another resource
new lib_1.CfnResource(stack2, 'SomeResource', { type: 'AWS::Some::Resource', properties: {
someProperty: new intrinsic_1.Intrinsic(resource1.ref),
} });
// THEN
const assembly = app.synth();
const template2 = assembly.getStack(stack2.stackName).template;
test.deepEqual(template2, {
Resources: {
SomeResource: {
Type: 'AWS::Some::Resource',
Properties: {
someProperty: { 'Fn::ImportValue': 'Stack1:ExportsOutputRefResource1D5D905A' }
}
}
}
});
test.done();
},
'cross-stack references in lazy tokens work'(test) {
// GIVEN
const app = new lib_1.App();
const stack1 = new lib_1.Stack(app, 'Stack1');
const account1 = new lib_1.ScopedAws(stack1).accountId;
const stack2 = new lib_1.Stack(app, 'Stack2');
// WHEN - used in another stack
new lib_1.CfnParameter(stack2, 'SomeParameter', { type: 'String', default: lib_1.Lazy.stringValue({ produce: () => account1 }) });
const assembly = app.synth();
const template1 = assembly.getStack(stack1.stackName).template;
const template2 = assembly.getStack(stack2.stackName).template;
// THEN
test.deepEqual(template1, {
Outputs: {
ExportsOutputRefAWSAccountIdAD568057: {
Value: { Ref: 'AWS::AccountId' },
Export: { Name: 'Stack1:ExportsOutputRefAWSAccountIdAD568057' }
}
}
});
test.deepEqual(template2, {
Parameters: {
SomeParameter: {
Type: 'String',
Default: { 'Fn::ImportValue': 'Stack1:ExportsOutputRefAWSAccountIdAD568057' }
}
}
});
test.done();
},
'Cross-stack use of Region and account returns nonscoped intrinsic because the two stacks must be in the same region anyway'(test) {
// GIVEN
const app = new lib_1.App();
const stack1 = new lib_1.Stack(app, 'Stack1');
const stack2 = new lib_1.Stack(app, 'Stack2');
// WHEN - used in another stack
new lib_1.CfnOutput(stack2, 'DemOutput', { value: stack1.region });
new lib_1.CfnOutput(stack2, 'DemAccount', { value: stack1.account });
// THEN
const assembly = app.synth();
const template2 = assembly.getStack(stack2.stackName).template;
test.deepEqual(template2, {
Outputs: {
DemOutput: {
Value: { Ref: 'AWS::Region' },
},
DemAccount: {
Value: { Ref: 'AWS::AccountId' },
}
}
});
test.done();
},
'cross-stack references in strings work'(test) {
// GIVEN
const app = new lib_1.App();
const stack1 = new lib_1.Stack(app, 'Stack1');
const account1 = new lib_1.ScopedAws(stack1).accountId;
const stack2 = new lib_1.Stack(app, 'Stack2');
// WHEN - used in another stack
new lib_1.CfnParameter(stack2, 'SomeParameter', { type: 'String', default: `TheAccountIs${account1}` });
const assembly = app.synth();
const template2 = assembly.getStack(stack2.stackName).template;
// THEN
test.deepEqual(template2, {
Parameters: {
SomeParameter: {
Type: 'String',
Default: { 'Fn::Join': ['', ['TheAccountIs', { 'Fn::ImportValue': 'Stack1:ExportsOutputRefAWSAccountIdAD568057' }]] }
}
}
});
test.done();
},
'Stacks can be children of other stacks (substack) and they will be synthesized separately'(test) {
// GIVEN
const app = new lib_1.App();
// WHEN
const parentStack = new lib_1.Stack(app, 'parent');
const childStack = new lib_1.Stack(parentStack, 'child');
new lib_1.CfnResource(parentStack, 'MyParentResource', { type: 'Resource::Parent' });
new lib_1.CfnResource(childStack, 'MyChildResource', { type: 'Resource::Child' });
// THEN
const assembly = app.synth();
test.deepEqual(assembly.getStack(parentStack.stackName).template, { Resources: { MyParentResource: { Type: 'Resource::Parent' } } });
test.deepEqual(assembly.getStack(childStack.stackName).template, { Resources: { MyChildResource: { Type: 'Resource::Child' } } });
test.done();
},
'cross-stack reference (substack references parent stack)'(test) {
// GIVEN
const app = new lib_1.App();
const parentStack = new lib_1.Stack(app, 'parent');
const childStack = new lib_1.Stack(parentStack, 'child');
// WHEN (a resource from the child stack references a resource from the parent stack)
const parentResource = new lib_1.CfnResource(parentStack, 'MyParentResource', { type: 'Resource::Parent' });
new lib_1.CfnResource(childStack, 'MyChildResource', {
type: 'Resource::Child',
properties: {
ChildProp: parentResource.getAtt('AttOfParentResource')
}
});
// THEN
const assembly = app.synth();
test.deepEqual(assembly.getStack(parentStack.stackName).template, {
Resources: { MyParentResource: { Type: 'Resource::Parent' } },
Outputs: { ExportsOutputFnGetAttMyParentResourceAttOfParentResourceC2D0BB9E: {
Value: { 'Fn::GetAtt': ['MyParentResource', 'AttOfParentResource'] },
Export: { Name: 'parent:ExportsOutputFnGetAttMyParentResourceAttOfParentResourceC2D0BB9E' }
}
}
});
test.deepEqual(assembly.getStack(childStack.stackName).template, {
Resources: {
MyChildResource: {
Type: 'Resource::Child',
Properties: {
ChildProp: {
'Fn::ImportValue': 'parent:ExportsOutputFnGetAttMyParentResourceAttOfParentResourceC2D0BB9E'
}
}
}
}
});
test.done();
},
'cross-stack reference (parent stack references substack)'(test) {
// GIVEN
const app = new lib_1.App();
const parentStack = new lib_1.Stack(app, 'parent');
const childStack = new lib_1.Stack(parentStack, 'child');
// WHEN (a resource from the child stack references a resource from the parent stack)
const childResource = new lib_1.CfnResource(childStack, 'MyChildResource', { type: 'Resource::Child' });
new lib_1.CfnResource(parentStack, 'MyParentResource', {
type: 'Resource::Parent',
properties: {
ParentProp: childResource.getAtt('AttributeOfChildResource')
}
});
// THEN
const assembly = app.synth();
test.deepEqual(assembly.getStack(parentStack.stackName).template, {
Resources: {
MyParentResource: {
Type: 'Resource::Parent',
Properties: {
ParentProp: { 'Fn::ImportValue': 'parentchild13F9359B:childExportsOutputFnGetAttMyChildResourceAttributeOfChildResource420052FC' }
}
}
}
});
test.deepEqual(assembly.getStack(childStack.stackName).template, {
Resources: {
MyChildResource: { Type: 'Resource::Child' }
},
Outputs: {
ExportsOutputFnGetAttMyChildResourceAttributeOfChildResource52813264: {
Value: { 'Fn::GetAtt': ['MyChildResource', 'AttributeOfChildResource'] },
Export: { Name: 'parentchild13F9359B:childExportsOutputFnGetAttMyChildResourceAttributeOfChildResource420052FC' }
}
}
});
test.done();
},
'cannot create cyclic reference between stacks'(test) {
// GIVEN
const app = new lib_1.App();
const stack1 = new lib_1.Stack(app, 'Stack1');
const account1 = new lib_1.ScopedAws(stack1).accountId;
const stack2 = new lib_1.Stack(app, 'Stack2');
const account2 = new lib_1.ScopedAws(stack2).accountId;
// WHEN
new lib_1.CfnParameter(stack2, 'SomeParameter', { type: 'String', default: account1 });
new lib_1.CfnParameter(stack1, 'SomeParameter', { type: 'String', default: account2 });
test.throws(() => {
lib_1.ConstructNode.prepare(app.node);
// tslint:disable-next-line:max-line-length
}, "'Stack2' depends on 'Stack1' (Stack2/SomeParameter -> Stack1.AWS::AccountId). Adding this dependency (Stack1/SomeParameter -> Stack2.AWS::AccountId) would create a cyclic reference.");
test.done();
},
'stacks know about their dependencies'(test) {
// GIVEN
const app = new lib_1.App();
const stack1 = new lib_1.Stack(app, 'Stack1');
const account1 = new lib_1.ScopedAws(stack1).accountId;
const stack2 = new lib_1.Stack(app, 'Stack2');
// WHEN
new lib_1.CfnParameter(stack2, 'SomeParameter', { type: 'String', default: account1 });
lib_1.ConstructNode.prepare(app.node);
// THEN
test.deepEqual(stack2.dependencies.map(s => s.node.id), ['Stack1']);
test.done();
},
'cannot create references to stacks in other regions/accounts'(test) {
// GIVEN
const app = new lib_1.App();
const stack1 = new lib_1.Stack(app, 'Stack1', { env: { account: '123456789012', region: 'es-norst-1' } });
const account1 = new lib_1.ScopedAws(stack1).accountId;
const stack2 = new lib_1.Stack(app, 'Stack2', { env: { account: '123456789012', region: 'es-norst-2' } });
// WHEN
new lib_1.CfnParameter(stack2, 'SomeParameter', { type: 'String', default: account1 });
test.throws(() => {
lib_1.ConstructNode.prepare(app.node);
}, /Can only reference cross stacks in the same region and account/);
test.done();
},
'urlSuffix does not imply a stack dependency'(test) {
// GIVEN
const app = new lib_1.App();
const first = new lib_1.Stack(app, 'First');
const second = new lib_1.Stack(app, 'Second');
// WHEN
new lib_1.CfnOutput(second, 'Output', {
value: first.urlSuffix
});
// THEN
app.synth();
test.equal(second.dependencies.length, 0);
test.done();
},
'stack with region supplied via props returns literal value'(test) {
// GIVEN
const app = new lib_1.App();
const stack = new lib_1.Stack(app, 'Stack1', { env: { account: '123456789012', region: 'es-norst-1' } });
// THEN
test.equal(stack.resolve(stack.region), 'es-norst-1');
test.done();
},
'overrideLogicalId(id) can be used to override the logical ID of a resource'(test) {
// GIVEN
const stack = new lib_1.Stack();
const bonjour = new lib_1.CfnResource(stack, 'BonjourResource', { type: 'Resource::Type' });
// { Ref } and { GetAtt }
new lib_1.CfnResource(stack, 'RefToBonjour', { type: 'Other::Resource', properties: {
RefToBonjour: bonjour.ref,
GetAttBonjour: bonjour.getAtt('TheAtt').toString()
} });
bonjour.overrideLogicalId('BOOM');
// THEN
test.deepEqual(util_1.toCloudFormation(stack), { Resources: { BOOM: { Type: 'Resource::Type' },
RefToBonjour: { Type: 'Other::Resource',
Properties: { RefToBonjour: { Ref: 'BOOM' },
GetAttBonjour: { 'Fn::GetAtt': ['BOOM', 'TheAtt'] } } } } });
test.done();
},
'Stack name can be overridden via properties'(test) {
// WHEN
const stack = new lib_1.Stack(undefined, 'Stack', { stackName: 'otherName' });
// THEN
test.deepEqual(stack.stackName, 'otherName');
test.done();
},
'Stack name is inherited from App name if available'(test) {
// WHEN
const root = new lib_1.App();
const app = new lib_1.Construct(root, 'Prod');
const stack = new lib_1.Stack(app, 'Stack');
// THEN
test.deepEqual(stack.stackName, 'ProdStackD5279B22');
test.done();
},
'stack construct id does not go through stack name validation if there is an explicit stack name'(test) {
// GIVEN
const app = new lib_1.App();
// WHEN
const stack = new lib_1.Stack(app, 'invalid as : stack name, but thats fine', {
stackName: 'valid-stack-name'
});
// THEN
const session = app.synth();
test.deepEqual(stack.stackName, 'valid-stack-name');
test.ok(session.tryGetArtifact('valid-stack-name'));
test.done();
},
'stack validation is performed on explicit stack name'(test) {
// GIVEN
const app = new lib_1.App();
// THEN
test.throws(() => new lib_1.Stack(app, 'boom', { stackName: 'invalid:stack:name' }), /Stack name must match the regular expression/);
test.done();
},
'Stack.of(stack) returns the correct stack'(test) {
const stack = new lib_1.Stack();
test.same(lib_1.Stack.of(stack), stack);
const parent = new lib_1.Construct(stack, 'Parent');
const construct = new lib_1.Construct(parent, 'Construct');
test.same(lib_1.Stack.of(construct), stack);
test.done();
},
'Stack.of() throws when there is no parent Stack'(test) {
const root = new lib_1.Construct(undefined, 'Root');
const construct = new lib_1.Construct(root, 'Construct');
test.throws(() => lib_1.Stack.of(construct), /No stack could be identified for the construct at path/);
test.done();
},
'Stack.of() works for substacks'(test) {
// GIVEN
const app = new lib_1.App();
// WHEN
const parentStack = new lib_1.Stack(app, 'ParentStack');
const parentResource = new lib_1.CfnResource(parentStack, 'ParentResource', { type: 'parent::resource' });
// we will define a substack under the /resource/... just for giggles.
const childStack = new lib_1.Stack(parentResource, 'ChildStack');
const childResource = new lib_1.CfnResource(childStack, 'ChildResource', { type: 'child::resource' });
// THEN
test.same(lib_1.Stack.of(parentStack), parentStack);
test.same(lib_1.Stack.of(parentResource), parentStack);
test.same(lib_1.Stack.of(childStack), childStack);
test.same(lib_1.Stack.of(childResource), childStack);
test.done();
},
'stack.availabilityZones falls back to Fn::GetAZ[0],[2] if region is not specified'(test) {
// GIVEN
const app = new lib_1.App();
const stack = new lib_1.Stack(app, 'MyStack');
// WHEN
const azs = stack.availabilityZones;
// THEN
test.deepEqual(stack.resolve(azs), [
{ "Fn::Select": [0, { "Fn::GetAZs": "" }] },
{ "Fn::Select": [1, { "Fn::GetAZs": "" }] }
]);
test.done();
},
'stack.templateFile contains the name of the cloudformation output'(test) {
// GIVEN
const app = new lib_1.App();
// WHEN
const stack1 = new lib_1.Stack(app, 'MyStack1');
const stack2 = new lib_1.Stack(app, 'MyStack2', { stackName: 'MyRealStack2' });
// THEN
test.deepEqual(stack1.templateFile, 'MyStack1.template.json');
test.deepEqual(stack2.templateFile, 'MyRealStack2.template.json');
test.done();
}
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGVzdC5zdGFjay5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbInRlc3Quc3RhY2sudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUNBLGdDQUErSTtBQUMvSSx3REFBcUQ7QUFDckQsaUNBQTBDO0FBNmxCMUMsTUFBTSxzQkFBdUIsU0FBUSxXQUFLO0lBRXhDLE1BQU07SUFFQyxpQkFBaUI7UUFDdEIsTUFBTSxRQUFRLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFM0MsbURBQW1EO1FBQ25ELFFBQVEsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsR0FBRztZQUN0RCxRQUFRLENBQUMsU0FBUyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQztRQUMzRCxPQUFPLFFBQVEsQ0FBQyxTQUFTLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDO1FBRWhFLE9BQU8sUUFBUSxDQUFDO0lBQ2xCLENBQUM7Q0FDRjtBQXptQkQsaUJBQVM7SUFDUCxpRkFBaUYsQ0FBQyxJQUFVO1FBQzFGLE1BQU0sS0FBSyxHQUFHLElBQUksV0FBSyxFQUFFLENBQUM7UUFDMUIsSUFBSSxDQUFDLFNBQVMsQ0FBQyx1QkFBZ0IsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFHLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDZCxDQUFDO0lBRUQsMkZBQTJGLENBQUMsSUFBVTtRQUNwRyxNQUFNLEtBQUssR0FBRyxJQUFJLFdBQUssRUFBRSxDQUFDO1FBQzFCLEtBQUssQ0FBQyxlQUFlLENBQUMscUJBQXFCLEdBQUcsbUJBQW1CLENBQUM7UUFDbEUsS0FBSyxDQUFDLGVBQWUsQ0FBQyxXQUFXLEdBQUcsd0JBQXdCLENBQUM7UUFDN0QsS0FBSyxDQUFDLGVBQWUsQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDO1FBQ3pDLElBQUksQ0FBQyxT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QUFNLEdBQUcsSUFBSSxXQUFLLENBQUMsR0FBRyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQzFDLE1BQU0sTUFBTSxHQUFHLElBQUksV0FBSyxDQUFDLEdBQUcsRUFBRSxVQUFVLEVBQUUsRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLENBQUMsQ0FBQztRQUV6RSxPQUFPO1FBQ1AsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLHdCQUF3QixDQUFDLENBQUM7UUFDOUQsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsWUFBWSxFQUFFLDRCQUE0QixDQUFDLENBQUM7UUFDbEUsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ2QsQ0FBQztDQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUZXN0IH0gZnJvbSAnbm9kZXVuaXQnO1xuaW1wb3J0IHsgQXBwLCBDZm5Db25kaXRpb24sIENmbkluY2x1ZGUsIENmbk91dHB1dCwgQ2ZuUGFyYW1ldGVyLCBDZm5SZXNvdXJjZSwgQ29uc3RydWN0LCBDb25zdHJ1Y3ROb2RlLCBMYXp5LCBTY29wZWRBd3MsIFN0YWNrIH0gZnJvbSAnLi4vbGliJztcbmltcG9ydCB7IEludHJpbnNpYyB9IGZyb20gJy4uL2xpYi9wcml2YXRlL2ludHJpbnNpYyc7XG5pbXBvcnQgeyB0b0Nsb3VkRm9ybWF0aW9uIH0gZnJvbSAnLi91dGlsJztcblxuZXhwb3J0ID0ge1xuICAnYSBzdGFjayBjYW4gYmUgc2VyaWFsaXplZCBpbnRvIGEgQ2xvdWRGb3JtYXRpb24gdGVtcGxhdGUsIGluaXRpYWxseSBpdFxcJ3MgZW1wdHknKHRlc3Q6IFRlc3QpIHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIHRlc3QuZGVlcEVxdWFsKHRvQ2xvdWRGb3JtYXRpb24oc3RhY2spLCB7IH0pO1xuICAgIHRlc3QuZG9uZSgpO1xuICB9LFxuXG4gICdzdGFjayBvYmplY3RzIGhhdmUgc29tZSB0ZW1wbGF0ZS1sZXZlbCBwcm9wZXRpZXMsIHN1Y2ggYXMgRGVzY3JpcHRpb24sIFZlcnNpb24sIFRyYW5zZm9ybScodGVzdDogVGVzdCkge1xuICAgIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gICAgc3RhY2sudGVtcGxhdGVPcHRpb25zLnRlbXBsYXRlRm9ybWF0VmVyc2lvbiA9ICdNeVRlbXBsYXRlVmVyc2lvbic7XG4gICAgc3RhY2sudGVtcGxhdGVPcHRpb25zLmRlc2NyaXB0aW9uID0gJ1RoaXMgaXMgbXkgZGVzY3JpcHRpb24nO1xuICAgIHN0YWNrLnRlbXBsYXRlT3B0aW9ucy50cmFuc2Zvcm0gPSAnU0FNeSc7XG4gICAgdGVzdC5kZWVwRXF1YWwodG9DbG91ZEZvcm1hdGlvbihzdGFjayksIHtcbiAgICAgIERlc2NyaXB0aW9uOiAnVGhpcyBpcyBteSBkZXNjcmlwdGlvbicsXG4gICAgICBBV1NUZW1wbGF0ZUZvcm1hdFZlcnNpb246ICdNeVRlbXBsYXRlVmVyc2lvbicsXG4gICAgICBUcmFuc2Zvcm06ICdTQU15J1xuICAgIH0pO1xuICAgIHRlc3QuZG9uZSgpO1xuICB9LFxuXG4gICdTdGFjay5pc1N0YWNrIGluZGljYXRlcyB0aGF0IGEgY29uc3RydWN0IGlzIGEgc3RhY2snKHRlc3Q6IFRlc3QpIHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAgIGNvbnN0IGMgPSBuZXcgQ29uc3RydWN0KHN0YWNrLCAnQ29uc3RydWN0Jyk7XG4gICAgdGVzdC5vayhTdGFjay5pc1N0YWNrKHN0YWNrKSk7XG4gICAgdGVzdC5vayghU3RhY2suaXNTdGFjayhjKSk7XG4gICAgdGVzdC5kb25lKCk7XG4gIH0sXG5cbiAgJ3N0YWNrLmlkIGlzIG5vdCBpbmNsdWRlZCBpbiB0aGUgbG9naWNhbCBpZGVudGl0aWVzIG9mIHJlc291cmNlcyB3aXRoaW4gaXQnKHRlc3Q6IFRlc3QpIHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjayh1bmRlZmluZWQsICdNeVN0YWNrJyk7XG4gICAgbmV3IENmblJlc291cmNlKHN0YWNrLCAnTXlSZXNvdXJjZScsIHsgdHlwZTogJ015UmVzb3VyY2VUeXBlJyB9KTtcblxuICAgIHRlc3QuZGVlcEVxdWFsKHRvQ2xvdWRGb3JtYXRpb24oc3RhY2spLCB7IFJlc291cmNlczogeyBNeVJlc291cmNlOiB7IFR5cGU6ICdNeVJlc291cmNlVHlwZScgfSB9IH0pO1xuICAgIHRlc3QuZG9uZSgpO1xuICB9LFxuXG4gICdzdGFjay50ZW1wbGF0ZU9wdGlvbnMgY2FuIGJlIHVzZWQgdG8gc2V0IHRlbXBsYXRlLWxldmVsIG9wdGlvbnMnKHRlc3Q6IFRlc3QpIHtcbiAgICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuXG4gICAgc3RhY2sudGVtcGxhdGVPcHRpb25zLmRlc2NyaXB0aW9uID0gJ1N0YWNrRGVzY3JpcHRpb24nO1xuICAgIHN0YWNrLnRlbXBsYXRlT3B0aW9ucy50ZW1wbGF0ZUZvcm1hdFZlcnNpb24gPSAnVGVtcGxhdGVWZXJzaW9uJztcbiAgICBzdGFjay50ZW1wbGF0ZU9wdGlvbnMudHJhbnNmb3JtID0gJ0RlcHJlY2F0ZWRGaWVsZCc7XG4gICAgc3RhY2sudGVtcGxhdGVPcHRpb25zLnRyYW5zZm9ybXMgPSBbJ1RyYW5zZm9ybSddO1xuICAgIHN0YWNrLnRlbXBsYXRlT3B0aW9ucy5tZXRhZGF0YSA9IHtcbiAgICAgIE1ldGFkYXRhS2V5OiAnTWV0YWRhdGFWYWx1ZSdcbiAgICB9O1xuXG4gICAgdGVzdC5kZWVwRXF1YWwodG9DbG91ZEZvcm1hdGlvbihzdGFjayksIHtcbiAgICAgIERlc2NyaXB0aW9uO