Skip to content

Commit 8e93b32

Browse files
authored
test(client-s3): integration tests for flexible checksums (#3360)
1 parent 8d9bfba commit 8e93b32

File tree

1 file changed

+150
-0
lines changed

1 file changed

+150
-0
lines changed
Lines changed: 150 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,150 @@
1+
/// <reference types="mocha" />
2+
import { ChecksumAlgorithm } from "@aws-sdk/middleware-flexible-checksums";
3+
import { HttpRequest } from "@aws-sdk/protocol-http";
4+
import { BuildMiddleware } from "@aws-sdk/types";
5+
import chai from "chai";
6+
import chaiAsPromised from "chai-as-promised";
7+
import { Readable } from "stream";
8+
9+
import { S3 } from "../src/S3";
10+
11+
chai.use(chaiAsPromised);
12+
const { expect } = chai;
13+
14+
describe("Flexible Checksums", () => {
15+
const testCases = [
16+
["", ChecksumAlgorithm.CRC32, "AAAAAA=="],
17+
["abc", ChecksumAlgorithm.CRC32, "NSRBwg=="],
18+
["Hello world", ChecksumAlgorithm.CRC32, "i9aeUg=="],
19+
20+
["", ChecksumAlgorithm.CRC32C, "AAAAAA=="],
21+
["abc", ChecksumAlgorithm.CRC32C, "Nks/tw=="],
22+
["Hello world", ChecksumAlgorithm.CRC32C, "crUfeA=="],
23+
24+
["", ChecksumAlgorithm.SHA1, "2jmj7l5rSw0yVb/vlWAYkK/YBwk="],
25+
["abc", ChecksumAlgorithm.SHA1, "qZk+NkcGgWq6PiVxeFDCbJzQ2J0="],
26+
["Hello world", ChecksumAlgorithm.SHA1, "e1AsOh9IyGCa4hLN+2Od7jlnP14="],
27+
28+
["", ChecksumAlgorithm.SHA256, "47DEQpj8HBSa+/TImW+5JCeuQeRkm5NMpJWZG3hSuFU="],
29+
["abc", ChecksumAlgorithm.SHA256, "ungWv48Bz+pBQUDeXa4iI7ADYaOWF3qctBD/YfIAFa0="],
30+
["Hello world", ChecksumAlgorithm.SHA256, "ZOyIygCyaOW6GjVnihtTFtIS9PNmskdyMlNKiuyjfzw="],
31+
];
32+
33+
describe("putObject", () => {
34+
testCases.forEach(([body, checksumAlgorithm, checksumValue]) => {
35+
const checksumHeader = `x-amz-checksum-${checksumAlgorithm.toLowerCase()}`;
36+
37+
describe(`sets ${checksumHeader}="${checksumValue}"" for checksum="${checksumAlgorithm}"`, () => {
38+
const getBodyAsReadableStream = (content: string) => {
39+
const readableStream = new Readable();
40+
const separator = " ";
41+
const wordsAsChunks = content.split(separator);
42+
wordsAsChunks.forEach((word, index) => {
43+
readableStream.push(word);
44+
if (index !== wordsAsChunks.length - 1) {
45+
readableStream.push(separator);
46+
}
47+
});
48+
readableStream.push(null);
49+
return readableStream;
50+
};
51+
52+
it(`when body is sent as a request`, async () => {
53+
const requestChecksumValidator: BuildMiddleware<any, any> = (next) => async (args) => {
54+
// middleware intercept the request and return it early
55+
const request = args.request as HttpRequest;
56+
const { headers } = request;
57+
expect(headers["x-amz-sdk-checksum-algorithm"]).to.equal(checksumAlgorithm);
58+
expect(headers[checksumHeader]).to.equal(checksumValue);
59+
return { output: {} as any, response: {} as any };
60+
};
61+
62+
const client = new S3({});
63+
client.middlewareStack.addRelativeTo(requestChecksumValidator, {
64+
relation: "after",
65+
toMiddleware: "flexibleChecksumsMiddleware",
66+
});
67+
68+
return await client.putObject({
69+
Bucket: "bucket",
70+
Key: "key",
71+
Body: body,
72+
ChecksumAlgorithm: checksumAlgorithm,
73+
});
74+
});
75+
76+
it(`when body is sent as a stream`, async () => {
77+
const requestChecksumValidator: BuildMiddleware<any, any> = (next) => async (args) => {
78+
// middleware intercept the request and return it early
79+
const request = args.request as HttpRequest;
80+
const { headers } = request;
81+
expect(headers["content-length"]).to.be.undefined;
82+
expect(headers["content-encoding"]).to.equal("aws-chunked");
83+
expect(headers["transfer-encoding"]).to.equal("chunked");
84+
expect(headers["x-amz-content-sha256"]).to.equal("STREAMING-UNSIGNED-PAYLOAD-TRAILER");
85+
expect(headers["x-amz-trailer"]).to.equal(checksumHeader);
86+
return { output: {} as any, response: {} as any };
87+
};
88+
89+
const client = new S3({});
90+
client.middlewareStack.addRelativeTo(requestChecksumValidator, {
91+
relation: "after",
92+
toMiddleware: "flexibleChecksumsMiddleware",
93+
});
94+
95+
const bodyStream = getBodyAsReadableStream(body);
96+
return await client.putObject({
97+
Bucket: "bucket",
98+
Key: "key",
99+
Body: bodyStream,
100+
ChecksumAlgorithm: checksumAlgorithm,
101+
});
102+
});
103+
});
104+
});
105+
});
106+
107+
describe("getObject", async () => {
108+
testCases.forEach(([body, checksumAlgorithm, checksumValue]) => {
109+
const checksumHeader = `x-amz-checksum-${checksumAlgorithm.toLowerCase()}`;
110+
111+
it(`validates ${checksumHeader}="${checksumValue}"" set for checksum="${checksumAlgorithm}"`, async () => {
112+
const responseBody = new Readable();
113+
responseBody.push(body);
114+
responseBody.push(null);
115+
const responseChecksumValidator: BuildMiddleware<any, any> = (next, context) => async (args) => {
116+
const request = args.request as HttpRequest;
117+
return {
118+
output: {
119+
$metadata: { attempts: 0, httpStatusCode: 200 },
120+
request,
121+
context,
122+
Body: responseBody,
123+
} as any,
124+
response: {
125+
body: responseBody,
126+
headers: {
127+
[checksumHeader]: checksumValue,
128+
},
129+
} as any,
130+
};
131+
};
132+
133+
const client = new S3({});
134+
client.middlewareStack.addRelativeTo(responseChecksumValidator, {
135+
relation: "after",
136+
toMiddleware: "flexibleChecksumsMiddleware",
137+
});
138+
139+
const { Body } = await client.getObject({
140+
Bucket: "bucket",
141+
Key: "key",
142+
ChecksumMode: "ENABLED",
143+
});
144+
(Body as Readable).on("data", (chunk) => {
145+
expect(chunk.toString()).to.equal(body);
146+
});
147+
});
148+
});
149+
});
150+
});

0 commit comments

Comments
 (0)