Skip to content

Commit

Permalink
fix(integ-tests): DeployAssert should be private (#20466)
Browse files Browse the repository at this point in the history
The `DeployAssert` construct is really an implementation detail that is
only used when making assertions as part of integration tests. This PR
makes the construct private and creates a public interface
(`IDeployAssert`).

This PR also:

- Removes the scope swap since we no longer need to pass around
`DeployAssert`.
- Removes some unused code (ResultsCollector).

----

### All Submissions:

* [ ] 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*
  • Loading branch information
corymhall authored May 23, 2022
1 parent e9cbda3 commit 0f52813
Show file tree
Hide file tree
Showing 17 changed files with 330 additions and 351 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,13 @@ const integ = new IntegTest(app, 'Destinations', {
testCases: [stack],
});

integ.assert.invokeFunction({
integ.assertions.invokeFunction({
functionName: stack.fn.functionName,
invocationType: InvocationType.EVENT,
payload: JSON.stringify({ status: 'OK' }),
});

const message = integ.assert.awsApiCall('SQS', 'receiveMessage', {
const message = integ.assertions.awsApiCall('SQS', 'receiveMessage', {
QueueUrl: stack.queue.queueUrl,
WaitTimeSeconds: 20,
});
Expand Down
4 changes: 2 additions & 2 deletions packages/@aws-cdk/aws-lambda/test/integ.bundling.ts
Original file line number Diff line number Diff line change
Expand Up @@ -47,10 +47,10 @@ const integ = new IntegTest(app, 'Bundling', {
stackUpdateWorkflow: false,
});

const invoke = integ.assert.invokeFunction({
const invoke = integ.assertions.invokeFunction({
functionName: stack.functionName,
});
invoke.assert(ExpectedResult.objectLike({
invoke.expect(ExpectedResult.objectLike({
Payload: '200',
}));
app.synth();
Original file line number Diff line number Diff line change
Expand Up @@ -46,17 +46,17 @@ const testCase = new IntegTest(app, 'PutEvents', {
});

// Start an execution
const start = testCase.assert.awsApiCall('StepFunctions', 'startExecution', {
const start = testCase.assertions.awsApiCall('StepFunctions', 'startExecution', {
stateMachineArn: sm.stateMachineArn,
});

// describe the results of the execution
const describe = testCase.assert.awsApiCall('StepFunctions', 'describeExecution', {
const describe = testCase.assertions.awsApiCall('StepFunctions', 'describeExecution', {
executionArn: start.getAttString('executionArn'),
});

// assert the results
describe.assert(ExpectedResult.objectLike({
describe.expect(ExpectedResult.objectLike({
status: 'SUCCEEDED',
}));

Expand Down
94 changes: 51 additions & 43 deletions packages/@aws-cdk/integ-tests/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -177,41 +177,50 @@ new IntegTest(app, 'Integ', { testCases: [stackUnderTest, testCaseWithAssets] })

This library also provides a utility to make assertions against the infrastructure that the integration test deploys.

The easiest way to do this is to create a `TestCase` and then access the `DeployAssert` that is automatically created.
There are two main scenarios in which assertions are created.

- Part of an integration test using `integ-runner`

In this case you would create an integration test using the `IntegTest` construct and then make assertions using the `assert` property.
You should **not** utilize the assertion constructs directly, but should instead use the `methods` on `IntegTest.assert`.

```ts
declare const app: App;
declare const stack: Stack;

const integ = new IntegTest(app, 'Integ', { testCases: [stack] });
integ.assert.awsApiCall('S3', 'getObject');
integ.assertions.awsApiCall('S3', 'getObject');
```

### DeployAssert

Assertions are created by using the `DeployAssert` construct. This construct creates it's own `Stack` separate from
any stacks that you create as part of your integration tests. This `Stack` is treated differently from other stacks
by the `integ-runner` tool. For example, this stack will not be diffed by the `integ-runner`.
- Part of a normal CDK deployment

Any assertions that you create should be created in the scope of `DeployAssert`. For example,
In this case you may be using assertions as part of a normal CDK deployment in order to make an assertion on the infrastructure
before the deployment is considered successful. In this case you can utilize the assertions constructs directly.

```ts
declare const app: App;
declare const myAppStack: Stack;

const assert = new DeployAssert(app);
new AwsApiCall(assert, 'GetObject', {
new AwsApiCall(myAppStack, 'GetObject', {
service: 'S3',
api: 'getObject',
});
```

### DeployAssert

Assertions are created by using the `DeployAssert` construct. This construct creates it's own `Stack` separate from
any stacks that you create as part of your integration tests. This `Stack` is treated differently from other stacks
by the `integ-runner` tool. For example, this stack will not be diffed by the `integ-runner`.

`DeployAssert` also provides utilities to register your own assertions.

```ts
declare const myCustomResource: CustomResource;
declare const stack: Stack;
declare const app: App;
const assert = new DeployAssert(app);
assert.assert(

const integ = new IntegTest(app, 'Integ', { testCases: [stack] });
integ.assertions.expect(
'CustomAssertion',
ExpectedResult.objectLike({ foo: 'bar' }),
ActualResult.fromCustomResource(myCustomResource, 'data'),
Expand All @@ -228,12 +237,12 @@ AWS API call to receive some data. This library does this by utilizing CloudForm
which means that CloudFormation will call out to a Lambda Function which will
use the AWS JavaScript SDK to make the API call.

This can be done by using the class directory:
This can be done by using the class directory (in the case of a normal deployment):

```ts
declare const assert: DeployAssert;
declare const stack: Stack;

new AwsApiCall(assert, 'MyAssertion', {
new AwsApiCall(stack, 'MyAssertion', {
service: 'SQS',
api: 'receiveMessage',
parameters: {
Expand All @@ -242,12 +251,15 @@ new AwsApiCall(assert, 'MyAssertion', {
});
```

Or by using the `awsApiCall` method on `DeployAssert`:
Or by using the `awsApiCall` method on `DeployAssert` (when writing integration tests):

```ts
declare const app: App;
const assert = new DeployAssert(app);
assert.awsApiCall('SQS', 'receiveMessage', {
declare const stack: Stack;
const integ = new IntegTest(app, 'Integ', {
testCases: [stack],
});
integ.assertions.awsApiCall('SQS', 'receiveMessage', {
QueueUrl: 'url',
});
```
Expand All @@ -270,32 +282,29 @@ const integ = new IntegTest(app, 'Integ', {
testCases: [stack],
});

integ.assert.invokeFunction({
integ.assertions.invokeFunction({
functionName: fn.functionName,
invocationType: InvocationType.EVENT,
payload: JSON.stringify({ status: 'OK' }),
});

const message = integ.assert.awsApiCall('SQS', 'receiveMessage', {
const message = integ.assertions.awsApiCall('SQS', 'receiveMessage', {
QueueUrl: queue.queueUrl,
WaitTimeSeconds: 20,
});

new EqualsAssertion(integ.assert, 'ReceiveMessage', {
actual: ActualResult.fromAwsApiCall(message, 'Messages.0.Body'),
expected: ExpectedResult.objectLike({
requestContext: {
condition: 'Success',
},
requestPayload: {
status: 'OK',
},
responseContext: {
statusCode: 200,
},
responsePayload: 'success',
}),
});
message.assertAtPath('Messages.0.Body', ExpectedResult.objectLike({
requestContext: {
condition: 'Success',
},
requestPayload: {
status: 'OK',
},
responseContext: {
statusCode: 200,
},
responsePayload: 'success',
}));
```

#### Match
Expand All @@ -305,9 +314,8 @@ can be used to construct the `ExpectedResult`.

```ts
declare const message: AwsApiCall;
declare const assert: DeployAssert;

message.assert(ExpectedResult.objectLike({
message.expect(ExpectedResult.objectLike({
Messages: Match.arrayWith([
{
Body: {
Expand Down Expand Up @@ -336,10 +344,10 @@ const integ = new IntegTest(app, 'IntegTest', {
testCases: [stack],
});

const invoke = integ.assert.invokeFunction({
const invoke = integ.assertions.invokeFunction({
functionName: lambdaFunction.functionName,
});
invoke.assert(ExpectedResult.objectLike({
invoke.expect(ExpectedResult.objectLike({
Payload: '200',
}));
```
Expand All @@ -359,17 +367,17 @@ const testCase = new IntegTest(app, 'IntegTest', {
});

// Start an execution
const start = testCase.assert.awsApiCall('StepFunctions', 'startExecution', {
const start = testCase.assertions.awsApiCall('StepFunctions', 'startExecution', {
stateMachineArn: sm.stateMachineArn,
});

// describe the results of the execution
const describe = testCase.assert.awsApiCall('StepFunctions', 'describeExecution', {
const describe = testCase.assertions.awsApiCall('StepFunctions', 'describeExecution', {
executionArn: start.getAttString('executionArn'),
});

// assert the results
describe.assert(ExpectedResult.objectLike({
describe.expect(ExpectedResult.objectLike({
status: 'SUCCEEDED',
}));
```
Expand Down
5 changes: 3 additions & 2 deletions packages/@aws-cdk/integ-tests/lib/assertions/common.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { CustomResource } from '@aws-cdk/core';
import { AwsApiCall } from './sdk';
import { IAwsApiCall } from './sdk';

/**
* Represents the "actual" results to compare
*/
Expand All @@ -16,7 +17,7 @@ export abstract class ActualResult {
/**
* Get the actual results from a AwsApiCall
*/
public static fromAwsApiCall(query: AwsApiCall, attribute: string): ActualResult {
public static fromAwsApiCall(query: IAwsApiCall, attribute: string): ActualResult {
return {
result: query.getAttString(attribute),
};
Expand Down
128 changes: 0 additions & 128 deletions packages/@aws-cdk/integ-tests/lib/assertions/deploy-assert.ts

This file was deleted.

4 changes: 2 additions & 2 deletions packages/@aws-cdk/integ-tests/lib/assertions/index.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export * from './assertions';
export * from './types';
export * from './sdk';
export * from './deploy-assert';
export * from './assertions';
export * from './providers';
export * from './common';
export * from './match';
Loading

0 comments on commit 0f52813

Please sign in to comment.