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==