Skip to content

Commit 7cac5d2

Browse files
authored
fix(integ-runner): integ-runner produces snapshot that doesn't validate (#666)
The integ-runner uses `synthFast` to produce the assembly that will be used to compare the snapshot to, to determine if there is "a change". However, when a snapshot has changed and a test is run, there is a fork: - In dry-run mode: `synthFast` will be used to produce the updated snapshot. - In real-mode, the result of `this.deploy()` will be the updated snapshot (but also: the next time it will be compared to the result of `synthFast`). We are running into a situation where the results of `synthFast` and `this.deploy` are different, and snapshot validation fails. In this change, we always generate the snapshot using `synthFast`, and ignore the template produced by `this.deploy()`. This makes sure that the templates will at least compile equal. I'm not sure why this ever worked this way, because the template that is deployed can be specialized to an account and region, but the snapshot can never be, so we need to investigate a little more. --- By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license
1 parent 628b04c commit 7cac5d2

File tree

3 files changed

+15
-25
lines changed

3 files changed

+15
-25
lines changed

packages/@aws-cdk/integ-runner/lib/runner/integ-test-runner.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ import * as chokidar from 'chokidar';
77
import * as fs from 'fs-extra';
88
import * as workerpool from 'workerpool';
99
import type { IntegRunnerOptions } from './runner-base';
10-
import { IntegRunner, DEFAULT_SYNTH_OPTIONS } from './runner-base';
10+
import { IntegRunner } from './runner-base';
1111
import * as logger from '../logger';
1212
import { chunks, exec, promiseWithResolvers } from '../utils';
1313
import type { DestructiveChange, AssertionResults, AssertionResult } from '../workers/common';
@@ -237,17 +237,11 @@ export class IntegTestRunner extends IntegRunner {
237237
updateWorkflowEnabled,
238238
options.testCaseName,
239239
);
240-
} else {
241-
await this.cdk.synthFast({
242-
execCmd: this.cdkApp.split(' '),
243-
context: this.getContext(actualTestSuite.enableLookups ? DEFAULT_SYNTH_OPTIONS.context : {}),
244-
env: DEFAULT_SYNTH_OPTIONS.env,
245-
output: path.relative(this.directory, this.cdkOutDir),
246-
});
247240
}
241+
248242
// only create the snapshot if there are no failed assertion results
249243
// (i.e. no failures)
250-
if (!assertionResults || !Object.values(assertionResults).some(result => result.status === 'fail')) {
244+
if (!Object.values(assertionResults ?? {}).some(result => result.status === 'fail')) {
251245
await this.createSnapshot();
252246
}
253247
} catch (e) {

packages/@aws-cdk/integ-runner/lib/runner/runner-base.ts

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -328,16 +328,12 @@ export abstract class IntegRunner {
328328

329329
// if lookups are enabled then we need to synth again
330330
// using dummy context and save that as the snapshot
331-
if ((await this.actualTestSuite()).enableLookups) {
332-
await this.cdk.synthFast({
333-
execCmd: this.cdkApp.split(' '),
334-
context: this.getContext(DEFAULT_SYNTH_OPTIONS.context),
335-
env: DEFAULT_SYNTH_OPTIONS.env,
336-
output: path.relative(this.directory, this.snapshotDir),
337-
});
338-
} else {
339-
fs.moveSync(this.cdkOutDir, this.snapshotDir, { overwrite: true });
340-
}
331+
await this.cdk.synthFast({
332+
execCmd: this.cdkApp.split(' '),
333+
context: this.getContext(DEFAULT_SYNTH_OPTIONS.context),
334+
env: DEFAULT_SYNTH_OPTIONS.env,
335+
output: path.relative(this.directory, this.snapshotDir),
336+
});
341337

342338
await this.cleanupSnapshot();
343339
}

packages/@aws-cdk/integ-runner/test/runner/integ-test-runner.test.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -59,7 +59,7 @@ describe('IntegTest runIntegTests', () => {
5959
// THEN
6060
expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(3);
6161
expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1);
62-
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1);
62+
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(2);
6363
expect(cdkMock.mocks.deploy).toHaveBeenCalledWith({
6464
app: 'xxxxx.test-with-snapshot.js.snapshot',
6565
requireApproval: 'never',
@@ -124,7 +124,7 @@ describe('IntegTest runIntegTests', () => {
124124
// THEN
125125
expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(1);
126126
expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1);
127-
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1);
127+
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(2);
128128
expect(cdkMock.mocks.deploy).toHaveBeenCalledWith({
129129
app: 'node xxxxx.integ-test1.js',
130130
requireApproval: 'never',
@@ -229,7 +229,7 @@ describe('IntegTest runIntegTests', () => {
229229
// THEN
230230
expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(3);
231231
expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1);
232-
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1);
232+
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(2);
233233
expect(cdkMock.mocks.deploy).toHaveBeenNthCalledWith(1, expect.objectContaining({
234234
app: 'xxxxx.test-with-snapshot.js.snapshot',
235235
context: expect.any(Object),
@@ -276,7 +276,7 @@ describe('IntegTest runIntegTests', () => {
276276
// THEN
277277
expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(1);
278278
expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(0);
279-
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1);
279+
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(2);
280280
});
281281

282282
test('dryrun', async () => {
@@ -340,7 +340,7 @@ describe('IntegTest runIntegTests', () => {
340340
// THEN
341341
expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(1);
342342
expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1);
343-
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1);
343+
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(2);
344344
expect(cdkMock.mocks.deploy).toHaveBeenCalledWith({
345345
app: 'node xxxxx.integ-test1.js',
346346
requireApproval: 'never',
@@ -623,7 +623,7 @@ describe('IntegTest runIntegTests', () => {
623623
// THEN
624624
expect(cdkMock.mocks.deploy).toHaveBeenCalledTimes(3);
625625
expect(cdkMock.mocks.destroy).toHaveBeenCalledTimes(1);
626-
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(1);
626+
expect(cdkMock.mocks.synthFast).toHaveBeenCalledTimes(2);
627627
expect(cdkMock.mocks.deploy).toHaveBeenCalledWith(expect.objectContaining({
628628
app: 'node --no-warnings xxxxx.test-with-snapshot.js',
629629
}));

0 commit comments

Comments
 (0)