diff.test.js
1 "use strict"; 2 Object.defineProperty(exports, "__esModule", { value: true }); 3 const stream_1 = require("stream"); 4 const string_decoder_1 = require("string_decoder"); 5 const cxschema = require("@aws-cdk/cloud-assembly-schema"); 6 const cloudformation_deployments_1 = require("../lib/api/cloudformation-deployments"); 7 const cdk_toolkit_1 = require("../lib/cdk-toolkit"); 8 const util_1 = require("./util"); 9 let cloudExecutable; 10 let cloudFormation; 11 let toolkit; 12 beforeEach(() => { 13 cloudExecutable = new util_1.MockCloudExecutable({ 14 stacks: [{ 15 stackName: 'A', 16 template: { resource: 'A' }, 17 }, 18 { 19 stackName: 'B', 20 depends: ['A'], 21 template: { resource: 'B' }, 22 }, 23 { 24 stackName: 'C', 25 depends: ['A'], 26 template: { resource: 'C' }, 27 metadata: { 28 '/resource': [ 29 { 30 type: cxschema.ArtifactMetadataEntryType.ERROR, 31 data: 'this is an error', 32 }, 33 ], 34 }, 35 }, 36 { 37 stackName: 'D', 38 template: { resource: 'D' }, 39 }], 40 }); 41 cloudFormation = util_1.instanceMockFrom(cloudformation_deployments_1.CloudFormationDeployments); 42 toolkit = new cdk_toolkit_1.CdkToolkit({ 43 cloudExecutable, 44 cloudFormation, 45 configuration: cloudExecutable.configuration, 46 sdkProvider: cloudExecutable.sdkProvider, 47 }); 48 // Default implementations 49 cloudFormation.readCurrentTemplate.mockImplementation((stackArtifact) => { 50 if (stackArtifact.stackName === 'D') { 51 return Promise.resolve({ resource: 'D' }); 52 } 53 return Promise.resolve({}); 54 }); 55 cloudFormation.deployStack.mockImplementation((options) => Promise.resolve({ 56 noOp: true, 57 outputs: {}, 58 stackArn: '', 59 stackArtifact: options.stack, 60 })); 61 }); 62 test('diff can diff multiple stacks', async () => { 63 // GIVEN 64 const buffer = new StringWritable(); 65 // WHEN 66 const exitCode = await toolkit.diff({ 67 stackNames: ['B'], 68 stream: buffer, 69 }); 70 // THEN 71 const plainTextOutput = buffer.data.replace(/\x1B\[[0-?]*[ -/]*[@-~]/g, ''); 72 expect(plainTextOutput).toContain('Stack A'); 73 expect(plainTextOutput).toContain('Stack B'); 74 expect(exitCode).toBe(0); 75 }); 76 test('exits with 1 with diffs and fail set to true', async () => { 77 // GIVEN 78 const buffer = new StringWritable(); 79 // WHEN 80 const exitCode = await toolkit.diff({ 81 stackNames: ['A'], 82 stream: buffer, 83 fail: true, 84 }); 85 // THEN 86 expect(exitCode).toBe(1); 87 }); 88 test('exits with 1 with diff in first stack, but not in second stack and fail set to true', async () => { 89 // GIVEN 90 const buffer = new StringWritable(); 91 // WHEN 92 const exitCode = await toolkit.diff({ 93 stackNames: ['A', 'D'], 94 stream: buffer, 95 fail: true, 96 }); 97 // THEN 98 expect(exitCode).toBe(1); 99 }); 100 test('throws an error during diffs on stack with error metadata', async () => { 101 const buffer = new StringWritable(); 102 // WHEN 103 await expect(() => toolkit.diff({ 104 stackNames: ['C'], 105 stream: buffer, 106 })).rejects.toThrow(/Found errors/); 107 }); 108 class StringWritable extends stream_1.Writable { 109 constructor(options = {}) { 110 super(options); 111 this._decoder = new string_decoder_1.StringDecoder(options && options.defaultEncoding); 112 this.data = ''; 113 } 114 _write(chunk, encoding, callback) { 115 if (encoding === 'buffer') { 116 chunk = this._decoder.write(chunk); 117 } 118 this.data += chunk; 119 callback(); 120 } 121 _final(callback) { 122 this.data += this._decoder.end(); 123 callback(); 124 } 125 } 126 //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlmZi50ZXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiZGlmZi50ZXN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUEsbUNBQWtDO0FBQ2xDLG1EQUFrRTtBQUNsRSwyREFBMkQ7QUFFM0Qsc0ZBQWtGO0FBQ2xGLG9EQUFnRDtBQUNoRCxpQ0FBK0Q7QUFFL0QsSUFBSSxlQUFvQyxDQUFDO0FBQ3pDLElBQUksY0FBc0QsQ0FBQztBQUMzRCxJQUFJLE9BQW1CLENBQUM7QUFDeEIsVUFBVSxDQUFDLEdBQUcsRUFBRTtJQUNkLGVBQWUsR0FBRyxJQUFJLDBCQUFtQixDQUFDO1FBQ3hDLE1BQU0sRUFBRSxDQUFDO2dCQUNQLFNBQVMsRUFBRSxHQUFHO2dCQUNkLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7YUFDNUI7WUFDRDtnQkFDRSxTQUFTLEVBQUUsR0FBRztnQkFDZCxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUM7Z0JBQ2QsUUFBUSxFQUFFLEVBQUUsUUFBUSxFQUFFLEdBQUcsRUFBRTthQUM1QjtZQUNEO2dCQUNFLFNBQVMsRUFBRSxHQUFHO2dCQUNkLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQztnQkFDZCxRQUFRLEVBQUUsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFO2dCQUMzQixRQUFRLEVBQUU7b0JBQ1IsV0FBVyxFQUFFO3dCQUNYOzRCQUNFLElBQUksRUFBRSxRQUFRLENBQUMseUJBQXlCLENBQUMsS0FBSzs0QkFDOUMsSUFBSSxFQUFFLGtCQUFrQjt5QkFDekI7cUJBQ0Y7aUJBQ0Y7YUFDRjtZQUNEO2dCQUNFLFNBQVMsRUFBRSxHQUFHO2dCQUNkLFFBQVEsRUFBRSxFQUFFLFFBQVEsRUFBRSxHQUFHLEVBQUU7YUFDNUIsQ0FBQztLQUNILENBQUMsQ0FBQztJQUVILGNBQWMsR0FBRyx1QkFBZ0IsQ0FBQyxzREFBeUIsQ0FBQyxDQUFDO0lBRTdELE9BQU8sR0FBRyxJQUFJLHdCQUFVLENBQUM7UUFDdkIs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Q1AsTUFBTSxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQztRQUM5QixVQUFVLEVBQUUsQ0FBQyxHQUFHLENBQUM7UUFDakIsTUFBTSxFQUFFLE1BQU07S0FDZixDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDO0FBQ3RDLENBQUMsQ0FBQyxDQUFDO0FBRUgsTUFBTSxjQUFlLFNBQVEsaUJBQVE7SUFJbkMsWUFBWSxVQUFlLEVBQUU7UUFDM0IsS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2YsSUFBSSxDQUFDLFFBQVEsR0FBRyxJQUFJLDhCQUFhLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUN0RSxJQUFJLENBQUMsSUFBSSxHQUFHLEVBQUUsQ0FBQztJQUNqQixDQUFDO0lBRU0sTUFBTSxDQUFDLEtBQVUsRUFBRSxRQUFnQixFQUFFLFFBQTZDO1FBQ3ZGLElBQUksUUFBUSxLQUFLLFFBQVEsRUFBRTtZQUN6QixLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUM7U0FDcEM7UUFDRCxJQUFJLENBQUMsSUFBSSxJQUFJLEtBQUssQ0FBQztRQUNuQixRQUFRLEVBQUUsQ0FBQztJQUNiLENBQUM7SUFFTSxNQUFNLENBQUMsUUFBd0M7UUFDcEQsSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBQ2pDLFFBQVEsRUFBRSxDQUFDO0lBQ2IsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgV3JpdGFibGUgfSBmcm9tICdzdHJlYW0nO1xuaW1wb3J0IHsgTm9kZVN0cmluZ0RlY29kZXIsIFN0cmluZ0RlY29kZXIgfSBmcm9tICdzdHJpbmdfZGVjb2Rlcic7XG5pbXBvcnQgKiBhcyBjeHNjaGVtYSBmcm9tICdAYXdzLWNkay9jbG91ZC1hc3NlbWJseS1zY2hlbWEnO1xuaW1wb3J0IHsgQ2xvdWRGb3JtYXRpb25TdGFja0FydGlmYWN0IH0gZnJvbSAnQGF3cy1jZGsvY3gtYXBpJztcbmltcG9ydCB7IENsb3VkRm9ybWF0aW9uRGVwbG95bWVudHMgfSBmcm9tICcuLi9saWIvYXBpL2Nsb3VkZm9ybWF0aW9uLWRlcGxveW1lbnRzJztcbmltcG9ydCB7IENka1Rvb2xraXQgfSBmcm9tICcuLi9saWIvY2RrLXRvb2xraXQnO1xuaW1wb3J0IHsgaW5zdGFuY2VNb2NrRnJvbSwgTW9ja0Nsb3VkRXhlY3V0YWJsZSB9IGZyb20gJy4vdXRpbCc7XG5cbmxldCBjbG91ZEV4ZWN1dGFibGU6IE1vY2tDbG91ZEV4ZWN1dGFibGU7XG5sZXQgY2xvdWRGb3JtYXRpb246IGplc3QuTW9ja2VkPENsb3VkRm9ybWF0aW9uRGVwbG95bWVudHM+O1xubGV0IHRvb2xraXQ6IENka1Rvb2xraXQ7XG5iZWZvcmVFYWNoKCgpID0+IHtcbiAgY2xvdWRFeGVjdXRhYmxlID0gbmV3IE1vY2tDbG91ZEV4ZWN1dGFibGUoe1xuICAgIHN0YWNrczogW3tcbiAgICAgIHN0YWNrTmFtZTogJ0EnLFxuICAgICAgdGVtcGxhdGU6IHsgcmVzb3VyY2U6ICdBJyB9LFxuICAgIH0sXG4gICAge1xuICAgICAgc3RhY2tOYW1lOiAnQicsXG4gICAgICBkZXBlbmRzOiBbJ0EnXSxcbiAgICAgIHRlbXBsYXRlOiB7IHJlc291cmNlOiAnQicgfSxcbiAgICB9LFxuICAgIHtcbiAgICAgIHN0YWNrTmFtZTogJ0MnLFxuICAgICAgZGVwZW5kczogWydBJ10sXG4gICAgICB0ZW1wbGF0ZTogeyByZXNvdXJjZTogJ0MnIH0sXG4gICAgICBtZXRhZGF0YToge1xuICAgICAgICAnL3Jlc291cmNlJzogW1xuICAgICAgICAgIHtcbiAgICAgICAgICAgIHR5cGU6IGN4c2NoZW1hLkFydGlmYWN0TWV0YWRhdGFFbnRyeVR5cGUuRVJST1IsXG4gICAgICAgICAgICBkYXRhOiAndGhpcyBpcyBhbiBlcnJvcicsXG4gICAgICAgICAgfSxcbiAgICAgICAgXSxcbiAgICAgIH0sXG4gICAgfSxcbiAgICB7XG4gICAgICBzdGFja05hbWU6ICdEJyxcbiAgICAgIHRlbXBsYXRlOiB7IHJlc291cmNlOiAnRCcgfSxcbiAgICB9XSxcbiAgfSk7XG5cbiAgY2xvdWRGb3JtYXRpb24gPSBpbnN0YW5jZU1vY2tGcm9tKENsb3VkRm9ybWF0aW9uRGVwbG95bWVudHMpO1xuXG4gIHRvb2xraXQgPSBuZXcgQ2RrVG9vbGtpdCh7XG4gICAgY2xvdWRFeGVjdXRhYmxlLFxuICAgIGNsb3VkRm9ybWF0aW9uLFxuICAgIGNvbmZpZ3VyYXRpb246IGNsb3VkRXhlY3V0YWJsZS5jb25maWd1cmF0aW9uLFxuICAgIHNka1Byb3ZpZGVyOiBjbG91ZEV4ZWN1dGFibGUuc2RrUHJvdmlkZXIsXG4gIH0pO1xuXG4gIC8vIERlZmF1bHQgaW1wbGVtZW50YXRpb25zXG4gIGNsb3VkRm9ybWF0aW9uLnJlYWRDdXJyZW50VGVtcGxhdGUubW9ja0ltcGxlbWVudGF0aW9uKChzdGFja0FydGlmYWN0OiBDbG91ZEZvcm1hdGlvblN0YWNrQXJ0aWZhY3QpID0+IHtcbiAgICBpZiAoc3RhY2tBcnRpZmFjdC5zdGFja05hbWUgPT09ICdEJykge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSh7IHJlc291cmNlOiAnRCcgfSk7XG4gICAgfVxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe30pO1xuICB9KTtcbiAgY2xvdWRGb3JtYXRpb24uZGVwbG95U3RhY2subW9ja0ltcGxlbWVudGF0aW9uKChvcHRpb25zKSA9PiBQcm9taXNlLnJlc29sdmUoe1xuICAgIG5vT3A6IHRydWUsXG4gICAgb3V0cHV0czoge30sXG4gICAgc3RhY2tBcm46ICcnLFxuICAgIHN0YWNrQXJ0aWZhY3Q6IG9wdGlvbnMuc3RhY2ssXG4gIH0pKTtcbn0pO1xuXG50ZXN0KCdkaWZmIGNhbiBkaWZmIG11bHRpcGxlIHN0YWNrcycsIGFzeW5jICgpID0+IHtcbiAgLy8gR0lWRU5cbiAgY29uc3QgYnVmZmVyID0gbmV3IFN0cmluZ1dyaXRhYmxlKCk7XG5cbiAgLy8gV0hFTlxuICBjb25zdCBleGl0Q29kZSA9IGF3YWl0IHRvb2xraXQuZGlmZih7XG4gICAgc3RhY2tOYW1lczogWydCJ10sXG4gICAgc3RyZWFtOiBidWZmZXIsXG4gIH0pO1xuXG4gIC8vIFRIRU5cbiAgY29uc3QgcGxhaW5UZXh0T3V0cHV0ID0gYnVmZmVyLmRhdGEucmVwbGFjZSgvXFx4MUJcXFtbMC0/XSpbIC0vXSpbQC1+XS9nLCAnJyk7XG4gIGV4cGVjdChwbGFpblRleHRPdXRwdXQpLnRvQ29udGFpbignU3RhY2sgQScpO1xuICBleHBlY3QocGxhaW5UZXh0T3V0cHV0KS50b0NvbnRhaW4oJ1N0YWNrIEInKTtcblxuICBleHBlY3QoZXhpdENvZGUpLnRvQmUoMCk7XG59KTtcblxudGVzdCgnZXhpdHMgd2l0aCAxIHdpdGggZGlmZnMgYW5kIGZhaWwgc2V0IHRvIHRydWUnLCBhc3luYyAoKSA9PiB7XG4gIC8vIEdJVkVOXG4gIGNvbnN0IGJ1ZmZlciA9IG5ldyBTdHJpbmdXcml0YWJsZSgpO1xuXG4gIC8vIFdIRU5cbiAgY29uc3QgZXhpdENvZGUgPSBhd2FpdCB0b29sa2l0LmRpZmYoe1xuICAgIHN0YWNrTmFtZXM6IFsnQSddLFxuICAgIHN0cmVhbTogYnVmZmVyLFxuICAgIGZhaWw6IHRydWUsXG4gIH0pO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGV4aXRDb2RlKS50b0JlKDEpO1xufSk7XG5cbnRlc3QoJ2V4aXRzIHdpdGggMSB3aXRoIGRpZmYgaW4gZmlyc3Qgc3RhY2ssIGJ1dCBub3QgaW4gc2Vjb25kIHN0YWNrIGFuZCBmYWlsIHNldCB0byB0cnVlJywgYXN5bmMgKCkgPT4ge1xuICAvLyBHSVZFTlxuICBjb25zdCBidWZmZXIgPSBuZXcgU3RyaW5nV3JpdGFibGUoKTtcblxuICAvLyBXSEVOXG4gIGNvbnN0IGV4aXRDb2RlID0gYXdhaXQgdG9vbGtpdC5kaWZmKHtcbiAgICBzdGFja05hbWVzOiBbJ0EnLCAnRCddLFxuICAgIHN0cmVhbTogYnVmZmVyLFxuICAgIGZhaWw6IHRydWUsXG4gIH0pO1xuXG4gIC8vIFRIRU5cbiAgZXhwZWN0KGV4aXRDb2RlKS50b0JlKDEpO1xufSk7XG5cbnRlc3QoJ3Rocm93cyBhbiBlcnJvciBkdXJpbmcgZGlmZnMgb24gc3RhY2sgd2l0aCBlcnJvciBtZXRhZGF0YScsIGFzeW5jICgpID0+IHtcbiAgY29uc3QgYnVmZmVyID0gbmV3IFN0cmluZ1dyaXRhYmxlKCk7XG5cbiAgLy8gV0hFTlxuICBhd2FpdCBleHBlY3QoKCkgPT4gdG9vbGtpdC5kaWZmKHtcbiAgICBzdGFja05hbWVzOiBbJ0MnXSxcbiAgICBzdHJlYW06IGJ1ZmZlcixcbiAgfSkpLnJlamVjdHMudG9UaHJvdygvRm91bmQgZXJyb3JzLyk7XG59KTtcblxuY2xhc3MgU3RyaW5nV3JpdGFibGUgZXh0ZW5kcyBXcml0YWJsZSB7XG4gIHB1YmxpYyBkYXRhOiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgX2RlY29kZXI6IE5vZGVTdHJpbmdEZWNvZGVyO1xuXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnM6IGFueSA9IHt9KSB7XG4gICAgc3VwZXIob3B0aW9ucyk7XG4gICAgdGhpcy5fZGVjb2RlciA9IG5ldyBTdHJpbmdEZWNvZGVyKG9wdGlvbnMgJiYgb3B0aW9ucy5kZWZhdWx0RW5jb2RpbmcpO1xuICAgIHRoaXMuZGF0YSA9ICcnO1xuICB9XG5cbiAgcHVibGljIF93cml0ZShjaHVuazogYW55LCBlbmNvZGluZzogc3RyaW5nLCBjYWxsYmFjazogKGVycm9yPzogRXJyb3IgfCB1bmRlZmluZWQpID0+IHZvaWQpIHtcbiAgICBpZiAoZW5jb2RpbmcgPT09ICdidWZmZXInKSB7XG4gICAgICBjaHVuayA9IHRoaXMuX2RlY29kZXIud3JpdGUoY2h1bmspO1xuICAgIH1cbiAgICB0aGlzLmRhdGEgKz0gY2h1bms7XG4gICAgY2FsbGJhY2soKTtcbiAgfVxuXG4gIHB1YmxpYyBfZmluYWwoY2FsbGJhY2s6IChlcnJvcj86IEVycm9yIHwgbnVsbCkgPT4gdm9pZCkge1xuICAgIHRoaXMuZGF0YSArPSB0aGlzLl9kZWNvZGVyLmVuZCgpO1xuICAgIGNhbGxiYWNrKCk7XG4gIH1cbn1cbiJdfQ==