stack-activity-monitor.test.js
1 "use strict"; 2 Object.defineProperty(exports, "__esModule", { value: true }); 3 const safe_1 = require("colors/safe"); 4 const stack_activity_monitor_1 = require("../../lib/api/util/cloudformation/stack-activity-monitor"); 5 const console_listener_1 = require("./console-listener"); 6 let TIMESTAMP; 7 let HUMAN_TIME; 8 beforeAll(() => { 9 TIMESTAMP = new Date().getTime(); 10 HUMAN_TIME = new Date(TIMESTAMP).toLocaleTimeString(); 11 }); 12 test('prints 0/4 progress report, when addActivity is called with an "IN_PROGRESS" ResourceStatus', () => { 13 const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ 14 resourceTypeColumnWidth: 23, 15 resourcesTotal: 3, 16 stream: process.stderr, 17 }); 18 const output = console_listener_1.stderr.inspectSync(() => { 19 historyActivityPrinter.addActivity({ 20 event: { 21 LogicalResourceId: 'stack1', 22 ResourceStatus: 'IN_PROGRESS', 23 Timestamp: new Date(TIMESTAMP), 24 ResourceType: 'AWS::CloudFormation::Stack', 25 StackId: '', 26 EventId: '', 27 StackName: '', 28 }, 29 }); 30 }); 31 expect(output[0].trim()).toStrictEqual(`0/4 |${HUMAN_TIME} | ${safe_1.reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${safe_1.reset(safe_1.bold('stack1'))}`); 32 }); 33 test('prints 1/4 progress report, when addActivity is called with an "UPDATE_COMPLETE" ResourceStatus', () => { 34 const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ 35 resourceTypeColumnWidth: 23, 36 resourcesTotal: 3, 37 stream: process.stderr, 38 }); 39 const output = console_listener_1.stderr.inspectSync(() => { 40 historyActivityPrinter.addActivity({ 41 event: { 42 LogicalResourceId: 'stack1', 43 ResourceStatus: 'UPDATE_COMPLETE', 44 Timestamp: new Date(TIMESTAMP), 45 ResourceType: 'AWS::CloudFormation::Stack', 46 StackId: '', 47 EventId: '', 48 StackName: '', 49 }, 50 }); 51 }); 52 expect(output[0].trim()).toStrictEqual(`1/4 |${HUMAN_TIME} | ${safe_1.green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${safe_1.green(safe_1.bold('stack1'))}`); 53 }); 54 test('prints 1/4 progress report, when addActivity is called with an "UPDATE_COMPLETE_CLEAN_IN_PROGRESS" ResourceStatus', () => { 55 const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ 56 resourceTypeColumnWidth: 23, 57 resourcesTotal: 3, 58 stream: process.stderr, 59 }); 60 const output = console_listener_1.stderr.inspectSync(() => { 61 historyActivityPrinter.addActivity({ 62 event: { 63 LogicalResourceId: 'stack1', 64 ResourceStatus: 'UPDATE_COMPLETE_CLEANUP_IN_PROGRESS', 65 Timestamp: new Date(TIMESTAMP), 66 ResourceType: 'AWS::CloudFormation::Stack', 67 StackId: '', 68 EventId: '', 69 StackName: '', 70 }, 71 }); 72 }); 73 expect(output[0].trim()).toStrictEqual(`1/4 |${HUMAN_TIME} | ${safe_1.green('UPDATE_COMPLETE_CLEA')} | AWS::CloudFormation::Stack | ${safe_1.green(safe_1.bold('stack1'))}`); 74 }); 75 test('prints 1/4 progress report, when addActivity is called with an "ROLLBACK_COMPLETE_CLEAN_IN_PROGRESS" ResourceStatus', () => { 76 const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ 77 resourceTypeColumnWidth: 23, 78 resourcesTotal: 3, 79 stream: process.stderr, 80 }); 81 const output = console_listener_1.stderr.inspectSync(() => { 82 historyActivityPrinter.addActivity({ 83 event: { 84 LogicalResourceId: 'stack1', 85 ResourceStatus: 'ROLLBACK_COMPLETE_CLEANUP_IN_PROGRESS', 86 Timestamp: new Date(TIMESTAMP), 87 ResourceType: 'AWS::CloudFormation::Stack', 88 StackId: '', 89 EventId: '', 90 StackName: '', 91 }, 92 }); 93 }); 94 expect(output[0].trim()).toStrictEqual(`1/4 |${HUMAN_TIME} | ${safe_1.yellow('ROLLBACK_COMPLETE_CL')} | AWS::CloudFormation::Stack | ${safe_1.yellow(safe_1.bold('stack1'))}`); 95 }); 96 test('prints 0/4 progress report, when addActivity is called with an "UPDATE_FAILED" ResourceStatus', () => { 97 const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ 98 resourceTypeColumnWidth: 23, 99 resourcesTotal: 3, 100 stream: process.stderr, 101 }); 102 const output = console_listener_1.stderr.inspectSync(() => { 103 historyActivityPrinter.addActivity({ 104 event: { 105 LogicalResourceId: 'stack1', 106 ResourceStatus: 'UPDATE_FAILED', 107 Timestamp: new Date(TIMESTAMP), 108 ResourceType: 'AWS::CloudFormation::Stack', 109 StackId: '', 110 EventId: '', 111 StackName: '', 112 }, 113 }); 114 }); 115 expect(output[0].trim()).toStrictEqual(`0/4 |${HUMAN_TIME} | ${safe_1.red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${safe_1.red(safe_1.bold('stack1'))}`); 116 }); 117 test('does not print "Failed Resources:" list, when all deployments are successful', () => { 118 const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ 119 resourceTypeColumnWidth: 23, 120 resourcesTotal: 1, 121 stream: process.stderr, 122 }); 123 const output = console_listener_1.stderr.inspectSync(() => { 124 historyActivityPrinter.addActivity({ 125 event: { 126 LogicalResourceId: 'stack1', 127 ResourceStatus: 'IN_PROGRESS', 128 Timestamp: new Date(TIMESTAMP), 129 ResourceType: 'AWS::CloudFormation::Stack', 130 StackId: '', 131 EventId: '', 132 StackName: '', 133 }, 134 }); 135 historyActivityPrinter.addActivity({ 136 event: { 137 LogicalResourceId: 'stack1', 138 ResourceStatus: 'UPDATE_COMPLETE', 139 Timestamp: new Date(TIMESTAMP), 140 ResourceType: 'AWS::CloudFormation::Stack', 141 StackId: '', 142 EventId: '', 143 StackName: '', 144 }, 145 }); 146 historyActivityPrinter.addActivity({ 147 event: { 148 LogicalResourceId: 'stack2', 149 ResourceStatus: 'UPDATE_COMPLETE', 150 Timestamp: new Date(TIMESTAMP), 151 ResourceType: 'AWS::CloudFormation::Stack', 152 StackId: '', 153 EventId: '', 154 StackName: '', 155 }, 156 }); 157 historyActivityPrinter.stop(); 158 }); 159 expect(output.length).toStrictEqual(3); 160 expect(output[0].trim()).toStrictEqual(`0/2 |${HUMAN_TIME} | ${safe_1.reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${safe_1.reset(safe_1.bold('stack1'))}`); 161 expect(output[1].trim()).toStrictEqual(`1/2 |${HUMAN_TIME} | ${safe_1.green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${safe_1.green(safe_1.bold('stack1'))}`); 162 expect(output[2].trim()).toStrictEqual(`2/2 |${HUMAN_TIME} | ${safe_1.green('UPDATE_COMPLETE ')} | AWS::CloudFormation::Stack | ${safe_1.green(safe_1.bold('stack2'))}`); 163 }); 164 test('prints "Failed Resources:" list, when at least one deployment fails', () => { 165 const historyActivityPrinter = new stack_activity_monitor_1.HistoryActivityPrinter({ 166 resourceTypeColumnWidth: 23, 167 resourcesTotal: 1, 168 stream: process.stderr, 169 }); 170 const output = console_listener_1.stderr.inspectSync(() => { 171 historyActivityPrinter.addActivity({ 172 event: { 173 LogicalResourceId: 'stack1', 174 ResourceStatus: 'IN_PROGRESS', 175 Timestamp: new Date(TIMESTAMP), 176 ResourceType: 'AWS::CloudFormation::Stack', 177 StackId: '', 178 EventId: '', 179 StackName: '', 180 }, 181 }); 182 historyActivityPrinter.addActivity({ 183 event: { 184 LogicalResourceId: 'stack1', 185 ResourceStatus: 'UPDATE_FAILED', 186 Timestamp: new Date(TIMESTAMP), 187 ResourceType: 'AWS::CloudFormation::Stack', 188 StackId: '', 189 EventId: '', 190 StackName: '', 191 }, 192 }); 193 historyActivityPrinter.stop(); 194 }); 195 expect(output.length).toStrictEqual(4); 196 expect(output[0].trim()).toStrictEqual(`0/2 |${HUMAN_TIME} | ${safe_1.reset('IN_PROGRESS ')} | AWS::CloudFormation::Stack | ${safe_1.reset(safe_1.bold('stack1'))}`); 197 expect(output[1].trim()).toStrictEqual(`0/2 |${HUMAN_TIME} | ${safe_1.red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${safe_1.red(safe_1.bold('stack1'))}`); 198 expect(output[2].trim()).toStrictEqual('Failed resources:'); 199 expect(output[3].trim()).toStrictEqual(`${HUMAN_TIME} | ${safe_1.red('UPDATE_FAILED ')} | AWS::CloudFormation::Stack | ${safe_1.red(safe_1.bold('stack1'))}`); 200 }); 201 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhY2stYWN0aXZpdHktbW9uaXRvci50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsic3RhY2stYWN0aXZpdHktbW9uaXRvci50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsc0NBQThEO0FBQzlELHFHQUFrRztBQUNsRyx5REFBNEM7QUFFNUMsSUFBSSxTQUFpQixDQUFDO0FBQ3RCLElBQUksVUFBa0IsQ0FBQztBQUV2QixTQUFTLENBQUMsR0FBRyxFQUFFO0lBQ2IsU0FBUyxHQUFHLElBQUksSUFBSSxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDakMsVUFBVSxHQUFHLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLGtCQUFrQixFQUFFLENBQUM7QUFDeEQsQ0FBQyxDQUFDLENBQUM7QUFHSCxJQUFJLENBQUMsNkZBQTZGLEVBQUUsR0FBRyxFQUFFO0lBQ3ZHLE1BQU0sc0JBQXNCLEdBQUcsSUFBSSwrQ0FBc0IsQ0FBQztRQUN4RCx1QkFBdUIsRUFBRSxFQUFFO1FBQzNCLGNBQWMsRUFBRSxDQUFDO1FBQ2pCLE1BQU0sRUFBRSxPQUFPLENBQUMsTUFBTTtLQUN2QixDQUFDLENBQUM7SUFFSCxNQUFNLE1BQU0sR0FBRyx5QkFBTSxDQUFDLFdBQVcsQ0FBQyxHQUFHLEVBQUU7UUFDckMsc0JBQXNCLENBQUMsV0FBVyxDQUFDO1lBQ2pDLEtBQUssRUFBRTtnQkFDTCxpQkFBaUIsRUFBRSxRQUFRO2dCQUMzQixjQUFjLEVBQUUsYUFBYTtnQkFDN0IsU0FBUyxFQUFFLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQztnQkFDOUIsWUFBWSxFQUFFLDRCQUE0QjtnQkFDMUMsT0FBTyxFQUFFLEVBQUU7Z0JBQ1gsT0FBTyxFQUFFLEVBQUU7Z0JBQ1gsU0FBUyxFQUFFLEVBQUU7YUFDZDtTQUNGLENBQUMsQ0FBQztJQUNMLENBQUMsQ0FBQyxDQUFDO0lBRUgsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxJ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QUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsUUFBUSxVQUFVLE1BQU0sVUFBRyxDQUFDLHNCQUFzQixDQUFDLG1DQUFtQyxVQUFHLENBQUMsV0FBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQ3BKLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxhQUFhLENBQUMsbUJBQW1CLENBQUMsQ0FBQztJQUM1RCxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsYUFBYSxDQUFDLEdBQUcsVUFBVSxNQUFNLFVBQUcsQ0FBQyxzQkFBc0IsQ0FBQyxtQ0FBbUMsVUFBRyxDQUFDLFdBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztBQUNqSixDQUFDLENBQUMsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGJvbGQsIHJlc2V0LCBncmVlbiwgeWVsbG93LCByZWQgfSBmcm9tICdjb2xvcnMvc2FmZSc7XG5pbXBvcnQgeyBIaXN0b3J5QWN0aXZpdHlQcmludGVyIH0gZnJvbSAnLi4vLi4vbGliL2FwaS91dGlsL2Nsb3VkZm9ybWF0aW9uL3N0YWNrLWFjdGl2aXR5LW1vbml0b3InO1xuaW1wb3J0IHsgc3RkZXJyIH0gZnJvbSAnLi9jb25zb2xlLWxpc3RlbmVyJztcblxubGV0IFRJTUVTVEFNUDogbnVtYmVyO1xubGV0IEhVTUFOX1RJTUU6IHN0cmluZztcblxuYmVmb3JlQWxsKCgpID0+IHtcbiAgVElNRVNUQU1QID0gbmV3IERhdGUoKS5nZXRUaW1lKCk7XG4gIEhVTUFOX1RJTUUgPSBuZXcgRGF0ZShUSU1FU1RBTVApLnRvTG9jYWxlVGltZVN0cmluZygpO1xufSk7XG5cblxudGVzdCgncHJpbnRzIDAvNCBwcm9ncmVzcyByZXBvcnQsIHdoZW4gYWRkQWN0aXZpdHkgaXMgY2FsbGVkIHdpdGggYW4gXCJJTl9QUk9HUkVTU1wiIFJlc291cmNlU3RhdHVzJywgKCkgPT4ge1xuICBjb25zdCBoaXN0b3J5QWN0aXZpdHlQcmludGVyID0gbmV3IEhpc3RvcnlBY3Rpdml0eVByaW50ZXIoe1xuICAgIHJlc291cmNlVHlwZUNvbHVtbldpZHRoOiAyMyxcbiAgICByZXNvdXJjZXNUb3RhbDogMyxcbiAgICBzdHJlYW06IHByb2Nlc3Muc3RkZXJyLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXQgPSBzdGRlcnIuaW5zcGVjdFN5bmMoKCkgPT4ge1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuYWRkQWN0aXZpdHkoe1xuICAgICAgZXZlbnQ6IHtcbiAgICAgICAgTG9naWNhbFJlc291cmNlSWQ6ICdzdGFjazEnLFxuICAgICAgICBSZXNvdXJjZVN0YXR1czogJ0lOX1BST0dSRVNTJyxcbiAgICAgICAgVGltZXN0YW1wOiBuZXcgRGF0ZShUSU1FU1RBTVApLFxuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFN0YWNrSWQ6ICcnLFxuICAgICAgICBFdmVudElkOiAnJyxcbiAgICAgICAgU3RhY2tOYW1lOiAnJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIGV4cGVjdChvdXRwdXRbMF0udHJpbSgpKS50b1N0cmljdEVxdWFsKGAwLzQgfCR7SFVNQU5fVElNRX0gfCAke3Jlc2V0KCdJTl9QUk9HUkVTUyAgICAgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtyZXNldChib2xkKCdzdGFjazEnKSl9YCk7XG59KTtcblxudGVzdCgncHJpbnRzIDEvNCBwcm9ncmVzcyByZXBvcnQsIHdoZW4gYWRkQWN0aXZpdHkgaXMgY2FsbGVkIHdpdGggYW4gXCJVUERBVEVfQ09NUExFVEVcIiBSZXNvdXJjZVN0YXR1cycsICgpID0+IHtcbiAgY29uc3QgaGlzdG9yeUFjdGl2aXR5UHJpbnRlciA9IG5ldyBIaXN0b3J5QWN0aXZpdHlQcmludGVyKHtcbiAgICByZXNvdXJjZVR5cGVDb2x1bW5XaWR0aDogMjMsXG4gICAgcmVzb3VyY2VzVG90YWw6IDMsXG4gICAgc3RyZWFtOiBwcm9jZXNzLnN0ZGVycixcbiAgfSk7XG5cbiAgY29uc3Qgb3V0cHV0ID0gc3RkZXJyLmluc3BlY3RTeW5jKCgpID0+IHtcbiAgICBoaXN0b3J5QWN0aXZpdHlQcmludGVyLmFkZEFjdGl2aXR5KHtcbiAgICAgIGV2ZW50OiB7XG4gICAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiAnc3RhY2sxJyxcbiAgICAgICAgUmVzb3VyY2VTdGF0dXM6ICdVUERBVEVfQ09NUExFVEUnLFxuICAgICAgICBUaW1lc3RhbXA6IG5ldyBEYXRlKFRJTUVTVEFNUCksXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgU3RhY2tJZDogJycsXG4gICAgICAgIEV2ZW50SWQ6ICcnLFxuICAgICAgICBTdGFja05hbWU6ICcnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfSk7XG5cbiAgZXhwZWN0KG91dHB1dFswXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYDEvNCB8JHtIVU1BTl9USU1FfSB8ICR7Z3JlZW4oJ1VQREFURV9DT01QTEVURSAgICAgJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke2dyZWVuKGJvbGQoJ3N0YWNrMScpKX1gKTtcbn0pO1xuXG50ZXN0KCdwcmludHMgMS80IHByb2dyZXNzIHJlcG9ydCwgd2hlbiBhZGRBY3Rpdml0eSBpcyBjYWxsZWQgd2l0aCBhbiBcIlVQREFURV9DT01QTEVURV9DTEVBTl9JTl9QUk9HUkVTU1wiIFJlc291cmNlU3RhdHVzJywgKCkgPT4ge1xuICBjb25zdCBoaXN0b3J5QWN0aXZpdHlQcmludGVyID0gbmV3IEhpc3RvcnlBY3Rpdml0eVByaW50ZXIoe1xuICAgIHJlc291cmNlVHlwZUNvbHVtbldpZHRoOiAyMyxcbiAgICByZXNvdXJjZXNUb3RhbDogMyxcbiAgICBzdHJlYW06IHByb2Nlc3Muc3RkZXJyLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXQgPSBzdGRlcnIuaW5zcGVjdFN5bmMoKCkgPT4ge1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuYWRkQWN0aXZpdHkoe1xuICAgICAgZXZlbnQ6IHtcbiAgICAgICAgTG9naWNhbFJlc291cmNlSWQ6ICdzdGFjazEnLFxuICAgICAgICBSZXNvdXJjZVN0YXR1czogJ1VQREFURV9DT01QTEVURV9DTEVBTlVQX0lOX1BST0dSRVNTJyxcbiAgICAgICAgVGltZXN0YW1wOiBuZXcgRGF0ZShUSU1FU1RBTVApLFxuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFN0YWNrSWQ6ICcnLFxuICAgICAgICBFdmVudElkOiAnJyxcbiAgICAgICAgU3RhY2tOYW1lOiAnJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH0pO1xuXG4gIGV4cGVjdChvdXRwdXRbMF0udHJpbSgpKS50b1N0cmljdEVxdWFsKGAxLzQgfCR7SFVNQU5fVElNRX0gfCAke2dyZWVuKCdVUERBVEVfQ09NUExFVEVfQ0xFQScpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtncmVlbihib2xkKCdzdGFjazEnKSl9YCk7XG59KTtcblxuXG50ZXN0KCdwcmludHMgMS80IHByb2dyZXNzIHJlcG9ydCwgd2hlbiBhZGRBY3Rpdml0eSBpcyBjYWxsZWQgd2l0aCBhbiBcIlJPTExCQUNLX0NPTVBMRVRFX0NMRUFOX0lOX1BST0dSRVNTXCIgUmVzb3VyY2VTdGF0dXMnLCAoKSA9PiB7XG4gIGNvbnN0IGhpc3RvcnlBY3Rpdml0eVByaW50ZXIgPSBuZXcgSGlzdG9yeUFjdGl2aXR5UHJpbnRlcih7XG4gICAgcmVzb3VyY2VUeXBlQ29sdW1uV2lkdGg6IDIzLFxuICAgIHJlc291cmNlc1RvdGFsOiAzLFxuICAgIHN0cmVhbTogcHJvY2Vzcy5zdGRlcnIsXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dCA9IHN0ZGVyci5pbnNwZWN0U3luYygoKSA9PiB7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnUk9MTEJBQ0tfQ09NUExFVEVfQ0xFQU5VUF9JTl9QUk9HUkVTUycsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJycsXG4gICAgICB9LFxuICAgIH0pO1xuICB9KTtcblxuICBleHBlY3Qob3V0cHV0WzBdLnRyaW0oKSkudG9TdHJpY3RFcXVhbChgMS80IHwke0hVTUFOX1RJTUV9IHwgJHt5ZWxsb3coJ1JPTExCQUNLX0NPTVBMRVRFX0NMJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke3llbGxvdyhib2xkKCdzdGFjazEnKSl9YCk7XG59KTtcblxudGVzdCgncHJpbnRzIDAvNCBwcm9ncmVzcyByZXBvcnQsIHdoZW4gYWRkQWN0aXZpdHkgaXMgY2FsbGVkIHdpdGggYW4gXCJVUERBVEVfRkFJTEVEXCIgUmVzb3VyY2VTdGF0dXMnLCAoKSA9PiB7XG4gIGNvbnN0IGhpc3RvcnlBY3Rpdml0eVByaW50ZXIgPSBuZXcgSGlzdG9yeUFjdGl2aXR5UHJpbnRlcih7XG4gICAgcmVzb3VyY2VUeXBlQ29sdW1uV2lkdGg6IDIzLFxuICAgIHJlc291cmNlc1RvdGFsOiAzLFxuICAgIHN0cmVhbTogcHJvY2Vzcy5zdGRlcnIsXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dCA9IHN0ZGVyci5pbnNwZWN0U3luYygoKSA9PiB7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnVVBEQVRFX0ZBSUxFRCcsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJycsXG4gICAgICB9LFxuICAgIH0pO1xuICB9KTtcblxuICBleHBlY3Qob3V0cHV0WzBdLnRyaW0oKSkudG9TdHJpY3RFcXVhbChgMC80IHwke0hVTUFOX1RJTUV9IHwgJHtyZWQoJ1VQREFURV9GQUlMRUQgICAgICAgJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke3JlZChib2xkKCdzdGFjazEnKSl9YCk7XG59KTtcblxuXG50ZXN0KCdkb2VzIG5vdCBwcmludCBcIkZhaWxlZCBSZXNvdXJjZXM6XCIgbGlzdCwgd2hlbiBhbGwgZGVwbG95bWVudHMgYXJlIHN1Y2Nlc3NmdWwnLCAoKSA9PiB7XG4gIGNvbnN0IGhpc3RvcnlBY3Rpdml0eVByaW50ZXIgPSBuZXcgSGlzdG9yeUFjdGl2aXR5UHJpbnRlcih7XG4gICAgcmVzb3VyY2VUeXBlQ29sdW1uV2lkdGg6IDIzLFxuICAgIHJlc291cmNlc1RvdGFsOiAxLFxuICAgIHN0cmVhbTogcHJvY2Vzcy5zdGRlcnIsXG4gIH0pO1xuXG4gIGNvbnN0IG91dHB1dCA9IHN0ZGVyci5pbnNwZWN0U3luYygoKSA9PiB7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnSU5fUFJPR1JFU1MnLFxuICAgICAgICBUaW1lc3RhbXA6IG5ldyBEYXRlKFRJTUVTVEFNUCksXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgU3RhY2tJZDogJycsXG4gICAgICAgIEV2ZW50SWQ6ICcnLFxuICAgICAgICBTdGFja05hbWU6ICcnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBoaXN0b3J5QWN0aXZpdHlQcmludGVyLmFkZEFjdGl2aXR5KHtcbiAgICAgIGV2ZW50OiB7XG4gICAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiAnc3RhY2sxJyxcbiAgICAgICAgUmVzb3VyY2VTdGF0dXM6ICdVUERBVEVfQ09NUExFVEUnLFxuICAgICAgICBUaW1lc3RhbXA6IG5ldyBEYXRlKFRJTUVTVEFNUCksXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgU3RhY2tJZDogJycsXG4gICAgICAgIEV2ZW50SWQ6ICcnLFxuICAgICAgICBTdGFja05hbWU6ICcnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBoaXN0b3J5QWN0aXZpdHlQcmludGVyLmFkZEFjdGl2aXR5KHtcbiAgICAgIGV2ZW50OiB7XG4gICAgICAgIExvZ2ljYWxSZXNvdXJjZUlkOiAnc3RhY2syJyxcbiAgICAgICAgUmVzb3VyY2VTdGF0dXM6ICdVUERBVEVfQ09NUExFVEUnLFxuICAgICAgICBUaW1lc3RhbXA6IG5ldyBEYXRlKFRJTUVTVEFNUCksXG4gICAgICAgIFJlc291cmNlVHlwZTogJ0FXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrJyxcbiAgICAgICAgU3RhY2tJZDogJycsXG4gICAgICAgIEV2ZW50SWQ6ICcnLFxuICAgICAgICBTdGFja05hbWU6ICcnLFxuICAgICAgfSxcbiAgICB9KTtcbiAgICBoaXN0b3J5QWN0aXZpdHlQcmludGVyLnN0b3AoKTtcbiAgfSk7XG5cbiAgZXhwZWN0KG91dHB1dC5sZW5ndGgpLnRvU3RyaWN0RXF1YWwoMyk7XG4gIGV4cGVjdChvdXRwdXRbMF0udHJpbSgpKS50b1N0cmljdEVxdWFsKGAwLzIgfCR7SFVNQU5fVElNRX0gfCAke3Jlc2V0KCdJTl9QUk9HUkVTUyAgICAgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtyZXNldChib2xkKCdzdGFjazEnKSl9YCk7XG4gIGV4cGVjdChvdXRwdXRbMV0udHJpbSgpKS50b1N0cmljdEVxdWFsKGAxLzIgfCR7SFVNQU5fVElNRX0gfCAke2dyZWVuKCdVUERBVEVfQ09NUExFVEUgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtncmVlbihib2xkKCdzdGFjazEnKSl9YCk7XG4gIGV4cGVjdChvdXRwdXRbMl0udHJpbSgpKS50b1N0cmljdEVxdWFsKGAyLzIgfCR7SFVNQU5fVElNRX0gfCAke2dyZWVuKCdVUERBVEVfQ09NUExFVEUgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtncmVlbihib2xkKCdzdGFjazInKSl9YCk7XG59KTtcblxudGVzdCgncHJpbnRzIFwiRmFpbGVkIFJlc291cmNlczpcIiBsaXN0LCB3aGVuIGF0IGxlYXN0IG9uZSBkZXBsb3ltZW50IGZhaWxzJywgKCkgPT4ge1xuICBjb25zdCBoaXN0b3J5QWN0aXZpdHlQcmludGVyID0gbmV3IEhpc3RvcnlBY3Rpdml0eVByaW50ZXIoe1xuICAgIHJlc291cmNlVHlwZUNvbHVtbldpZHRoOiAyMyxcbiAgICByZXNvdXJjZXNUb3RhbDogMSxcbiAgICBzdHJlYW06IHByb2Nlc3Muc3RkZXJyLFxuICB9KTtcblxuICBjb25zdCBvdXRwdXQgPSBzdGRlcnIuaW5zcGVjdFN5bmMoKCkgPT4ge1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuYWRkQWN0aXZpdHkoe1xuICAgICAgZXZlbnQ6IHtcbiAgICAgICAgTG9naWNhbFJlc291cmNlSWQ6ICdzdGFjazEnLFxuICAgICAgICBSZXNvdXJjZVN0YXR1czogJ0lOX1BST0dSRVNTJyxcbiAgICAgICAgVGltZXN0YW1wOiBuZXcgRGF0ZShUSU1FU1RBTVApLFxuICAgICAgICBSZXNvdXJjZVR5cGU6ICdBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjaycsXG4gICAgICAgIFN0YWNrSWQ6ICcnLFxuICAgICAgICBFdmVudElkOiAnJyxcbiAgICAgICAgU3RhY2tOYW1lOiAnJyxcbiAgICAgIH0sXG4gICAgfSk7XG4gICAgaGlzdG9yeUFjdGl2aXR5UHJpbnRlci5hZGRBY3Rpdml0eSh7XG4gICAgICBldmVudDoge1xuICAgICAgICBMb2dpY2FsUmVzb3VyY2VJZDogJ3N0YWNrMScsXG4gICAgICAgIFJlc291cmNlU3RhdHVzOiAnVVBEQVRFX0ZBSUxFRCcsXG4gICAgICAgIFRpbWVzdGFtcDogbmV3IERhdGUoVElNRVNUQU1QKSxcbiAgICAgICAgUmVzb3VyY2VUeXBlOiAnQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2snLFxuICAgICAgICBTdGFja0lkOiAnJyxcbiAgICAgICAgRXZlbnRJZDogJycsXG4gICAgICAgIFN0YWNrTmFtZTogJycsXG4gICAgICB9LFxuICAgIH0pO1xuICAgIGhpc3RvcnlBY3Rpdml0eVByaW50ZXIuc3RvcCgpO1xuICB9KTtcblxuICBleHBlY3Qob3V0cHV0Lmxlbmd0aCkudG9TdHJpY3RFcXVhbCg0KTtcbiAgZXhwZWN0KG91dHB1dFswXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYDAvMiB8JHtIVU1BTl9USU1FfSB8ICR7cmVzZXQoJ0lOX1BST0dSRVNTICAgICAgICAgJyl9IHwgQVdTOjpDbG91ZEZvcm1hdGlvbjo6U3RhY2sgfCAke3Jlc2V0KGJvbGQoJ3N0YWNrMScpKX1gKTtcbiAgZXhwZWN0KG91dHB1dFsxXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYDAvMiB8JHtIVU1BTl9USU1FfSB8ICR7cmVkKCdVUERBVEVfRkFJTEVEICAgICAgICcpfSB8IEFXUzo6Q2xvdWRGb3JtYXRpb246OlN0YWNrIHwgJHtyZWQoYm9sZCgnc3RhY2sxJykpfWApO1xuICBleHBlY3Qob3V0cHV0WzJdLnRyaW0oKSkudG9TdHJpY3RFcXVhbCgnRmFpbGVkIHJlc291cmNlczonKTtcbiAgZXhwZWN0KG91dHB1dFszXS50cmltKCkpLnRvU3RyaWN0RXF1YWwoYCR7SFVNQU5fVElNRX0gfCAke3JlZCgnVVBEQVRFX0ZBSUxFRCAgICAgICAnKX0gfCBBV1M6OkNsb3VkRm9ybWF0aW9uOjpTdGFjayB8ICR7cmVkKGJvbGQoJ3N0YWNrMScpKX1gKTtcbn0pO1xuIl19