@aws-solutions-constructs/core
Version:
Core CDK Construct for patterns library
251 lines • 30.7 kB
JavaScript
"use strict";
/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License"). You may not use this file except in compliance
* with the License. A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* or in the 'license' file accompanying this file. This file is distributed on an 'AS IS' BASIS, WITHOUT WARRANTIES
* OR CONDITIONS OF ANY KIND, express or implied. See the License for the specific language governing permissions
* and limitations under the License.
*/
Object.defineProperty(exports, "__esModule", { value: true });
const aws_cdk_lib_1 = require("aws-cdk-lib");
const defaults = require("../");
const ec2 = require("aws-cdk-lib/aws-ec2");
const assertions_1 = require("aws-cdk-lib/assertions");
const vpc_helper_1 = require("../lib/vpc-helper");
const vpc_defaults_1 = require("../lib/vpc-defaults");
test("Test minimal deployment with no properties", () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultIsolatedVpcProps)(),
});
const template = assertions_1.Template.fromStack(stack);
template.hasResourceProperties('AWS::EC2::VPC', {
EnableDnsHostnames: true,
EnableDnsSupport: true,
});
template.resourceCountIs('AWS::EC2::Subnet', 2);
template.resourceCountIs('AWS::EC2::InternetGateway', 0);
});
test('Test deployment w/ user provided custom properties', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
userVpcProps: {
enableDnsHostnames: false,
enableDnsSupport: false,
ipAddresses: ec2.IpAddresses.cidr('172.168.0.0/19'),
},
});
assertions_1.Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPC', {
CidrBlock: '172.168.0.0/19',
EnableDnsHostnames: false,
EnableDnsSupport: false,
});
});
test('Test deployment w/ construct provided custom properties', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
constructVpcProps: {
enableDnsHostnames: true,
enableDnsSupport: true,
ipAddresses: ec2.IpAddresses.cidr('172.168.0.0/19'),
},
});
assertions_1.Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPC', {
CidrBlock: '172.168.0.0/19',
EnableDnsHostnames: true,
EnableDnsSupport: true,
});
});
test('Test deployment w/ construct and user provided custom properties', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
userVpcProps: {
enableDnsHostnames: false,
enableDnsSupport: false,
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
},
constructVpcProps: {
enableDnsHostnames: false,
enableDnsSupport: false,
ipAddresses: ec2.IpAddresses.cidr('172.168.0.0/19'),
},
});
assertions_1.Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPC', {
CidrBlock: '172.168.0.0/19',
EnableDnsHostnames: false,
EnableDnsSupport: false,
});
});
test('Test deployment w/ construct and user provided custom properties', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
const v = defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
userVpcProps: {
enableDnsHostnames: false,
enableDnsSupport: false,
ipAddresses: ec2.IpAddresses.cidr('10.0.0.0/16'),
},
constructVpcProps: {
enableDnsHostnames: true,
enableDnsSupport: true,
natGateways: 0,
subnetConfiguration: [
{
cidrMask: 18,
name: 'isolated',
subnetType: ec2.SubnetType.PRIVATE_ISOLATED,
},
],
},
});
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, v, defaults.ServiceEndpointTypes.SQS);
// Expect 2 isolated subnets (usual error condition is 2 public/2 private)
const template = assertions_1.Template.fromStack(stack);
template.resourceCountIs('AWS::EC2::Subnet', 2);
template.resourceCountIs('AWS::EC2::InternetGateway', 0);
});
test('Test deployment w/ existing VPC provided', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
const testExistingVpc = defaults.getTestVpc(stack);
const newVpc = defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
existingVpc: testExistingVpc,
});
expect(newVpc).toBe(testExistingVpc);
});
test('Test adding Gateway Endpoint', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
const testVpc = defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
});
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, vpc_helper_1.ServiceEndpointTypes.DYNAMODB);
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, vpc_helper_1.ServiceEndpointTypes.SQS);
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, vpc_helper_1.ServiceEndpointTypes.SNS);
// Assertion
const template = assertions_1.Template.fromStack(stack);
template.hasResourceProperties('AWS::EC2::VPCEndpoint', {
VpcEndpointType: 'Gateway',
});
template.hasResourceProperties('AWS::EC2::VPCEndpoint', {
VpcEndpointType: 'Interface',
});
template.resourceCountIs('AWS::EC2::VPCEndpoint', 3);
});
test('Test adding Interface Endpoint', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
const testVpc = defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
});
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, vpc_helper_1.ServiceEndpointTypes.SNS);
// Assertion
assertions_1.Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', {
VpcEndpointType: 'Interface',
});
});
test('Test adding SAGEMAKER_RUNTIME Interface Endpoint', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
const testVpc = defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
});
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, vpc_helper_1.ServiceEndpointTypes.SAGEMAKER_RUNTIME);
// Assertion
assertions_1.Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', {
VpcEndpointType: 'Interface',
});
});
test('Test adding a second Endpoint of same service', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
const testVpc = defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
});
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, vpc_helper_1.ServiceEndpointTypes.SNS);
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, vpc_helper_1.ServiceEndpointTypes.SNS);
// Assertion
assertions_1.Template.fromStack(stack).resourceCountIs('AWS::EC2::VPCEndpoint', 1);
});
test('Test adding bad Endpoint', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
const testVpc = defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
});
const app = () => {
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, 'string');
};
// Assertion
expect(app).toThrowError();
});
test('Test adding Events Interface Endpoint', () => {
// Stack
const stack = new aws_cdk_lib_1.Stack();
// Build VPC
const testVpc = defaults.buildVpc(stack, {
defaultVpcProps: (0, vpc_defaults_1.DefaultPublicPrivateVpcProps)(),
});
(0, vpc_helper_1.AddAwsServiceEndpoint)(stack, testVpc, vpc_helper_1.ServiceEndpointTypes.EVENTS);
// Assertion
assertions_1.Template.fromStack(stack).hasResourceProperties('AWS::EC2::VPCEndpoint', {
VpcEndpointType: 'Interface',
});
});
// ---------------------------
// Prop Tests
// ---------------------------
test('Test fail Vpc check with deployVpc', () => {
const stack = new aws_cdk_lib_1.Stack();
const props = {
deployVpc: true,
existingVpc: defaults.buildVpc(stack, {
defaultVpcProps: defaults.DefaultPublicPrivateVpcProps(),
}),
};
const app = () => {
defaults.CheckVpcProps(props);
};
// Assertion
expect(app).toThrowError('Error - Either provide an existingVpc or some combination of deployVpc and vpcProps, but not both.\n');
});
test('Test fail Vpc check with vpcProps', () => {
const stack = new aws_cdk_lib_1.Stack();
const props = {
vpcProps: defaults.DefaultPublicPrivateVpcProps(),
existingVpc: defaults.buildVpc(stack, {
defaultVpcProps: defaults.DefaultPublicPrivateVpcProps(),
}),
};
const app = () => {
defaults.CheckVpcProps(props);
};
// Assertion
expect(app).toThrowError('Error - Either provide an existingVpc or some combination of deployVpc and vpcProps, but not both.\n');
});
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidnBjLWhlbHBlci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsidnBjLWhlbHBlci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7Ozs7Ozs7R0FXRzs7QUFFSCw2Q0FBb0M7QUFDcEMsZ0NBQWdDO0FBQ2hDLDJDQUEyQztBQUMzQyx1REFBa0Q7QUFDbEQsa0RBQWdGO0FBQ2hGLHNEQUE0RjtBQUU1RixJQUFJLENBQUMsNENBQTRDLEVBQUUsR0FBRyxFQUFFO0lBQ3RELFFBQVE7SUFDUixNQUFNLEtBQUssR0FBRyxJQUFJLG1CQUFLLEVBQUUsQ0FBQztJQUMxQixZQUFZO0lBQ1osUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUU7UUFDdkIsZUFBZSxFQUFFLElBQUEsc0NBQXVCLEdBQUU7S0FDM0MsQ0FBQyxDQUFDO0lBRUgsTUFBTSxRQUFRLEdBQUcscUJBQVEsQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0MsUUFBUSxDQUFDLHFCQUFxQixDQUFDLGVBQWUsRUFBRTtRQUM5QyxrQkFBa0IsRUFBRSxJQUFJO1FBQ3hCLGdCQUFnQixFQUFFLElBQUk7S0FDdkIsQ0FBQyxDQUFDO0lBRUgsUUFBUSxDQUFDLGVBQWUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLENBQUMsQ0FBQztJQUNoRCxRQUFRLENBQUMsZUFBZSxDQUFDLDJCQUEyQixFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQzNELENBQUMsQ0FBQyxDQUFDO0FBRUgsSUFBSSxDQUFDLG9EQUFvRCxFQUFFLEdBQUcsRUFBRTtJQUM5RCxRQUFRO0lBQ1IsTUFBTSxLQUFLLEdBQUcsSUFBSSxtQkFBSyxFQUFFLENBQUM7SUFDMUIsWUFBWTtJQUNaLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFO1FBQ3ZCLGVBQWUsRUFBRSxJQUFBLDJDQUE0QixHQUFFO1FBQy9DLFlBQVksRUFBRTtZQUNaLGtCQUFrQixFQUFFLEtBQUs7WUFDekIsZ0JBQWdCLEVB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LFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFO1lBQ3BDLGVBQWUsRUFBRSxRQUFRLENBQUMsNEJBQTRCLEVBQUU7U0FDekQsQ0FBQztLQUNILENBQUM7SUFFRixNQUFNLEdBQUcsR0FBRyxHQUFHLEVBQUU7UUFDZixRQUFRLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUMsQ0FBQztJQUVGLFlBQVk7SUFDWixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsWUFBWSxDQUFDLHNHQUFzRyxDQUFDLENBQUM7QUFDbkksQ0FBQyxDQUFDLENBQUM7QUFFSCxJQUFJLENBQUMsbUNBQW1DLEVBQUUsR0FBRyxFQUFFO0lBQzdDLE1BQU0sS0FBSyxHQUFHLElBQUksbUJBQUssRUFBRSxDQUFDO0lBRTFCLE1BQU0sS0FBSyxHQUF5QjtRQUNsQyxRQUFRLEVBQUUsUUFBUSxDQUFDLDRCQUE0QixFQUFFO1FBQ2pELFdBQVcsRUFBRSxRQUFRLENBQUMsUUFBUSxDQUFDLEtBQUssRUFBRTtZQUNwQyxlQUFlLEVBQUUsUUFBUSxDQUFDLDRCQUE0QixFQUFFO1NBQ3pELENBQUM7S0FDSCxDQUFDO0lBRUYsTUFBTSxHQUFHLEdBQUcsR0FBRyxFQUFFO1FBQ2YsUUFBUSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUNoQyxDQUFDLENBQUM7SUFFRixZQUFZO0lBQ1osTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLFlBQVksQ0FBQyxzR0FBc0csQ0FBQyxDQUFDO0FBQ25JLENBQUMsQ0FBQyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgQ29weXJpZ2h0IEFtYXpvbi5jb20sIEluYy4gb3IgaXRzIGFmZmlsaWF0ZXMuIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogIExpY2Vuc2VkIHVuZGVyIHRoZSBBcGFjaGUgTGljZW5zZSwgVmVyc2lvbiAyLjAgKHRoZSBcIkxpY2Vuc2VcIikuIFlvdSBtYXkgbm90IHVzZSB0aGlzIGZpbGUgZXhjZXB0IGluIGNvbXBsaWFuY2VcbiAqICB3aXRoIHRoZSBMaWNlbnNlLiBBIGNvcHkgb2YgdGhlIExpY2Vuc2UgaXMgbG9jYXRlZCBhdFxuICpcbiAqICAgICAgaHR0cDovL3d3dy5hcGFjaGUub3JnL2xpY2Vuc2VzL0xJQ0VOU0UtMi4wXG4gKlxuICogIG9yIGluIHRoZSAnbGljZW5zZScgZmlsZSBhY2NvbXBhbnlpbmcgdGhpcyBmaWxlLiBUaGlzIGZpbGUgaXMgZGlzdHJpYnV0ZWQgb24gYW4gJ0FTIElTJyBCQVNJUywgV0lUSE9VVCBXQVJSQU5USUVTXG4gKiAgT1IgQ09ORElUSU9OUyBPRiBBTlkgS0lORCwgZXhwcmVzcyBvciBpbXBsaWVkLiBTZWUgdGhlIExpY2Vuc2UgZm9yIHRoZSBzcGVjaWZpYyBsYW5ndWFnZSBnb3Zlcm5pbmcgcGVybWlzc2lvbnNcbiAqICBhbmQgbGltaXRhdGlvbnMgdW5kZXIgdGhlIExpY2Vuc2UuXG4gKi9cblxuaW1wb3J0IHsgU3RhY2sgfSBmcm9tICdhd3MtY2RrLWxpYic7XG5pbXBvcnQgKiBhcyBkZWZhdWx0cyBmcm9tICcuLi8nO1xuaW1wb3J0ICogYXMgZWMyIGZyb20gJ2F3cy1jZGstbGliL2F3cy1lYzInO1xuaW1wb3J0IHsgVGVtcGxhdGUgfSBmcm9tICdhd3MtY2RrLWxpYi9hc3NlcnRpb25zJztcbmltcG9ydCB7IEFkZEF3c1NlcnZpY2VFbmRwb2ludCwgU2VydmljZUVuZHBvaW50VHlwZXMgfSBmcm9tICcuLi9saWIvdnBjLWhlbHBlcic7XG5pbXBvcnQgeyBEZWZhdWx0UHVibGljUHJpdmF0ZVZwY1Byb3BzLCBEZWZhdWx0SXNvbGF0ZWRWcGNQcm9wcyB9IGZyb20gJy4uL2xpYi92cGMtZGVmYXVsdHMnO1xuXG50ZXN0KFwiVGVzdCBtaW5pbWFsIGRlcGxveW1lbnQgd2l0aCBubyBwcm9wZXJ0aWVzXCIsICgpID0+IHtcbiAgLy8gU3RhY2tcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgLy8gQnVpbGQgVlBDXG4gIGRlZmF1bHRzLmJ1aWxkVnBjKHN0YWNrLCB7XG4gICAgZGVmYXVsdFZwY1Byb3BzOiBEZWZhdWx0SXNvbGF0ZWRWcGNQcm9wcygpLFxuICB9KTtcblxuICBjb25zdCB0ZW1wbGF0ZSA9IFRlbXBsYXRlLmZyb21TdGFjayhzdGFjayk7XG4gIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpFQzI6OlZQQycsIHtcbiAgICBFbmFibGVEbnNIb3N0bmFtZXM6IHRydWUsXG4gICAgRW5hYmxlRG5zU3VwcG9ydDogdHJ1ZSxcbiAgfSk7XG5cbiAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkVDMjo6U3VibmV0JywgMik7XG4gIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcygnQVdTOjpFQzI6OkludGVybmV0R2F0ZXdheScsIDApO1xufSk7XG5cbnRlc3QoJ1Rlc3QgZGVwbG95bWVudCB3LyB1c2VyIHByb3ZpZGVkIGN1c3RvbSBwcm9wZXJ0aWVzJywgKCkgPT4ge1xuICAvLyBTdGFja1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAvLyBCdWlsZCBWUENcbiAgZGVmYXVsdHMuYnVpbGRWcGMoc3RhY2ssIHtcbiAgICBkZWZhdWx0VnBjUHJvcHM6IERlZmF1bHRQdWJsaWNQcml2YXRlVnBjUHJvcHMoKSxcbiAgICB1c2VyVnBjUHJvcHM6IHtcbiAgICAgIGVuYWJsZURuc0hvc3RuYW1lczogZmFsc2UsXG4gICAgICBlbmFibGVEbnNTdXBwb3J0OiBmYWxzZSxcbiAgICAgIGlwQWRkcmVzc2VzOiBlYzIuSXBBZGRyZXNzZXMuY2lkcignMTcyLjE2OC4wLjAvMTknKSxcbiAgICB9LFxuICB9KTtcbiAgVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RUMyOjpWUEMnLCB7XG4gICAgQ2lkckJsb2NrOiAnMTcyLjE2OC4wLjAvMTknLFxuICAgIEVuYWJsZURuc0hvc3RuYW1lczogZmFsc2UsXG4gICAgRW5hYmxlRG5zU3VwcG9ydDogZmFsc2UsXG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3QgZGVwbG95bWVudCB3LyBjb25zdHJ1Y3QgcHJvdmlkZWQgY3VzdG9tIHByb3BlcnRpZXMnLCAoKSA9PiB7XG4gIC8vIFN0YWNrXG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gIC8vIEJ1aWxkIFZQQ1xuICBkZWZhdWx0cy5idWlsZFZwYyhzdGFjaywge1xuICAgIGRlZmF1bHRWcGNQcm9wczogRGVmYXVsdFB1YmxpY1ByaXZhdGVWcGNQcm9wcygpLFxuICAgIGNvbnN0cnVjdFZwY1Byb3BzOiB7XG4gICAgICBlbmFibGVEbnNIb3N0bmFtZXM6IHRydWUsXG4gICAgICBlbmFibGVEbnNTdXBwb3J0OiB0cnVlLFxuICAgICAgaXBBZGRyZXNzZXM6IGVjMi5JcEFkZHJlc3Nlcy5jaWRyKCcxNzIuMTY4LjAuMC8xOScpLFxuICAgIH0sXG4gIH0pO1xuICBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpFQzI6OlZQQycsIHtcbiAgICBDaWRyQmxvY2s6ICcxNzIuMTY4LjAuMC8xOScsXG4gICAgRW5hYmxlRG5zSG9zdG5hbWVzOiB0cnVlLFxuICAgIEVuYWJsZURuc1N1cHBvcnQ6IHRydWUsXG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3QgZGVwbG95bWVudCB3LyBjb25zdHJ1Y3QgYW5kIHVzZXIgcHJvdmlkZWQgY3VzdG9tIHByb3BlcnRpZXMnLCAoKSA9PiB7XG4gIC8vIFN0YWNrXG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gIC8vIEJ1aWxkIFZQQ1xuICBkZWZhdWx0cy5idWlsZFZwYyhzdGFjaywge1xuICAgIGRlZmF1bHRWcGNQcm9wczogRGVmYXVsdFB1YmxpY1ByaXZhdGVWcGNQcm9wcygpLFxuICAgIHVzZXJWcGNQcm9wczoge1xuICAgICAgZW5hYmxlRG5zSG9zdG5hbWVzOiBmYWxzZSxcbiAgICAgIGVuYWJsZURuc1N1cHBvcnQ6IGZhbHNlLFxuICAgICAgaXBBZGRyZXNzZXM6IGVjMi5JcEFkZHJlc3Nlcy5jaWRyKCcxMC4wLjAuMC8xNicpLFxuICAgIH0sXG4gICAgY29uc3RydWN0VnBjUHJvcHM6IHtcbiAgICAgIGVuYWJsZURuc0hvc3RuYW1lczogZmFsc2UsXG4gICAgICBlbmFibGVEbnNTdXBwb3J0OiBmYWxzZSxcbiAgICAgIGlwQWRkcmVzc2VzOiBlYzIuSXBBZGRyZXNzZXMuY2lkcignMTcyLjE2OC4wLjAvMTknKSxcbiAgICB9LFxuICB9KTtcbiAgVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RUMyOjpWUEMnLCB7XG4gICAgQ2lkckJsb2NrOiAnMTcyLjE2OC4wLjAvMTknLFxuICAgIEVuYWJsZURuc0hvc3RuYW1lczogZmFsc2UsXG4gICAgRW5hYmxlRG5zU3VwcG9ydDogZmFsc2UsXG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3QgZGVwbG95bWVudCB3LyBjb25zdHJ1Y3QgYW5kIHVzZXIgcHJvdmlkZWQgY3VzdG9tIHByb3BlcnRpZXMnLCAoKSA9PiB7XG4gIC8vIFN0YWNrXG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gIC8vIEJ1aWxkIFZQQ1xuICBjb25zdCB2ID0gZGVmYXVsdHMuYnVpbGRWcGMoc3RhY2ssIHtcbiAgICBkZWZhdWx0VnBjUHJvcHM6IERlZmF1bHRQdWJsaWNQcml2YXRlVnBjUHJvcHMoKSxcbiAgICB1c2VyVnBjUHJvcHM6IHtcbiAgICAgIGVuYWJsZURuc0hvc3RuYW1lczogZmFsc2UsXG4gICAgICBlbmFibGVEbnNTdXBwb3J0OiBmYWxzZSxcbiAgICAgIGlwQWRkcmVzc2VzOiBlYzIuSXBBZGRyZXNzZXMuY2lkcignMTAuMC4wLjAvMTYnKSxcbiAgICB9LFxuICAgIGNvbnN0cnVjdFZwY1Byb3BzOiB7XG4gICAgICBlbmFibGVEbnNIb3N0bmFtZXM6IHRydWUsXG4gICAgICBlbmFibGVEbnNTdXBwb3J0OiB0cnVlLFxuICAgICAgbmF0R2F0ZXdheXM6IDAsXG4gICAgICBzdWJuZXRDb25maWd1cmF0aW9uOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBjaWRyTWFzazogMTgsXG4gICAgICAgICAgbmFtZTogJ2lzb2xhdGVkJyxcbiAgICAgICAgICBzdWJuZXRUeXBlOiBlYzIuU3VibmV0VHlwZS5QUklWQVRFX0lTT0xBVEVELFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9LFxuICB9KTtcbiAgQWRkQXdzU2VydmljZUVuZHBvaW50KHN0YWNrLCB2LCBkZWZhdWx0cy5TZXJ2aWNlRW5kcG9pbnRUeXBlcy5TUVMpO1xuXG4gIC8vIEV4cGVjdCAyIGlzb2xhdGVkIHN1Ym5ldHMgKHVzdWFsIGVycm9yIGNvbmRpdGlvbiBpcyAyIHB1YmxpYy8yIHByaXZhdGUpXG4gIGNvbnN0IHRlbXBsYXRlID0gVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKTtcbiAgdGVtcGxhdGUucmVzb3VyY2VDb3VudElzKCdBV1M6OkVDMjo6U3VibmV0JywgMik7XG4gIHRlbXBsYXRlLnJlc291cmNlQ291bnRJcygnQVdTOjpFQzI6OkludGVybmV0R2F0ZXdheScsIDApO1xufSk7XG5cbnRlc3QoJ1Rlc3QgZGVwbG95bWVudCB3LyBleGlzdGluZyBWUEMgcHJvdmlkZWQnLCAoKSA9PiB7XG4gIC8vIFN0YWNrXG4gIGNvbnN0IHN0YWNrID0gbmV3IFN0YWNrKCk7XG4gIC8vIEJ1aWxkIFZQQ1xuICBjb25zdCB0ZXN0RXhpc3RpbmdWcGMgPSBkZWZhdWx0cy5nZXRUZXN0VnBjKHN0YWNrKTtcblxuICBjb25zdCBuZXdWcGMgPSBkZWZhdWx0cy5idWlsZFZwYyhzdGFjaywge1xuICAgIGRlZmF1bHRWcGNQcm9wczogRGVmYXVsdFB1YmxpY1ByaXZhdGVWcGNQcm9wcygpLFxuICAgIGV4aXN0aW5nVnBjOiB0ZXN0RXhpc3RpbmdWcGMsXG4gIH0pO1xuXG4gIGV4cGVjdChuZXdWcGMpLnRvQmUodGVzdEV4aXN0aW5nVnBjKTtcbn0pO1xuXG50ZXN0KCdUZXN0IGFkZGluZyBHYXRld2F5IEVuZHBvaW50JywgKCkgPT4ge1xuICAvLyBTdGFja1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAvLyBCdWlsZCBWUENcbiAgY29uc3QgdGVzdFZwYyA9IGRlZmF1bHRzLmJ1aWxkVnBjKHN0YWNrLCB7XG4gICAgZGVmYXVsdFZwY1Byb3BzOiBEZWZhdWx0UHVibGljUHJpdmF0ZVZwY1Byb3BzKCksXG4gIH0pO1xuXG4gIEFkZEF3c1NlcnZpY2VFbmRwb2ludChzdGFjaywgdGVzdFZwYywgU2VydmljZUVuZHBvaW50VHlwZXMuRFlOQU1PREIpO1xuICBBZGRBd3NTZXJ2aWNlRW5kcG9pbnQoc3RhY2ssIHRlc3RWcGMsIFNlcnZpY2VFbmRwb2ludFR5cGVzLlNRUyk7XG4gIEFkZEF3c1NlcnZpY2VFbmRwb2ludChzdGFjaywgdGVzdFZwYywgU2VydmljZUVuZHBvaW50VHlwZXMuU05TKTtcblxuICAvLyBBc3NlcnRpb25cbiAgY29uc3QgdGVtcGxhdGUgPSBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spO1xuICB0ZW1wbGF0ZS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RUMyOjpWUENFbmRwb2ludCcsIHtcbiAgICBWcGNFbmRwb2ludFR5cGU6ICdHYXRld2F5JyxcbiAgfSk7XG4gIHRlbXBsYXRlLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpFQzI6OlZQQ0VuZHBvaW50Jywge1xuICAgIFZwY0VuZHBvaW50VHlwZTogJ0ludGVyZmFjZScsXG4gIH0pO1xuICB0ZW1wbGF0ZS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6RUMyOjpWUENFbmRwb2ludCcsIDMpO1xufSk7XG5cbnRlc3QoJ1Rlc3QgYWRkaW5nIEludGVyZmFjZSBFbmRwb2ludCcsICgpID0+IHtcbiAgLy8gU3RhY2tcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgLy8gQnVpbGQgVlBDXG4gIGNvbnN0IHRlc3RWcGMgPSBkZWZhdWx0cy5idWlsZFZwYyhzdGFjaywge1xuICAgIGRlZmF1bHRWcGNQcm9wczogRGVmYXVsdFB1YmxpY1ByaXZhdGVWcGNQcm9wcygpLFxuICB9KTtcblxuICBBZGRBd3NTZXJ2aWNlRW5kcG9pbnQoc3RhY2ssIHRlc3RWcGMsIFNlcnZpY2VFbmRwb2ludFR5cGVzLlNOUyk7XG5cbiAgLy8gQXNzZXJ0aW9uXG4gIFRlbXBsYXRlLmZyb21TdGFjayhzdGFjaykuaGFzUmVzb3VyY2VQcm9wZXJ0aWVzKCdBV1M6OkVDMjo6VlBDRW5kcG9pbnQnLCB7XG4gICAgVnBjRW5kcG9pbnRUeXBlOiAnSW50ZXJmYWNlJyxcbiAgfSk7XG59KTtcblxudGVzdCgnVGVzdCBhZGRpbmcgU0FHRU1BS0VSX1JVTlRJTUUgSW50ZXJmYWNlIEVuZHBvaW50JywgKCkgPT4ge1xuICAvLyBTdGFja1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAvLyBCdWlsZCBWUENcbiAgY29uc3QgdGVzdFZwYyA9IGRlZmF1bHRzLmJ1aWxkVnBjKHN0YWNrLCB7XG4gICAgZGVmYXVsdFZwY1Byb3BzOiBEZWZhdWx0UHVibGljUHJpdmF0ZVZwY1Byb3BzKCksXG4gIH0pO1xuXG4gIEFkZEF3c1NlcnZpY2VFbmRwb2ludChzdGFjaywgdGVzdFZwYywgU2VydmljZUVuZHBvaW50VHlwZXMuU0FHRU1BS0VSX1JVTlRJTUUpO1xuXG4gIC8vIEFzc2VydGlvblxuICBUZW1wbGF0ZS5mcm9tU3RhY2soc3RhY2spLmhhc1Jlc291cmNlUHJvcGVydGllcygnQVdTOjpFQzI6OlZQQ0VuZHBvaW50Jywge1xuICAgIFZwY0VuZHBvaW50VHlwZTogJ0ludGVyZmFjZScsXG4gIH0pO1xufSk7XG5cbnRlc3QoJ1Rlc3QgYWRkaW5nIGEgc2Vjb25kIEVuZHBvaW50IG9mIHNhbWUgc2VydmljZScsICgpID0+IHtcbiAgLy8gU3RhY2tcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgLy8gQnVpbGQgVlBDXG4gIGNvbnN0IHRlc3RWcGMgPSBkZWZhdWx0cy5idWlsZFZwYyhzdGFjaywge1xuICAgIGRlZmF1bHRWcGNQcm9wczogRGVmYXVsdFB1YmxpY1ByaXZhdGVWcGNQcm9wcygpLFxuICB9KTtcblxuICBBZGRBd3NTZXJ2aWNlRW5kcG9pbnQoc3RhY2ssIHRlc3RWcGMsIFNlcnZpY2VFbmRwb2ludFR5cGVzLlNOUyk7XG4gIEFkZEF3c1NlcnZpY2VFbmRwb2ludChzdGFjaywgdGVzdFZwYywgU2VydmljZUVuZHBvaW50VHlwZXMuU05TKTtcblxuICAvLyBBc3NlcnRpb25cbiAgVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5yZXNvdXJjZUNvdW50SXMoJ0FXUzo6RUMyOjpWUENFbmRwb2ludCcsIDEpO1xufSk7XG5cbnRlc3QoJ1Rlc3QgYWRkaW5nIGJhZCBFbmRwb2ludCcsICgpID0+IHtcbiAgLy8gU3RhY2tcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcbiAgLy8gQnVpbGQgVlBDXG4gIGNvbnN0IHRlc3RWcGMgPSBkZWZhdWx0cy5idWlsZFZwYyhzdGFjaywge1xuICAgIGRlZmF1bHRWcGNQcm9wczogRGVmYXVsdFB1YmxpY1ByaXZhdGVWcGNQcm9wcygpLFxuICB9KTtcblxuICBjb25zdCBhcHAgPSAoKSA9PiB7XG4gICAgQWRkQXdzU2VydmljZUVuZHBvaW50KHN0YWNrLCB0ZXN0VnBjLCAnc3RyaW5nJyBhcyBTZXJ2aWNlRW5kcG9pbnRUeXBlcyk7XG4gIH07XG4gIC8vIEFzc2VydGlvblxuICBleHBlY3QoYXBwKS50b1Rocm93RXJyb3IoKTtcbn0pO1xuXG50ZXN0KCdUZXN0IGFkZGluZyBFdmVudHMgSW50ZXJmYWNlIEVuZHBvaW50JywgKCkgPT4ge1xuICAvLyBTdGFja1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuICAvLyBCdWlsZCBWUENcbiAgY29uc3QgdGVzdFZwYyA9IGRlZmF1bHRzLmJ1aWxkVnBjKHN0YWNrLCB7XG4gICAgZGVmYXVsdFZwY1Byb3BzOiBEZWZhdWx0UHVibGljUHJpdmF0ZVZwY1Byb3BzKCksXG4gIH0pO1xuXG4gIEFkZEF3c1NlcnZpY2VFbmRwb2ludChzdGFjaywgdGVzdFZwYywgU2VydmljZUVuZHBvaW50VHlwZXMuRVZFTlRTKTtcblxuICAvLyBBc3NlcnRpb25cbiAgVGVtcGxhdGUuZnJvbVN0YWNrKHN0YWNrKS5oYXNSZXNvdXJjZVByb3BlcnRpZXMoJ0FXUzo6RUMyOjpWUENFbmRwb2ludCcsIHtcbiAgICBWcGNFbmRwb2ludFR5cGU6ICdJbnRlcmZhY2UnLFxuICB9KTtcbn0pO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFByb3AgVGVzdHNcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxudGVzdCgnVGVzdCBmYWlsIFZwYyBjaGVjayB3aXRoIGRlcGxveVZwYycsICgpID0+IHtcbiAgY29uc3Qgc3RhY2sgPSBuZXcgU3RhY2soKTtcblxuICBjb25zdCBwcm9wczogZGVmYXVsdHMuVnBjUHJvcHNTZXQgPSB7XG4gICAgZGVwbG95VnBjOiB0cnVlLFxuICAgIGV4aXN0aW5nVnBjOiBkZWZhdWx0cy5idWlsZFZwYyhzdGFjaywge1xuICAgICAgZGVmYXVsdFZwY1Byb3BzOiBkZWZhdWx0cy5EZWZhdWx0UHVibGljUHJpdmF0ZVZwY1Byb3BzKCksXG4gICAgfSksXG4gIH07XG5cbiAgY29uc3QgYXBwID0gKCkgPT4ge1xuICAgIGRlZmF1bHRzLkNoZWNrVnBjUHJvcHMocHJvcHMpO1xuICB9O1xuXG4gIC8vIEFzc2VydGlvblxuICBleHBlY3QoYXBwKS50b1Rocm93RXJyb3IoJ0Vycm9yIC0gRWl0aGVyIHByb3ZpZGUgYW4gZXhpc3RpbmdWcGMgb3Igc29tZSBjb21iaW5hdGlvbiBvZiBkZXBsb3lWcGMgYW5kIHZwY1Byb3BzLCBidXQgbm90IGJvdGguXFxuJyk7XG59KTtcblxudGVzdCgnVGVzdCBmYWlsIFZwYyBjaGVjayB3aXRoIHZwY1Byb3BzJywgKCkgPT4ge1xuICBjb25zdCBzdGFjayA9IG5ldyBTdGFjaygpO1xuXG4gIGNvbnN0IHByb3BzOiBkZWZhdWx0cy5WcGNQcm9wc1NldCA9IHtcbiAgICB2cGNQcm9wczogZGVmYXVsdHMuRGVmYXVsdFB1YmxpY1ByaXZhdGVWcGNQcm9wcygpLFxuICAgIGV4aXN0aW5nVnBjOiBkZWZhdWx0cy5idWlsZFZwYyhzdGFjaywge1xuICAgICAgZGVmYXVsdFZwY1Byb3BzOiBkZWZhdWx0cy5EZWZhdWx0UHVibGljUHJpdmF0ZVZwY1Byb3BzKCksXG4gICAgfSksXG4gIH07XG5cbiAgY29uc3QgYXBwID0gKCkgPT4ge1xuICAgIGRlZmF1bHRzLkNoZWNrVnBjUHJvcHMocHJvcHMpO1xuICB9O1xuXG4gIC8vIEFzc2VydGlvblxuICBleHBlY3QoYXBwKS50b1Rocm93RXJyb3IoJ0Vycm9yIC0gRWl0aGVyIHByb3ZpZGUgYW4gZXhpc3RpbmdWcGMgb3Igc29tZSBjb21iaW5hdGlvbiBvZiBkZXBsb3lWcGMgYW5kIHZwY1Byb3BzLCBidXQgbm90IGJvdGguXFxuJyk7XG59KTtcbiJdfQ==