aws-cdk
Version:
CDK Toolkit, the command line tool for CDK apps
281 lines • 38.1 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
/* eslint-disable import/order */
const cxschema = require("@aws-cdk/cloud-assembly-schema");
const cloud_assembly_1 = require("../../lib/api/cxapp/cloud-assembly");
const util_1 = require("../util");
const assembly_versions_1 = require("./assembly-versions");
test('select all top level stacks in the presence of nested assemblies', async () => {
// GIVEN
const cxasm = await testNestedCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ allTopLevel: true, patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks });
// THEN
expect(x.stackCount).toBe(2);
expect(x.stackIds).toContain('witherrors');
expect(x.stackIds).toContain('withouterrors');
});
test('select stacks by glob pattern', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ patterns: ['with*'] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks });
// THEN
expect(x.stackCount).toBe(3);
expect(x.stackIds).toContain('witherrors');
expect(x.stackIds).toContain('withouterrors');
});
test('select behavior: all', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks });
// THEN
expect(x.stackCount).toBe(3);
});
test('select behavior: none', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.None });
// THEN
expect(x.stackCount).toBe(0);
});
test('select behavior: single', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
await expect(cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.OnlySingle }))
.rejects.toThrow('Since this app includes more than a single stack, specify which stacks to use (wildcards are supported) or specify `--all`');
});
test('stack list error contains node paths', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
await expect(cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.OnlySingle }))
.rejects.toThrow('withouterrorsNODEPATH');
});
test('select behavior: repeat', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ patterns: ['withouterrorsNODEPATH', 'withouterrorsNODEPATH'] }, {
defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks,
});
// THEN
expect(x.stackCount).toBe(1);
});
test('select behavior with nested assemblies: all', async () => {
// GIVEN
const cxasm = await testNestedCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks });
// THEN
expect(x.stackCount).toBe(3);
});
test('select behavior with nested assemblies: none', async () => {
// GIVEN
const cxasm = await testNestedCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.None });
// THEN
expect(x.stackCount).toBe(0);
});
test('select behavior with nested assemblies: single', async () => {
// GIVEN
const cxasm = await testNestedCloudAssembly();
// WHEN
await expect(cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.OnlySingle }))
.rejects.toThrow('Since this app includes more than a single stack, specify which stacks to use (wildcards are supported) or specify `--all`');
});
test('select behavior with nested assemblies: repeat', async () => {
// GIVEN
const cxasm = await testNestedCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ patterns: ['deeply/hidden/withouterrors', 'nested'] }, {
defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks,
});
// THEN
expect(x.stackCount).toBe(2);
});
test('select behavior with no stacks and ignore stacks option', async () => {
// GIVEN
const cxasm = await testCloudAssemblyNoStacks();
// WHEN
const x = await cxasm.selectStacks({ patterns: [] }, {
defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks,
ignoreNoStacks: true,
});
// THEN
expect(x.stackCount).toBe(0);
});
test('select behavior with no stacks and no ignore stacks option', async () => {
// GIVEN
const cxasm = await testCloudAssemblyNoStacks();
// WHEN & THEN
await expect(cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks, ignoreNoStacks: false }))
.rejects.toThrow('This app contains no stacks');
});
test('select behavior with no stacks and default ignore stacks options (false)', async () => {
// GIVEN
const cxasm = await testCloudAssemblyNoStacks();
// WHEN & THEN
await expect(cxasm.selectStacks({ patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks }))
.rejects.toThrow('This app contains no stacks');
});
describe('StackCollection', () => {
test('returns hierarchicalIds', async () => {
// GIVEN
const cxasm = await testNestedCloudAssembly();
// WHEN
const x = await cxasm.selectStacks({ allTopLevel: true, patterns: [] }, { defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks });
// THEN
expect(x.stackCount).toBe(2);
expect(x.hierarchicalIds).toEqual(['witherrors', 'deeply/hidden/withouterrors']);
});
describe('validateMetadata', () => {
test('do not throw when selecting stack without errors', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const selected = await cxasm.selectStacks({ patterns: ['withouterrorsNODEPATH'] }, {
defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks,
});
await selected.validateMetadata();
// THEN
expect(selected.stackCount).toBe(1);
expect(selected.firstStack.template.resource).toBe('noerrorresource');
});
test('do not throw when selecting stack with warnings', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const selected = await cxasm.selectStacks({ patterns: ['withwarns'] }, {
defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks,
});
await selected.validateMetadata();
// THEN
expect(selected.stackCount).toBe(1);
expect(selected.firstStack.template.resource).toBe('warnresource');
});
test('do not throw when selecting stack with errors but errors are ignored', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const selected = await cxasm.selectStacks({ patterns: ['witherrors'] }, {
defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks,
});
await selected.validateMetadata('none');
// THEN
expect(selected.stackCount).toBe(1);
expect(selected.firstStack.template.resource).toBe('errorresource');
});
test('do throw when selecting stack with errors', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const selected = await cxasm.selectStacks({ patterns: ['witherrors'] }, {
defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks,
});
// THEN
expect(selected.stackCount).toBe(1);
await expect(async () => selected.validateMetadata()).rejects.toThrow(/Found errors/);
});
test('do throw when selecting stack with warnings and we are on strict mode', async () => {
// GIVEN
const cxasm = await testCloudAssembly();
// WHEN
const selected = await cxasm.selectStacks({ patterns: ['withwarns'] }, {
defaultBehavior: cloud_assembly_1.DefaultSelection.AllStacks,
});
// THEN
expect(selected.stackCount).toBe(1);
await expect(async () => selected.validateMetadata('warn')).rejects.toThrow(/Found warnings/);
});
});
});
async function testCloudAssembly({ env } = {}) {
const cloudExec = new util_1.MockCloudExecutable({
stacks: [{
stackName: 'withouterrors',
displayName: 'withouterrorsNODEPATH',
env,
template: { resource: 'noerrorresource' },
},
{
stackName: 'witherrors',
env,
template: { resource: 'errorresource' },
metadata: {
'/resource': [
{
type: cxschema.ArtifactMetadataEntryType.ERROR,
data: 'this is an error',
},
],
},
},
{
stackName: 'withwarns',
env,
template: { resource: 'warnresource' },
metadata: {
'/resource': [
{
type: cxschema.ArtifactMetadataEntryType.WARN,
data: 'this is a warning',
},
],
},
}],
});
return cloudExec.synthesize();
}
async function testCloudAssemblyNoStacks() {
const cloudExec = new util_1.MockCloudExecutable({
stacks: [],
});
return cloudExec.synthesize();
}
async function testNestedCloudAssembly({ env } = {}) {
const cloudExec = new util_1.MockCloudExecutable({
stacks: [{
stackName: 'withouterrors',
env,
template: { resource: 'noerrorresource' },
// The nesting in the path should be independent of the position in the tree
displayName: 'deeply/hidden/withouterrors',
},
{
stackName: 'witherrors',
env,
template: { resource: 'errorresource' },
metadata: {
'/resource': [
{
type: cxschema.ArtifactMetadataEntryType.ERROR,
data: 'this is an error',
},
],
},
}],
nestedAssemblies: [{
stacks: [{
stackName: 'nested',
env,
template: { resource: 'nestederror' },
metadata: {
'/resource': [
{
type: cxschema.ArtifactMetadataEntryType.ERROR,
data: 'this is another error',
},
],
},
}],
}],
});
const asm = await cloudExec.synthesize();
return (0, assembly_versions_1.cliAssemblyWithForcedVersion)(asm, '30.0.0');
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2xvdWQtYXNzZW1ibHkudGVzdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbImNsb3VkLWFzc2VtYmx5LnRlc3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpQ0FBaUM7QUFDakMsMkRBQTJEO0FBQzNELHVFQUFzRTtBQUN0RSxrQ0FBOEM7QUFDOUMsMkRBQW1FO0FBRW5FLElBQUksQ0FBQyxrRUFBa0UsRUFBRSxLQUFLLElBQUksRUFBRTtJQUNsRixRQUFRO0lBQ1IsTUFBTSxLQUFLLEdBQUcsTUFBTSx1QkFBdUIsRUFBRSxDQUFDO0lBRTlDLE9BQU87SUFDUCxNQUFNLENBQUMsR0FBRyxNQUFNLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLGVBQWUsRUFBRSxpQ0FBZ0IsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO0lBRXpILE9BQU87SUFDUCxNQUFNLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3QixNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUMzQyxNQUFNLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsQ0FBQztBQUNoRCxDQUFDLENBQUMsQ0FBQztBQUVILElBQUksQ0FBQywrQkFBK0IsRUFBRSxLQUFLLElBQUksRUFBRTtJQUMvQyxRQUFRO0lBQ1IsTUFBTSxLQUFLLEdBQUcsTUFBTSxpQkFBaUIsRUFBRSxDQUFDO0lBRXhDLE9BQU87SUFDUCxNQUFNLENBQUMsR0FBRyxNQUFNLEtBQUssQ0FBQyxZQUFZLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsZUFBZSxFQUFFLGlDQUFnQixDQUFDLFNBQVMsRUFBRSxDQUFDLENB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QyxLQUFLOzRCQUM5QyxJQUFJLEVBQUUsa0JBQWtCO3lCQUN6QjtxQkFDRjtpQkFDRjthQUNGLENBQUM7UUFDRixnQkFBZ0IsRUFBRSxDQUFDO2dCQUNqQixNQUFNLEVBQUUsQ0FBQzt3QkFDUCxTQUFTLEVBQUUsUUFBUTt3QkFDbkIsR0FBRzt3QkFDSCxRQUFRLEVBQUUsRUFBRSxRQUFRLEVBQUUsYUFBYSxFQUFFO3dCQUNyQyxRQUFRLEVBQUU7NEJBQ1IsV0FBVyxFQUFFO2dDQUNYO29DQUNFLElBQUksRUFBRSxRQUFRLENBQUMseUJBQXlCLENBQUMsS0FBSztvQ0FDOUMsSUFBSSxFQUFFLHVCQUF1QjtpQ0FDOUI7NkJBQ0Y7eUJBQ0Y7cUJBQ0YsQ0FBQzthQUNILENBQUM7S0FDSCxDQUFDLENBQUM7SUFFSCxNQUFNLEdBQUcsR0FBRyxNQUFNLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztJQUN6QyxPQUFPLElBQUEsZ0RBQTRCLEVBQUMsR0FBRyxFQUFFLFFBQVEsQ0FBQyxDQUFDO0FBQ3JELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvb3JkZXIgKi9cbmltcG9ydCAqIGFzIGN4c2NoZW1hIGZyb20gJ0Bhd3MtY2RrL2Nsb3VkLWFzc2VtYmx5LXNjaGVtYSc7XG5pbXBvcnQgeyBEZWZhdWx0U2VsZWN0aW9uIH0gZnJvbSAnLi4vLi4vbGliL2FwaS9jeGFwcC9jbG91ZC1hc3NlbWJseSc7XG5pbXBvcnQgeyBNb2NrQ2xvdWRFeGVjdXRhYmxlIH0gZnJvbSAnLi4vdXRpbCc7XG5pbXBvcnQgeyBjbGlBc3NlbWJseVdpdGhGb3JjZWRWZXJzaW9uIH0gZnJvbSAnLi9hc3NlbWJseS12ZXJzaW9ucyc7XG5cbnRlc3QoJ3NlbGVjdCBhbGwgdG9wIGxldmVsIHN0YWNrcyBpbiB0aGUgcHJlc2VuY2Ugb2YgbmVzdGVkIGFzc2VtYmxpZXMnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGN4YXNtID0gYXdhaXQgdGVzdE5lc3RlZENsb3VkQXNzZW1ibHkoKTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IHggPSBhd2FpdCBjeGFzbS5zZWxlY3RTdGFja3MoeyBhbGxUb3BMZXZlbDogdHJ1ZSwgcGF0dGVybnM6IFtdIH0sIHsgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLkFsbFN0YWNrcyB9KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdCh4LnN0YWNrQ291bnQpLnRvQmUoMik7XG4gIGV4cGVjdCh4LnN0YWNrSWRzKS50b0NvbnRhaW4oJ3dpdGhlcnJvcnMnKTtcbiAgZXhwZWN0KHguc3RhY2tJZHMpLnRvQ29udGFpbignd2l0aG91dGVycm9ycycpO1xufSk7XG5cbnRlc3QoJ3NlbGVjdCBzdGFja3MgYnkgZ2xvYiBwYXR0ZXJuJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBjeGFzbSA9IGF3YWl0IHRlc3RDbG91ZEFzc2VtYmx5KCk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCB4ID0gYXdhaXQgY3hhc20uc2VsZWN0U3RhY2tzKHsgcGF0dGVybnM6IFsnd2l0aConXSB9LCB7IGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5BbGxTdGFja3MgfSk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QoeC5zdGFja0NvdW50KS50b0JlKDMpO1xuICBleHBlY3QoeC5zdGFja0lkcykudG9Db250YWluKCd3aXRoZXJyb3JzJyk7XG4gIGV4cGVjdCh4LnN0YWNrSWRzKS50b0NvbnRhaW4oJ3dpdGhvdXRlcnJvcnMnKTtcbn0pO1xuXG50ZXN0KCdzZWxlY3QgYmVoYXZpb3I6IGFsbCcsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY3hhc20gPSBhd2FpdCB0ZXN0Q2xvdWRBc3NlbWJseSgpO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgeCA9IGF3YWl0IGN4YXNtLnNlbGVjdFN0YWNrcyh7IHBhdHRlcm5zOiBbXSB9LCB7IGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5BbGxTdGFja3MgfSk7XG5cbiAgLy8gVEhFTlxuICBleHBlY3QoeC5zdGFja0NvdW50KS50b0JlKDMpO1xufSk7XG5cbnRlc3QoJ3NlbGVjdCBiZWhhdmlvcjogbm9uZScsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY3hhc20gPSBhd2FpdCB0ZXN0Q2xvdWRBc3NlbWJseSgpO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgeCA9IGF3YWl0IGN4YXNtLnNlbGVjdFN0YWNrcyh7IHBhdHRlcm5zOiBbXSB9LCB7IGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5Ob25lIH0pO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KHguc3RhY2tDb3VudCkudG9CZSgwKTtcbn0pO1xuXG50ZXN0KCdzZWxlY3QgYmVoYXZpb3I6IHNpbmdsZScsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY3hhc20gPSBhd2FpdCB0ZXN0Q2xvdWRBc3NlbWJseSgpO1xuXG4gIC8vIFdIRU5cbiAgYXdhaXQgZXhwZWN0KGN4YXNtLnNlbGVjdFN0YWNrcyh7IHBhdHRlcm5zOiBbXSB9LCB7IGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5Pbmx5U2luZ2xlIH0pKVxuICAgIC5yZWplY3RzLnRvVGhyb3coJ1NpbmNlIHRoaXMgYXBwIGluY2x1ZGVzIG1vcmUgdGhhbiBhIHNpbmdsZSBzdGFjaywgc3BlY2lmeSB3aGljaCBzdGFja3MgdG8gdXNlICh3aWxkY2FyZHMgYXJlIHN1cHBvcnRlZCkgb3Igc3BlY2lmeSBgLS1hbGxgJyk7XG59KTtcblxudGVzdCgnc3RhY2sgbGlzdCBlcnJvciBjb250YWlucyBub2RlIHBhdGhzJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBjeGFzbSA9IGF3YWl0IHRlc3RDbG91ZEFzc2VtYmx5KCk7XG5cbiAgLy8gV0hFTlxuICBhd2FpdCBleHBlY3QoY3hhc20uc2VsZWN0U3RhY2tzKHsgcGF0dGVybnM6IFtdIH0sIHsgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLk9ubHlTaW5nbGUgfSkpXG4gICAgLnJlamVjdHMudG9UaHJvdygnd2l0aG91dGVycm9yc05PREVQQVRIJyk7XG59KTtcblxudGVzdCgnc2VsZWN0IGJlaGF2aW9yOiByZXBlYXQnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGN4YXNtID0gYXdhaXQgdGVzdENsb3VkQXNzZW1ibHkoKTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IHggPSBhd2FpdCBjeGFzbS5zZWxlY3RTdGFja3MoeyBwYXR0ZXJuczogWyd3aXRob3V0ZXJyb3JzTk9ERVBBVEgnLCAnd2l0aG91dGVycm9yc05PREVQQVRIJ10gfSwge1xuICAgIGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5BbGxTdGFja3MsXG4gIH0pO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KHguc3RhY2tDb3VudCkudG9CZSgxKTtcbn0pO1xuXG50ZXN0KCdzZWxlY3QgYmVoYXZpb3Igd2l0aCBuZXN0ZWQgYXNzZW1ibGllczogYWxsJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBjeGFzbSA9IGF3YWl0IHRlc3ROZXN0ZWRDbG91ZEFzc2VtYmx5KCk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCB4ID0gYXdhaXQgY3hhc20uc2VsZWN0U3RhY2tzKHsgcGF0dGVybnM6IFtdIH0sIHsgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLkFsbFN0YWNrcyB9KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdCh4LnN0YWNrQ291bnQpLnRvQmUoMyk7XG59KTtcblxudGVzdCgnc2VsZWN0IGJlaGF2aW9yIHdpdGggbmVzdGVkIGFzc2VtYmxpZXM6IG5vbmUnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGN4YXNtID0gYXdhaXQgdGVzdE5lc3RlZENsb3VkQXNzZW1ibHkoKTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IHggPSBhd2FpdCBjeGFzbS5zZWxlY3RTdGFja3MoeyBwYXR0ZXJuczogW10gfSwgeyBkZWZhdWx0QmVoYXZpb3I6IERlZmF1bHRTZWxlY3Rpb24uTm9uZSB9KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdCh4LnN0YWNrQ291bnQpLnRvQmUoMCk7XG59KTtcblxudGVzdCgnc2VsZWN0IGJlaGF2aW9yIHdpdGggbmVzdGVkIGFzc2VtYmxpZXM6IHNpbmdsZScsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgY3hhc20gPSBhd2FpdCB0ZXN0TmVzdGVkQ2xvdWRBc3NlbWJseSgpO1xuXG4gIC8vIFdIRU5cbiAgYXdhaXQgZXhwZWN0KGN4YXNtLnNlbGVjdFN0YWNrcyh7IHBhdHRlcm5zOiBbXSB9LCB7IGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5Pbmx5U2luZ2xlIH0pKVxuICAgIC5yZWplY3RzLnRvVGhyb3coJ1NpbmNlIHRoaXMgYXBwIGluY2x1ZGVzIG1vcmUgdGhhbiBhIHNpbmdsZSBzdGFjaywgc3BlY2lmeSB3aGljaCBzdGFja3MgdG8gdXNlICh3aWxkY2FyZHMgYXJlIHN1cHBvcnRlZCkgb3Igc3BlY2lmeSBgLS1hbGxgJyk7XG59KTtcblxudGVzdCgnc2VsZWN0IGJlaGF2aW9yIHdpdGggbmVzdGVkIGFzc2VtYmxpZXM6IHJlcGVhdCcsIGFzeW5jKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBjeGFzbSA9IGF3YWl0IHRlc3ROZXN0ZWRDbG91ZEFzc2VtYmx5KCk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCB4ID0gYXdhaXQgY3hhc20uc2VsZWN0U3RhY2tzKHsgcGF0dGVybnM6IFsnZGVlcGx5L2hpZGRlbi93aXRob3V0ZXJyb3JzJywgJ25lc3RlZCddIH0sIHtcbiAgICBkZWZhdWx0QmVoYXZpb3I6IERlZmF1bHRTZWxlY3Rpb24uQWxsU3RhY2tzLFxuICB9KTtcblxuICAvLyBUSEVOXG4gIGV4cGVjdCh4LnN0YWNrQ291bnQpLnRvQmUoMik7XG59KTtcblxudGVzdCgnc2VsZWN0IGJlaGF2aW9yIHdpdGggbm8gc3RhY2tzIGFuZCBpZ25vcmUgc3RhY2tzIG9wdGlvbicsIGFzeW5jKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBjeGFzbSA9IGF3YWl0IHRlc3RDbG91ZEFzc2VtYmx5Tm9TdGFja3MoKTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IHggPSBhd2FpdCBjeGFzbS5zZWxlY3RTdGFja3MoeyBwYXR0ZXJuczogW10gfSwge1xuICAgIGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5BbGxTdGFja3MsXG4gICAgaWdub3JlTm9TdGFja3M6IHRydWUsXG4gIH0pO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KHguc3RhY2tDb3VudCkudG9CZSgwKTtcbn0pO1xuXG50ZXN0KCdzZWxlY3QgYmVoYXZpb3Igd2l0aCBubyBzdGFja3MgYW5kIG5vIGlnbm9yZSBzdGFja3Mgb3B0aW9uJywgYXN5bmMoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGN4YXNtID0gYXdhaXQgdGVzdENsb3VkQXNzZW1ibHlOb1N0YWNrcygpO1xuXG4gIC8vIFdIRU4gJiBUSEVOXG4gIGF3YWl0IGV4cGVjdChjeGFzbS5zZWxlY3RTdGFja3MoeyBwYXR0ZXJuczogW10gfSwgeyBkZWZhdWx0QmVoYXZpb3I6IERlZmF1bHRTZWxlY3Rpb24uQWxsU3RhY2tzLCBpZ25vcmVOb1N0YWNrczogZmFsc2UgfSkpXG4gICAgLnJlamVjdHMudG9UaHJvdygnVGhpcyBhcHAgY29udGFpbnMgbm8gc3RhY2tzJyk7XG59KTtcblxudGVzdCgnc2VsZWN0IGJlaGF2aW9yIHdpdGggbm8gc3RhY2tzIGFuZCBkZWZhdWx0IGlnbm9yZSBzdGFja3Mgb3B0aW9ucyAoZmFsc2UpJywgYXN5bmMoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGN4YXNtID0gYXdhaXQgdGVzdENsb3VkQXNzZW1ibHlOb1N0YWNrcygpO1xuXG4gIC8vIFdIRU4gJiBUSEVOXG4gIGF3YWl0IGV4cGVjdChjeGFzbS5zZWxlY3RTdGFja3MoeyBwYXR0ZXJuczogW10gfSwgeyBkZWZhdWx0QmVoYXZpb3I6IERlZmF1bHRTZWxlY3Rpb24uQWxsU3RhY2tzIH0pKVxuICAgIC5yZWplY3RzLnRvVGhyb3coJ1RoaXMgYXBwIGNvbnRhaW5zIG5vIHN0YWNrcycpO1xufSk7XG5cbmRlc2NyaWJlKCdTdGFja0NvbGxlY3Rpb24nLCAoKSA9PiB7XG4gIHRlc3QoJ3JldHVybnMgaGllcmFyY2hpY2FsSWRzJywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIEdJVkVOXG4gICAgY29uc3QgY3hhc20gPSBhd2FpdCB0ZXN0TmVzdGVkQ2xvdWRBc3NlbWJseSgpO1xuXG4gICAgLy8gV0hFTlxuICAgIGNvbnN0IHggPSBhd2FpdCBjeGFzbS5zZWxlY3RTdGFja3MoeyBhbGxUb3BMZXZlbDogdHJ1ZSwgcGF0dGVybnM6IFtdIH0sIHsgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLkFsbFN0YWNrcyB9KTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QoeC5zdGFja0NvdW50KS50b0JlKDIpO1xuICAgIGV4cGVjdCh4LmhpZXJhcmNoaWNhbElkcykudG9FcXVhbChbJ3dpdGhlcnJvcnMnLCAnZGVlcGx5L2hpZGRlbi93aXRob3V0ZXJyb3JzJ10pO1xuICB9KTtcblxuICBkZXNjcmliZSgndmFsaWRhdGVNZXRhZGF0YScsICgpID0+IHtcbiAgICB0ZXN0KCdkbyBub3QgdGhyb3cgd2hlbiBzZWxlY3Rpbmcgc3RhY2sgd2l0aG91dCBlcnJvcnMnLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gR0lWRU5cbiAgICAgIGNvbnN0IGN4YXNtID0gYXdhaXQgdGVzdENsb3VkQXNzZW1ibHkoKTtcblxuICAgICAgLy8gV0hFTlxuICAgICAgY29uc3Qgc2VsZWN0ZWQgPSBhd2FpdCBjeGFzbS5zZWxlY3RTdGFja3MoIHsgcGF0dGVybnM6IFsnd2l0aG91dGVycm9yc05PREVQQVRIJ10gfSwge1xuICAgICAgICBkZWZhdWx0QmVoYXZpb3I6IERlZmF1bHRTZWxlY3Rpb24uQWxsU3RhY2tzLFxuICAgICAgfSk7XG4gICAgICBhd2FpdCBzZWxlY3RlZC52YWxpZGF0ZU1ldGFkYXRhKCk7XG5cbiAgICAgIC8vIFRIRU5cbiAgICAgIGV4cGVjdChzZWxlY3RlZC5zdGFja0NvdW50KS50b0JlKDEpO1xuICAgICAgZXhwZWN0KHNlbGVjdGVkLmZpcnN0U3RhY2sudGVtcGxhdGUucmVzb3VyY2UpLnRvQmUoJ25vZXJyb3JyZXNvdXJjZScpO1xuICAgIH0pO1xuXG4gICAgdGVzdCgnZG8gbm90IHRocm93IHdoZW4gc2VsZWN0aW5nIHN0YWNrIHdpdGggd2FybmluZ3MnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBHSVZFTlxuICAgICAgY29uc3QgY3hhc20gPSBhd2FpdCB0ZXN0Q2xvdWRBc3NlbWJseSgpO1xuXG4gICAgICAvLyBXSEVOXG4gICAgICBjb25zdCBzZWxlY3RlZCA9IGF3YWl0IGN4YXNtLnNlbGVjdFN0YWNrcyggeyBwYXR0ZXJuczogWyd3aXRod2FybnMnXSB9LCB7XG4gICAgICAgIGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5BbGxTdGFja3MsXG4gICAgICB9KTtcbiAgICAgIGF3YWl0IHNlbGVjdGVkLnZhbGlkYXRlTWV0YWRhdGEoKTtcblxuICAgICAgLy8gVEhFTlxuICAgICAgZXhwZWN0KHNlbGVjdGVkLnN0YWNrQ291bnQpLnRvQmUoMSk7XG4gICAgICBleHBlY3Qoc2VsZWN0ZWQuZmlyc3RTdGFjay50ZW1wbGF0ZS5yZXNvdXJjZSkudG9CZSgnd2FybnJlc291cmNlJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdkbyBub3QgdGhyb3cgd2hlbiBzZWxlY3Rpbmcgc3RhY2sgd2l0aCBlcnJvcnMgYnV0IGVycm9ycyBhcmUgaWdub3JlZCcsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEdJVkVOXG4gICAgICBjb25zdCBjeGFzbSA9IGF3YWl0IHRlc3RDbG91ZEFzc2VtYmx5KCk7XG5cbiAgICAgIC8vIFdIRU5cbiAgICAgIGNvbnN0IHNlbGVjdGVkID0gYXdhaXQgY3hhc20uc2VsZWN0U3RhY2tzKHsgcGF0dGVybnM6IFsnd2l0aGVycm9ycyddIH0sIHtcbiAgICAgICAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLkFsbFN0YWNrcyxcbiAgICAgIH0pO1xuICAgICAgYXdhaXQgc2VsZWN0ZWQudmFsaWRhdGVNZXRhZGF0YSgnbm9uZScpO1xuXG4gICAgICAvLyBUSEVOXG4gICAgICBleHBlY3Qoc2VsZWN0ZWQuc3RhY2tDb3VudCkudG9CZSgxKTtcbiAgICAgIGV4cGVjdChzZWxlY3RlZC5maXJzdFN0YWNrLnRlbXBsYXRlLnJlc291cmNlKS50b0JlKCdlcnJvcnJlc291cmNlJyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdkbyB0aHJvdyB3aGVuIHNlbGVjdGluZyBzdGFjayB3aXRoIGVycm9ycycsIGFzeW5jICgpID0+IHtcbiAgICAgIC8vIEdJVkVOXG4gICAgICBjb25zdCBjeGFzbSA9IGF3YWl0IHRlc3RDbG91ZEFzc2VtYmx5KCk7XG5cbiAgICAgIC8vIFdIRU5cbiAgICAgIGNvbnN0IHNlbGVjdGVkID0gYXdhaXQgY3hhc20uc2VsZWN0U3RhY2tzKHsgcGF0dGVybnM6IFsnd2l0aGVycm9ycyddIH0sIHtcbiAgICAgICAgZGVmYXVsdEJlaGF2aW9yOiBEZWZhdWx0U2VsZWN0aW9uLkFsbFN0YWNrcyxcbiAgICAgIH0pO1xuXG4gICAgICAvLyBUSEVOXG4gICAgICBleHBlY3Qoc2VsZWN0ZWQuc3RhY2tDb3VudCkudG9CZSgxKTtcbiAgICAgIGF3YWl0IGV4cGVjdChhc3luYyAoKSA9PiBzZWxlY3RlZC52YWxpZGF0ZU1ldGFkYXRhKCkpLnJlamVjdHMudG9UaHJvdygvRm91bmQgZXJyb3JzLyk7XG4gICAgfSk7XG5cbiAgICB0ZXN0KCdkbyB0aHJvdyB3aGVuIHNlbGVjdGluZyBzdGFjayB3aXRoIHdhcm5pbmdzIGFuZCB3ZSBhcmUgb24gc3RyaWN0IG1vZGUnLCBhc3luYyAoKSA9PiB7XG4gICAgICAvLyBHSVZFTlxuICAgICAgY29uc3QgY3hhc20gPSBhd2FpdCB0ZXN0Q2xvdWRBc3NlbWJseSgpO1xuXG4gICAgICAvLyBXSEVOXG4gICAgICBjb25zdCBzZWxlY3RlZCA9IGF3YWl0IGN4YXNtLnNlbGVjdFN0YWNrcyggeyBwYXR0ZXJuczogWyd3aXRod2FybnMnXSB9LCB7XG4gICAgICAgIGRlZmF1bHRCZWhhdmlvcjogRGVmYXVsdFNlbGVjdGlvbi5BbGxTdGFja3MsXG4gICAgICB9KTtcblxuICAgICAgLy8gVEhFTlxuICAgICAgZXhwZWN0KHNlbGVjdGVkLnN0YWNrQ291bnQpLnRvQmUoMSk7XG4gICAgICBhd2FpdCBleHBlY3QoYXN5bmMgKCkgPT4gc2VsZWN0ZWQudmFsaWRhdGVNZXRhZGF0YSgnd2FybicpKS5yZWplY3RzLnRvVGhyb3coL0ZvdW5kIHdhcm5pbmdzLyk7XG4gICAgfSk7XG4gIH0pO1xufSk7XG5cbmFzeW5jIGZ1bmN0aW9uIHRlc3RDbG91ZEFzc2VtYmx5KHsgZW52IH06IHsgZW52Pzogc3RyaW5nOyB2ZXJzaW9uUmVwb3J0aW5nPzogYm9vbGVhbiB9ID0ge30pIHtcbiAgY29uc3QgY2xvdWRFeGVjID0gbmV3IE1vY2tDbG91ZEV4ZWN1dGFibGUoe1xuICAgIHN0YWNrczogW3tcbiAgICAgIHN0YWNrTmFtZTogJ3dpdGhvdXRlcnJvcnMnLFxuICAgICAgZGlzcGxheU5hbWU6ICd3aXRob3V0ZXJyb3JzTk9ERVBBVEgnLFxuICAgICAgZW52LFxuICAgICAgdGVtcGxhdGU6IHsgcmVzb3VyY2U6ICdub2Vycm9ycmVzb3VyY2UnIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBzdGFja05hbWU6ICd3aXRoZXJyb3JzJyxcbiAgICAgIGVudixcbiAgICAgIHRlbXBsYXRlOiB7IHJlc291cmNlOiAnZXJyb3JyZXNvdXJjZScgfSxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICcvcmVzb3VyY2UnOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogY3hzY2hlbWEuQXJ0aWZhY3RNZXRhZGF0YUVudHJ5VHlwZS5FUlJPUixcbiAgICAgICAgICAgIGRhdGE6ICd0aGlzIGlzIGFuIGVycm9yJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIHN0YWNrTmFtZTogJ3dpdGh3YXJucycsXG4gICAgICBlbnYsXG4gICAgICB0ZW1wbGF0ZTogeyByZXNvdXJjZTogJ3dhcm5yZXNvdXJjZScgfSxcbiAgICAgIG1ldGFkYXRhOiB7XG4gICAgICAgICcvcmVzb3VyY2UnOiBbXG4gICAgICAgICAge1xuICAgICAgICAgICAgdHlwZTogY3hzY2hlbWEuQXJ0aWZhY3RNZXRhZGF0YUVudHJ5VHlwZS5XQVJOLFxuICAgICAgICAgICAgZGF0YTogJ3RoaXMgaXMgYSB3YXJuaW5nJyxcbiAgICAgICAgICB9LFxuICAgICAgICBdLFxuICAgICAgfSxcbiAgICB9XSxcbiAgfSk7XG5cbiAgcmV0dXJuIGNsb3VkRXhlYy5zeW50aGVzaXplKCk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIHRlc3RDbG91ZEFzc2VtYmx5Tm9TdGFja3MoKSB7XG4gIGNvbnN0IGNsb3VkRXhlYyA9IG5ldyBNb2NrQ2xvdWRFeGVjdXRhYmxlKHtcbiAgICBzdGFja3M6IFtdLFxuICB9KTtcblxuICByZXR1cm4gY2xvdWRFeGVjLnN5bnRoZXNpemUoKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gdGVzdE5lc3RlZENsb3VkQXNzZW1ibHkoeyBlbnYgfTogeyBlbnY/OiBzdHJpbmc7IHZlcnNpb25SZXBvcnRpbmc/OiBib29sZWFuIH0gPSB7fSkge1xuICBjb25zdCBjbG91ZEV4ZWMgPSBuZXcgTW9ja0Nsb3VkRXhlY3V0YWJsZSh7XG4gICAgc3RhY2tzOiBbe1xuICAgICAgc3RhY2tOYW1lOiAnd2l0aG91dGVycm9ycycsXG4gICAgICBlbnYsXG4gICAgICB0ZW1wbGF0ZTogeyByZXNvdXJjZTogJ25vZXJyb3JyZXNvdXJjZScgfSxcbiAgICAgIC8vIFRoZSBuZXN0aW5nIGluIHRoZSBwYXRoIHNob3VsZCBiZSBpbmRlcGVuZGVudCBvZiB0aGUgcG9zaXRpb24gaW4gdGhlIHRyZWVcbiAgICAgIGRpc3BsYXlOYW1lOiAnZGVlcGx5L2hpZGRlbi93aXRob3V0ZXJyb3JzJyxcbiAgICB9LFxuICAgIHtcbiAgICAgIHN0YWNrTmFtZTogJ3dpdGhlcnJvcnMnLFxuICAgICAgZW52LFxuICAgICAgdGVtcGxhdGU6IHsgcmVzb3VyY2U6ICdlcnJvcnJlc291cmNlJyB9LFxuICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgJy9yZXNvdXJjZSc6IFtcbiAgICAgICAgICB7XG4gICAgICAgICAgICB0eXBlOiBjeHNjaGVtYS5BcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLkVSUk9SLFxuICAgICAgICAgICAgZGF0YTogJ3RoaXMgaXMgYW4gZXJyb3InLFxuICAgICAgICAgIH0sXG4gICAgICAgIF0sXG4gICAgICB9LFxuICAgIH1dLFxuICAgIG5lc3RlZEFzc2VtYmxpZXM6IFt7XG4gICAgICBzdGFja3M6IFt7XG4gICAgICAgIHN0YWNrTmFtZTogJ25lc3RlZCcsXG4gICAgICAgIGVudixcbiAgICAgICAgdGVtcGxhdGU6IHsgcmVzb3VyY2U6ICduZXN0ZWRlcnJvcicgfSxcbiAgICAgICAgbWV0YWRhdGE6IHtcbiAgICAgICAgICAnL3Jlc291cmNlJzogW1xuICAgICAgICAgICAge1xuICAgICAgICAgICAgICB0eXBlOiBjeHNjaGVtYS5BcnRpZmFjdE1ldGFkYXRhRW50cnlUeXBlLkVSUk9SLFxuICAgICAgICAgICAgICBkYXRhOiAndGhpcyBpcyBhbm90aGVyIGVycm9yJyxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgXSxcbiAgICAgICAgfSxcbiAgICAgIH1dLFxuICAgIH1dLFxuICB9KTtcblxuICBjb25zdCBhc20gPSBhd2FpdCBjbG91ZEV4ZWMuc3ludGhlc2l6ZSgpO1xuICByZXR1cm4gY2xpQXNzZW1ibHlXaXRoRm9yY2VkVmVyc2lvbihhc20sICczMC4wLjAnKTtcbn1cbiJdfQ==