|
1 | | -import { getE2eTestResources, requireRequestsFrom } from "@aws-sdk/aws-util-test/src"; |
| 1 | +import { requireRequestsFrom } from "@aws-sdk/aws-util-test/src"; |
2 | 2 | import { S3 } from "@aws-sdk/client-s3"; |
3 | 3 | import { Upload } from "@aws-sdk/lib-storage"; |
4 | | -import { getHttpDebugLogPlugin } from "@aws-sdk/middleware-http-debug-log/src"; |
5 | 4 | import { HttpResponse } from "@smithy/protocol-http"; |
6 | 5 | import { randomBytes } from "crypto"; |
7 | 6 | import { Readable } from "node:stream"; |
8 | 7 | import { describe, expect, test as it } from "vitest"; |
9 | 8 |
|
10 | 9 | describe("lib storage integration test", () => { |
11 | | - const example = async () => { |
12 | | - const e2eTestResourcesEnv = await getE2eTestResources(); |
13 | | - Object.assign(process.env, e2eTestResourcesEnv); |
14 | | - |
15 | | - const region = process?.env?.AWS_SMOKE_TEST_REGION as string; |
16 | | - const Bucket = process?.env?.AWS_SMOKE_TEST_BUCKET as string; |
17 | | - const data = randomBytes(6 * 1024 * 1024); |
18 | | - |
19 | | - const s3 = new S3({ |
20 | | - region, |
21 | | - }); |
22 | | - const Key = `MPU-${Date.now()}`; |
23 | | - |
24 | | - const client = new S3({ |
25 | | - region, |
26 | | - }); |
27 | | - // This will print out all requests and responses so you can use |
28 | | - // them in an integration mock later. |
29 | | - client.middlewareStack.use( |
30 | | - getHttpDebugLogPlugin({ |
31 | | - request: { |
32 | | - url: true, |
33 | | - command: true, |
34 | | - method: true, |
35 | | - }, |
36 | | - response: { |
37 | | - statusCode: true, |
38 | | - headers: true, |
39 | | - body: true, |
40 | | - formatBody: true, |
41 | | - }, |
42 | | - }) |
43 | | - ); |
44 | | - |
45 | | - await new Upload({ |
46 | | - client, |
47 | | - params: { |
48 | | - Bucket, |
49 | | - Key, |
50 | | - Body: data, |
51 | | - }, |
52 | | - }).done(); |
53 | | - |
54 | | - await s3.deleteObject({ |
55 | | - Bucket, |
56 | | - Key, |
57 | | - }); |
58 | | - }; |
59 | | - |
60 | 10 | it("example of how to write an integration test that includes responses", async () => { |
61 | 11 | const client = new S3({ |
62 | 12 | region: "us-west-2", |
@@ -277,4 +227,77 @@ describe("lib storage integration test", () => { |
277 | 227 |
|
278 | 228 | expect(uploadOutput).toMatchObject(commandOutputs.CompleteMultipartUploadCommand[0]); |
279 | 229 | }); |
| 230 | + |
| 231 | + it("verifies PutObject response is properly mapped to Upload response for small files", async () => { |
| 232 | + const client = new S3({ |
| 233 | + region: "us-west-2", |
| 234 | + credentials: { |
| 235 | + accessKeyId: "INTEG", |
| 236 | + secretAccessKey: "INTEG", |
| 237 | + }, |
| 238 | + }); |
| 239 | + |
| 240 | + const commandOutputs: Record<string, any[]> = {}; |
| 241 | + |
| 242 | + client.middlewareStack.add((next, context) => async (args) => { |
| 243 | + const r = await next(args); |
| 244 | + commandOutputs[context.commandName!] = commandOutputs[context.commandName!] ?? []; |
| 245 | + commandOutputs[context.commandName!].push(r.output); |
| 246 | + return r; |
| 247 | + }); |
| 248 | + |
| 249 | + requireRequestsFrom(client) |
| 250 | + .toMatch({ |
| 251 | + hostname: /amazon/, |
| 252 | + }) |
| 253 | + .respondWith( |
| 254 | + new HttpResponse({ |
| 255 | + statusCode: 200, |
| 256 | + headers: { |
| 257 | + "x-amz-id-2": |
| 258 | + "abc123def456ghi789jkl012mno345pqr678stu901vwx234yzA567BCD890EFG123HIJ456KLM789NOP012QRS345TUV", |
| 259 | + "x-amz-request-id": "ABCD1234EFGH5678", |
| 260 | + date: "Fri, 26 Sep 2025 17:30:00 GMT", |
| 261 | + etag: '"d41d8cd98f00b204e9800998ecf8427e"', |
| 262 | + "x-amz-checksum-crc32": "AAAAAA==", |
| 263 | + "x-amz-checksum-type": "CRC32", |
| 264 | + "x-amz-server-side-encryption": "AES256", |
| 265 | + "x-amz-version-id": "null", |
| 266 | + "content-length": "0", |
| 267 | + server: "AmazonS3", |
| 268 | + }, |
| 269 | + }) |
| 270 | + ); |
| 271 | + |
| 272 | + const uploadOutput = await new Upload({ |
| 273 | + client, |
| 274 | + params: { |
| 275 | + Bucket: "bucket", |
| 276 | + Key: "small-file-key", |
| 277 | + Body: randomBytes(1024), // 1KB - small enough to use PutObject |
| 278 | + }, |
| 279 | + }).done(); |
| 280 | + |
| 281 | + expect(commandOutputs).toEqual({ |
| 282 | + PutObjectCommand: [ |
| 283 | + { |
| 284 | + $metadata: { |
| 285 | + httpStatusCode: 200, |
| 286 | + requestId: "ABCD1234EFGH5678", |
| 287 | + extendedRequestId: |
| 288 | + "abc123def456ghi789jkl012mno345pqr678stu901vwx234yzA567BCD890EFG123HIJ456KLM789NOP012QRS345TUV", |
| 289 | + attempts: 1, |
| 290 | + totalRetryDelay: 0, |
| 291 | + }, |
| 292 | + ETag: '"d41d8cd98f00b204e9800998ecf8427e"', |
| 293 | + ChecksumCRC32: "AAAAAA==", |
| 294 | + ChecksumType: "CRC32", |
| 295 | + ServerSideEncryption: "AES256", |
| 296 | + VersionId: "null", |
| 297 | + }, |
| 298 | + ], |
| 299 | + }); |
| 300 | + |
| 301 | + expect(uploadOutput).toMatchObject(commandOutputs.PutObjectCommand[0]); |
| 302 | + }); |
280 | 303 | }, 60_000); |
0 commit comments