UNPKG

aws-cdk

Version:

CDK Toolkit, the command line tool for CDK apps

489 lines 53.8 kB
"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