Skip to content

Commit 57585c7

Browse files
authored
chore(integ-tests): Applying type coercion to byte array when necessary (#27092)
#27009 introduced support for `Uint8Array` if users want to send data with the same types as those declared in the SDK v3 API. But existing tests, that use strings, will break. Apply type coercion when necessary. ---- *By submitting this pull request, I confirm that my contribution is made under the terms of the Apache-2.0 license*
1 parent 4e98067 commit 57585c7

File tree

8 files changed

+187
-31969
lines changed

8 files changed

+187
-31969
lines changed

packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.binary-payload.js.snapshot/asset.020364985d409cf8bf611edf535aedca3c0d7c0dd7f21ba847b79a41d9bf0dce.bundle/index.js

-31,954
This file was deleted.

packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.binary-payload.js.snapshot/integtestDefaultTestDeployAssert24D5C536.assets.json

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,28 @@
11
{
22
"version": "34.0.0",
33
"files": {
4-
"020364985d409cf8bf611edf535aedca3c0d7c0dd7f21ba847b79a41d9bf0dce": {
4+
"e6687baf1807038e7f7c1491f44379c5b84bec1eac25667aaa6b38ef78dff400": {
55
"source": {
6-
"path": "asset.020364985d409cf8bf611edf535aedca3c0d7c0dd7f21ba847b79a41d9bf0dce.bundle",
6+
"path": "asset.e6687baf1807038e7f7c1491f44379c5b84bec1eac25667aaa6b38ef78dff400.bundle",
77
"packaging": "zip"
88
},
99
"destinations": {
1010
"current_account-current_region": {
1111
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
12-
"objectKey": "020364985d409cf8bf611edf535aedca3c0d7c0dd7f21ba847b79a41d9bf0dce.zip",
12+
"objectKey": "e6687baf1807038e7f7c1491f44379c5b84bec1eac25667aaa6b38ef78dff400.zip",
1313
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
1414
}
1515
}
1616
},
17-
"d10734fe0522d2d30eb5916fd9a45d4ddf9ec42fd308c30e000cbd7ad11f7a39": {
17+
"e89e8285f3bd8e37ab8fb821889173f1bf1426ff88fd9f62a60f7a40376618aa": {
1818
"source": {
1919
"path": "integtestDefaultTestDeployAssert24D5C536.template.json",
2020
"packaging": "file"
2121
},
2222
"destinations": {
2323
"current_account-current_region": {
2424
"bucketName": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}",
25-
"objectKey": "d10734fe0522d2d30eb5916fd9a45d4ddf9ec42fd308c30e000cbd7ad11f7a39.json",
25+
"objectKey": "e89e8285f3bd8e37ab8fb821889173f1bf1426ff88fd9f62a60f7a40376618aa.json",
2626
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-file-publishing-role-${AWS::AccountId}-${AWS::Region}"
2727
}
2828
}

packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.binary-payload.js.snapshot/integtestDefaultTestDeployAssert24D5C536.template.json

+62-2
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@
3232
}
3333
},
3434
"flattenResponse": "false",
35-
"salt": "1693996483504"
35+
"salt": "1694426182342"
3636
},
3737
"UpdateReplacePolicy": "Delete",
3838
"DeletionPolicy": "Delete"
@@ -63,6 +63,24 @@
6363
"PolicyDocument": {
6464
"Version": "2012-10-17",
6565
"Statement": [
66+
{
67+
"Action": [
68+
"lambda:Invoke"
69+
],
70+
"Effect": "Allow",
71+
"Resource": [
72+
"*"
73+
]
74+
},
75+
{
76+
"Effect": "Allow",
77+
"Action": [
78+
"lambda:InvokeFunction"
79+
],
80+
"Resource": [
81+
"*"
82+
]
83+
},
6684
{
6785
"Action": [
6886
"lambda:Invoke"
@@ -95,7 +113,7 @@
95113
"S3Bucket": {
96114
"Fn::Sub": "cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}"
97115
},
98-
"S3Key": "020364985d409cf8bf611edf535aedca3c0d7c0dd7f21ba847b79a41d9bf0dce.zip"
116+
"S3Key": "e6687baf1807038e7f7c1491f44379c5b84bec1eac25667aaa6b38ef78dff400.zip"
99117
},
100118
"Timeout": 120,
101119
"Handler": "index.handler",
@@ -106,6 +124,40 @@
106124
]
107125
}
108126
}
127+
},
128+
"AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4": {
129+
"Type": "Custom::DeployAssert@SdkCallLambdainvoke",
130+
"Properties": {
131+
"ServiceToken": {
132+
"Fn::GetAtt": [
133+
"SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F",
134+
"Arn"
135+
]
136+
},
137+
"service": "Lambda",
138+
"api": "invoke",
139+
"expected": "{\"$ObjectLike\":{\"Payload\":{\"name\":\"world\"}}}",
140+
"parameters": {
141+
"FunctionName": {
142+
"Fn::Join": [
143+
"",
144+
[
145+
"\"",
146+
{
147+
"Fn::ImportValue": "IntegBinaryPayload:ExportsOutputReffn5FF616E3BE1A8BD6"
148+
},
149+
"\""
150+
]
151+
]
152+
},
153+
"InvocationType": "\"RequestResponse\"",
154+
"Payload": "\"{\\\"name\\\":\\\"world\\\"}\""
155+
},
156+
"flattenResponse": "false",
157+
"salt": "1694426182343"
158+
},
159+
"UpdateReplacePolicy": "Delete",
160+
"DeletionPolicy": "Delete"
109161
}
110162
},
111163
"Outputs": {
@@ -116,6 +168,14 @@
116168
"assertion"
117169
]
118170
}
171+
},
172+
"AssertionResultsAwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4": {
173+
"Value": {
174+
"Fn::GetAtt": [
175+
"AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4",
176+
"assertion"
177+
]
178+
}
119179
}
120180
},
121181
"Parameters": {

packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.binary-payload.js.snapshot/manifest.json

+13-1
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,7 @@
8282
"validateOnSynth": false,
8383
"assumeRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-deploy-role-${AWS::AccountId}-${AWS::Region}",
8484
"cloudFormationExecutionRoleArn": "arn:${AWS::Partition}:iam::${AWS::AccountId}:role/cdk-hnb659fds-cfn-exec-role-${AWS::AccountId}-${AWS::Region}",
85-
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/d10734fe0522d2d30eb5916fd9a45d4ddf9ec42fd308c30e000cbd7ad11f7a39.json",
85+
"stackTemplateAssetObjectUrl": "s3://cdk-hnb659fds-assets-${AWS::AccountId}-${AWS::Region}/e89e8285f3bd8e37ab8fb821889173f1bf1426ff88fd9f62a60f7a40376618aa.json",
8686
"requiresBootstrapStackVersion": 6,
8787
"bootstrapStackVersionSsmParameter": "/cdk-bootstrap/hnb659fds/version",
8888
"additionalDependencies": [
@@ -123,6 +123,18 @@
123123
"data": "SingletonFunction1488541a7b23466481b69b4408076b81HandlerCD40AE9F"
124124
}
125125
],
126+
"/integ-test/DefaultTest/DeployAssert/AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4/Default/Default": [
127+
{
128+
"type": "aws:cdk:logicalId",
129+
"data": "AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4"
130+
}
131+
],
132+
"/integ-test/DefaultTest/DeployAssert/AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4/AssertionResults": [
133+
{
134+
"type": "aws:cdk:logicalId",
135+
"data": "AssertionResultsAwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4"
136+
}
137+
],
126138
"/integ-test/DefaultTest/DeployAssert/BootstrapVersion": [
127139
{
128140
"type": "aws:cdk:logicalId",

packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.binary-payload.js.snapshot/tree.json

+54
Original file line numberDiff line numberDiff line change
@@ -247,6 +247,60 @@
247247
"version": "10.2.70"
248248
}
249249
},
250+
"AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4": {
251+
"id": "AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4",
252+
"path": "integ-test/DefaultTest/DeployAssert/AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4",
253+
"children": {
254+
"SdkProvider": {
255+
"id": "SdkProvider",
256+
"path": "integ-test/DefaultTest/DeployAssert/AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4/SdkProvider",
257+
"children": {
258+
"AssertionsProvider": {
259+
"id": "AssertionsProvider",
260+
"path": "integ-test/DefaultTest/DeployAssert/AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4/SdkProvider/AssertionsProvider",
261+
"constructInfo": {
262+
"fqn": "constructs.Construct",
263+
"version": "10.2.70"
264+
}
265+
}
266+
},
267+
"constructInfo": {
268+
"fqn": "@aws-cdk/integ-tests-alpha.AssertionsProvider",
269+
"version": "0.0.0"
270+
}
271+
},
272+
"Default": {
273+
"id": "Default",
274+
"path": "integ-test/DefaultTest/DeployAssert/AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4/Default",
275+
"children": {
276+
"Default": {
277+
"id": "Default",
278+
"path": "integ-test/DefaultTest/DeployAssert/AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4/Default/Default",
279+
"constructInfo": {
280+
"fqn": "aws-cdk-lib.CfnResource",
281+
"version": "0.0.0"
282+
}
283+
}
284+
},
285+
"constructInfo": {
286+
"fqn": "aws-cdk-lib.CustomResource",
287+
"version": "0.0.0"
288+
}
289+
},
290+
"AssertionResults": {
291+
"id": "AssertionResults",
292+
"path": "integ-test/DefaultTest/DeployAssert/AwsApiCallLambdainvokefadfa108bb2726119308f73d0e24d8d4/AssertionResults",
293+
"constructInfo": {
294+
"fqn": "aws-cdk-lib.CfnOutput",
295+
"version": "0.0.0"
296+
}
297+
}
298+
},
299+
"constructInfo": {
300+
"fqn": "@aws-cdk/integ-tests-alpha.AwsApiCall",
301+
"version": "0.0.0"
302+
}
303+
},
250304
"BootstrapVersion": {
251305
"id": "BootstrapVersion",
252306
"path": "integ-test/DefaultTest/DeployAssert/BootstrapVersion",

packages/@aws-cdk-testing/framework-integ/test/aws-lambda/test/integ.binary-payload.ts

+20-4
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,8 @@ const fn = new Function(stack, 'fn', {
1515
`),
1616
});
1717

18-
const buf = Buffer.from(JSON.stringify({ name: 'world' }));
18+
const inputString = JSON.stringify({ name: 'world' });
19+
const buf = Buffer.from(inputString);
1920
const data = new Uint8Array(
2021
buf.buffer,
2122
buf.byteOffset,
@@ -26,16 +27,31 @@ const testCase = new IntegTest(app, 'integ-test', {
2627
testCases: [stack],
2728
});
2829

29-
const invoke = testCase.assertions.awsApiCall('Lambda', 'invoke', {
30+
const invokeWithByteArray = testCase.assertions.awsApiCall('Lambda', 'invoke', {
3031
FunctionName: fn.functionName,
3132
InvocationType: 'RequestResponse',
3233
Payload: data,
3334
});
3435

35-
invoke.provider.addToRolePolicy({
36+
invokeWithByteArray.provider.addToRolePolicy({
3637
Effect: 'Allow',
3738
Action: ['lambda:InvokeFunction'],
3839
Resource: ['*'],
3940
});
4041

41-
invoke.expect(ExpectedResult.objectLike({ Payload: { name: 'world' } }));
42+
const invokeWithString = testCase.assertions.awsApiCall('Lambda', 'invoke', {
43+
FunctionName: fn.functionName,
44+
InvocationType: 'RequestResponse',
45+
Payload: inputString,
46+
});
47+
48+
invokeWithString.provider.addToRolePolicy({
49+
Effect: 'Allow',
50+
Action: ['lambda:InvokeFunction'],
51+
Resource: ['*'],
52+
});
53+
54+
// Expect the same behaviour, regardless of whether the input is a string or a byte array
55+
invokeWithByteArray.expect(ExpectedResult.objectLike({ Payload: { name: 'world' } }));
56+
invokeWithString.expect(ExpectedResult.objectLike({ Payload: { name: 'world' } }));
57+

packages/@aws-cdk/integ-tests-alpha/lib/assertions/providers/lambda-handler/sdk.ts

+7-2
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,11 @@
11
/* eslint-disable no-console */
22
import { CustomResourceHandler } from './base';
33
import { AwsApiCallRequest, AwsApiCallResult } from './types';
4-
import { getV3ClientPackageName, findV3ClientConstructor } from '@aws-cdk/sdk-v2-to-v3-adapter';
4+
import {
5+
getV3ClientPackageName,
6+
findV3ClientConstructor,
7+
coerceApiParametersToUint8Array,
8+
} from '@aws-cdk/sdk-v2-to-v3-adapter';
59
import { decodeParameters, parseJsonPayload } from './utils';
610

711
/**
@@ -80,7 +84,8 @@ export class AwsApiCallHandler extends CustomResourceHandler<AwsApiCallRequest,
8084
const client = getServiceClient(sdkPkg);
8185

8286
const Command = getSdkCommand(sdkPkg, request.api);
83-
const commandInput = (request.parameters && decodeParameters(request.parameters)) ?? {};
87+
const parameters = (request.parameters && decodeParameters(request.parameters)) ?? {};
88+
const commandInput = coerceApiParametersToUint8Array(request.service, request.api, parameters);
8489

8590
console.log(`SDK request to ${sdkPkg.service}.${request.api} with parameters ${JSON.stringify(commandInput)}`);
8691
const response = await client.send(new Command(commandInput));

packages/@aws-cdk/integ-tests-alpha/test/assertions/providers/lambda-handler/sdk.test.ts

+26-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
// Copyright 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
2-
import { S3Client, ListObjectsOutput, ListObjectsCommand } from '@aws-sdk/client-s3';
2+
import { S3Client, ListObjectsOutput, ListObjectsCommand, PutObjectCommand } from '@aws-sdk/client-s3';
33
import { DescribeInstancesCommand, EC2Client } from '@aws-sdk/client-ec2';
44
import { mockClient } from 'aws-sdk-client-mock';
55
import { AwsApiCallRequest, AwsApiCallResult } from '../../../../lib/assertions';
@@ -157,6 +157,31 @@ describe('SdkHandler', () => {
157157
// THEN
158158
expect(ec2Mock).toHaveReceivedCommandWith(DescribeInstancesCommand, { NextToken: 'To"ken' });
159159
});
160+
161+
test('byte array coercion', async () => {
162+
// GIVEN
163+
s3Mock.on(PutObjectCommand).resolves({ });
164+
const handler = sdkHandler() as any;
165+
const request: AwsApiCallRequest = {
166+
service: 'S3',
167+
api: 'putObject',
168+
parameters: {
169+
Bucket: '"myBucket"',
170+
Key: '"foo"',
171+
Body: '"abc"',
172+
},
173+
};
174+
175+
// WHEN
176+
await handler.processEvent(request);
177+
178+
// THEN
179+
expect(s3Mock).toHaveReceivedCommandWith(PutObjectCommand, {
180+
Bucket: 'myBucket',
181+
Key: 'foo',
182+
Body: Uint8Array.from([97, 98, 99]),
183+
});
184+
});
160185
});
161186

162187
test('restrict output path', async () => {

0 commit comments

Comments
 (0)