assets.test.js
1 "use strict"; 2 Object.defineProperty(exports, "__esModule", { value: true }); 3 const assets_1 = require("../lib/assets"); 4 const asset_manifest_builder_1 = require("../lib/util/asset-manifest-builder"); 5 const util_1 = require("./util"); 6 const mock_sdk_1 = require("./util/mock-sdk"); 7 const mock_toolkitinfo_1 = require("./util/mock-toolkitinfo"); 8 let toolkit; 9 let assets; 10 beforeEach(() => { 11 toolkit = new mock_toolkitinfo_1.MockToolkitInfo(new mock_sdk_1.MockSdk()); 12 assets = new asset_manifest_builder_1.AssetManifestBuilder(); 13 }); 14 describe('file assets', () => { 15 test('convert to manifest and parameters', async () => { 16 // GIVEN 17 const stack = stackWithAssets([ 18 { 19 sourceHash: 'source-hash', 20 path: __filename, 21 id: 'SomeStackSomeResource4567', 22 packaging: 'file', 23 s3BucketParameter: 'BucketParameter', 24 s3KeyParameter: 'KeyParameter', 25 artifactHashParameter: 'ArtifactHashParameter', 26 }, 27 ]); 28 // WHEN 29 const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit); 30 // THEN 31 expect(params).toEqual({ 32 BucketParameter: 'MockToolkitBucketName', 33 KeyParameter: 'assets/SomeStackSomeResource4567/||source-hash.js', 34 ArtifactHashParameter: 'source-hash', 35 }); 36 expect(assets.toManifest('.').entries).toEqual([ 37 expect.objectContaining({ 38 destination: { 39 bucketName: 'MockToolkitBucketName', 40 objectKey: 'assets/SomeStackSomeResource4567/source-hash.js', 41 }, 42 source: { 43 packaging: 'file', 44 path: __filename, 45 }, 46 }), 47 ]); 48 }); 49 test('hash and ID the same => only one path component', async () => { 50 // GIVEN 51 const stack = stackWithAssets([ 52 { 53 sourceHash: 'source-hash', 54 path: __filename, 55 id: 'source-hash', 56 packaging: 'file', 57 s3BucketParameter: 'BucketParameter', 58 s3KeyParameter: 'KeyParameter', 59 artifactHashParameter: 'ArtifactHashParameter', 60 }, 61 ]); 62 // WHEN 63 await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit); 64 // THEN 65 expect(assets.toManifest('.').entries).toEqual([ 66 expect.objectContaining({ 67 destination: { 68 bucketName: 'MockToolkitBucketName', 69 objectKey: 'assets/source-hash.js', 70 }, 71 }), 72 ]); 73 }); 74 test('reuse', async () => { 75 // GIVEN 76 const stack = stackWithAssets([ 77 { 78 path: __filename, 79 id: 'SomeStackSomeResource4567', 80 packaging: 'file', 81 s3BucketParameter: 'BucketParameter', 82 s3KeyParameter: 'KeyParameter', 83 artifactHashParameter: 'ArtifactHashParameter', 84 sourceHash: 'boom', 85 }, 86 ]); 87 // WHEN 88 const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit, ['SomeStackSomeResource4567']); 89 // THEN 90 expect(params).toEqual({}); 91 expect(assets.toManifest('.').entries).toEqual([]); 92 }); 93 }); 94 describe('docker assets', () => { 95 test('parameter and no repository name (old)', async () => { 96 // GIVEN 97 const stack = stackWithAssets([ 98 { 99 id: 'Stack:Construct/ABC123', 100 imageNameParameter: 'MyParameter', 101 packaging: 'container-image', 102 path: '/foo', 103 sourceHash: '0123456789abcdef', 104 }, 105 ]); 106 mockFn(toolkit.prepareEcrRepository).mockResolvedValue({ repositoryUri: 'docker.uri' }); 107 // WHEN 108 const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit); 109 // THEN 110 expect(toolkit.prepareEcrRepository).toHaveBeenCalledWith('cdk/stack-construct-abc123'); 111 expect(params).toEqual({ 112 MyParameter: 'docker.uri:0123456789abcdef', 113 }); 114 expect(assets.toManifest('.').entries).toEqual([ 115 expect.objectContaining({ 116 type: 'docker-image', 117 destination: { 118 imageTag: '0123456789abcdef', 119 repositoryName: 'cdk/stack-construct-abc123', 120 }, 121 source: { 122 directory: '/foo', 123 }, 124 }), 125 ]); 126 }); 127 test('if parameter is left out then repo and tag are required', async () => { 128 // GIVEN 129 const stack = stackWithAssets([ 130 { 131 id: 'Stack:Construct/ABC123', 132 packaging: 'container-image', 133 path: '/foo', 134 sourceHash: '0123456789abcdef', 135 }, 136 ]); 137 await expect(assets_1.addMetadataAssetsToManifest(stack, assets, toolkit)).rejects.toThrow('Invalid Docker image asset'); 138 }); 139 test('no parameter and repo/tag name (new)', async () => { 140 // GIVEN 141 const stack = stackWithAssets([ 142 { 143 id: 'Stack:Construct/ABC123', 144 repositoryName: 'reponame', 145 imageTag: '12345', 146 packaging: 'container-image', 147 path: '/foo', 148 sourceHash: '0123456789abcdef', 149 }, 150 ]); 151 mockFn(toolkit.prepareEcrRepository).mockResolvedValue({ repositoryUri: 'docker.uri' }); 152 // WHEN 153 const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit); 154 // THEN 155 expect(toolkit.prepareEcrRepository).toHaveBeenCalledWith('reponame'); 156 expect(params).toEqual({}); // No parameters! 157 expect(assets.toManifest('.').entries).toEqual([ 158 expect.objectContaining({ 159 type: 'docker-image', 160 destination: { 161 imageTag: '12345', 162 repositoryName: 'reponame', 163 }, 164 source: { 165 directory: '/foo', 166 }, 167 }), 168 ]); 169 }); 170 test('reuse', async () => { 171 // GIVEN 172 const stack = stackWithAssets([ 173 { 174 path: __dirname, 175 id: 'SomeStackSomeResource4567', 176 packaging: 'container-image', 177 imageNameParameter: 'asdf', 178 sourceHash: 'source-hash', 179 }, 180 ]); 181 // WHEN 182 const params = await assets_1.addMetadataAssetsToManifest(stack, assets, toolkit, ['SomeStackSomeResource4567']); 183 // THEN 184 expect(params).toEqual({}); 185 expect(assets.toManifest('.').entries).toEqual([]); 186 }); 187 }); 188 function stackWithAssets(assetEntries) { 189 return util_1.testStack({ 190 stackName: 'SomeStack', 191 assets: assetEntries, 192 template: { 193 Resources: { 194 SomeResource: { 195 Type: 'AWS::Something::Something', 196 }, 197 }, 198 }, 199 }); 200 } 201 function mockFn(fn) { 202 if (!jest.isMockFunction(fn)) { 203 throw new Error(`Not a mock function: ${fn}`); 204 } 205 return fn; 206 } 207 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXNzZXRzLnRlc3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyJhc3NldHMudGVzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUVBLDBDQUE0RDtBQUM1RCwrRUFBMEU7QUFDMUUsaUNBQW1DO0FBQ25DLDhDQUEwQztBQUMxQyw4REFBMEQ7QUFFMUQsSUFBSSxPQUFvQixDQUFDO0FBQ3pCLElBQUksTUFBNEIsQ0FBQztBQUNqQyxVQUFVLENBQUMsR0FBRyxFQUFFO0lBQ2QsT0FBTyxHQUFHLElBQUksa0NBQWUsQ0FBQyxJQUFJLGtCQUFPLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sR0FBRyxJQUFJLDZDQUFvQixFQUFFLENBQUM7QUFDdEMsQ0FBQyxDQUFDLENBQUM7QUFFSCxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRTtJQUMzQixJQUFJLENBQUMsb0NBQW9DLEVBQUUsS0FBSyxJQUFJLEVBQUU7UUFDcEQsUUFBUTtRQUNSLE1BQU0sS0FBSyxHQUFHLGVBQWUsQ0FBQztZQUM1QjtnQkFDRSxVQUFVLEVBQUUsYUFBYTtnQkFDekIsSUFBSSxFQUFFLFVBQVU7Z0JBQ2hCLEVBQUUsRUFBRSwyQkFBMkI7Z0JBQy9CLFNBQVMsRUFBRSxNQUFNO2dCQUNqQixpQkFBaUIsRUFBRSxpQkFBaUI7Z0JBQ3BDLGNBQWMsRUFBRSxjQUFjO2dCQUM5QixxQkFBcUIsRUFBRSx1QkFBdUI7YUFDL0M7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPO1FBQ1AsTUFBTSxNQUFNLEdBQUcsTUFBTSxvQ0FBMkIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBRXpFLE9BQU87UUFDUCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQ3JCLGVBQWUsRUFBRSx1QkFBdUI7WUFDeEMsWUFBWSxFQUFFLG1EQUFtRDtZQUNqRSxxQkFBcUIsRUFBRSxhQUFhO1NBQ3JDLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxN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QjtnQkFDL0IsU0FBUyxFQUFFLGlCQUFpQjtnQkFDNUIsa0JBQWtCLEVBQUUsTUFBTTtnQkFDMUIsVUFBVSxFQUFFLGFBQWE7YUFDMUI7U0FDRixDQUFDLENBQUM7UUFFSCxPQUFPO1FBQ1AsTUFBTSxNQUFNLEdBQUcsTUFBTSxvQ0FBMkIsQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sRUFBRSxDQUFDLDJCQUEyQixDQUFDLENBQUMsQ0FBQztRQUV4RyxPQUFPO1FBQ1AsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE9BQU8sQ0FBQyxFQUN0QixDQUFDLENBQUM7UUFFSCxNQUFNLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDckQsQ0FBQyxDQUFDLENBQUM7QUFDTCxDQUFDLENBQUMsQ0FBQztBQUVILFNBQVMsZUFBZSxDQUFDLFlBQWtDO0lBQ3pELE9BQU8sZ0JBQVMsQ0FBQztRQUNmLFNBQVMsRUFBRSxXQUFXO1FBQ3RCLE1BQU0sRUFBRSxZQUFZO1FBQ3BCLFFBQVEsRUFBRTtZQUNSLFNBQVMsRUFBRTtnQkFDVCxZQUFZLEVBQUU7b0JBQ1osSUFBSSxFQUFFLDJCQUEyQjtpQkFDbEM7YUFDRjtTQUNGO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELFNBQVMsTUFBTSxDQUFrQyxFQUFLO0lBQ3BELElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQyxFQUFFO1FBQzVCLE1BQU0sSUFBSSxLQUFLLENBQUMsd0JBQXdCLEVBQUUsRUFBRSxDQUFDLENBQUM7S0FDL0M7SUFDRCxPQUFPLEVBQUUsQ0FBQztBQUNaLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBc3NldE1ldGFkYXRhRW50cnkgfSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0IHsgVG9vbGtpdEluZm8gfSBmcm9tICcuLi9saWIvYXBpJztcbmltcG9ydCB7IGFkZE1ldGFkYXRhQXNzZXRzVG9NYW5pZmVzdCB9IGZyb20gJy4uL2xpYi9hc3NldHMnO1xuaW1wb3J0IHsgQXNzZXRNYW5pZmVzdEJ1aWxkZXIgfSBmcm9tICcuLi9saWIvdXRpbC9hc3NldC1tYW5pZmVzdC1idWlsZGVyJztcbmltcG9ydCB7IHRlc3RTdGFjayB9IGZyb20gJy4vdXRpbCc7XG5pbXBvcnQgeyBNb2NrU2RrIH0gZnJvbSAnLi91dGlsL21vY2stc2RrJztcbmltcG9ydCB7IE1vY2tUb29sa2l0SW5mbyB9IGZyb20gJy4vdXRpbC9tb2NrLXRvb2xraXRpbmZvJztcblxubGV0IHRvb2xraXQ6IFRvb2xraXRJbmZvO1xubGV0IGFzc2V0czogQXNzZXRNYW5pZmVzdEJ1aWxkZXI7XG5iZWZvcmVFYWNoKCgpID0+IHtcbiAgdG9vbGtpdCA9IG5ldyBNb2NrVG9vbGtpdEluZm8obmV3IE1vY2tTZGsoKSk7XG4gIGFzc2V0cyA9IG5ldyBBc3NldE1hbmlmZXN0QnVpbGRlcigpO1xufSk7XG5cbmRlc2NyaWJlKCdmaWxlIGFzc2V0cycsICgpID0+IHtcbiAgdGVzdCgnY29udmVydCB0byBtYW5pZmVzdCBhbmQgcGFyYW1ldGVycycsIGFzeW5jICgpID0+IHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tXaXRoQXNzZXRzKFtcbiAgICAgIHtcbiAgICAgICAgc291cmNlSGFzaDogJ3NvdXJjZS1oYXNoJyxcbiAgICAgICAgcGF0aDogX19maWxlbmFtZSxcbiAgICAgICAgaWQ6ICdTb21lU3RhY2tTb21lUmVzb3VyY2U0NTY3JyxcbiAgICAgICAgcGFja2FnaW5nOiAnZmlsZScsXG4gICAgICAgIHMzQnVja2V0UGFyYW1ldGVyOiAnQnVja2V0UGFyYW1ldGVyJyxcbiAgICAgICAgczNLZXlQYXJhbWV0ZXI6ICdLZXlQYXJhbWV0ZXInLFxuICAgICAgICBhcnRpZmFjdEhhc2hQYXJhbWV0ZXI6ICdBcnRpZmFjdEhhc2hQYXJhbWV0ZXInLFxuICAgICAgfSxcbiAgICBdKTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhZGRNZXRhZGF0YUFzc2V0c1RvTWFuaWZlc3Qoc3RhY2ssIGFzc2V0cywgdG9vbGtpdCk7XG5cbiAgICAvLyBUSEVOXG4gICAgZXhwZWN0KHBhcmFtcykudG9FcXVhbCh7XG4gICAgICBCdWNrZXRQYXJhbWV0ZXI6ICdNb2NrVG9vbGtpdEJ1Y2tldE5hbWUnLFxuICAgICAgS2V5UGFyYW1ldGVyOiAnYXNzZXRzL1NvbWVTdGFja1NvbWVSZXNvdXJjZTQ1NjcvfHxzb3VyY2UtaGFzaC5qcycsXG4gICAgICBBcnRpZmFjdEhhc2hQYXJhbWV0ZXI6ICdzb3VyY2UtaGFzaCcsXG4gICAgfSk7XG5cbiAgICBleHBlY3QoYXNzZXRzLnRvTWFuaWZlc3QoJy4nKS5lbnRyaWVzKS50b0VxdWFsKFtcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgZGVzdGluYXRpb246IHtcbiAgICAgICAgICBidWNrZXROYW1lOiAnTW9ja1Rvb2xraXRCdWNrZXROYW1lJyxcbiAgICAgICAgICBvYmplY3RLZXk6ICdhc3NldHMvU29tZVN0YWNrU29tZVJlc291cmNlNDU2Ny9zb3VyY2UtaGFzaC5qcycsXG4gICAgICAgIH0sXG4gICAgICAgIHNvdXJjZToge1xuICAgICAgICAgIHBhY2thZ2luZzogJ2ZpbGUnLFxuICAgICAgICAgIHBhdGg6IF9fZmlsZW5hbWUsXG4gICAgICAgIH0sXG4gICAgICB9KSxcbiAgICBdKTtcbiAgfSk7XG5cbiAgdGVzdCgnaGFzaCBhbmQgSUQgdGhlIHNhbWUgPT4gb25seSBvbmUgcGF0aCBjb21wb25lbnQnLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBzdGFjayA9IHN0YWNrV2l0aEFzc2V0cyhbXG4gICAgICB7XG4gICAgICAgIHNvdXJjZUhhc2g6ICdzb3VyY2UtaGFzaCcsXG4gICAgICAgIHBhdGg6IF9fZmlsZW5hbWUsXG4gICAgICAgIGlkOiAnc291cmNlLWhhc2gnLFxuICAgICAgICBwYWNrYWdpbmc6ICdmaWxlJyxcbiAgICAgICAgczNCdWNrZXRQYXJhbWV0ZXI6ICdCdWNrZXRQYXJhbWV0ZXInLFxuICAgICAgICBzM0tleVBhcmFtZXRlcjogJ0tleVBhcmFtZXRlcicsXG4gICAgICAgIGFydGlmYWN0SGFzaFBhcmFtZXRlcjogJ0FydGlmYWN0SGFzaFBhcmFtZXRlcicsXG4gICAgICB9LFxuICAgIF0pO1xuXG4gICAgLy8gV0hFTlxuICAgIGF3YWl0IGFkZE1ldGFkYXRhQXNzZXRzVG9NYW5pZmVzdChzdGFjaywgYXNzZXRzLCB0b29sa2l0KTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QoYXNzZXRzLnRvTWFuaWZlc3QoJy4nKS5lbnRyaWVzKS50b0VxdWFsKFtcbiAgICAgIGV4cGVjdC5vYmplY3RDb250YWluaW5nKHtcbiAgICAgICAgZGVzdGluYXRpb246IHtcbiAgICAgICAgICBidWNrZXROYW1lOiAnTW9ja1Rvb2xraXRCdWNrZXROYW1lJyxcbiAgICAgICAgICBvYmplY3RLZXk6ICdhc3NldHMvc291cmNlLWhhc2guanMnLFxuICAgICAgICB9LFxuICAgICAgfSksXG4gICAgXSk7XG4gIH0pO1xuXG4gIHRlc3QoJ3JldXNlJywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIEdJVkVOXG4gICAgY29uc3Qgc3RhY2sgPSBzdGFja1dpdGhBc3NldHMoW1xuICAgICAge1xuICAgICAgICBwYXRoOiBfX2ZpbGVuYW1lLFxuICAgICAgICBpZDogJ1NvbWVTdGFja1NvbWVSZXNvdXJjZTQ1NjcnLFxuICAgICAgICBwYWNrYWdpbmc6ICdmaWxlJyxcbiAgICAgICAgczNCdWNrZXRQYXJhbWV0ZXI6ICdCdWNrZXRQYXJhbWV0ZXInLFxuICAgICAgICBzM0tleVBhcmFtZXRlcjogJ0tleVBhcmFtZXRlcicsXG4gICAgICAgIGFydGlmYWN0SGFzaFBhcmFtZXRlcjogJ0FydGlmYWN0SGFzaFBhcmFtZXRlcicsXG4gICAgICAgIHNvdXJjZUhhc2g6ICdib29tJyxcbiAgICAgIH0sXG4gICAgXSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3QgcGFyYW1zID0gYXdhaXQgYWRkTWV0YWRhdGFBc3NldHNUb01hbmlmZXN0KHN0YWNrLCBhc3NldHMsIHRvb2xraXQsIFsnU29tZVN0YWNrU29tZVJlc291cmNlNDU2NyddKTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QocGFyYW1zKS50b0VxdWFsKHtcbiAgICB9KTtcblxuICAgIGV4cGVjdChhc3NldHMudG9NYW5pZmVzdCgnLicpLmVudHJpZXMpLnRvRXF1YWwoW10pO1xuICB9KTtcbn0pO1xuXG5kZXNjcmliZSgnZG9ja2VyIGFzc2V0cycsICgpID0+IHtcbiAgdGVzdCgncGFyYW1ldGVyIGFuZCBubyByZXBvc2l0b3J5IG5hbWUgKG9sZCknLCBhc3luYyAoKSA9PiB7XG4gICAgLy8gR0lWRU5cbiAgICBjb25zdCBzdGFjayA9IHN0YWNrV2l0aEFzc2V0cyhbXG4gICAgICB7XG4gICAgICAgIGlkOiAnU3RhY2s6Q29uc3RydWN0L0FCQzEyMycsXG4gICAgICAgIGltYWdlTmFtZVBhcmFtZXRlcjogJ015UGFyYW1ldGVyJyxcbiAgICAgICAgcGFja2FnaW5nOiAnY29udGFpbmVyLWltYWdlJyxcbiAgICAgICAgcGF0aDogJy9mb28nLFxuICAgICAgICBzb3VyY2VIYXNoOiAnMDEyMzQ1Njc4OWFiY2RlZicsXG4gICAgICB9LFxuICAgIF0pO1xuICAgIG1vY2tGbih0b29sa2l0LnByZXBhcmVFY3JSZXBvc2l0b3J5KS5tb2NrUmVzb2x2ZWRWYWx1ZSh7IHJlcG9zaXRvcnlVcmk6ICdkb2NrZXIudXJpJyB9KTtcblxuICAgIC8vIFdIRU5cbiAgICBjb25zdCBwYXJhbXMgPSBhd2FpdCBhZGRNZXRhZGF0YUFzc2V0c1RvTWFuaWZlc3Qoc3RhY2ssIGFzc2V0cywgdG9vbGtpdCk7XG5cbiAgICAvLyBUSEVOXG4gICAgZXhwZWN0KHRvb2xraXQucHJlcGFyZUVjclJlcG9zaXRvcnkpLnRvSGF2ZUJlZW5DYWxsZWRXaXRoKCdjZGsvc3RhY2stY29uc3RydWN0LWFiYzEyMycpO1xuICAgIGV4cGVjdChwYXJhbXMpLnRvRXF1YWwoe1xuICAgICAgTXlQYXJhbWV0ZXI6ICdkb2NrZXIudXJpOjAxMjM0NTY3ODlhYmNkZWYnLFxuICAgIH0pO1xuICAgIGV4cGVjdChhc3NldHMudG9NYW5pZmVzdCgnLicpLmVudHJpZXMpLnRvRXF1YWwoW1xuICAgICAgZXhwZWN0Lm9iamVjdENvbnRhaW5pbmcoe1xuICAgICAgICB0eXBlOiAnZG9ja2VyLWltYWdlJyxcbiAgICAgICAgZGVzdGluYXRpb246IHtcbiAgICAgICAgICBpbWFnZVRhZzogJzAxMjM0NTY3ODlhYmNkZWYnLFxuICAgICAgICAgIHJlcG9zaXRvcnlOYW1lOiAnY2RrL3N0YWNrLWNvbnN0cnVjdC1hYmMxMjMnLFxuICAgICAgICB9LFxuICAgICAgICBzb3VyY2U6IHtcbiAgICAgICAgICBkaXJlY3Rvcnk6ICcvZm9vJyxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF0pO1xuICB9KTtcblxuICB0ZXN0KCdpZiBwYXJhbWV0ZXIgaXMgbGVmdCBvdXQgdGhlbiByZXBvIGFuZCB0YWcgYXJlIHJlcXVpcmVkJywgYXN5bmMgKCkgPT4ge1xuICAgIC8vIEdJVkVOXG4gICAgY29uc3Qgc3RhY2sgPSBzdGFja1dpdGhBc3NldHMoW1xuICAgICAge1xuICAgICAgICBpZDogJ1N0YWNrOkNvbnN0cnVjdC9BQkMxMjMnLFxuICAgICAgICBwYWNrYWdpbmc6ICdjb250YWluZXItaW1hZ2UnLFxuICAgICAgICBwYXRoOiAnL2ZvbycsXG4gICAgICAgIHNvdXJjZUhhc2g6ICcwMTIzNDU2Nzg5YWJjZGVmJyxcbiAgICAgIH0sXG4gICAgXSk7XG5cbiAgICBhd2FpdCBleHBlY3QoYWRkTWV0YWRhdGFBc3NldHNUb01hbmlmZXN0KHN0YWNrLCBhc3NldHMsIHRvb2xraXQpKS5yZWplY3RzLnRvVGhyb3coJ0ludmFsaWQgRG9ja2VyIGltYWdlIGFzc2V0Jyk7XG4gIH0pO1xuXG4gIHRlc3QoJ25vIHBhcmFtZXRlciBhbmQgcmVwby90YWcgbmFtZSAobmV3KScsIGFzeW5jICgpID0+IHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tXaXRoQXNzZXRzKFtcbiAgICAgIHtcbiAgICAgICAgaWQ6ICdTdGFjazpDb25zdHJ1Y3QvQUJDMTIzJyxcbiAgICAgICAgcmVwb3NpdG9yeU5hbWU6ICdyZXBvbmFtZScsXG4gICAgICAgIGltYWdlVGFnOiAnMTIzNDUnLFxuICAgICAgICBwYWNrYWdpbmc6ICdjb250YWluZXItaW1hZ2UnLFxuICAgICAgICBwYXRoOiAnL2ZvbycsXG4gICAgICAgIHNvdXJjZUhhc2g6ICcwMTIzNDU2Nzg5YWJjZGVmJyxcbiAgICAgIH0sXG4gICAgXSk7XG4gICAgbW9ja0ZuKHRvb2xraXQucHJlcGFyZUVjclJlcG9zaXRvcnkpLm1vY2tSZXNvbHZlZFZhbHVlKHsgcmVwb3NpdG9yeVVyaTogJ2RvY2tlci51cmknIH0pO1xuXG4gICAgLy8gV0hFTlxuICAgIGNvbnN0IHBhcmFtcyA9IGF3YWl0IGFkZE1ldGFkYXRhQXNzZXRzVG9NYW5pZmVzdChzdGFjaywgYXNzZXRzLCB0b29sa2l0KTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QodG9vbGtpdC5wcmVwYXJlRWNyUmVwb3NpdG9yeSkudG9IYXZlQmVlbkNhbGxlZFdpdGgoJ3JlcG9uYW1lJyk7XG4gICAgZXhwZWN0KHBhcmFtcykudG9FcXVhbCh7fSk7IC8vIE5vIHBhcmFtZXRlcnMhXG4gICAgZXhwZWN0KGFzc2V0cy50b01hbmlmZXN0KCcuJykuZW50cmllcykudG9FcXVhbChbXG4gICAgICBleHBlY3Qub2JqZWN0Q29udGFpbmluZyh7XG4gICAgICAgIHR5cGU6ICdkb2NrZXItaW1hZ2UnLFxuICAgICAgICBkZXN0aW5hdGlvbjoge1xuICAgICAgICAgIGltYWdlVGFnOiAnMTIzNDUnLFxuICAgICAgICAgIHJlcG9zaXRvcnlOYW1lOiAncmVwb25hbWUnLFxuICAgICAgICB9LFxuICAgICAgICBzb3VyY2U6IHtcbiAgICAgICAgICBkaXJlY3Rvcnk6ICcvZm9vJyxcbiAgICAgICAgfSxcbiAgICAgIH0pLFxuICAgIF0pO1xuICB9KTtcblxuICB0ZXN0KCdyZXVzZScsIGFzeW5jICgpID0+IHtcbiAgICAvLyBHSVZFTlxuICAgIGNvbnN0IHN0YWNrID0gc3RhY2tXaXRoQXNzZXRzKFtcbiAgICAgIHtcbiAgICAgICAgcGF0aDogX19kaXJuYW1lLFxuICAgICAgICBpZDogJ1NvbWVTdGFja1NvbWVSZXNvdXJjZTQ1NjcnLFxuICAgICAgICBwYWNrYWdpbmc6ICdjb250YWluZXItaW1hZ2UnLFxuICAgICAgICBpbWFnZU5hbWVQYXJhbWV0ZXI6ICdhc2RmJyxcbiAgICAgICAgc291cmNlSGFzaDogJ3NvdXJjZS1oYXNoJyxcbiAgICAgIH0sXG4gICAgXSk7XG5cbiAgICAvLyBXSEVOXG4gICAgY29uc3QgcGFyYW1zID0gYXdhaXQgYWRkTWV0YWRhdGFBc3NldHNUb01hbmlmZXN0KHN0YWNrLCBhc3NldHMsIHRvb2xraXQsIFsnU29tZVN0YWNrU29tZVJlc291cmNlNDU2NyddKTtcblxuICAgIC8vIFRIRU5cbiAgICBleHBlY3QocGFyYW1zKS50b0VxdWFsKHtcbiAgICB9KTtcblxuICAgIGV4cGVjdChhc3NldHMudG9NYW5pZmVzdCgnLicpLmVudHJpZXMpLnRvRXF1YWwoW10pO1xuICB9KTtcbn0pO1xuXG5mdW5jdGlvbiBzdGFja1dpdGhBc3NldHMoYXNzZXRFbnRyaWVzOiBBc3NldE1ldGFkYXRhRW50cnlbXSkge1xuICByZXR1cm4gdGVzdFN0YWNrKHtcbiAgICBzdGFja05hbWU6ICdTb21lU3RhY2snLFxuICAgIGFzc2V0czogYXNzZXRFbnRyaWVzLFxuICAgIHRlbXBsYXRlOiB7XG4gICAgICBSZXNvdXJjZXM6IHtcbiAgICAgICAgU29tZVJlc291cmNlOiB7XG4gICAgICAgICAgVHlwZTogJ0FXUzo6U29tZXRoaW5nOjpTb21ldGhpbmcnLFxuICAgICAgICB9LFxuICAgICAgfSxcbiAgICB9LFxuICB9KTtcbn1cblxuZnVuY3Rpb24gbW9ja0ZuPEYgZXh0ZW5kcyAoLi4ueHM6IGFueVtdKSA9PiBhbnk+KGZuOiBGKTogamVzdC5Nb2NrPFJldHVyblR5cGU8Rj4+IHtcbiAgaWYgKCFqZXN0LmlzTW9ja0Z1bmN0aW9uKGZuKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgTm90IGEgbW9jayBmdW5jdGlvbjogJHtmbn1gKTtcbiAgfVxuICByZXR1cm4gZm47XG59XG4iXX0=