Skip to content

Commit b4f8d91

Browse files
authored
feat(integ-tests): add IntegTest to group test cases (#20015)
Add a new construct, `IntegTest` that contains a list of `IntegTestCase`s. This new construct is now responsible for starting the synthesis of the manifests. Previously, it was `IntegTestCase` that did this. But this results in the last `IntegTestCase` to be synthesized to override all other test cases. ---- ### All Submissions: * [x] Have you followed the guidelines in our [Contributing guide?](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md) ### Adding new Unconventional Dependencies: * [ ] This PR adds new unconventional dependencies following the process described [here](https://github.com/aws/aws-cdk/blob/master/CONTRIBUTING.md/#adding-new-unconventional-dependencies) ### New Features * [ ] Have you added the new feature to an [integration test](https://github.com/aws/aws-cdk/blob/master/INTEGRATION_TESTS.md)? * [ ] Did you use `yarn integ` to deploy the infrastructure and generate the snapshot (i.e. `yarn integ` without `--dry-run`)? *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 0848312 commit b4f8d91

File tree

6 files changed

+132
-16
lines changed

6 files changed

+132
-16
lines changed

packages/@aws-cdk/integ-tests/README.md

+16-4
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ certain handler:
2323

2424
```ts
2525
interface StackUnderTestProps extends StackProps {
26-
functionProps?: lambda.FunctionProps;
26+
architecture?: lambda.Architecture;
2727
}
2828

2929
class StackUnderTest extends Stack {
@@ -34,7 +34,7 @@ class StackUnderTest extends Stack {
3434
runtime: lambda.Runtime.NODEJS_12_X,
3535
handler: 'index.handler',
3636
code: lambda.Code.fromAsset(path.join(__dirname, 'lambda-handler')),
37-
...props.functionProps,
37+
architecture: props.architecture,
3838
});
3939
}
4040
}
@@ -67,7 +67,8 @@ class StackUnderTest extends Stack {
6767
const app = new App();
6868

6969
const stack = new Stack(app, 'stack');
70-
new IntegTestCase(stack, 'DifferentArchitectures', {
70+
71+
const differentArchsCase = new IntegTestCase(stack, 'DifferentArchitectures', {
7172
stacks: [
7273
new StackUnderTest(app, 'Stack1', {
7374
architecture: lambda.Architecture.ARM_64,
@@ -77,6 +78,13 @@ new IntegTestCase(stack, 'DifferentArchitectures', {
7778
}),
7879
],
7980
});
81+
82+
// There must be exactly one instance of TestCase per file
83+
new IntegTest(app, 'integ-test', {
84+
85+
// Register as many test cases as you want here
86+
testCases: [differentArchsCase],
87+
});
8088
```
8189

8290
This is all the instruction you need for the integration test runner to know
@@ -90,7 +98,7 @@ const stackUnderTest = new Stack(app, 'StackUnderTest', /* ... */);
9098

9199
const stack = new Stack(app, 'stack');
92100

93-
new IntegTestCase(stack, 'CustomizedDeploymentWorkflow', {
101+
const testCase = new IntegTestCase(stack, 'CustomizedDeploymentWorkflow', {
94102
stacks: [stackUnderTest],
95103
diffAssets: true,
96104
stackUpdateWorkflow: true,
@@ -108,5 +116,9 @@ new IntegTestCase(stack, 'CustomizedDeploymentWorkflow', {
108116
},
109117
},
110118
});
119+
120+
new IntegTest(app, 'integ-test', {
121+
testCases: [testCase],
122+
});
111123
```
112124

Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import { IntegManifest, Manifest } from '@aws-cdk/cloud-assembly-schema';
2+
import { ISynthesisSession } from '@aws-cdk/core';
3+
import { IntegManifestWriter } from './manifest-writer';
4+
import { IntegTestCase } from './test-case';
5+
6+
const emptyManifest: IntegManifest = {
7+
version: '',
8+
testCases: { },
9+
};
10+
11+
export class IntegManifestSynthesizer {
12+
constructor(private readonly testCases: IntegTestCase[]) {}
13+
14+
synthesize(session: ISynthesisSession) {
15+
const manifest = this.testCases
16+
.map(tc => tc.manifest)
17+
.reduce(mergeManifests, emptyManifest);
18+
19+
const snapshotDir = session.assembly.outdir;
20+
21+
IntegManifestWriter.write(manifest, snapshotDir);
22+
}
23+
}
24+
25+
function mergeManifests(m1: IntegManifest, m2: IntegManifest): IntegManifest {
26+
return {
27+
version: Manifest.version(),
28+
testCases: { ...m1.testCases, ...m2.testCases },
29+
};
30+
}

packages/@aws-cdk/integ-tests/lib/test-case.ts

+39-11
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
1-
import { IntegManifest, TestCase, TestOptions } from '@aws-cdk/cloud-assembly-schema';
2-
import { attachCustomSynthesis, ISynthesisSession, Stack } from '@aws-cdk/core';
3-
import { IntegManifestWriter } from './manifest-writer';
1+
import { IntegManifest, Manifest, TestCase, TestOptions } from '@aws-cdk/cloud-assembly-schema';
2+
import { attachCustomSynthesis, Stack, ISynthesisSession } from '@aws-cdk/core';
3+
import { IntegManifestSynthesizer } from './manifest-synthesizer';
44

55
// keep this import separate from other imports to reduce chance for merge conflicts with v2-main
66
// eslint-disable-next-line no-duplicate-imports, import/order
@@ -21,18 +21,46 @@ export interface IntegTestCaseProps extends TestOptions {
2121
* apply to all stacks under this case.
2222
*/
2323
export class IntegTestCase extends Construct {
24-
constructor(scope: Construct, id: string, props: IntegTestCaseProps) {
24+
constructor(scope: Construct, private readonly id: string, private readonly props: IntegTestCaseProps) {
2525
super(scope, id);
26+
}
27+
28+
/**
29+
* The integration test manifest for this test case. Manifests are used
30+
* by the integration test runner.
31+
*/
32+
get manifest(): IntegManifest {
33+
return {
34+
version: Manifest.version(),
35+
testCases: { [this.id]: toTestCase(this.props) },
36+
};
37+
}
38+
}
39+
40+
/**
41+
* Integration test properties
42+
*/
43+
export interface IntegTestProps {
44+
/**
45+
* List of test cases that make up this test
46+
*/
47+
readonly testCases: IntegTestCase[];
48+
}
2649

50+
/**
51+
* A collection of test cases. Each test case file should contain exactly one
52+
* instance of this class.
53+
*/
54+
export class IntegTest extends Construct {
55+
constructor(scope: Construct, id: string, private readonly props: IntegTestProps) {
56+
super(scope, id);
57+
}
58+
59+
protected onPrepare(): void {
2760
attachCustomSynthesis(this, {
2861
onSynthesize: (session: ISynthesisSession) => {
29-
const snapshotDir = session.assembly.outdir;
30-
const manifest: IntegManifest = {
31-
version: '',
32-
testCases: { [id]: toTestCase(props) },
33-
};
34-
35-
IntegManifestWriter.write(manifest, snapshotDir);
62+
const synthesizer = new IntegManifestSynthesizer(this.props.testCases);
63+
synthesizer.synthesize(session);
3664
},
3765
});
3866
}

packages/@aws-cdk/integ-tests/package.json

+1
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,7 @@
7070
"dependencies": {
7171
"@aws-cdk/cloud-assembly-schema": "0.0.0",
7272
"@aws-cdk/core": "0.0.0",
73+
"@aws-cdk/cx-api": "0.0.0",
7374
"constructs": "^3.3.69"
7475
},
7576
"repository": {

packages/@aws-cdk/integ-tests/rosetta/default.ts-fixture

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import * as lambda from '@aws-cdk/aws-lambda';
2-
import { IntegTestCase } from '@aws-cdk/integ-tests';
2+
import { IntegTestCase, IntegTest } from '@aws-cdk/integ-tests';
33
import {
44
App,
55
Construct,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
import * as fs from 'fs';
2+
import * as os from 'os';
3+
import * as path from 'path';
4+
import { App, Stack } from '@aws-cdk/core';
5+
import { CloudAssemblyBuilder } from '@aws-cdk/cx-api';
6+
import { IntegTestCase } from '../lib';
7+
import { IntegManifestSynthesizer } from '../lib/manifest-synthesizer';
8+
import { IntegManifestWriter } from '../lib/manifest-writer';
9+
10+
describe(IntegManifestSynthesizer, () => {
11+
it('synthesizes a multiple manifests', () => {
12+
const write = jest.spyOn(IntegManifestWriter, 'write');
13+
14+
const app = new App();
15+
const stack = new Stack(app, 'stack');
16+
const tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cdk-test'));
17+
const assembly = new CloudAssemblyBuilder(tmpDir);
18+
19+
const synthesizer = new IntegManifestSynthesizer([
20+
new IntegTestCase(stack, 'case1', {
21+
stacks: [new Stack(app, 'stack-under-test-1')],
22+
}),
23+
new IntegTestCase(stack, 'case2', {
24+
stacks: [new Stack(app, 'stack-under-test-2')],
25+
}),
26+
]);
27+
28+
synthesizer.synthesize({
29+
assembly,
30+
outdir: 'asdas',
31+
});
32+
33+
expect(write).toHaveBeenCalledWith({
34+
version: '17.0.0',
35+
testCases: {
36+
case1: {
37+
stacks: ['stack-under-test-1'],
38+
},
39+
case2: {
40+
stacks: ['stack-under-test-2'],
41+
},
42+
},
43+
}, tmpDir);
44+
});
45+
});

0 commit comments

Comments
 (0)