aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
489 lines • 53.8 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
const cxschema = require("@aws-cdk/cloud-assembly-schema");
;
const util_1 = require("./util");
const bootstrap_1 = require("../lib/api/bootstrap");
const cdk_toolkit_1 = require("../lib/cli/cdk-toolkit");
const list_stacks_1 = require("../lib/list-stacks");
describe('list', () => {
let cloudFormation;
let bootstrapper;
beforeEach(() => {
jest.resetAllMocks();
bootstrapper = (0, util_1.instanceMockFrom)(bootstrap_1.Bootstrapper);
bootstrapper.bootstrapEnvironment.mockResolvedValue({ noOp: false, outputs: {} });
});
test('stacks with no dependencies', async () => {
let cloudExecutable = new util_1.MockCloudExecutable({
stacks: [
MockStack.MOCK_STACK_A,
{
stackName: 'Test-Stack-B',
template: { Resources: { TemplateName: 'Test-Stack-B' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
},
],
});
// GIVEN
const toolkit = new cdk_toolkit_1.CdkToolkit({
cloudExecutable,
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: cloudFormation,
});
// WHEN
const workflow = await (0, list_stacks_1.listStacks)(toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-B'] });
// THEN
expect(JSON.stringify(workflow)).toEqual(JSON.stringify([{
id: 'Test-Stack-A',
name: 'Test-Stack-A',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
},
{
id: 'Test-Stack-B',
name: 'Test-Stack-B',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
}]));
});
test('stacks with dependent stacks', async () => {
let cloudExecutable = new util_1.MockCloudExecutable({
stacks: [
MockStack.MOCK_STACK_A,
{
stackName: 'Test-Stack-B',
template: { Resources: { TemplateName: 'Test-Stack-B' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-A'],
},
],
});
// GIVEN
const toolkit = new cdk_toolkit_1.CdkToolkit({
cloudExecutable,
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: cloudFormation,
});
// WHEN
const workflow = await (0, list_stacks_1.listStacks)(toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-B'] });
// THEN
expect(JSON.stringify(workflow)).toEqual(JSON.stringify([{
id: 'Test-Stack-A',
name: 'Test-Stack-A',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
},
{
id: 'Test-Stack-B',
name: 'Test-Stack-B',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-A',
dependencies: [],
}],
}]));
});
// In the context where we have a display name set to hieraricalId/stackName
// we would need to pass in the displayName to list the stacks.
test('stacks with dependent stacks and have display name set to hieraricalId/stackName', async () => {
let cloudExecutable = new util_1.MockCloudExecutable({
stacks: [
MockStack.MOCK_STACK_A,
{
stackName: 'Test-Stack-B',
template: { Resources: { TemplateName: 'Test-Stack-B' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-A'],
displayName: 'Test-Stack-A/Test-Stack-B',
},
],
});
// GIVEN
const toolkit = new cdk_toolkit_1.CdkToolkit({
cloudExecutable,
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: cloudFormation,
});
// WHEN
const workflow = await (0, list_stacks_1.listStacks)(toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-A/Test-Stack-B'] });
// THEN
expect(JSON.stringify(workflow)).toEqual(JSON.stringify([{
id: 'Test-Stack-A',
name: 'Test-Stack-A',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
},
{
id: 'Test-Stack-A/Test-Stack-B',
name: 'Test-Stack-B',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-A',
dependencies: [],
}],
}]));
});
test('stacks with display names and have nested dependencies', async () => {
let cloudExecutable = new util_1.MockCloudExecutable({
stacks: [
MockStack.MOCK_STACK_A,
{
stackName: 'Test-Stack-B',
template: { Resources: { TemplateName: 'Test-Stack-B' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-A'],
displayName: 'Test-Stack-A/Test-Stack-B',
},
{
stackName: 'Test-Stack-C',
template: { Resources: { TemplateName: 'Test-Stack-C' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-C': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-B'],
displayName: 'Test-Stack-A/Test-Stack-B/Test-Stack-C',
},
],
});
// GIVEN
const toolkit = new cdk_toolkit_1.CdkToolkit({
cloudExecutable,
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: cloudFormation,
});
// WHEN
const workflow = await (0, list_stacks_1.listStacks)(toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-A/Test-Stack-B', 'Test-Stack-A/Test-Stack-B/Test-Stack-C'] });
// THEN
expect(JSON.stringify(workflow)).toEqual(JSON.stringify([{
id: 'Test-Stack-A',
name: 'Test-Stack-A',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
},
{
id: 'Test-Stack-A/Test-Stack-B',
name: 'Test-Stack-B',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-A',
dependencies: [],
}],
},
{
id: 'Test-Stack-A/Test-Stack-B/Test-Stack-C',
name: 'Test-Stack-C',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-A/Test-Stack-B',
dependencies: [{
id: 'Test-Stack-A',
dependencies: [],
}],
}],
}]));
});
test('stacks with nested dependencies', async () => {
let cloudExecutable = new util_1.MockCloudExecutable({
stacks: [
MockStack.MOCK_STACK_A,
{
stackName: 'Test-Stack-B',
template: { Resources: { TemplateName: 'Test-Stack-B' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-A'],
},
{
stackName: 'Test-Stack-C',
template: { Resources: { TemplateName: 'Test-Stack-C' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-C': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-B'],
},
],
});
// GIVEN
const toolkit = new cdk_toolkit_1.CdkToolkit({
cloudExecutable,
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: cloudFormation,
});
// WHEN
const workflow = await (0, list_stacks_1.listStacks)(toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-B', 'Test-Stack-C'] });
// THEN
expect(JSON.stringify(workflow)).toEqual(JSON.stringify([{
id: 'Test-Stack-A',
name: 'Test-Stack-A',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
},
{
id: 'Test-Stack-B',
name: 'Test-Stack-B',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-A',
dependencies: [],
}],
},
{
id: 'Test-Stack-C',
name: 'Test-Stack-C',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-B',
dependencies: [{
id: 'Test-Stack-A',
dependencies: [],
}],
}],
}]));
});
// In the context of stacks with cross-stack or cross-region references,
// the dependency mechanism is responsible for appropriately applying dependencies at the correct hierarchy level,
// typically at the top-level stacks.
// This involves handling the establishment of cross-references between stacks or nested stacks
// and generating assets for nested stack templates as necessary.
test('stacks with cross stack referencing', async () => {
let cloudExecutable = new util_1.MockCloudExecutable({
stacks: [
{
stackName: 'Test-Stack-A',
template: {
Resources: {
MyBucket1Reference: {
Type: 'AWS::CloudFormation::Stack',
Properties: {
TemplateURL: 'XXXXXXXXXXXXXXXXXXXXXXXXX',
Parameters: {
BucketName: { 'Fn::GetAtt': ['MyBucket1', 'Arn'] },
},
},
},
},
},
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-A': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-C'],
},
MockStack.MOCK_STACK_C,
],
});
// GIVEN
const toolkit = new cdk_toolkit_1.CdkToolkit({
cloudExecutable,
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: cloudFormation,
});
// WHEN
const workflow = await (0, list_stacks_1.listStacks)(toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-C'] });
// THEN
expect(JSON.stringify(workflow)).toEqual(JSON.stringify([{
id: 'Test-Stack-C',
name: 'Test-Stack-C',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [],
},
{
id: 'Test-Stack-A',
name: 'Test-Stack-A',
environment: {
account: '123456789012',
region: 'bermuda-triangle-1',
name: 'aws://123456789012/bermuda-triangle-1',
},
dependencies: [{
id: 'Test-Stack-C',
dependencies: [],
}],
}]));
});
test('stacks with circular dependencies should error out', async () => {
let cloudExecutable = new util_1.MockCloudExecutable({
stacks: [
{
stackName: 'Test-Stack-A',
template: { Resources: { TemplateName: 'Test-Stack-A' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-A': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-B'],
},
{
stackName: 'Test-Stack-B',
template: { Resources: { TemplateName: 'Test-Stack-B' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-B': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
depends: ['Test-Stack-A'],
},
],
});
// GIVEN
const toolkit = new cdk_toolkit_1.CdkToolkit({
cloudExecutable,
configuration: cloudExecutable.configuration,
sdkProvider: cloudExecutable.sdkProvider,
deployments: cloudFormation,
});
// WHEN
await expect(() => (0, list_stacks_1.listStacks)(toolkit, { selectors: ['Test-Stack-A', 'Test-Stack-B'] })).rejects.toThrow('Could not determine ordering');
});
});
class MockStack {
}
MockStack.MOCK_STACK_A = {
stackName: 'Test-Stack-A',
template: { Resources: { TemplateName: 'Test-Stack-A' } },
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-A': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
};
MockStack.MOCK_STACK_C = {
stackName: 'Test-Stack-C',
template: {
Resources: {
MyBucket1: {
Type: 'AWS::S3::Bucket',
Properties: {
AccessControl: 'PublicRead',
},
DeletionPolicy: 'Retain',
},
},
},
env: 'aws://123456789012/bermuda-triangle-1',
metadata: {
'/Test-Stack-C': [
{
type: cxschema.ArtifactMetadataEntryType.STACK_TAGS,
},
],
},
};
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC1zdGFja3MudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImxpc3Qtc3RhY2tzLnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSwyREFBMkQ7QUFBQSxDQUFDO0FBQzVELGlDQUFrRjtBQUNsRixvREFBb0Q7QUFFcEQsd0RBQW9EO0FBQ3BELG9EQUFnRDtBQUVoRCxRQUFRLENBQUMsTUFBTSxFQUFFLEdBQUcsRUFBRTtJQUNwQixJQUFJLGNBQXdDLENBQUM7SUFDN0MsSUFBSSxZQUF1QyxDQUFDO0lBRTVDLFVBQVUsQ0FBQyxHQUFHLEVBQUU7UUFDZCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFckIsWUFBWSxHQUFHLElBQUEsdUJBQWdCLEVBQUMsd0JBQVksQ0FBQyxDQUFDO1FBQzlDLFlBQVksQ0FBQyxvQkFBb0IsQ0FBQyxpQkFBaUIsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsRUFBUyxDQUFDLENBQUM7SUFDM0YsQ0FBQyxDQUFDLENBQUM7SUFFSCxJQUFJLENBQUMsNkJBQTZCLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDN0MsSUFBSSxlQUFlLEdBQUcsSUFBSSwwQkFBbUIsQ0FBQztZQUM1QyxNQUFNLEVBQUU7Z0JBQ04sU0FBUyxDQUFDLFlBQVk7Z0JBQ3RCO29CQUNFLFNBQVMsRUFBRSxjQUFjO29CQUN6QixRQUFRLEVBQUUsRUFBRSxTQUFTLEVBQUUsRUFBRSxZQUFZLEVBQUUsY0FBYyxFQUFFLEVBQUU7b0JBQ3pELEdBQUcsRUFBRSx1Q0FBdUM7b0JBQzVDLFFBQVEsRUFBRTt3QkFDUixlQUFlLEVBQUU7NEJBQ2Y7Z0NBQ0UsSUFBSSxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxVQUFVOzZCQUNwRDt5QkFDRjtxQkFDRjtpQkFDRjthQUNGO1NBQ0YsQ0FBQyxDQUFDO1FBQ0gsUUFBUTtRQUNSLE1BQU0sT0FBTyxHQUFHLElBQUksd0JBQVUsQ0FBQztZQUM3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QUFDLENBQUMsQ0FBQztBQUNMLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxTQUFTOztBQUNVLHNCQUFZLEdBQXNCO0lBQ3ZELFNBQVMsRUFBRSxjQUFjO0lBQ3pCLFFBQVEsRUFBRSxFQUFFLFNBQVMsRUFBRSxFQUFFLFlBQVksRUFBRSxjQUFjLEVBQUUsRUFBRTtJQUN6RCxHQUFHLEVBQUUsdUNBQXVDO0lBQzVDLFFBQVEsRUFBRTtRQUNSLGVBQWUsRUFBRTtZQUNmO2dCQUNFLElBQUksRUFBRSxRQUFRLENBQUMseUJBQXlCLENBQUMsVUFBVTthQUNwRDtTQUNGO0tBQ0Y7Q0FDRixDQUFDO0FBQ3FCLHNCQUFZLEdBQXNCO0lBQ3ZELFNBQVMsRUFBRSxjQUFjO0lBQ3pCLFFBQVEsRUFBRTtRQUNSLFNBQVMsRUFBRTtZQUNULFNBQVMsRUFBRTtnQkFDVCxJQUFJLEVBQUUsaUJBQWlCO2dCQUN2QixVQUFVLEVBQUU7b0JBQ1YsYUFBYSxFQUFFLFlBQVk7aUJBQzVCO2dCQUNELGNBQWMsRUFBRSxRQUFRO2FBQ3pCO1NBQ0Y7S0FDRjtJQUNELEdBQUcsRUFBRSx1Q0FBdUM7SUFDNUMsUUFBUSxFQUFFO1FBQ1IsZUFBZSxFQUFFO1lBQ2Y7Z0JBQ0UsSUFBSSxFQUFFLFFBQVEsQ0FBQyx5QkFBeUIsQ0FBQyxVQUFVO2FBQ3BEO1NBQ0Y7S0FDRjtDQUNGLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBjeHNjaGVtYSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnOztcbmltcG9ydCB7IGluc3RhbmNlTW9ja0Zyb20sIE1vY2tDbG91ZEV4ZWN1dGFibGUsIFRlc3RTdGFja0FydGlmYWN0IH0gZnJvbSAnLi91dGlsJztcbmltcG9ydCB7IEJvb3RzdHJhcHBlciB9IGZyb20gJy4uL2xpYi9hcGkvYm9vdHN0cmFwJztcbmltcG9ydCB7IERlcGxveW1lbnRzIH0gZnJvbSAnLi4vbGliL2FwaS9kZXBsb3ltZW50cyc7XG5pbXBvcnQgeyBDZGtUb29sa2l0IH0gZnJvbSAnLi4vbGliL2NsaS9jZGstdG9vbGtpdCc7XG5pbXBvcnQgeyBsaXN0U3RhY2tzIH0gZnJvbSAnLi4vbGliL2xpc3Qtc3RhY2tzJztcblxuZGVzY3JpYmUoJ2xpc3QnLCAoKSA9PiB7XG4gIGxldCBjbG91ZEZvcm1hdGlvbjogamVzdC5Nb2NrZWQ8RGVwbG95bWVudHM+O1xuICBsZXQgYm9vdHN0cmFwcGVyOiBqZXN0Lk1vY2tlZDxCb290c3RyYXBwZXI+O1xuXG4gIGJlZm9yZUVhY2goKCkgPT4ge1xuICAgIGplc3QucmVzZXRBbGxNb2NrcygpO1xuXG4gICAgYm9vdHN0cmFwcGVyID0gaW5zdGFuY2VNb2NrRnJvbShCb290c3RyYXBwZXIpO1xuICAgIGJvb3RzdHJhcHBlci5ib290c3RyYXBFbnZpcm9ubWVudC5tb2NrUmVzb2x2ZWRWYWx1ZSh7IG5vT3A6IGZhbHNlLCBvdXRwdXRzOiB7fSB9IGFzIGFueSk7XG4gIH0pO1xuXG4gIHRlc3QoJ3N0YWNrcyB3aXRoIG5vIGRlcGVuZGVuY2llcycsIGFzeW5jICgpID0+IHtcbiAgICBsZXQgY2xvdWRFeGVjdXRhYmxlID0gbmV3IE1vY2tDbG91ZEV4ZWN1dGFibGUoe1xuICAgICAgc3RhY2tzOiBbXG4gICAgICAgIE1vY2tTdGFjay5NT0NLX1NUQUNLX0EsXG4gICAgICAgIHtcbiAgICAgICAgICBzdGFja05hbWU6ICdUZXN0LVN0YWNrLUInLFxuICAgICAgICAgIHRlbXBsYXRlOiB7IFJlc291cmNlczogeyBUZW1wbGF0ZU5hbWU6ICdUZXN0LVN0YWNrLUInIH0gfSxcbiAgICAgICAgICBlbnY6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgJy9UZXN0LVN0YWNrLUInOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBjeHNjaGVtYS5BcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLlNUQUNLX1RBR1MsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgIH0sXG4gICAgICBdLFxuICAgIH0pO1xuICAgIC8vIEdJVkVOXG4gICAgY29uc3QgdG9vbGtpdCA9IG5ldyBDZGtUb29sa2l0KHtcbiAgICAgIGNsb3VkRXhlY3V0YWJsZSxcbiAgICAgIGNvbmZpZ3VyYXRpb246IGNsb3VkRXhlY3V0YWJsZS5jb25maWd1cmF0aW9uLFxuICAgICAgc2RrUHJvdmlkZXI6IGNsb3VkRXhlY3V0YWJsZS5zZGtQcm92aWRlcixcbiAgICAgIGRlcGxveW1lbnRzOiBjbG91ZEZvcm1hdGlvbixcbiAgICB9KTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCB3b3JrZmxvdyA9IGF3YWl0IGxpc3RTdGFja3ModG9vbGtpdCwgeyBzZWxlY3RvcnM6IFsnVGVzdC1TdGFjay1BJywgJ1Rlc3QtU3RhY2stQiddIH0pO1xuXG4gICAgLy8gVEhFTlxuICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeSh3b3JrZmxvdykpLnRvRXF1YWwoSlNPTi5zdHJpbmdpZnkoW3tcbiAgICAgIGlkOiAnVGVzdC1TdGFjay1BJyxcbiAgICAgIG5hbWU6ICdUZXN0LVN0YWNrLUEnLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgYWNjb3VudDogJzEyMzQ1Njc4OTAxMicsXG4gICAgICAgIHJlZ2lvbjogJ2Jlcm11ZGEtdHJpYW5nbGUtMScsXG4gICAgICAgIG5hbWU6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgIH0sXG4gICAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgIH0sXG4gICAge1xuICAgICAgaWQ6ICdUZXN0LVN0YWNrLUInLFxuICAgICAgbmFtZTogJ1Rlc3QtU3RhY2stQicsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJyxcbiAgICAgICAgcmVnaW9uOiAnYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgbmFtZTogJ2F3czovLzEyMzQ1Njc4OTAxMi9iZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgfSxcbiAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgfV0pKTtcbiAgfSk7XG5cbiAgdGVzdCgnc3RhY2tzIHdpdGggZGVwZW5kZW50IHN0YWNrcycsIGFzeW5jICgpID0+IHtcbiAgICBsZXQgY2xvdWRFeGVjdXRhYmxlID0gbmV3IE1vY2tDbG91ZEV4ZWN1dGFibGUoe1xuICAgICAgc3RhY2tzOiBbXG4gICAgICAgIE1vY2tTdGFjay5NT0NLX1NUQUNLX0EsXG4gICAgICAgIHtcbiAgICAgICAgICBzdGFja05hbWU6ICdUZXN0LVN0YWNrLUInLFxuICAgICAgICAgIHRlbXBsYXRlOiB7IFJlc291cmNlczogeyBUZW1wbGF0ZU5hbWU6ICdUZXN0LVN0YWNrLUInIH0gfSxcbiAgICAgICAgICBlbnY6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgJy9UZXN0LVN0YWNrLUInOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBjeHNjaGVtYS5BcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLlNUQUNLX1RBR1MsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZGVwZW5kczogWydUZXN0LVN0YWNrLUEnXSxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHRvb2xraXQgPSBuZXcgQ2RrVG9vbGtpdCh7XG4gICAgICBjbG91ZEV4ZWN1dGFibGUsXG4gICAgICBjb25maWd1cmF0aW9uOiBjbG91ZEV4ZWN1dGFibGUuY29uZmlndXJhdGlvbixcbiAgICAgIHNka1Byb3ZpZGVyOiBjbG91ZEV4ZWN1dGFibGUuc2RrUHJvdmlkZXIsXG4gICAgICBkZXBsb3ltZW50czogY2xvdWRGb3JtYXRpb24sXG4gICAgfSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3Qgd29ya2Zsb3cgPSBhd2FpdCBsaXN0U3RhY2tzKCB0b29sa2l0LCB7IHNlbGVjdG9yczogWydUZXN0LVN0YWNrLUEnLCAnVGVzdC1TdGFjay1CJ10gfSk7XG5cbiAgICAvLyBUSEVOXG4gICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHdvcmtmbG93KSkudG9FcXVhbChKU09OLnN0cmluZ2lmeShbe1xuICAgICAgaWQ6ICdUZXN0LVN0YWNrLUEnLFxuICAgICAgbmFtZTogJ1Rlc3QtU3RhY2stQScsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJyxcbiAgICAgICAgcmVnaW9uOiAnYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgbmFtZTogJ2F3czovLzEyMzQ1Njc4OTAxMi9iZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgfSxcbiAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogJ1Rlc3QtU3RhY2stQicsXG4gICAgICBuYW1lOiAnVGVzdC1TdGFjay1CJyxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIGFjY291bnQ6ICcxMjM0NTY3ODkwMTInLFxuICAgICAgICByZWdpb246ICdiZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgICBuYW1lOiAnYXdzOi8vMTIzNDU2Nzg5MDEyL2Jlcm11ZGEtdHJpYW5nbGUtMScsXG4gICAgICB9LFxuICAgICAgZGVwZW5kZW5jaWVzOiBbe1xuICAgICAgICBpZDogJ1Rlc3QtU3RhY2stQScsXG4gICAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgICB9XSxcbiAgICB9XSkpO1xuICB9KTtcblxuICAvLyBJbiB0aGUgY29udGV4dCB3aGVyZSB3ZSBoYXZlIGEgZGlzcGxheSBuYW1lIHNldCB0byBoaWVyYXJpY2FsSWQvc3RhY2tOYW1lXG4gIC8vIHdlIHdvdWxkIG5lZWQgdG8gcGFzcyBpbiB0aGUgZGlzcGxheU5hbWUgdG8gbGlzdCB0aGUgc3RhY2tzLlxuICB0ZXN0KCdzdGFja3Mgd2l0aCBkZXBlbmRlbnQgc3RhY2tzIGFuZCBoYXZlIGRpc3BsYXkgbmFtZSBzZXQgdG8gaGllcmFyaWNhbElkL3N0YWNrTmFtZScsIGFzeW5jICgpID0+IHtcbiAgICBsZXQgY2xvdWRFeGVjdXRhYmxlID0gbmV3IE1vY2tDbG91ZEV4ZWN1dGFibGUoe1xuICAgICAgc3RhY2tzOiBbXG4gICAgICAgIE1vY2tTdGFjay5NT0NLX1NUQUNLX0EsXG4gICAgICAgIHtcbiAgICAgICAgICBzdGFja05hbWU6ICdUZXN0LVN0YWNrLUInLFxuICAgICAgICAgIHRlbXBsYXRlOiB7IFJlc291cmNlczogeyBUZW1wbGF0ZU5hbWU6ICdUZXN0LVN0YWNrLUInIH0gfSxcbiAgICAgICAgICBlbnY6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgJy9UZXN0LVN0YWNrLUInOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBjeHNjaGVtYS5BcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLlNUQUNLX1RBR1MsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZGVwZW5kczogWydUZXN0LVN0YWNrLUEnXSxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1Rlc3QtU3RhY2stQS9UZXN0LVN0YWNrLUInLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIC8vIEdJVkVOXG4gICAgY29uc3QgdG9vbGtpdCA9IG5ldyBDZGtUb29sa2l0KHtcbiAgICAgIGNsb3VkRXhlY3V0YWJsZSxcbiAgICAgIGNvbmZpZ3VyYXRpb246IGNsb3VkRXhlY3V0YWJsZS5jb25maWd1cmF0aW9uLFxuICAgICAgc2RrUHJvdmlkZXI6IGNsb3VkRXhlY3V0YWJsZS5zZGtQcm92aWRlcixcbiAgICAgIGRlcGxveW1lbnRzOiBjbG91ZEZvcm1hdGlvbixcbiAgICB9KTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCB3b3JrZmxvdyA9IGF3YWl0IGxpc3RTdGFja3MoIHRvb2xraXQsIHsgc2VsZWN0b3JzOiBbJ1Rlc3QtU3RhY2stQScsICdUZXN0LVN0YWNrLUEvVGVzdC1TdGFjay1CJ10gfSk7XG5cbiAgICAvLyBUSEVOXG4gICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHdvcmtmbG93KSkudG9FcXVhbChKU09OLnN0cmluZ2lmeShbe1xuICAgICAgaWQ6ICdUZXN0LVN0YWNrLUEnLFxuICAgICAgbmFtZTogJ1Rlc3QtU3RhY2stQScsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJyxcbiAgICAgICAgcmVnaW9uOiAnYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgbmFtZTogJ2F3czovLzEyMzQ1Njc4OTAxMi9iZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgfSxcbiAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogJ1Rlc3QtU3RhY2stQS9UZXN0LVN0YWNrLUInLFxuICAgICAgbmFtZTogJ1Rlc3QtU3RhY2stQicsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJyxcbiAgICAgICAgcmVnaW9uOiAnYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgbmFtZTogJ2F3czovLzEyMzQ1Njc4OTAxMi9iZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgfSxcbiAgICAgIGRlcGVuZGVuY2llczogW3tcbiAgICAgICAgaWQ6ICdUZXN0LVN0YWNrLUEnLFxuICAgICAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgICAgfV0sXG4gICAgfV0pKTtcbiAgfSk7XG5cbiAgdGVzdCgnc3RhY2tzIHdpdGggZGlzcGxheSBuYW1lcyBhbmQgaGF2ZSBuZXN0ZWQgZGVwZW5kZW5jaWVzJywgYXN5bmMgKCkgPT4ge1xuICAgIGxldCBjbG91ZEV4ZWN1dGFibGUgPSBuZXcgTW9ja0Nsb3VkRXhlY3V0YWJsZSh7XG4gICAgICBzdGFja3M6IFtcbiAgICAgICAgTW9ja1N0YWNrLk1PQ0tfU1RBQ0tfQSxcbiAgICAgICAge1xuICAgICAgICAgIHN0YWNrTmFtZTogJ1Rlc3QtU3RhY2stQicsXG4gICAgICAgICAgdGVtcGxhdGU6IHsgUmVzb3VyY2VzOiB7IFRlbXBsYXRlTmFtZTogJ1Rlc3QtU3RhY2stQicgfSB9LFxuICAgICAgICAgIGVudjogJ2F3czovLzEyMzQ1Njc4OTAxMi9iZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICAnL1Rlc3QtU3RhY2stQic6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IGN4c2NoZW1hLkFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuU1RBQ0tfVEFHUyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBkZXBlbmRzOiBbJ1Rlc3QtU3RhY2stQSddLFxuICAgICAgICAgIGRpc3BsYXlOYW1lOiAnVGVzdC1TdGFjay1BL1Rlc3QtU3RhY2stQicsXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBzdGFja05hbWU6ICdUZXN0LVN0YWNrLUMnLFxuICAgICAgICAgIHRlbXBsYXRlOiB7IFJlc291cmNlczogeyBUZW1wbGF0ZU5hbWU6ICdUZXN0LVN0YWNrLUMnIH0gfSxcbiAgICAgICAgICBlbnY6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgJy9UZXN0LVN0YWNrLUMnOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBjeHNjaGVtYS5BcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLlNUQUNLX1RBR1MsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZGVwZW5kczogWydUZXN0LVN0YWNrLUInXSxcbiAgICAgICAgICBkaXNwbGF5TmFtZTogJ1Rlc3QtU3RhY2stQS9UZXN0LVN0YWNrLUIvVGVzdC1TdGFjay1DJyxcbiAgICAgICAgfSxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHRvb2xraXQgPSBuZXcgQ2RrVG9vbGtpdCh7XG4gICAgICBjbG91ZEV4ZWN1dGFibGUsXG4gICAgICBjb25maWd1cmF0aW9uOiBjbG91ZEV4ZWN1dGFibGUuY29uZmlndXJhdGlvbixcbiAgICAgIHNka1Byb3ZpZGVyOiBjbG91ZEV4ZWN1dGFibGUuc2RrUHJvdmlkZXIsXG4gICAgICBkZXBsb3ltZW50czogY2xvdWRGb3JtYXRpb24sXG4gICAgfSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3Qgd29ya2Zsb3cgPSBhd2FpdCBsaXN0U3RhY2tzKCB0b29sa2l0LCB7IHNlbGVjdG9yczogWydUZXN0LVN0YWNrLUEnLCAnVGVzdC1TdGFjay1BL1Rlc3QtU3RhY2stQicsICdUZXN0LVN0YWNrLUEvVGVzdC1TdGFjay1CL1Rlc3QtU3RhY2stQyddIH0pO1xuXG4gICAgLy8gVEhFTlxuICAgIGV4cGVjdChKU09OLnN0cmluZ2lmeSh3b3JrZmxvdykpLnRvRXF1YWwoSlNPTi5zdHJpbmdpZnkoW3tcbiAgICAgIGlkOiAnVGVzdC1TdGFjay1BJyxcbiAgICAgIG5hbWU6ICdUZXN0LVN0YWNrLUEnLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgYWNjb3VudDogJzEyMzQ1Njc4OTAxMicsXG4gICAgICAgIHJlZ2lvbjogJ2Jlcm11ZGEtdHJpYW5nbGUtMScsXG4gICAgICAgIG5hbWU6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgIH0sXG4gICAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgIH0sXG4gICAge1xuICAgICAgaWQ6ICdUZXN0LVN0YWNrLUEvVGVzdC1TdGFjay1CJyxcbiAgICAgIG5hbWU6ICdUZXN0LVN0YWNrLUInLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgYWNjb3VudDogJzEyMzQ1Njc4OTAxMicsXG4gICAgICAgIHJlZ2lvbjogJ2Jlcm11ZGEtdHJpYW5nbGUtMScsXG4gICAgICAgIG5hbWU6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgIH0sXG4gICAgICBkZXBlbmRlbmNpZXM6IFt7XG4gICAgICAgIGlkOiAnVGVzdC1TdGFjay1BJyxcbiAgICAgICAgZGVwZW5kZW5jaWVzOiBbXSxcbiAgICAgIH1dLFxuICAgIH0sXG4gICAge1xuICAgICAgaWQ6ICdUZXN0LVN0YWNrLUEvVGVzdC1TdGFjay1CL1Rlc3QtU3RhY2stQycsXG4gICAgICBuYW1lOiAnVGVzdC1TdGFjay1DJyxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIGFjY291bnQ6ICcxMjM0NTY3ODkwMTInLFxuICAgICAgICByZWdpb246ICdiZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgICBuYW1lOiAnYXdzOi8vMTIzNDU2Nzg5MDEyL2Jlcm11ZGEtdHJpYW5nbGUtMScsXG4gICAgICB9LFxuICAgICAgZGVwZW5kZW5jaWVzOiBbe1xuICAgICAgICBpZDogJ1Rlc3QtU3RhY2stQS9UZXN0LVN0YWNrLUInLFxuICAgICAgICBkZXBlbmRlbmNpZXM6IFt7XG4gICAgICAgICAgaWQ6ICdUZXN0LVN0YWNrLUEnLFxuICAgICAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgICAgIH1dLFxuICAgICAgfV0sXG4gICAgfV0pKTtcbiAgfSk7XG5cbiAgdGVzdCgnc3RhY2tzIHdpdGggbmVzdGVkIGRlcGVuZGVuY2llcycsIGFzeW5jICgpID0+IHtcbiAgICBsZXQgY2xvdWRFeGVjdXRhYmxlID0gbmV3IE1vY2tDbG91ZEV4ZWN1dGFibGUoe1xuICAgICAgc3RhY2tzOiBbXG4gICAgICAgIE1vY2tTdGFjay5NT0NLX1NUQUNLX0EsXG4gICAgICAgIHtcbiAgICAgICAgICBzdGFja05hbWU6ICdUZXN0LVN0YWNrLUInLFxuICAgICAgICAgIHRlbXBsYXRlOiB7IFJlc291cmNlczogeyBUZW1wbGF0ZU5hbWU6ICdUZXN0LVN0YWNrLUInIH0gfSxcbiAgICAgICAgICBlbnY6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgJy9UZXN0LVN0YWNrLUInOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBjeHNjaGVtYS5BcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLlNUQUNLX1RBR1MsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZGVwZW5kczogWydUZXN0LVN0YWNrLUEnXSxcbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIHN0YWNrTmFtZTogJ1Rlc3QtU3RhY2stQycsXG4gICAgICAgICAgdGVtcGxhdGU6IHsgUmVzb3VyY2VzOiB7IFRlbXBsYXRlTmFtZTogJ1Rlc3QtU3RhY2stQycgfSB9LFxuICAgICAgICAgIGVudjogJ2F3czovLzEyMzQ1Njc4OTAxMi9iZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICAgICAnL1Rlc3QtU3RhY2stQyc6IFtcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHR5cGU6IGN4c2NoZW1hLkFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuU1RBQ0tfVEFHUyxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBkZXBlbmRzOiBbJ1Rlc3QtU3RhY2stQiddLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIC8vIEdJVkVOXG4gICAgY29uc3QgdG9vbGtpdCA9IG5ldyBDZGtUb29sa2l0KHtcbiAgICAgIGNsb3VkRXhlY3V0YWJsZSxcbiAgICAgIGNvbmZpZ3VyYXRpb246IGNsb3VkRXhlY3V0YWJsZS5jb25maWd1cmF0aW9uLFxuICAgICAgc2RrUHJvdmlkZXI6IGNsb3VkRXhlY3V0YWJsZS5zZGtQcm92aWRlcixcbiAgICAgIGRlcGxveW1lbnRzOiBjbG91ZEZvcm1hdGlvbixcbiAgICB9KTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCB3b3JrZmxvdyA9IGF3YWl0IGxpc3RTdGFja3MoIHRvb2xraXQsIHsgc2VsZWN0b3JzOiBbJ1Rlc3QtU3RhY2stQScsICdUZXN0LVN0YWNrLUInLCAnVGVzdC1TdGFjay1DJ10gfSk7XG5cbiAgICAvLyBUSEVOXG4gICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHdvcmtmbG93KSkudG9FcXVhbChKU09OLnN0cmluZ2lmeShbe1xuICAgICAgaWQ6ICdUZXN0LVN0YWNrLUEnLFxuICAgICAgbmFtZTogJ1Rlc3QtU3RhY2stQScsXG4gICAgICBlbnZpcm9ubWVudDoge1xuICAgICAgICBhY2NvdW50OiAnMTIzNDU2Nzg5MDEyJyxcbiAgICAgICAgcmVnaW9uOiAnYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgbmFtZTogJ2F3czovLzEyMzQ1Njc4OTAxMi9iZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgfSxcbiAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgfSxcbiAgICB7XG4gICAgICBpZDogJ1Rlc3QtU3RhY2stQicsXG4gICAgICBuYW1lOiAnVGVzdC1TdGFjay1CJyxcbiAgICAgIGVudmlyb25tZW50OiB7XG4gICAgICAgIGFjY291bnQ6ICcxMjM0NTY3ODkwMTInLFxuICAgICAgICByZWdpb246ICdiZXJtdWRhLXRyaWFuZ2xlLTEnLFxuICAgICAgICBuYW1lOiAnYXdzOi8vMTIzNDU2Nzg5MDEyL2Jlcm11ZGEtdHJpYW5nbGUtMScsXG4gICAgICB9LFxuICAgICAgZGVwZW5kZW5jaWVzOiBbe1xuICAgICAgICBpZDogJ1Rlc3QtU3RhY2stQScsXG4gICAgICAgIGRlcGVuZGVuY2llczogW10sXG4gICAgICB9XSxcbiAgICB9LFxuICAgIHtcbiAgICAgIGlkOiAnVGVzdC1TdGFjay1DJyxcbiAgICAgIG5hbWU6ICdUZXN0LVN0YWNrLUMnLFxuICAgICAgZW52aXJvbm1lbnQ6IHtcbiAgICAgICAgYWNjb3VudDogJzEyMzQ1Njc4OTAxMicsXG4gICAgICAgIHJlZ2lvbjogJ2Jlcm11ZGEtdHJpYW5nbGUtMScsXG4gICAgICAgIG5hbWU6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgIH0sXG4gICAgICBkZXBlbmRlbmNpZXM6IFt7XG4gICAgICAgIGlkOiAnVGVzdC1TdGFjay1CJyxcbiAgICAgICAgZGVwZW5kZW5jaWVzOiBbe1xuICAgICAgICAgIGlkOiAnVGVzdC1TdGFjay1BJyxcbiAgICAgICAgICBkZXBlbmRlbmNpZXM6IFtdLFxuICAgICAgICB9XSxcbiAgICAgIH1dLFxuICAgIH1dKSk7XG4gIH0pO1xuXG4gIC8vIEluIHRoZSBjb250ZXh0IG9mIHN0YWNrcyB3aXRoIGNyb3NzLXN0YWNrIG9yIGNyb3NzLXJlZ2lvbiByZWZlcmVuY2VzLFxuICAvLyB0aGUgZGVwZW5kZW5jeSBtZWNoYW5pc20gaXMgcmVzcG9uc2libGUgZm9yIGFwcHJvcHJpYXRlbHkgYXBwbHlpbmcgZGVwZW5kZW5jaWVzIGF0IHRoZSBjb3JyZWN0IGhpZXJhcmNoeSBsZXZlbCxcbiAgLy8gdHlwaWNhbGx5IGF0IHRoZSB0b3AtbGV2ZWwgc3RhY2tzLlxuICAvLyBUaGlzIGludm9sdmVzIGhhbmRsaW5nIHRoZSBlc3RhYmxpc2htZW50IG9mIGNyb3NzLXJlZmVyZW5jZXMgYmV0d2VlbiBzdGFja3Mgb3IgbmVzdGVkIHN0YWNrc1xuICAvLyBhbmQgZ2VuZXJhdGluZyBhc3NldHMgZm9yIG5lc3RlZCBzdGFjayB0ZW1wbGF0ZXMgYXMgbmVjZXNzYXJ5LlxuICB0ZXN0KCdzdGFja3Mgd2l0aCBjcm9zcyBzdGFjayByZWZlcmVuY2luZycsIGFzeW5jICgpID0+IHtcbiAgICBsZXQgY2xvdWRFeGVjdXRhYmxlID0gbmV3IE1vY2tDbG91ZEV4ZWN1dGFibGUoe1xuICAgICAgc3RhY2tzOiBbXG4gICAgICAgIHtcbiAgICAgICAgICBzdGFja05hbWU6ICdUZXN0LVN0YWNrLUEnLFxuICAgICAgICAgIHRlbXBsYXRlOiB7XG4gICAgICAgICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgICAgICAgTXlCdWNrZXQxUmVmZXJlbmNlOiB7XG4gICAgICAgICAgICAgICAgVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgICAgICAgICBQcm9wZXJ0aWVzOiB7XG4gICAgICAgICAgICAgICAgICBUZW1wbGF0ZVVSTDogJ1hYWFhYWFhYWFhYWFhYWFhYWFhYWFhYWFgnLFxuICAgICAgICAgICAgICAgICAgUGFyYW1ldGVyczoge1xuICAgICAgICAgICAgICAgICAgICBCdWNrZXROYW1lOiB7ICdGbjo6R2V0QXR0JzogWydNeUJ1Y2tldDEnLCAnQXJuJ10gfSxcbiAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSxcbiAgICAgICAgICBlbnY6ICdhd3M6Ly8xMjM0NTY3ODkwMTIvYmVybXVkYS10cmlhbmdsZS0xJyxcbiAgICAgICAgICBtZXRhZGF0YToge1xuICAgICAgICAgICAgJy9UZXN0LVN0YWNrLUEnOiBbXG4gICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICB0eXBlOiBjeHNjaGVtYS5BcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLlNUQUNLX1RBR1MsXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0sXG4gICAgICAgICAgZGVwZW5kczogWydUZXN0LVN0YWNrLUMnXSxcbiAgICAgICAgfSxcbiAgICAgICAgTW9ja1N0YWNrLk1PQ0tfU1RBQ0tfQyxcbiAgICAgIF0sXG4gICAgfSk7XG5cbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHRvb2xraXQgPSBuZXcgQ2RrVG9vbGtpdCh7XG4gICAgICBjbG91ZEV4ZWN1dGFibGUsXG4gICAgICBjb25maWd1cmF0aW9uOiBjbG91ZEV4ZWN1dGFibGUuY29uZmlndXJhdGlvbixcbiAgICAgIHNka1Byb3ZpZGVyOiBjbG91ZEV4ZWN1dGFibGUuc2RrUHJvdmlkZXIsXG4gICAgICBkZXBsb3ltZW50czogY2xvdWRGb3JtYXRpb24sXG4gICAgfSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3Qgd29ya2Zsb3cgPSBhd2FpdCBsaXN0U3RhY2tzKCB0b29sa2l0LCB7IHNlbGVjdG9yczogWydUZXN0LVN0YWNrLUEnLCAnVGVzdC1TdGFjay1DJ10gfSk7XG5cbiAgICAvLyBUSEVOXG4gICAgZXhwZWN0KEpTT04uc3RyaW5naWZ5KHdvcmtmbG93KSkudG9FcXVhbChKU09OLnN0cmluZ2lmeShbe1xuICAgICAgaWQ6ICdUZXN0LVN0YWNrLUMnLFxuICAgICAgbmFtZTogJ1Rlc3QtU3RhY2stQycsXG4g