From 8eb049d398becc3d724d1c6dc92f0a5e5e82ed00 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Fri, 11 Nov 2022 13:11:52 +0000 Subject: [PATCH 1/8] chore(integ-runner): refactor snapshot tests and cdk mock --- .../@aws-cdk/integ-runner/test/helpers.ts | 84 +++++- .../test/runner/integ-test-runner.test.ts | 99 +++--- .../test/runner/integ-test-suite.test.ts | 5 +- .../test/runner/snapshot-test-runner.test.ts | 283 ++++++------------ 4 files changed, 203 insertions(+), 268 deletions(-) diff --git a/packages/@aws-cdk/integ-runner/test/helpers.ts b/packages/@aws-cdk/integ-runner/test/helpers.ts index 05090927c4658..238bb77e1695d 100644 --- a/packages/@aws-cdk/integ-runner/test/helpers.ts +++ b/packages/@aws-cdk/integ-runner/test/helpers.ts @@ -1,24 +1,86 @@ import { ICdk, CdkCliWrapper, CdkCliWrapperOptions, SynthFastOptions, DestroyOptions, ListOptions, SynthOptions, DeployOptions } from 'cdk-cli-wrapper'; +import { IntegSnapshotRunner, IntegTest } from '../lib/runner'; +import { DestructiveChange, Diagnostic } from '../lib/workers'; + +export interface MockCdkMocks { + deploy?: jest.MockedFn<(options: DeployOptions) => void>; + synth?: jest.MockedFn<(options: SynthOptions) => void>; + synthFast?: jest.MockedFn<(options: SynthFastOptions) => void>; + destroy?: jest.MockedFn<(options: DestroyOptions) => void>; + list?: jest.MockedFn<(options: ListOptions) => string>; +} export class MockCdkProvider { public readonly cdk: ICdk; + public readonly mocks: MockCdkMocks = {}; + constructor(options: CdkCliWrapperOptions) { this.cdk = new CdkCliWrapper(options); } - public mockDeploy(mock?: (options: DeployOptions) => void) { - this.cdk.deploy = mock ?? jest.fn().mockImplementation(); + public mockDeploy(mock?: MockCdkMocks['deploy']) { + this.mocks.deploy = mock ?? jest.fn().mockImplementation(); + this.cdk.deploy = this.mocks.deploy; } - public mockSynth(mock?: (options: SynthOptions) => void) { - this.cdk.synth = mock ?? jest.fn().mockImplementation(); + public mockSynth(mock?: MockCdkMocks['synth']) { + this.mocks.synth = mock ?? jest.fn().mockImplementation(); + this.cdk.synth = this.mocks.synth; } - public mockSynthFast(mock?: (options: SynthFastOptions) => void) { - this.cdk.synthFast = mock ?? jest.fn().mockImplementation(); + public mockSynthFast(mock?: MockCdkMocks['synthFast']) { + this.mocks.synthFast = mock ?? jest.fn().mockImplementation(); + this.cdk.synthFast = this.mocks.synthFast; } - public mockDestroy(mock?: (options: DestroyOptions) => void) { - this.cdk.destroy = mock ?? jest.fn().mockImplementation(); + public mockDestroy(mock?: MockCdkMocks['destroy']) { + this.mocks.destroy = mock ?? jest.fn().mockImplementation(); + this.cdk.destroy = this.mocks.destroy; } - public mockList(mock?: (options: ListOptions) => string) { - this.cdk.list = mock ?? jest.fn().mockImplementation(); + public mockList(mock?: MockCdkMocks['list']) { + this.mocks.list = mock ?? jest.fn().mockImplementation(); + this.cdk.list = this.mocks.list; } -} + public mockAll(mocks: MockCdkMocks = {}): Required { + this.mockDeploy(mocks.deploy); + this.mockSynth(mocks.synth); + this.mockSynthFast(mocks.synthFast); + this.mockDestroy(mocks.destroy); + this.mockList(mocks.list); + + return this.mocks as Required; + } + + + /** + * Run a test of the testSnapshot method + * @param integTestFile This name is used to determined the expected (committed) snapshot + * @param actualSnapshot The directory of the snapshot that is used for of the actual (current) app + * @returns Diagnostics as they would be returned by testSnapshot + */ + public snapshotTest(integTestFile: string, actualSnapshot?: string): { + diagnostics: Diagnostic[], + destructiveChanges: DestructiveChange[] + } { + // WHEN + const integTest = new IntegSnapshotRunner({ + cdk: this.cdk, + test: new IntegTest({ + fileName: 'test/test-data/' + integTestFile, + discoveryRoot: 'test/test-data', + }), + integOutDir: actualSnapshot ? 'test/test-data/' + actualSnapshot : undefined, + }); + const results = integTest.testSnapshot(); + + // THEN + expect(this.mocks.synthFast).toHaveBeenCalledTimes(2); + expect(this.mocks.synthFast).toHaveBeenCalledWith({ + env: expect.objectContaining({ + CDK_INTEG_ACCOUNT: '12345678', + CDK_INTEG_REGION: 'test-region', + }), + execCmd: ['node', integTestFile], + output: actualSnapshot ?? `cdk-integ.out.${integTestFile}.snapshot`, + }); + + return results; + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts b/packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts index 8a2b9cbfca984..6efc89727907e 100644 --- a/packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts +++ b/packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts @@ -1,34 +1,19 @@ import * as child_process from 'child_process'; import { Manifest } from '@aws-cdk/cloud-assembly-schema'; import { AVAILABILITY_ZONE_FALLBACK_CONTEXT_KEY } from '@aws-cdk/cx-api'; -import { SynthFastOptions, DestroyOptions, ListOptions, SynthOptions, DeployOptions } from 'cdk-cli-wrapper'; import * as fs from 'fs-extra'; import { IntegTestRunner, IntegTest } from '../../lib/runner'; import { MockCdkProvider } from '../helpers'; let cdkMock: MockCdkProvider; -let synthMock: (options: SynthOptions) => void; -let synthFastMock: (options: SynthFastOptions) => void; -let deployMock: (options: DeployOptions) => void; -let listMock: (options: ListOptions) => string; -let destroyMock: (options: DestroyOptions) => void; let spawnSyncMock: jest.SpyInstance; let removeSyncMock: jest.SpyInstance; + beforeEach(() => { cdkMock = new MockCdkProvider({ directory: 'test/test-data' }); - listMock = jest.fn().mockImplementation(() => { - return 'stackabc'; - }); + cdkMock.mockAll().list.mockImplementation(() => 'stackabc'); jest.spyOn(Manifest, 'saveIntegManifest').mockImplementation(); - synthMock = jest.fn().mockImplementation(); - deployMock = jest.fn().mockImplementation(); - destroyMock = jest.fn().mockImplementation(); - synthFastMock = jest.fn().mockImplementation(); - cdkMock.mockSynth(synthMock); - cdkMock.mockList(listMock); - cdkMock.mockDeploy(deployMock); - cdkMock.mockSynthFast(synthFastMock); - cdkMock.mockDestroy(destroyMock); + spawnSyncMock = jest.spyOn(child_process, 'spawnSync').mockReturnValue({ status: 0, stderr: Buffer.from('stderr'), @@ -63,10 +48,10 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(deployMock).toHaveBeenCalledTimes(2); - expect(destroyMock).toHaveBeenCalledTimes(1); - expect(synthFastMock).toHaveBeenCalledTimes(1); - expect(deployMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(2); + expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.deploy).toHaveBeenCalledWith({ app: 'xxxxx.test-with-snapshot.js.snapshot', requireApproval: 'never', pathMetadata: false, @@ -81,7 +66,7 @@ describe('IntegTest runIntegTests', () => { lookups: false, stacks: ['test-stack'], }); - expect(deployMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.deploy).toHaveBeenCalledWith({ app: 'node xxxxx.test-with-snapshot.js', requireApproval: 'never', pathMetadata: false, @@ -98,7 +83,7 @@ describe('IntegTest runIntegTests', () => { rollback: false, stacks: ['test-stack', 'new-test-stack'], }); - expect(destroyMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.destroy).toHaveBeenCalledWith({ app: 'node xxxxx.test-with-snapshot.js', pathMetadata: false, assetMetadata: false, @@ -129,10 +114,10 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(deployMock).toHaveBeenCalledTimes(1); - expect(destroyMock).toHaveBeenCalledTimes(1); - expect(synthFastMock).toHaveBeenCalledTimes(1); - expect(deployMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.deploy).toHaveBeenCalledWith({ app: 'node xxxxx.integ-test1.js', requireApproval: 'never', pathMetadata: false, @@ -147,7 +132,7 @@ describe('IntegTest runIntegTests', () => { stacks: ['stack1'], output: 'cdk-integ.out.xxxxx.integ-test1.js.snapshot', }); - expect(destroyMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.destroy).toHaveBeenCalledWith({ app: 'node xxxxx.integ-test1.js', pathMetadata: false, assetMetadata: false, @@ -173,10 +158,10 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(deployMock).toHaveBeenCalledTimes(1); - expect(destroyMock).toHaveBeenCalledTimes(1); - expect(synthFastMock).toHaveBeenCalledTimes(2); - expect(deployMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(2); + expect(cdkMock.mocks.deploy).toHaveBeenCalledWith({ app: 'node xxxxx.test-with-snapshot-assets-diff.js', requireApproval: 'never', pathMetadata: false, @@ -193,7 +178,7 @@ describe('IntegTest runIntegTests', () => { output: 'cdk-integ.out.xxxxx.test-with-snapshot-assets-diff.js.snapshot', profile: undefined, }); - expect(synthFastMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.synthFast).toHaveBeenCalledWith({ execCmd: ['node', 'xxxxx.test-with-snapshot-assets-diff.js'], env: expect.objectContaining({ CDK_INTEG_ACCOUNT: '12345678', @@ -202,7 +187,7 @@ describe('IntegTest runIntegTests', () => { }), output: 'xxxxx.test-with-snapshot-assets-diff.js.snapshot', }); - expect(destroyMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.destroy).toHaveBeenCalledWith({ app: 'node xxxxx.test-with-snapshot-assets-diff.js', pathMetadata: false, assetMetadata: false, @@ -233,9 +218,9 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(deployMock).toHaveBeenCalledTimes(1); - expect(destroyMock).toHaveBeenCalledTimes(0); - expect(synthFastMock).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(0); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1); }); test('dryrun', () => { @@ -253,9 +238,9 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(deployMock).toHaveBeenCalledTimes(0); - expect(destroyMock).toHaveBeenCalledTimes(0); - expect(synthFastMock).toHaveBeenCalledTimes(2); + expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(0); + expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(0); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(2); }); test('generate snapshot', () => { @@ -269,8 +254,8 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(synthFastMock).toHaveBeenCalledTimes(1); - expect(synthFastMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledWith({ execCmd: ['node', 'xxxxx.integ-test1.js'], output: 'cdk-integ.out.xxxxx.integ-test1.js.snapshot', env: expect.objectContaining({ @@ -295,10 +280,10 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(deployMock).toHaveBeenCalledTimes(1); - expect(destroyMock).toHaveBeenCalledTimes(1); - expect(synthFastMock).toHaveBeenCalledTimes(1); - expect(deployMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.deploy).toHaveBeenCalledWith({ app: 'node xxxxx.integ-test1.js', requireApproval: 'never', pathMetadata: false, @@ -315,7 +300,7 @@ describe('IntegTest runIntegTests', () => { stacks: ['stack1'], output: 'cdk-integ.out.xxxxx.integ-test1.js.snapshot', }); - expect(destroyMock).toHaveBeenCalledWith({ + expect(cdkMock.mocks.destroy).toHaveBeenCalledWith({ app: 'node xxxxx.integ-test1.js', pathMetadata: false, assetMetadata: false, @@ -546,15 +531,15 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(deployMock).toHaveBeenCalledWith(expect.objectContaining({ + expect(cdkMock.mocks.deploy).toHaveBeenCalledWith(expect.objectContaining({ verbose, debug, })); - expect(deployMock).toHaveBeenCalledWith(expect.objectContaining({ + expect(cdkMock.mocks.deploy).toHaveBeenCalledWith(expect.objectContaining({ verbose, debug, })); - expect(destroyMock).toHaveBeenCalledWith(expect.objectContaining({ + expect(cdkMock.mocks.destroy).toHaveBeenCalledWith(expect.objectContaining({ verbose, debug, })); @@ -575,16 +560,16 @@ describe('IntegTest runIntegTests', () => { }); // THEN - expect(deployMock).toHaveBeenCalledTimes(2); - expect(destroyMock).toHaveBeenCalledTimes(1); - expect(synthFastMock).toHaveBeenCalledTimes(1); - expect(deployMock).toHaveBeenCalledWith(expect.objectContaining({ + expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(2); + expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.deploy).toHaveBeenCalledWith(expect.objectContaining({ app: 'node --no-warnings xxxxx.test-with-snapshot.js', })); - expect(synthFastMock).toHaveBeenCalledWith(expect.objectContaining({ + expect(cdkMock.mocks.synthFast).toHaveBeenCalledWith(expect.objectContaining({ execCmd: ['node', '--no-warnings', 'xxxxx.test-with-snapshot.js'], })); - expect(destroyMock).toHaveBeenCalledWith(expect.objectContaining({ + expect(cdkMock.mocks.destroy).toHaveBeenCalledWith(expect.objectContaining({ app: 'node --no-warnings xxxxx.test-with-snapshot.js', })); }); diff --git a/packages/@aws-cdk/integ-runner/test/runner/integ-test-suite.test.ts b/packages/@aws-cdk/integ-runner/test/runner/integ-test-suite.test.ts index 873f7d01e9426..8534f8bc1b71f 100644 --- a/packages/@aws-cdk/integ-runner/test/runner/integ-test-suite.test.ts +++ b/packages/@aws-cdk/integ-runner/test/runner/integ-test-suite.test.ts @@ -1,8 +1,7 @@ import * as path from 'path'; -import { ListOptions } from 'cdk-cli-wrapper'; import * as mockfs from 'mock-fs'; import { IntegTestSuite, LegacyIntegTestSuite } from '../../lib/runner/integ-test-suite'; -import { MockCdkProvider } from '../helpers'; +import { MockCdkMocks, MockCdkProvider } from '../helpers'; describe('Integration test cases', () => { const testsFile = '/tmp/foo/bar/does/not/exist/integ.json'; @@ -125,7 +124,7 @@ describe('Integration test cases', () => { describe('Legacy Integration test cases', () => { let cdkMock: MockCdkProvider; - let listMock: (options: ListOptions) => string; + let listMock: MockCdkMocks['list']; const testsFile = '/tmp/foo/bar/does/not/exist/integ.test.js'; beforeEach(() => { cdkMock = new MockCdkProvider({ directory: 'test/test-data' }); diff --git a/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts b/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts index ba1d7853164bb..89101796b966e 100644 --- a/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts +++ b/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts @@ -1,31 +1,24 @@ import * as child_process from 'child_process'; import * as path from 'path'; -import { SynthFastOptions, DestroyOptions, ListOptions, SynthOptions, DeployOptions } from 'cdk-cli-wrapper'; import * as fs from 'fs-extra'; import { IntegSnapshotRunner, IntegTest } from '../../lib/runner'; import { DiagnosticReason } from '../../lib/workers/common'; import { MockCdkProvider } from '../helpers'; let cdkMock: MockCdkProvider; -let synthMock: (options: SynthOptions) => void; -let synthFastMock: (options: SynthFastOptions) => void; -let deployMock: (options: DeployOptions) => void; -let listMock: (options: ListOptions) => string; -let destroyMock: (options: DestroyOptions) => void; + +const currentCwd = process.cwd(); +beforeAll(() => { + process.chdir(path.join(__dirname, '../..')); +}); +afterAll(() => { + process.chdir(currentCwd); +}); + beforeEach(() => { cdkMock = new MockCdkProvider({ directory: 'test/test-data' }); - listMock = jest.fn().mockImplementation(() => { - return 'stackabc'; - }); - synthMock = jest.fn().mockImplementation(); - deployMock = jest.fn().mockImplementation(); - destroyMock = jest.fn().mockImplementation(); - synthFastMock = jest.fn().mockImplementation(); - cdkMock.mockSynth(synthMock); - cdkMock.mockList(listMock); - cdkMock.mockDeploy(deployMock); - cdkMock.mockSynthFast(synthFastMock); - cdkMock.mockDestroy(destroyMock); + cdkMock.mockAll().list.mockImplementation(() => 'stackabc'); + jest.spyOn(child_process, 'spawnSync').mockImplementation(); jest.spyOn(process.stderr, 'write').mockImplementation(() => { return true; }); jest.spyOn(process.stdout, 'write').mockImplementation(() => { return true; }); @@ -44,83 +37,33 @@ afterEach(() => { describe('IntegTest runSnapshotTests', () => { test('with defaults no diff', () => { // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: 'test/test-data/xxxxx.test-with-snapshot.js', - discoveryRoot: 'test/test-data', - }), - integOutDir: 'test/test-data/xxxxx.test-with-snapshot.js.snapshot', - }); - const results = integTest.testSnapshot(); + const results = cdkMock.snapshotTest('xxxxx.test-with-snapshot.js', 'xxxxx.test-with-snapshot.js.snapshot'); // THEN - expect(synthFastMock).toHaveBeenCalledTimes(2); - expect(synthFastMock).toHaveBeenCalledWith({ - env: expect.objectContaining({ - CDK_INTEG_ACCOUNT: '12345678', - CDK_INTEG_REGION: 'test-region', - }), - execCmd: ['node', 'xxxxx.test-with-snapshot.js'], - output: 'xxxxx.test-with-snapshot.js.snapshot', - }); expect(results.diagnostics).toEqual([]); }); test('new stack in actual', () => { // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: 'test/test-data/xxxxx.test-with-snapshot.js', - discoveryRoot: 'test/test-data', - }), - }); - const results = integTest.testSnapshot(); + const results = cdkMock.snapshotTest('xxxxx.test-with-snapshot.js'); // THEN - expect(synthFastMock).toHaveBeenCalledTimes(2); - expect(synthFastMock).toHaveBeenCalledWith({ - env: expect.objectContaining({ - CDK_INTEG_ACCOUNT: '12345678', - CDK_INTEG_REGION: 'test-region', - }), - execCmd: ['node', 'xxxxx.test-with-snapshot.js'], - output: 'cdk-integ.out.xxxxx.test-with-snapshot.js.snapshot', - }); expect(results.diagnostics).toEqual(expect.arrayContaining([expect.objectContaining({ reason: DiagnosticReason.SNAPSHOT_FAILED, - testName: integTest.testName, + testName: 'xxxxx.test-with-snapshot', message: 'new-test-stack does not exist in snapshot, but does in actual', })])); }); test('with defaults and diff', () => { // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: 'test/test-data/xxxxx.test-with-snapshot.js', - discoveryRoot: 'test/test-data', - }), - integOutDir: 'test/test-data/xxxxx.test-with-snapshot-diff.js.snapshot', - }); - const results = integTest.testSnapshot(); + const results = cdkMock.snapshotTest('xxxxx.test-with-snapshot.js', 'xxxxx.test-with-snapshot-diff.js.snapshot'); // THEN - expect(synthFastMock).toHaveBeenCalledTimes(2); - expect(synthFastMock).toHaveBeenCalledWith({ - execCmd: ['node', 'xxxxx.test-with-snapshot.js'], - env: expect.objectContaining({ - CDK_INTEG_ACCOUNT: '12345678', - CDK_INTEG_REGION: 'test-region', - }), - output: 'xxxxx.test-with-snapshot-diff.js.snapshot', - }); expect(results.diagnostics).toEqual(expect.arrayContaining([ expect.objectContaining({ reason: DiagnosticReason.SNAPSHOT_FAILED, - testName: integTest.testName, + testName: 'xxxxx.test-with-snapshot', message: expect.stringContaining('foobar'), }), ])); @@ -138,152 +81,98 @@ describe('IntegTest runSnapshotTests', () => { test('dont diff new asset hashes', () => { // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: path.join(__dirname, '../test-data/xxxxx.test-with-new-assets-diff.js'), - discoveryRoot: 'test/test-data', - }), - integOutDir: 'test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot', - }); - const results = integTest.testSnapshot(); - expect(results.diagnostics).toEqual([]); + const results = cdkMock.snapshotTest('xxxxx.test-with-new-assets-diff.js', 'cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot'); // THEN - expect(synthFastMock).toHaveBeenCalledTimes(2); - expect(synthFastMock).toHaveBeenCalledWith({ - execCmd: ['node', 'xxxxx.test-with-new-assets-diff.js'], - env: expect.objectContaining({ - CDK_INTEG_ACCOUNT: '12345678', - CDK_INTEG_REGION: 'test-region', - }), - output: 'cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot', - }); + expect(results.diagnostics).toEqual([]); }); test('diff new asset hashes', () => { // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: path.join(__dirname, '../test-data/xxxxx.test-with-new-assets.js'), - discoveryRoot: 'test/test-data', - }), - integOutDir: 'test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot', - }); - const results = integTest.testSnapshot(); + const results = cdkMock.snapshotTest('xxxxx.test-with-new-assets.js', 'cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot'); // THEN expect(results.diagnostics).toEqual(expect.arrayContaining([expect.objectContaining({ reason: DiagnosticReason.SNAPSHOT_FAILED, - testName: integTest.testName, + testName: 'xxxxx.test-with-new-assets', message: expect.stringContaining('S3Key'), })])); }); - test('dont diff asset hashes', () => { - // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: path.join(__dirname, '../test-data/xxxxx.test-with-snapshot-assets-diff.js'), - discoveryRoot: 'test/test-data', - }), - integOutDir: 'test/test-data/xxxxx.test-with-snapshot-assets.js.snapshot', - }); - const results = integTest.testSnapshot(); - expect(results.diagnostics).toEqual([]); - - // THEN - expect(synthFastMock).toHaveBeenCalledTimes(2); - expect(synthFastMock).toHaveBeenCalledWith({ - execCmd: ['node', 'xxxxx.test-with-snapshot-assets-diff.js'], - env: expect.objectContaining({ - CDK_INTEG_ACCOUNT: '12345678', - CDK_INTEG_REGION: 'test-region', - }), - output: 'xxxxx.test-with-snapshot-assets.js.snapshot', - }); - }); + describe('Legacy parameter based assets ', () => { + test('diff asset hashes', () => { + // WHEN + const results = cdkMock.snapshotTest('xxxxx.test-with-snapshot-assets.js', 'xxxxx.test-with-snapshot-assets-diff.js.snapshot'); - test('determine test stack via pragma', () => { - // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: 'test/test-data/xxxxx.integ-test1.js', - discoveryRoot: 'test', - }), - integOutDir: 'does/not/exist', + // THEN + expect(results.diagnostics).toEqual(expect.arrayContaining([expect.objectContaining({ + reason: DiagnosticReason.SNAPSHOT_FAILED, + testName: 'xxxxx.test-with-snapshot-assets', + message: expect.stringContaining('Parameters'), + })])); }); - // THEN - expect(integTest.actualTests()).toEqual(expect.objectContaining({ - 'xxxxx.integ-test1': { - diffAssets: false, - stackUpdateWorkflow: true, - stacks: ['stack1'], - }, - })); - expect(listMock).toHaveBeenCalledTimes(0); - }); + test('dont diff asset hashes', () => { + // WHEN + const results = cdkMock.snapshotTest('xxxxx.test-with-snapshot-assets-diff.js', 'xxxxx.test-with-snapshot-assets.js.snapshot'); - test('get stacks from list, no pragma', async () => { - // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: 'test/test-data/xxxxx.integ-test2.js', - discoveryRoot: 'test', - }), - integOutDir: 'does/not/exist', - }); - - // THEN - expect(integTest.actualTests()).toEqual(expect.objectContaining({ - 'xxxxx.integ-test2': { - diffAssets: false, - stackUpdateWorkflow: true, - stacks: ['stackabc'], - }, - })); - expect(synthFastMock).toHaveBeenCalledTimes(1); - expect(synthFastMock).toHaveBeenCalledWith({ - execCmd: ['node', 'xxxxx.integ-test2.js'], - env: expect.objectContaining({ - CDK_INTEG_ACCOUNT: '12345678', - CDK_INTEG_REGION: 'test-region', - }), - output: '../../does/not/exist', + // THEN + expect(results.diagnostics).toEqual([]); }); }); - test('diff asset hashes', () => { - // WHEN - const integTest = new IntegSnapshotRunner({ - cdk: cdkMock.cdk, - test: new IntegTest({ - fileName: path.join(__dirname, '../test-data/xxxxx.test-with-snapshot-assets.js'), - discoveryRoot: 'test/test-data', - }), - integOutDir: 'test/test-data/xxxxx.test-with-snapshot-assets-diff.js.snapshot', + describe('Legacy Integ Tests', () => { + test('determine test stack via pragma', () => { + // WHEN + const integTest = new IntegSnapshotRunner({ + cdk: cdkMock.cdk, + test: new IntegTest({ + fileName: 'test/test-data/xxxxx.integ-test1.js', + discoveryRoot: 'test', + }), + integOutDir: 'does/not/exist', + }); + + // THEN + expect(integTest.actualTests()).toEqual(expect.objectContaining({ + 'xxxxx.integ-test1': { + diffAssets: false, + stackUpdateWorkflow: true, + stacks: ['stack1'], + }, + })); + expect(cdkMock.mocks.list).toHaveBeenCalledTimes(0); + }); + + test('get stacks from list, no pragma', async () => { + // WHEN + const integTest = new IntegSnapshotRunner({ + cdk: cdkMock.cdk, + test: new IntegTest({ + fileName: 'test/test-data/xxxxx.integ-test2.js', + discoveryRoot: 'test', + }), + integOutDir: 'does/not/exist', + }); + + // THEN + expect(integTest.actualTests()).toEqual(expect.objectContaining({ + 'xxxxx.integ-test2': { + diffAssets: false, + stackUpdateWorkflow: true, + stacks: ['stackabc'], + }, + })); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1); + expect(cdkMock.mocks.synthFast).toHaveBeenCalledWith({ + execCmd: ['node', 'xxxxx.integ-test2.js'], + env: expect.objectContaining({ + CDK_INTEG_ACCOUNT: '12345678', + CDK_INTEG_REGION: 'test-region', + }), + output: '../../does/not/exist', + }); }); - const results = integTest.testSnapshot(); - // THEN - expect(synthFastMock).toHaveBeenCalledTimes(2); - expect(synthFastMock).toHaveBeenCalledWith({ - execCmd: ['node', 'xxxxx.test-with-snapshot-assets.js'], - env: expect.objectContaining({ - CDK_INTEG_ACCOUNT: '12345678', - CDK_INTEG_REGION: 'test-region', - }), - output: 'xxxxx.test-with-snapshot-assets-diff.js.snapshot', - }); - expect(results.diagnostics).toEqual(expect.arrayContaining([expect.objectContaining({ - reason: DiagnosticReason.SNAPSHOT_FAILED, - testName: integTest.testName, - message: expect.stringContaining('Parameters'), - })])); }); }); From e31a2fad2624868edf9b5ca2b14b991418aa5c59 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Fri, 11 Nov 2022 14:37:50 +0000 Subject: [PATCH 2/8] feat(integ-runner): snapshots will now diff nested stack templates --- .../lib/runner/private/cloud-assembly.ts | 34 +- .../lib/runner/snapshot-test-runner.ts | 222 +++++----- .../integ-runner/lib/workers/common.ts | 5 + packages/@aws-cdk/integ-runner/package.json | 5 + .../@aws-cdk/integ-runner/test/cli.test.ts | 1 + .../@aws-cdk/integ-runner/test/helpers.ts | 1 + .../test/runner/snapshot-test-runner.test.ts | 15 + .../test/test-data/assets/code-asset/.keep | 0 ...efaultTestDeployAssert9F80D3B6.assets.json | 19 + ...aultTestDeployAssert9F80D3B6.template.json | 36 ++ .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 141 +++++++ .../test-stack.assets.json | 45 ++ .../test-stack.template.json | 115 ++++++ ...ststacknested140612C4.nested.template.json | 63 +++ .../tree.json | 387 ++++++++++++++++++ ...efaultTestDeployAssert9F80D3B6.assets.json | 19 + ...aultTestDeployAssert9F80D3B6.template.json | 36 ++ .../.keep | 0 .../cdk.out | 1 + .../integ.json | 12 + .../manifest.json | 141 +++++++ .../test-stack.assets.json | 45 ++ .../test-stack.template.json | 115 ++++++ ...ststacknested140612C4.nested.template.json | 60 +++ .../tree.json | 387 ++++++++++++++++++ .../test-data/xxxxx.test-with-nested-stack.ts | 32 ++ packages/cdk-assets/lib/asset-manifest.ts | 27 +- 29 files changed, 1873 insertions(+), 104 deletions(-) create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/assets/code-asset/.keep create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/test-stack.assets.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/test-stack.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/teststacknested140612C4.nested.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/asset.b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68/.keep create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/test-stack.assets.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/test-stack.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/teststacknested140612C4.nested.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts diff --git a/packages/@aws-cdk/integ-runner/lib/runner/private/cloud-assembly.ts b/packages/@aws-cdk/integ-runner/lib/runner/private/cloud-assembly.ts index 71a08392615db..9420f2113561a 100644 --- a/packages/@aws-cdk/integ-runner/lib/runner/private/cloud-assembly.ts +++ b/packages/@aws-cdk/integ-runner/lib/runner/private/cloud-assembly.ts @@ -78,6 +78,25 @@ export class AssemblyManifestReader { return stacks; } + /** + * Get the nested stacks for a given stack + * returns a map of artifactId to CloudFormation template + */ + public getNestedStacksForStack(stackId: string): Record { + const nestedTemplates: string[] = this.getAssetManifestsForStack(stackId).flatMap( + manifest => manifest.files + .filter(asset => asset.source.path?.endsWith('.nested.template.json')) + .map(asset => asset.source.path!), + ); + + const nestedStacks: Record = Object.fromEntries(nestedTemplates.map(templateFile => ([ + templateFile.split('.', 1)[0], + fs.readJSONSync(path.resolve(this.directory, templateFile)), + ]))); + + return nestedStacks; + } + /** * Write trace data to the assembly manifest metadata */ @@ -125,6 +144,19 @@ export class AssemblyManifestReader { return assets; } + /** + * Return a list of asset artifacts for a given stack + */ + public getAssetManifestsForStack(stackId: string): AssetManifest[] { + return Object.values(this.manifest.artifacts ?? {}) + .filter(artifact => + artifact.type === ArtifactType.ASSET_MANIFEST && (artifact.properties as AssetManifestProperties)?.file === `${stackId}.assets.json`) + .map(artifact => { + const fileName = (artifact.properties as AssetManifestProperties).file; + return AssetManifest.fromFile(path.join(this.directory, fileName)); + }); + } + /** * Get a list of assets from the assembly manifest */ @@ -153,7 +185,7 @@ export class AssemblyManifestReader { assetManifest.entries.forEach(entry => { if (entry.type === 'file') { const source = (entry as FileManifestEntry).source; - if (source.path && source.path.startsWith('asset.')) { + if (source.path && (source.path.startsWith('asset.') || source.path.endsWith('nested.template.json'))) { assets.push(entry as FileManifestEntry); } } else if (entry.type === 'docker-image') { diff --git a/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts b/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts index fd7ef514d51a0..c832d1a3f5437 100644 --- a/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts +++ b/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts @@ -6,6 +6,25 @@ import { Diagnostic, DiagnosticReason, DestructiveChange, SnapshotVerificationOp import { AssemblyManifestReader } from './private/cloud-assembly'; import { IntegRunnerOptions, IntegRunner, DEFAULT_SYNTH_OPTIONS } from './runner-base'; +interface SnapshotAssembly { + /** + * Map of stacks that are part of this assembly + */ + [key: string]: { + /** + * All templates for this stack, including nested stacks + */ + templates: { + [key: string]: any + }, + + /** + * List of asset Ids that are used by this assembly + */ + assets: string[] + } +} + /** * Runner for snapshot tests. This handles orchestrating * the validation of the integration test snapshots @@ -24,15 +43,7 @@ export class IntegSnapshotRunner extends IntegRunner { public testSnapshot(options: SnapshotVerificationOptions = {}): { diagnostics: Diagnostic[], destructiveChanges: DestructiveChange[] } { let doClean = true; try { - // read the existing snapshot - const expectedStacks = this.readAssembly(this.snapshotDir); - // only diff stacks that are part of the test case - const expectedStacksToDiff: Record = {}; - for (const [stackName, template] of Object.entries(expectedStacks)) { - if (this.expectedTestSuite?.stacks.includes(stackName)) { - expectedStacksToDiff[stackName] = template; - } - } + const expectedSnapshotAssembly = this.getSnapshotAssembly(this.snapshotDir, this.expectedTestSuite?.stacks); // synth the integration test // FIXME: ideally we should not need to run this again if @@ -52,18 +63,10 @@ export class IntegSnapshotRunner extends IntegRunner { }); // read the "actual" snapshot - const actualDir = this.cdkOutDir; - const actualStacks = this.readAssembly(actualDir); - // only diff stacks that are part of the test case - const actualStacksToDiff: Record = {}; - for (const [stackName, template] of Object.entries(actualStacks)) { - if (this.actualTestSuite.stacks.includes(stackName)) { - actualStacksToDiff[stackName] = template; - } - } + const actualSnapshotAssembly = this.getSnapshotAssembly(this.cdkOutDir, this.actualTestSuite.stacks); // diff the existing snapshot (expected) with the integration test (actual) - const diagnostics = this.diffAssembly(expectedStacksToDiff, actualStacksToDiff); + const diagnostics = this.diffAssembly(expectedSnapshotAssembly, actualSnapshotAssembly); if (diagnostics.diagnostics.length) { // Attach additional messages to the first diagnostic @@ -72,7 +75,7 @@ export class IntegSnapshotRunner extends IntegRunner { if (options.retain) { additionalMessages.push( `(Failure retained) Expected: ${path.relative(process.cwd(), this.snapshotDir)}`, - ` Actual: ${path.relative(process.cwd(), actualDir)}`, + ` Actual: ${path.relative(process.cwd(), this.cdkOutDir)}`, ), doClean = false; } @@ -107,6 +110,36 @@ export class IntegSnapshotRunner extends IntegRunner { } } + /** + * For a given cloud assembly return a collection of all templates + * that should be part of the snapshot and any required meta data. + * + * @param cloudAssemblyDir The directory of the cloud assembly to look for snapshots + * @param pickStacks Pick only these stacks from the cloud assembly + * @returns A SnapshotAssembly, the collection of all templates in this snapshot and required meta data + */ + private getSnapshotAssembly(cloudAssemblyDir: string, pickStacks: string[] = []): SnapshotAssembly { + const assembly = this.readAssembly(cloudAssemblyDir); + const stacks = assembly.stacks; + const snapshots: SnapshotAssembly = {}; + for (const [stackName, stackTemplate] of Object.entries(stacks)) { + if (pickStacks.includes(stackName)) { + const manifest = AssemblyManifestReader.fromPath(cloudAssemblyDir); + const assets = manifest.getAssetIdsForStack(stackName); + + snapshots[stackName] = { + templates: { + [stackName]: stackTemplate, + ...assembly.getNestedStacksForStack(stackName), + }, + assets, + }; + } + } + + return snapshots; + } + /** * For a given stack return all resource types that are allowed to be destroyed * as part of a stack update @@ -131,86 +164,94 @@ export class IntegSnapshotRunner extends IntegRunner { * @returns any diagnostics and any destructive changes */ private diffAssembly( - expected: Record, - actual: Record, + expected: SnapshotAssembly, + actual: SnapshotAssembly, ): { diagnostics: Diagnostic[], destructiveChanges: DestructiveChange[] } { const failures: Diagnostic[] = []; const destructiveChanges: DestructiveChange[] = []; // check if there is a CFN template in the current snapshot // that does not exist in the "actual" snapshot - for (const templateId of Object.keys(expected)) { - if (!actual.hasOwnProperty(templateId)) { - failures.push({ - testName: this.testName, - reason: DiagnosticReason.SNAPSHOT_FAILED, - message: `${templateId} exists in snapshot, but not in actual`, - }); + for (const [stackId, stack] of Object.entries(expected)) { + for (const templateId of Object.keys(stack.templates)) { + if (!actual[stackId]?.templates[templateId]) { + failures.push({ + testName: this.testName, + stackName: templateId, + reason: DiagnosticReason.SNAPSHOT_FAILED, + message: `${templateId} exists in snapshot, but not in actual`, + }); + } } } - for (const templateId of Object.keys(actual)) { + for (const [stackId, stack] of Object.entries(actual)) { + for (const templateId of Object.keys(stack.templates)) { // check if there is a CFN template in the "actual" snapshot // that does not exist in the current snapshot - if (!expected.hasOwnProperty(templateId)) { - failures.push({ - testName: this.testName, - reason: DiagnosticReason.SNAPSHOT_FAILED, - message: `${templateId} does not exist in snapshot, but does in actual`, - }); - continue; - } else { - let actualTemplate = actual[templateId]; - let expectedTemplate = expected[templateId]; - const allowedDestroyTypes = this.getAllowedDestroyTypesForStack(templateId) ?? []; - - // if we are not verifying asset hashes then remove the specific - // asset hashes from the templates so they are not part of the diff - // comparison - if (!this.actualTestSuite.getOptionsForStack(templateId)?.diffAssets) { - actualTemplate = this.canonicalizeTemplate(actualTemplate, templateId, this.cdkOutDir); - expectedTemplate = this.canonicalizeTemplate(expectedTemplate, templateId, this.snapshotDir); - } - const templateDiff = diffTemplate(expectedTemplate, actualTemplate); - if (!templateDiff.isEmpty) { - // go through all the resource differences and check for any - // "destructive" changes - templateDiff.resources.forEachDifference((logicalId: string, change: ResourceDifference) => { + if (!expected[stackId]?.templates[templateId]) { + failures.push({ + testName: this.testName, + stackName: templateId, + reason: DiagnosticReason.SNAPSHOT_FAILED, + message: `${templateId} does not exist in snapshot, but does in actual`, + }); + continue; + } else { + let actualTemplate = actual[stackId].templates[templateId]; + let expectedTemplate = expected[stackId].templates[templateId]; + + // if we are not verifying asset hashes then remove the specific + // asset hashes from the templates so they are not part of the diff + // comparison + if (!this.actualTestSuite.getOptionsForStack(stackId)?.diffAssets) { + actualTemplate = this.canonicalizeTemplate(actualTemplate, actual[stackId].assets); + expectedTemplate = this.canonicalizeTemplate(expectedTemplate, expected[stackId].assets); + } + const templateDiff = diffTemplate(expectedTemplate, actualTemplate); + if (!templateDiff.isEmpty) { + const allowedDestroyTypes = this.getAllowedDestroyTypesForStack(stackId) ?? []; + + // go through all the resource differences and check for any + // "destructive" changes + templateDiff.resources.forEachDifference((logicalId: string, change: ResourceDifference) => { // if the change is a removal it will not show up as a 'changeImpact' // so need to check for it separately, unless it is a resourceType that // has been "allowed" to be destroyed - const resourceType = change.oldValue?.Type ?? change.newValue?.Type; - if (resourceType && allowedDestroyTypes.includes(resourceType)) { - return; - } - if (change.isRemoval) { - destructiveChanges.push({ - impact: ResourceImpact.WILL_DESTROY, - logicalId, - stackName: templateId, - }); - } else { - switch (change.changeImpact) { - case ResourceImpact.MAY_REPLACE: - case ResourceImpact.WILL_ORPHAN: - case ResourceImpact.WILL_DESTROY: - case ResourceImpact.WILL_REPLACE: - destructiveChanges.push({ - impact: change.changeImpact, - logicalId, - stackName: templateId, - }); - break; + const resourceType = change.oldValue?.Type ?? change.newValue?.Type; + if (resourceType && allowedDestroyTypes.includes(resourceType)) { + return; } - } - }); - const writable = new StringWritable({}); - formatDifferences(writable, templateDiff); - failures.push({ - reason: DiagnosticReason.SNAPSHOT_FAILED, - message: writable.data, - testName: this.testName, - }); + if (change.isRemoval) { + destructiveChanges.push({ + impact: ResourceImpact.WILL_DESTROY, + logicalId, + stackName: templateId, + }); + } else { + switch (change.changeImpact) { + case ResourceImpact.MAY_REPLACE: + case ResourceImpact.WILL_ORPHAN: + case ResourceImpact.WILL_DESTROY: + case ResourceImpact.WILL_REPLACE: + destructiveChanges.push({ + impact: change.changeImpact, + logicalId, + stackName: templateId, + }); + break; + } + } + }); + const writable = new StringWritable({}); + formatDifferences(writable, templateDiff); + failures.push({ + reason: DiagnosticReason.SNAPSHOT_FAILED, + message: writable.data, + stackName: templateId, + testName: this.testName, + }); + } } } } @@ -221,11 +262,8 @@ export class IntegSnapshotRunner extends IntegRunner { }; } - private readAssembly(dir: string): Record { - const assembly = AssemblyManifestReader.fromPath(dir); - const stacks = assembly.stacks; - - return stacks; + private readAssembly(dir: string): AssemblyManifestReader { + return AssemblyManifestReader.fromPath(dir); } /** @@ -234,7 +272,7 @@ export class IntegSnapshotRunner extends IntegRunner { * This makes it possible to compare templates if all that's different between * them is the hashes of the asset values. */ - private canonicalizeTemplate(template: any, stackName: string, manifestDir: string): any { + private canonicalizeTemplate(template: any, assets: string[]): any { const assetsSeen = new Set(); const stringSubstitutions = new Array<[RegExp, string]>(); @@ -262,8 +300,6 @@ export class IntegSnapshotRunner extends IntegRunner { // find assets defined in the asset manifest try { - const manifest = AssemblyManifestReader.fromPath(manifestDir); - const assets = manifest.getAssetIdsForStack(stackName); assets.forEach(asset => { if (!assetsSeen.has(asset)) { assetsSeen.add(asset); diff --git a/packages/@aws-cdk/integ-runner/lib/workers/common.ts b/packages/@aws-cdk/integ-runner/lib/workers/common.ts index 7f49cb73b864c..fc8babd7a05a9 100644 --- a/packages/@aws-cdk/integ-runner/lib/workers/common.ts +++ b/packages/@aws-cdk/integ-runner/lib/workers/common.ts @@ -221,6 +221,11 @@ export interface Diagnostic { */ readonly testName: string; + /** + * The name of the stack + */ + readonly stackName: string; + /** * The diagnostic message */ diff --git a/packages/@aws-cdk/integ-runner/package.json b/packages/@aws-cdk/integ-runner/package.json index 2f9199680f427..809b2a923cc9d 100644 --- a/packages/@aws-cdk/integ-runner/package.json +++ b/packages/@aws-cdk/integ-runner/package.json @@ -52,7 +52,12 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/cdk-build-tools": "0.0.0", + "@aws-cdk/core": "0.0.0", + "@aws-cdk/aws-lambda": "0.0.0", + "@aws-cdk/aws-sns": "0.0.0", + "@aws-cdk/integ-tests": "0.0.0", "@types/mock-fs": "^4.13.1", + "constructs": "^10.0.0", "mock-fs": "^4.14.0", "@aws-cdk/pkglint": "0.0.0", "@types/fs-extra": "^8.1.2", diff --git a/packages/@aws-cdk/integ-runner/test/cli.test.ts b/packages/@aws-cdk/integ-runner/test/cli.test.ts index bf61aa7633aac..95d53dd58b706 100644 --- a/packages/@aws-cdk/integ-runner/test/cli.test.ts +++ b/packages/@aws-cdk/integ-runner/test/cli.test.ts @@ -32,6 +32,7 @@ describe('CLI', () => { [ 'xxxxx.integ-test1.js', 'xxxxx.integ-test2.js', + 'xxxxx.test-with-nested-stack.js', 'xxxxx.test-with-new-assets-diff.js', 'xxxxx.test-with-new-assets.js', 'xxxxx.test-with-snapshot-assets-diff.js', diff --git a/packages/@aws-cdk/integ-runner/test/helpers.ts b/packages/@aws-cdk/integ-runner/test/helpers.ts index 238bb77e1695d..6f60379a8f7b6 100644 --- a/packages/@aws-cdk/integ-runner/test/helpers.ts +++ b/packages/@aws-cdk/integ-runner/test/helpers.ts @@ -68,6 +68,7 @@ export class MockCdkProvider { }), integOutDir: actualSnapshot ? 'test/test-data/' + actualSnapshot : undefined, }); + integTest.actualTests(); const results = integTest.testSnapshot(); // THEN diff --git a/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts b/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts index 89101796b966e..958380e5df5ef 100644 --- a/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts +++ b/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts @@ -99,6 +99,21 @@ describe('IntegTest runSnapshotTests', () => { })])); }); + describe('Nested Stacks', () => { + test('it will compare snapshots for nested stacks', () => { + // WHEN + const results = cdkMock.snapshotTest('xxxxx.test-with-nested-stack.js', 'xxxxx.test-with-nested-stack-changed.js.snapshot'); + + // THEN + expect(results.diagnostics).toEqual(expect.arrayContaining([expect.objectContaining({ + reason: DiagnosticReason.SNAPSHOT_FAILED, + testName: 'xxxxx.test-with-nested-stack', + stackName: expect.stringContaining('teststacknested'), + message: expect.stringContaining('AWS::SNS::Topic'), + })])); + }); + }); + describe('Legacy parameter based assets ', () => { test('diff asset hashes', () => { // WHEN diff --git a/packages/@aws-cdk/integ-runner/test/test-data/assets/code-asset/.keep b/packages/@aws-cdk/integ-runner/test/test-data/assets/code-asset/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json new file mode 100644 index 0000000000000..91488886727c6 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/cdk.out b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/integ.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/integ.json new file mode 100644 index 0000000000000..56b2c82cb6d9e --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "21.0.0", + "testCases": { + "TestWithNestedStack/DefaultTest": { + "stacks": [ + "test-stack" + ], + "assertionStack": "TestWithNestedStack/DefaultTest/DeployAssert", + "assertionStackName": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/manifest.json new file mode 100644 index 0000000000000..e45aa1d70111d --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/manifest.json @@ -0,0 +1,141 @@ +{ + "version": "21.0.0", + "artifacts": { + "test-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "test-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "test-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "test-stack.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "test-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "test-stack.assets" + ], + "metadata": { + "/test-stack/MyFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunctionServiceRole3C357FF2" + } + ], + "/test-stack/MyFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunction3BAA72D1" + } + ], + "/test-stack/nested/MyTopic/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyTopic86869434" + } + ], + "/test-stack/nested/MyNestedFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyNestedFunctionServiceRole56B518B8" + } + ], + "/test-stack/nested/MyNestedFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyNestedFunctionA0269B76" + } + ], + "/test-stack/nested.NestedStack/nested.NestedStackResource": [ + { + "type": "aws:cdk:logicalId", + "data": "nestedNestedStacknestedNestedStackResource3DD143BF" + } + ], + "/test-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/test-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "test-stack" + }, + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets" + ], + "metadata": { + "/TestWithNestedStack/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/TestWithNestedStack/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "TestWithNestedStack/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/test-stack.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/test-stack.assets.json new file mode 100644 index 0000000000000..06cae34119b66 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/test-stack.assets.json @@ -0,0 +1,45 @@ +{ + "version": "21.0.0", + "files": { + "CHANGED_ASSET_HASH": { + "source": { + "path": "asset.CHANGED_ASSET_HASH", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "CHANGED_ASSET_HASH.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234": { + "source": { + "path": "teststacknested140612C4.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381": { + "source": { + "path": "test-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/test-stack.template.json new file mode 100644 index 0000000000000..7418c1ab361ac --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/test-stack.template.json @@ -0,0 +1,115 @@ +{ + "Resources": { + "MyFunctionServiceRole3C357FF2": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "MyFunction3BAA72D1": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionServiceRole3C357FF2", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyFunctionServiceRole3C357FF2" + ] + }, + "nestedNestedStacknestedNestedStackResource3DD143BF": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json" + ] + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/teststacknested140612C4.nested.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/teststacknested140612C4.nested.template.json new file mode 100644 index 0000000000000..0e7b67cd27fe5 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/teststacknested140612C4.nested.template.json @@ -0,0 +1,63 @@ +{ + "Resources": { + "MyTopic86869434": { + "Type": "AWS::SNS::Topic", + "Properties": { + "DisplayName": "MyTopic" + } + }, + "MyNestedFunctionServiceRole56B518B8": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "MyNestedFunctionA0269B76": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "CHANGED_ASSET_HASH.zip" + }, + "Role": { + "Fn::GetAtt": [ + "MyNestedFunctionServiceRole56B518B8", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyNestedFunctionServiceRole56B518B8" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/tree.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/tree.json new file mode 100644 index 0000000000000..8597834c8351d --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack-changed.js.snapshot/tree.json @@ -0,0 +1,387 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "test-stack": { + "id": "test-stack", + "path": "test-stack", + "children": { + "MyFunction": { + "id": "MyFunction", + "path": "test-stack/MyFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "test-stack/MyFunction/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "test-stack/MyFunction/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/MyFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/MyFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "MyFunctionServiceRole3C357FF2", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "nested": { + "id": "nested", + "path": "test-stack/nested", + "children": { + "MyTopic": { + "id": "MyTopic", + "path": "test-stack/nested/MyTopic", + "children": { + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyTopic/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SNS::Topic", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-sns.CfnTopic", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-sns.Topic", + "version": "0.0.0" + } + }, + "MyNestedFunction": { + "id": "MyNestedFunction", + "path": "test-stack/nested/MyNestedFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "test-stack/nested/MyNestedFunction/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "test-stack/nested/MyNestedFunction/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyNestedFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "test-stack/nested/MyNestedFunction/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "test-stack/nested/MyNestedFunction/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "test-stack/nested/MyNestedFunction/Code/AssetBucket", + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3-assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyNestedFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68.zip" + }, + "role": { + "Fn::GetAtt": [ + "MyNestedFunctionServiceRole56B518B8", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.NestedStack", + "version": "0.0.0" + } + }, + "nested.NestedStack": { + "id": "nested.NestedStack", + "path": "test-stack/nested.NestedStack", + "children": { + "nested.NestedStackResource": { + "id": "nested.NestedStackResource", + "path": "test-stack/nested.NestedStack/nested.NestedStackResource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFormation::Stack", + "aws:cdk:cloudformation:props": { + "templateUrl": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CfnStack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "test-stack/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "test-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "TestWithNestedStack": { + "id": "TestWithNestedStack", + "path": "TestWithNestedStack", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "TestWithNestedStack/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "TestWithNestedStack/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "TestWithNestedStack/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "TestWithNestedStack/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "TestWithNestedStack/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json new file mode 100644 index 0000000000000..91488886727c6 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/asset.b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68/.keep b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/asset.b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68/.keep new file mode 100644 index 0000000000000..e69de29bb2d1d diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/cdk.out b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/integ.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/integ.json new file mode 100644 index 0000000000000..56b2c82cb6d9e --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/integ.json @@ -0,0 +1,12 @@ +{ + "version": "21.0.0", + "testCases": { + "TestWithNestedStack/DefaultTest": { + "stacks": [ + "test-stack" + ], + "assertionStack": "TestWithNestedStack/DefaultTest/DeployAssert", + "assertionStackName": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/manifest.json new file mode 100644 index 0000000000000..e45aa1d70111d --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/manifest.json @@ -0,0 +1,141 @@ +{ + "version": "21.0.0", + "artifacts": { + "test-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "test-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "test-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "test-stack.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "test-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "test-stack.assets" + ], + "metadata": { + "/test-stack/MyFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunctionServiceRole3C357FF2" + } + ], + "/test-stack/MyFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunction3BAA72D1" + } + ], + "/test-stack/nested/MyTopic/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyTopic86869434" + } + ], + "/test-stack/nested/MyNestedFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyNestedFunctionServiceRole56B518B8" + } + ], + "/test-stack/nested/MyNestedFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyNestedFunctionA0269B76" + } + ], + "/test-stack/nested.NestedStack/nested.NestedStackResource": [ + { + "type": "aws:cdk:logicalId", + "data": "nestedNestedStacknestedNestedStackResource3DD143BF" + } + ], + "/test-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/test-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "test-stack" + }, + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets" + ], + "metadata": { + "/TestWithNestedStack/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/TestWithNestedStack/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "TestWithNestedStack/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/test-stack.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/test-stack.assets.json new file mode 100644 index 0000000000000..9232e135ecce2 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/test-stack.assets.json @@ -0,0 +1,45 @@ +{ + "version": "21.0.0", + "files": { + "b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68": { + "source": { + "path": "asset.b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234": { + "source": { + "path": "teststacknested140612C4.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381": { + "source": { + "path": "test-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/test-stack.template.json new file mode 100644 index 0000000000000..7418c1ab361ac --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/test-stack.template.json @@ -0,0 +1,115 @@ +{ + "Resources": { + "MyFunctionServiceRole3C357FF2": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "MyFunction3BAA72D1": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionServiceRole3C357FF2", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyFunctionServiceRole3C357FF2" + ] + }, + "nestedNestedStacknestedNestedStackResource3DD143BF": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json" + ] + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/teststacknested140612C4.nested.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/teststacknested140612C4.nested.template.json new file mode 100644 index 0000000000000..68c6227f90d58 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/teststacknested140612C4.nested.template.json @@ -0,0 +1,60 @@ +{ + "Resources": { + "MyTopic86869434": { + "Type": "AWS::SNS::Topic" + }, + "MyNestedFunctionServiceRole56B518B8": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "MyNestedFunctionA0269B76": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68.zip" + }, + "Role": { + "Fn::GetAtt": [ + "MyNestedFunctionServiceRole56B518B8", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyNestedFunctionServiceRole56B518B8" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/tree.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/tree.json new file mode 100644 index 0000000000000..8597834c8351d --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.js.snapshot/tree.json @@ -0,0 +1,387 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "test-stack": { + "id": "test-stack", + "path": "test-stack", + "children": { + "MyFunction": { + "id": "MyFunction", + "path": "test-stack/MyFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "test-stack/MyFunction/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "test-stack/MyFunction/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/MyFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/MyFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "MyFunctionServiceRole3C357FF2", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "nested": { + "id": "nested", + "path": "test-stack/nested", + "children": { + "MyTopic": { + "id": "MyTopic", + "path": "test-stack/nested/MyTopic", + "children": { + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyTopic/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SNS::Topic", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-sns.CfnTopic", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-sns.Topic", + "version": "0.0.0" + } + }, + "MyNestedFunction": { + "id": "MyNestedFunction", + "path": "test-stack/nested/MyNestedFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "test-stack/nested/MyNestedFunction/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "test-stack/nested/MyNestedFunction/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyNestedFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "test-stack/nested/MyNestedFunction/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "test-stack/nested/MyNestedFunction/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "test-stack/nested/MyNestedFunction/Code/AssetBucket", + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3-assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyNestedFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68.zip" + }, + "role": { + "Fn::GetAtt": [ + "MyNestedFunctionServiceRole56B518B8", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.NestedStack", + "version": "0.0.0" + } + }, + "nested.NestedStack": { + "id": "nested.NestedStack", + "path": "test-stack/nested.NestedStack", + "children": { + "nested.NestedStackResource": { + "id": "nested.NestedStackResource", + "path": "test-stack/nested.NestedStack/nested.NestedStackResource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFormation::Stack", + "aws:cdk:cloudformation:props": { + "templateUrl": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CfnStack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "test-stack/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "test-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "TestWithNestedStack": { + "id": "TestWithNestedStack", + "path": "TestWithNestedStack", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "TestWithNestedStack/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "TestWithNestedStack/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "TestWithNestedStack/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "TestWithNestedStack/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "TestWithNestedStack/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts new file mode 100644 index 0000000000000..b9e8e8dc39be4 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts @@ -0,0 +1,32 @@ +/** + * This is NOT a real integ test! + * It is used to test functionality of the integ-runner. + */ +import * as lambda from '@aws-cdk/aws-lambda'; +import * as sns from '@aws-cdk/aws-sns'; +import * as cdk from '@aws-cdk/core'; +import * as integ from '@aws-cdk/integ-tests'; + +const app = new cdk.App(); + +const stack = new cdk.Stack(app, 'test-stack'); +new lambda.Function(stack, 'MyFunction', { + code: new lambda.InlineCode('foo'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_14_X, +}); + +const nestedStack = new cdk.NestedStack(stack, 'nested', {}); +new sns.Topic(nestedStack, 'MyTopic'); +new lambda.Function(nestedStack, 'MyNestedFunction', { + code: lambda.Code.fromAsset('assets/code-asset'), + handler: 'index.handler', + runtime: lambda.Runtime.NODEJS_14_X, +}); + + +new integ.IntegTest(app, 'TestWithNestedStack', { + testCases: [stack], +}); + +app.synth(); \ No newline at end of file diff --git a/packages/cdk-assets/lib/asset-manifest.ts b/packages/cdk-assets/lib/asset-manifest.ts index 1e4f240212042..bb5d468085823 100644 --- a/packages/cdk-assets/lib/asset-manifest.ts +++ b/packages/cdk-assets/lib/asset-manifest.ts @@ -113,20 +113,27 @@ export class AssetManifest { ...makeEntries(this.manifest.files || {}, FileManifestEntry), ...makeEntries(this.manifest.dockerImages || {}, DockerImageManifestEntry), ]; + } - function makeEntries( - assets: Record }>, - ctor: new (id: DestinationIdentifier, source: A, destination: B) => C): C[] { + /** + * List of assets, splat out to destinations + */ + public get files(): FileManifestEntry[] { + return makeEntries(this.manifest.files || {}, FileManifestEntry); + } +} - const ret = new Array(); - for (const [assetId, asset] of Object.entries(assets)) { - for (const [destId, destination] of Object.entries(asset.destinations)) { - ret.push(new ctor(new DestinationIdentifier(assetId, destId), asset.source, destination)); - } - } - return ret; +function makeEntries( + assets: Record }>, + ctor: new (id: DestinationIdentifier, source: A, destination: B) => C): C[] { + + const ret = new Array(); + for (const [assetId, asset] of Object.entries(assets)) { + for (const [destId, destination] of Object.entries(asset.destinations)) { + ret.push(new ctor(new DestinationIdentifier(assetId, destId), asset.source, destination)); } } + return ret; } type AssetType = 'files' | 'dockerImages'; From f8bb68850ec047207d476f137ebedb1d3bcff28a Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Wed, 9 Nov 2022 14:16:16 +0000 Subject: [PATCH 3/8] fix(integ-runner): asset hashes of nested stack templates are not ignored --- .../lib/runner/snapshot-test-runner.ts | 6 +- .../integ-runner/lib/workers/common.ts | 5 + .../test/runner/snapshot-test-runner.test.ts | 24 ++ ...StackResourceA7AEBA6B.nested.template.json | 1 + .../test-stack.assets.json | 13 + .../test-stack.template.json | 15 +- ...StackResourceA7AEBA6B.nested.template.json | 1 + .../test-stack.assets.json | 13 + .../test-stack.template.json | 6 + ...efaultTestDeployAssert9F80D3B6.assets.json | 19 + ...aultTestDeployAssert9F80D3B6.template.json | 36 ++ .../cdk.out | 1 + .../integ.json | 11 + .../manifest.json | 141 +++++++ .../test-stack.assets.json | 45 ++ .../test-stack.template.json | 115 ++++++ ...ststacknested140612C4.nested.template.json | 63 +++ .../tree.json | 387 ++++++++++++++++++ .../xxxxx.test-with-asset-in-nested-stack.ts | 1 + ...StackResourceA7AEBA6B.nested.template.json | 1 + .../test-stack.assets.json | 13 + .../test-stack.template.json | 6 + ...StackResourceA7AEBA6B.nested.template.json | 1 + .../test-stack.assets.json | 13 + .../test-stack.template.json | 6 + 25 files changed, 935 insertions(+), 8 deletions(-) create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/cdk.out create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/integ.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/manifest.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/test-stack.assets.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/test-stack.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/teststacknested140612C4.nested.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/tree.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.ts create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json create mode 100644 packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json diff --git a/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts b/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts index c832d1a3f5437..7d42ee8e8f712 100644 --- a/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts +++ b/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts @@ -198,13 +198,16 @@ export class IntegSnapshotRunner extends IntegRunner { }); continue; } else { + const config = { + diffAssets: this.actualTestSuite.getOptionsForStack(stackId)?.diffAssets, + }; let actualTemplate = actual[stackId].templates[templateId]; let expectedTemplate = expected[stackId].templates[templateId]; // if we are not verifying asset hashes then remove the specific // asset hashes from the templates so they are not part of the diff // comparison - if (!this.actualTestSuite.getOptionsForStack(stackId)?.diffAssets) { + if (!config.diffAssets) { actualTemplate = this.canonicalizeTemplate(actualTemplate, actual[stackId].assets); expectedTemplate = this.canonicalizeTemplate(expectedTemplate, expected[stackId].assets); } @@ -250,6 +253,7 @@ export class IntegSnapshotRunner extends IntegRunner { message: writable.data, stackName: templateId, testName: this.testName, + config, }); } } diff --git a/packages/@aws-cdk/integ-runner/lib/workers/common.ts b/packages/@aws-cdk/integ-runner/lib/workers/common.ts index fc8babd7a05a9..8a91212226548 100644 --- a/packages/@aws-cdk/integ-runner/lib/workers/common.ts +++ b/packages/@aws-cdk/integ-runner/lib/workers/common.ts @@ -245,6 +245,11 @@ export interface Diagnostic { * Additional messages to print */ readonly additionalMessages?: string[]; + + /** + * Relevant config options that were used for the integ test + */ + readonly config?: Record; } export function printSummary(total: number, failed: number): void { diff --git a/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts b/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts index 958380e5df5ef..0e425f3ca1bfb 100644 --- a/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts +++ b/packages/@aws-cdk/integ-runner/test/runner/snapshot-test-runner.test.ts @@ -65,6 +65,7 @@ describe('IntegTest runSnapshotTests', () => { reason: DiagnosticReason.SNAPSHOT_FAILED, testName: 'xxxxx.test-with-snapshot', message: expect.stringContaining('foobar'), + config: { diffAssets: true }, }), ])); expect(results.destructiveChanges).not.toEqual([{ @@ -96,6 +97,13 @@ describe('IntegTest runSnapshotTests', () => { reason: DiagnosticReason.SNAPSHOT_FAILED, testName: 'xxxxx.test-with-new-assets', message: expect.stringContaining('S3Key'), + config: { diffAssets: true }, + }), + expect.objectContaining({ + reason: DiagnosticReason.SNAPSHOT_FAILED, + testName: 'xxxxx.test-with-new-assets', + message: expect.stringContaining('TemplateURL'), + config: { diffAssets: true }, })])); }); @@ -110,6 +118,21 @@ describe('IntegTest runSnapshotTests', () => { testName: 'xxxxx.test-with-nested-stack', stackName: expect.stringContaining('teststacknested'), message: expect.stringContaining('AWS::SNS::Topic'), + config: { diffAssets: false }, + })])); + }); + + test('it will diff assets for nested stacks', () => { + // WHEN + const results = cdkMock.snapshotTest('xxxxx.test-with-nested-stack.js', 'xxxxx.test-with-asset-in-nested-stack.js.snapshot'); + + // THEN + expect(results.diagnostics).toEqual(expect.arrayContaining([expect.objectContaining({ + reason: DiagnosticReason.SNAPSHOT_FAILED, + testName: 'xxxxx.test-with-nested-stack', + stackName: expect.stringContaining('teststacknested'), + message: expect.stringContaining('S3Key'), + config: { diffAssets: true }, })])); }); }); @@ -124,6 +147,7 @@ describe('IntegTest runSnapshotTests', () => { reason: DiagnosticReason.SNAPSHOT_FAILED, testName: 'xxxxx.test-with-snapshot-assets', message: expect.stringContaining('Parameters'), + config: { diffAssets: true }, })])); }); diff --git a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json new file mode 100644 index 0000000000000..0967ef424bce6 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json @@ -0,0 +1 @@ +{} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.assets.json index 04bcd2f5c1a4a..fce044c483fbb 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.assets.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.assets.json @@ -26,6 +26,19 @@ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } + }, + "DIFFERENT_NESTED_STACK_HASH": { + "source": { + "path": "SomeNestedStackResourceA7AEBA6B.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "DIFFERENT_NESTED_STACK_HASH.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } } }, "dockerImages": {} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.template.json index 2beb6ac288dd2..8cd369391cf55 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.template.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.template.json @@ -38,17 +38,18 @@ "S3Key": "be270bbdebe0851c887569796e3997437cca54ce86893ed94788500448e92825.zip" }, "Role": { - "Fn::GetAtt": [ - "MyFunction1ServiceRole9852B06B", - "Arn" - ] + "Fn::GetAtt": ["MyFunction1ServiceRole9852B06B", "Arn"] }, "Handler": "index.handler", "Runtime": "nodejs14.x" }, - "DependsOn": [ - "MyFunction1ServiceRole9852B06B" - ] + "DependsOn": ["MyFunction1ServiceRole9852B06B"] + }, + "SomeNestedStackResourceA7AEBA6B": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": "https://s3.unknown-region.amazonaws.com/cdk-hnb659fds-assets-unknown-account-unknown-region/DIFFERENT_NESTED_STACK_HASH.json" + } } } } diff --git a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json new file mode 100644 index 0000000000000..0967ef424bce6 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json @@ -0,0 +1 @@ +{} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/test-stack.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/test-stack.assets.json index 9fce39f0cb708..0dd89136db1b9 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/test-stack.assets.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/test-stack.assets.json @@ -26,6 +26,19 @@ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } + }, + "6f980d09d47a00a7d5001feeb3994d1909bc5294e309d69bd4fbc815622f6fa9": { + "source": { + "path": "SomeNestedStackResourceA7AEBA6B.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "6f980d09d47a00a7d5001feeb3994d1909bc5294e309d69bd4fbc815622f6fa9.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } } }, "dockerImages": {} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/test-stack.template.json index fe60c3f20c5c3..8abdf236198f1 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/test-stack.template.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/cdk-integ.out.xxxxx.test-with-new-assets.js.snapshot/test-stack.template.json @@ -49,6 +49,12 @@ "DependsOn": [ "MyFunction1ServiceRole9852B06B" ] + }, + "SomeNestedStackResourceA7AEBA6B": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": "https://s3.unknown-region.amazonaws.com/cdk-hnb659fds-assets-unknown-account-unknown-region/6f980d09d47a00a7d5001feeb3994d1909bc5294e309d69bd4fbc815622f6fa9.json" + } } } } diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json new file mode 100644 index 0000000000000..91488886727c6 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json @@ -0,0 +1,19 @@ +{ + "version": "21.0.0", + "files": { + "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22": { + "source": { + "path": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json new file mode 100644 index 0000000000000..ad9d0fb73d1dd --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json @@ -0,0 +1,36 @@ +{ + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/cdk.out b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/cdk.out new file mode 100644 index 0000000000000..8ecc185e9dbee --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/cdk.out @@ -0,0 +1 @@ +{"version":"21.0.0"} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/integ.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/integ.json new file mode 100644 index 0000000000000..0e800e1a3fc32 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/integ.json @@ -0,0 +1,11 @@ +{ + "version": "21.0.0", + "testCases": { + "TestWithNestedStack/DefaultTest": { + "stacks": ["test-stack"], + "diffAssets": true, + "assertionStack": "TestWithNestedStack/DefaultTest/DeployAssert", + "assertionStackName": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6" + } + } +} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/manifest.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/manifest.json new file mode 100644 index 0000000000000..e45aa1d70111d --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/manifest.json @@ -0,0 +1,141 @@ +{ + "version": "21.0.0", + "artifacts": { + "test-stack.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "test-stack.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "test-stack": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "test-stack.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "test-stack.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "test-stack.assets" + ], + "metadata": { + "/test-stack/MyFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunctionServiceRole3C357FF2" + } + ], + "/test-stack/MyFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyFunction3BAA72D1" + } + ], + "/test-stack/nested/MyTopic/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyTopic86869434" + } + ], + "/test-stack/nested/MyNestedFunction/ServiceRole/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyNestedFunctionServiceRole56B518B8" + } + ], + "/test-stack/nested/MyNestedFunction/Resource": [ + { + "type": "aws:cdk:logicalId", + "data": "MyNestedFunctionA0269B76" + } + ], + "/test-stack/nested.NestedStack/nested.NestedStackResource": [ + { + "type": "aws:cdk:logicalId", + "data": "nestedNestedStacknestedNestedStackResource3DD143BF" + } + ], + "/test-stack/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/test-stack/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "test-stack" + }, + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets": { + "type": "cdk:asset-manifest", + "properties": { + "file": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6": { + "type": "aws:cloudformation:stack", + "environment": "aws://unknown-account/unknown-region", + "properties": { + "templateFile": "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.template.json", + "validateOnSynth": false, + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}", + "cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}", + "stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/21fbb51d7b23f6a6c262b46a9caee79d744a3ac019fd45422d988b96d44b2a22.json", + "requiresBootstrapStackVersion": 6, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version", + "additionalDependencies": [ + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets" + ], + "lookupRole": { + "arn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-lookup-role-${AWS::AccountId}-${AWS::Region}", + "requiresBootstrapStackVersion": 8, + "bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version" + } + }, + "dependencies": [ + "TestWithNestedStackDefaultTestDeployAssert9F80D3B6.assets" + ], + "metadata": { + "/TestWithNestedStack/DefaultTest/DeployAssert/BootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "BootstrapVersion" + } + ], + "/TestWithNestedStack/DefaultTest/DeployAssert/CheckBootstrapVersion": [ + { + "type": "aws:cdk:logicalId", + "data": "CheckBootstrapVersion" + } + ] + }, + "displayName": "TestWithNestedStack/DefaultTest/DeployAssert" + }, + "Tree": { + "type": "cdk:tree", + "properties": { + "file": "tree.json" + } + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/test-stack.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/test-stack.assets.json new file mode 100644 index 0000000000000..06cae34119b66 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/test-stack.assets.json @@ -0,0 +1,45 @@ +{ + "version": "21.0.0", + "files": { + "CHANGED_ASSET_HASH": { + "source": { + "path": "asset.CHANGED_ASSET_HASH", + "packaging": "zip" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "CHANGED_ASSET_HASH.zip", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234": { + "source": { + "path": "teststacknested140612C4.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + }, + "e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381": { + "source": { + "path": "test-stack.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "e329bc2347c70a89ff078c2c93444d2b59a21f04cbf91afff7e9e5cab307b381.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } + } + }, + "dockerImages": {} +} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/test-stack.template.json new file mode 100644 index 0000000000000..7418c1ab361ac --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/test-stack.template.json @@ -0,0 +1,115 @@ +{ + "Resources": { + "MyFunctionServiceRole3C357FF2": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "MyFunction3BAA72D1": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "ZipFile": "foo" + }, + "Role": { + "Fn::GetAtt": [ + "MyFunctionServiceRole3C357FF2", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyFunctionServiceRole3C357FF2" + ] + }, + "nestedNestedStacknestedNestedStackResource3DD143BF": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json" + ] + ] + } + }, + "UpdateReplacePolicy": "Delete", + "DeletionPolicy": "Delete" + } + }, + "Parameters": { + "BootstrapVersion": { + "Type": "AWS::SSM::Parameter::Value", + "Default": "/cdk-bootstrap/hnb659fds/version", + "Description": "Version of the CDK Bootstrap resources in this environment, automatically retrieved from SSM Parameter Store. [cdk:skip]" + } + }, + "Rules": { + "CheckBootstrapVersion": { + "Assertions": [ + { + "Assert": { + "Fn::Not": [ + { + "Fn::Contains": [ + [ + "1", + "2", + "3", + "4", + "5" + ], + { + "Ref": "BootstrapVersion" + } + ] + } + ] + }, + "AssertDescription": "CDK bootstrap stack version 6 required. Please run 'cdk bootstrap' with a recent version of the CDK CLI." + } + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/teststacknested140612C4.nested.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/teststacknested140612C4.nested.template.json new file mode 100644 index 0000000000000..0e7b67cd27fe5 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/teststacknested140612C4.nested.template.json @@ -0,0 +1,63 @@ +{ + "Resources": { + "MyTopic86869434": { + "Type": "AWS::SNS::Topic", + "Properties": { + "DisplayName": "MyTopic" + } + }, + "MyNestedFunctionServiceRole56B518B8": { + "Type": "AWS::IAM::Role", + "Properties": { + "AssumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "ManagedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "MyNestedFunctionA0269B76": { + "Type": "AWS::Lambda::Function", + "Properties": { + "Code": { + "S3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "S3Key": "CHANGED_ASSET_HASH.zip" + }, + "Role": { + "Fn::GetAtt": [ + "MyNestedFunctionServiceRole56B518B8", + "Arn" + ] + }, + "Handler": "index.handler", + "Runtime": "nodejs14.x" + }, + "DependsOn": [ + "MyNestedFunctionServiceRole56B518B8" + ] + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/tree.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/tree.json new file mode 100644 index 0000000000000..8597834c8351d --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.js.snapshot/tree.json @@ -0,0 +1,387 @@ +{ + "version": "tree-0.1", + "tree": { + "id": "App", + "path": "", + "children": { + "test-stack": { + "id": "test-stack", + "path": "test-stack", + "children": { + "MyFunction": { + "id": "MyFunction", + "path": "test-stack/MyFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "test-stack/MyFunction/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "test-stack/MyFunction/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/MyFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/MyFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "zipFile": "foo" + }, + "role": { + "Fn::GetAtt": [ + "MyFunctionServiceRole3C357FF2", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + }, + "nested": { + "id": "nested", + "path": "test-stack/nested", + "children": { + "MyTopic": { + "id": "MyTopic", + "path": "test-stack/nested/MyTopic", + "children": { + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyTopic/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::SNS::Topic", + "aws:cdk:cloudformation:props": {} + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-sns.CfnTopic", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-sns.Topic", + "version": "0.0.0" + } + }, + "MyNestedFunction": { + "id": "MyNestedFunction", + "path": "test-stack/nested/MyNestedFunction", + "children": { + "ServiceRole": { + "id": "ServiceRole", + "path": "test-stack/nested/MyNestedFunction/ServiceRole", + "children": { + "ImportServiceRole": { + "id": "ImportServiceRole", + "path": "test-stack/nested/MyNestedFunction/ServiceRole/ImportServiceRole", + "constructInfo": { + "fqn": "@aws-cdk/core.Resource", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyNestedFunction/ServiceRole/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::IAM::Role", + "aws:cdk:cloudformation:props": { + "assumeRolePolicyDocument": { + "Statement": [ + { + "Action": "sts:AssumeRole", + "Effect": "Allow", + "Principal": { + "Service": "lambda.amazonaws.com" + } + } + ], + "Version": "2012-10-17" + }, + "managedPolicyArns": [ + { + "Fn::Join": [ + "", + [ + "arn:", + { + "Ref": "AWS::Partition" + }, + ":iam::aws:policy/service-role/AWSLambdaBasicExecutionRole" + ] + ] + } + ] + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.CfnRole", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-iam.Role", + "version": "0.0.0" + } + }, + "Code": { + "id": "Code", + "path": "test-stack/nested/MyNestedFunction/Code", + "children": { + "Stage": { + "id": "Stage", + "path": "test-stack/nested/MyNestedFunction/Code/Stage", + "constructInfo": { + "fqn": "@aws-cdk/core.AssetStaging", + "version": "0.0.0" + } + }, + "AssetBucket": { + "id": "AssetBucket", + "path": "test-stack/nested/MyNestedFunction/Code/AssetBucket", + "constructInfo": { + "fqn": "@aws-cdk/aws-s3.BucketBase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-s3-assets.Asset", + "version": "0.0.0" + } + }, + "Resource": { + "id": "Resource", + "path": "test-stack/nested/MyNestedFunction/Resource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::Lambda::Function", + "aws:cdk:cloudformation:props": { + "code": { + "s3Bucket": { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "s3Key": "b7826d21185e020066e56b133136e1082372d08cf21209a8823ac39710782f68.zip" + }, + "role": { + "Fn::GetAtt": [ + "MyNestedFunctionServiceRole56B518B8", + "Arn" + ] + }, + "handler": "index.handler", + "runtime": "nodejs14.x" + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.CfnFunction", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/aws-lambda.Function", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.NestedStack", + "version": "0.0.0" + } + }, + "nested.NestedStack": { + "id": "nested.NestedStack", + "path": "test-stack/nested.NestedStack", + "children": { + "nested.NestedStackResource": { + "id": "nested.NestedStackResource", + "path": "test-stack/nested.NestedStack/nested.NestedStackResource", + "attributes": { + "aws:cdk:cloudformation:type": "AWS::CloudFormation::Stack", + "aws:cdk:cloudformation:props": { + "templateUrl": { + "Fn::Join": [ + "", + [ + "https://s3.", + { + "Ref": "AWS::Region" + }, + ".", + { + "Ref": "AWS::URLSuffix" + }, + "/", + { + "Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}" + }, + "/68d244d71d1a0f2942feda5bea8f07b26ee3b09b4e9df7eac4296dcaf8532234.json" + ] + ] + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.CfnStack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "test-stack/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "test-stack/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + }, + "TestWithNestedStack": { + "id": "TestWithNestedStack", + "path": "TestWithNestedStack", + "children": { + "DefaultTest": { + "id": "DefaultTest", + "path": "TestWithNestedStack/DefaultTest", + "children": { + "Default": { + "id": "Default", + "path": "TestWithNestedStack/DefaultTest/Default", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + }, + "DeployAssert": { + "id": "DeployAssert", + "path": "TestWithNestedStack/DefaultTest/DeployAssert", + "children": { + "BootstrapVersion": { + "id": "BootstrapVersion", + "path": "TestWithNestedStack/DefaultTest/DeployAssert/BootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnParameter", + "version": "0.0.0" + } + }, + "CheckBootstrapVersion": { + "id": "CheckBootstrapVersion", + "path": "TestWithNestedStack/DefaultTest/DeployAssert/CheckBootstrapVersion", + "constructInfo": { + "fqn": "@aws-cdk/core.CfnRule", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.Stack", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTestCase", + "version": "0.0.0" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/integ-tests.IntegTest", + "version": "0.0.0" + } + }, + "Tree": { + "id": "Tree", + "path": "Tree", + "constructInfo": { + "fqn": "constructs.Construct", + "version": "10.1.154" + } + } + }, + "constructInfo": { + "fqn": "@aws-cdk/core.App", + "version": "0.0.0" + } + } +} \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.ts b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.ts new file mode 100644 index 0000000000000..ff230f9f7e58e --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.ts @@ -0,0 +1 @@ +/// !cdk-integ test-stack pragma:include-assets-hashes diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json new file mode 100644 index 0000000000000..0967ef424bce6 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json @@ -0,0 +1 @@ +{} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.assets.json index 04bcd2f5c1a4a..fce044c483fbb 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.assets.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.assets.json @@ -26,6 +26,19 @@ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } + }, + "DIFFERENT_NESTED_STACK_HASH": { + "source": { + "path": "SomeNestedStackResourceA7AEBA6B.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "DIFFERENT_NESTED_STACK_HASH.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } } }, "dockerImages": {} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.template.json index 2beb6ac288dd2..d564a1f01fa3a 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.template.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets-diff.js.snapshot/test-stack.template.json @@ -49,6 +49,12 @@ "DependsOn": [ "MyFunction1ServiceRole9852B06B" ] + }, + "SomeNestedStackResourceA7AEBA6B": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": "https://s3.unknown-region.amazonaws.com/cdk-hnb659fds-assets-unknown-account-unknown-region/DIFFERENT_NESTED_STACK_HASH.json" + } } } } diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json new file mode 100644 index 0000000000000..0967ef424bce6 --- /dev/null +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/SomeNestedStackResourceA7AEBA6B.nested.template.json @@ -0,0 +1 @@ +{} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/test-stack.assets.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/test-stack.assets.json index 9fce39f0cb708..0dd89136db1b9 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/test-stack.assets.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/test-stack.assets.json @@ -26,6 +26,19 @@ "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" } } + }, + "6f980d09d47a00a7d5001feeb3994d1909bc5294e309d69bd4fbc815622f6fa9": { + "source": { + "path": "SomeNestedStackResourceA7AEBA6B.nested.template.json", + "packaging": "file" + }, + "destinations": { + "current_account-current_region": { + "bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}", + "objectKey": "6f980d09d47a00a7d5001feeb3994d1909bc5294e309d69bd4fbc815622f6fa9.json", + "assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}" + } + } } }, "dockerImages": {} diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/test-stack.template.json b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/test-stack.template.json index fe60c3f20c5c3..8abdf236198f1 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/test-stack.template.json +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-new-assets.js.snapshot/test-stack.template.json @@ -49,6 +49,12 @@ "DependsOn": [ "MyFunction1ServiceRole9852B06B" ] + }, + "SomeNestedStackResourceA7AEBA6B": { + "Type": "AWS::CloudFormation::Stack", + "Properties": { + "TemplateURL": "https://s3.unknown-region.amazonaws.com/cdk-hnb659fds-assets-unknown-account-unknown-region/6f980d09d47a00a7d5001feeb3994d1909bc5294e309d69bd4fbc815622f6fa9.json" + } } } } From c56bbc8ee840646f136d5e8fe0ab292969e4de31 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Wed, 16 Nov 2022 10:13:25 +0000 Subject: [PATCH 4/8] chore: readme change --- packages/@aws-cdk/integ-runner/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/packages/@aws-cdk/integ-runner/README.md b/packages/@aws-cdk/integ-runner/README.md index 308d6da190f6f..6fb4a983d339a 100644 --- a/packages/@aws-cdk/integ-runner/README.md +++ b/packages/@aws-cdk/integ-runner/README.md @@ -169,6 +169,8 @@ Test Results: Tests: 1 passed, 1 total ``` +Nested stack templates are also compared as part of the snapshot. However asset hashes are ignored by default. To enable diff for asset hashes, set `diffAssets: true` of `IntegTestProps`. + #### Update Workflow By default, integration tests are run with the "update workflow" enabled. This can be disabled by using the `--disable-update-workflow` command line option. From b4c67fe25e608c4b0359b67b72aed710dea80f94 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Wed, 16 Nov 2022 10:40:36 +0000 Subject: [PATCH 5/8] fixup cli test --- packages/@aws-cdk/integ-runner/test/cli.test.ts | 8 +------- .../test-data/xxxxx.test-with-asset-in-nested-stack.ts | 2 +- .../test/test-data/xxxxx.test-with-nested-stack.ts | 5 +++-- 3 files changed, 5 insertions(+), 10 deletions(-) diff --git a/packages/@aws-cdk/integ-runner/test/cli.test.ts b/packages/@aws-cdk/integ-runner/test/cli.test.ts index 95d53dd58b706..cd17ce7205d63 100644 --- a/packages/@aws-cdk/integ-runner/test/cli.test.ts +++ b/packages/@aws-cdk/integ-runner/test/cli.test.ts @@ -26,18 +26,12 @@ describe('CLI', () => { }); test('find by custom pattern', async () => { - await main(['--list', '--directory=test/test-data', '--test-regex="^xxxxx\..*\.js$"']); + await main(['--list', '--directory=test/test-data', '--test-regex="^xxxxx\.integ-test[12]\.js$"']); expect(stdoutMock.mock.calls).toEqual([[ [ 'xxxxx.integ-test1.js', 'xxxxx.integ-test2.js', - 'xxxxx.test-with-nested-stack.js', - 'xxxxx.test-with-new-assets-diff.js', - 'xxxxx.test-with-new-assets.js', - 'xxxxx.test-with-snapshot-assets-diff.js', - 'xxxxx.test-with-snapshot-assets.js', - 'xxxxx.test-with-snapshot.js', '', ].join('\n'), ]]); diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.ts b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.ts index ff230f9f7e58e..936441d73e003 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.ts +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-asset-in-nested-stack.ts @@ -1 +1 @@ -/// !cdk-integ test-stack pragma:include-assets-hashes +/// !cdk-integ test-stack \ No newline at end of file diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts index b9e8e8dc39be4..9e46b38ab8ced 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts @@ -1,6 +1,7 @@ /** * This is NOT a real integ test! - * It is used to test functionality of the integ-runner. + * It is used to create snapshots for testing the integ-runner. + * Kep around so that adjustments are easier in future. */ import * as lambda from '@aws-cdk/aws-lambda'; import * as sns from '@aws-cdk/aws-sns'; @@ -29,4 +30,4 @@ new integ.IntegTest(app, 'TestWithNestedStack', { testCases: [stack], }); -app.synth(); \ No newline at end of file +app.synth(); From a88f6ff5e236ffbc5dbec550c11780533a617817 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Wed, 16 Nov 2022 11:09:05 +0000 Subject: [PATCH 6/8] test if that fixes the build :shrug: --- packages/@aws-cdk/integ-runner/package.json | 5 --- .../test-data/xxxxx.test-with-nested-stack.ts | 34 +------------------ 2 files changed, 1 insertion(+), 38 deletions(-) diff --git a/packages/@aws-cdk/integ-runner/package.json b/packages/@aws-cdk/integ-runner/package.json index 809b2a923cc9d..2f9199680f427 100644 --- a/packages/@aws-cdk/integ-runner/package.json +++ b/packages/@aws-cdk/integ-runner/package.json @@ -52,12 +52,7 @@ "license": "Apache-2.0", "devDependencies": { "@aws-cdk/cdk-build-tools": "0.0.0", - "@aws-cdk/core": "0.0.0", - "@aws-cdk/aws-lambda": "0.0.0", - "@aws-cdk/aws-sns": "0.0.0", - "@aws-cdk/integ-tests": "0.0.0", "@types/mock-fs": "^4.13.1", - "constructs": "^10.0.0", "mock-fs": "^4.14.0", "@aws-cdk/pkglint": "0.0.0", "@types/fs-extra": "^8.1.2", diff --git a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts index 9e46b38ab8ced..936441d73e003 100644 --- a/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts +++ b/packages/@aws-cdk/integ-runner/test/test-data/xxxxx.test-with-nested-stack.ts @@ -1,33 +1 @@ -/** - * This is NOT a real integ test! - * It is used to create snapshots for testing the integ-runner. - * Kep around so that adjustments are easier in future. - */ -import * as lambda from '@aws-cdk/aws-lambda'; -import * as sns from '@aws-cdk/aws-sns'; -import * as cdk from '@aws-cdk/core'; -import * as integ from '@aws-cdk/integ-tests'; - -const app = new cdk.App(); - -const stack = new cdk.Stack(app, 'test-stack'); -new lambda.Function(stack, 'MyFunction', { - code: new lambda.InlineCode('foo'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_14_X, -}); - -const nestedStack = new cdk.NestedStack(stack, 'nested', {}); -new sns.Topic(nestedStack, 'MyTopic'); -new lambda.Function(nestedStack, 'MyNestedFunction', { - code: lambda.Code.fromAsset('assets/code-asset'), - handler: 'index.handler', - runtime: lambda.Runtime.NODEJS_14_X, -}); - - -new integ.IntegTest(app, 'TestWithNestedStack', { - testCases: [stack], -}); - -app.synth(); +/// !cdk-integ test-stack \ No newline at end of file From 5b21ef431661ddfe2aa57c74fb27160e467c6484 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Wed, 16 Nov 2022 11:11:50 +0000 Subject: [PATCH 7/8] minor docstring fix --- packages/cdk-assets/lib/asset-manifest.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/cdk-assets/lib/asset-manifest.ts b/packages/cdk-assets/lib/asset-manifest.ts index bb5d468085823..280a692860bff 100644 --- a/packages/cdk-assets/lib/asset-manifest.ts +++ b/packages/cdk-assets/lib/asset-manifest.ts @@ -116,7 +116,7 @@ export class AssetManifest { } /** - * List of assets, splat out to destinations + * List of file assets, splat out to destinations */ public get files(): FileManifestEntry[] { return makeEntries(this.manifest.files || {}, FileManifestEntry); From 37b009a86324cfcd86ebbaa106cf06c67545a5c9 Mon Sep 17 00:00:00 2001 From: Momo Kornher Date: Wed, 16 Nov 2022 16:09:48 +0000 Subject: [PATCH 8/8] Update packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts Co-authored-by: Cory Hall <43035978+corymhall@users.noreply.github.com> --- .../@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts b/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts index 7d42ee8e8f712..3f2915f833da0 100644 --- a/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts +++ b/packages/@aws-cdk/integ-runner/lib/runner/snapshot-test-runner.ts @@ -10,12 +10,12 @@ interface SnapshotAssembly { /** * Map of stacks that are part of this assembly */ - [key: string]: { + [stackName: string]: { /** * All templates for this stack, including nested stacks */ templates: { - [key: string]: any + [templateId: string]: any }, /**