Skip to content

Commit 396fc77

Browse files
authored
test(client-s3): convert some read ops to waiters (#6622)
1 parent 62ae71a commit 396fc77

File tree

2 files changed

+102
-19
lines changed

2 files changed

+102
-19
lines changed

clients/client-s3/test/e2e/S3.browser.e2e.spec.ts

+58-11
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
import type { S3, SelectObjectContentEventStream } from "@aws-sdk/client-s3";
22
import { fromNodeProviderChain } from "@aws-sdk/credential-providers";
33
import { FetchHttpHandler } from "@smithy/fetch-http-handler";
4-
import { afterEach, beforeAll, beforeEach, describe, expect, test as it } from "vitest";
4+
import { afterAll, afterEach, beforeAll, beforeEach, describe, expect, onTestFailed, test as it } from "vitest";
55

66
import { getIntegTestResources } from "../../../../tests/e2e/get-integ-test-resources";
77
import { getRuntimeConfig } from "../../src/runtimeConfig.browser";
8-
import { S3 as S3Impl } from "../browser-build/browser-s3-bundle";
8+
import { S3 as S3Impl, waitUntilObjectExists } from "../browser-build/browser-s3-bundle";
99
import { createBuffer } from "./helpers";
1010

1111
describe("@aws-sdk/client-s3", () => {
@@ -14,6 +14,11 @@ describe("@aws-sdk/client-s3", () => {
1414
let region: string;
1515
let mrapArn: string;
1616
let Key = `${Date.now()}`;
17+
const errors = [] as any[];
18+
let testFailed = false;
19+
const setTestFailed = () => {
20+
testFailed = true;
21+
};
1722

1823
beforeAll(async () => {
1924
const integTestResourcesEnv = await getIntegTestResources();
@@ -28,10 +33,28 @@ describe("@aws-sdk/client-s3", () => {
2833
region,
2934
credentials: fromNodeProviderChain(),
3035
requestHandler: new FetchHttpHandler(),
36+
logger: {
37+
trace() {},
38+
debug() {},
39+
info() {},
40+
warn() {},
41+
error(entry: any) {
42+
errors.push(entry);
43+
},
44+
},
3145
})
3246
) as unknown as S3;
3347
});
3448

49+
afterAll(() => {
50+
if (testFailed) {
51+
console.info("Test failed, logging errors collecting during test.");
52+
for (const error of errors) {
53+
console.error(error);
54+
}
55+
}
56+
});
57+
3558
describe("PutObject", () => {
3659
beforeEach(() => {
3760
Key = `${Date.now()}`;
@@ -47,6 +70,7 @@ describe("@aws-sdk/client-s3", () => {
4770
// Caused by: RequestContentLengthMismatchError: Request body length does not match content-length header
4871
// only in vitest + happy-dom.
4972
it.skip("should succeed with blob body", async () => {
73+
onTestFailed(setTestFailed);
5074
const blob = new Blob([buf]);
5175
const result = await client.putObject({
5276
Bucket,
@@ -58,6 +82,7 @@ describe("@aws-sdk/client-s3", () => {
5882
});
5983

6084
it("should succeed with TypedArray body", async () => {
85+
onTestFailed(setTestFailed);
6186
const result = await client.putObject({
6287
Bucket,
6388
Key,
@@ -67,6 +92,7 @@ describe("@aws-sdk/client-s3", () => {
6792
});
6893

6994
it("should succeed with ReadableStream body", async () => {
95+
onTestFailed(setTestFailed);
7096
const length = 10 * 1000; // 10KB
7197
const chunkSize = 10;
7298
const readableStream = new ReadableStream({
@@ -102,6 +128,7 @@ describe("@aws-sdk/client-s3", () => {
102128
});
103129

104130
it("should succeed with valid body payload", async () => {
131+
onTestFailed(setTestFailed);
105132
// prepare the object.
106133
const body = createBuffer("1MB");
107134

@@ -133,7 +160,9 @@ describe("@aws-sdk/client-s3", () => {
133160
afterEach(async () => {
134161
await client.deleteObject({ Bucket, Key });
135162
});
163+
136164
it("should succeed with valid bucket", async () => {
165+
onTestFailed(setTestFailed);
137166
const result = await client.listObjects({
138167
Bucket,
139168
});
@@ -142,6 +171,7 @@ describe("@aws-sdk/client-s3", () => {
142171
});
143172

144173
it("should throw with invalid bucket", () => {
174+
onTestFailed(setTestFailed);
145175
expect(() => client.listObjects({ Bucket: "invalid-bucket" })).rejects.toThrow();
146176
});
147177
});
@@ -150,9 +180,11 @@ describe("@aws-sdk/client-s3", () => {
150180
let UploadId: string;
151181
let Etag: string;
152182
const multipartObjectKey = `${Key}-multipart`;
183+
153184
beforeEach(() => {
154185
Key = `${Date.now()}`;
155186
});
187+
156188
afterEach(async () => {
157189
if (UploadId) {
158190
await client.abortMultipartUpload({
@@ -168,7 +200,9 @@ describe("@aws-sdk/client-s3", () => {
168200
});
169201

170202
it("should successfully create, upload list and complete", async () => {
171-
//create multipart upload
203+
onTestFailed(setTestFailed);
204+
205+
// create multipart upload
172206
const createResult = await client.createMultipartUpload({
173207
Bucket,
174208
Key: multipartObjectKey,
@@ -209,15 +243,23 @@ describe("@aws-sdk/client-s3", () => {
209243
expect(completeResult.$metadata.httpStatusCode).toEqual(200);
210244

211245
//validate the object is uploaded
212-
const headResult = await client.headObject({
213-
Bucket,
214-
Key: multipartObjectKey,
215-
});
216-
expect(headResult.$metadata.httpStatusCode).toEqual(200);
246+
const waiterState = await waitUntilObjectExists(
247+
{
248+
client,
249+
maxWaitTime: 60,
250+
},
251+
{
252+
Bucket,
253+
Key: multipartObjectKey,
254+
}
255+
);
256+
expect(waiterState.state).toEqual("SUCCESS");
217257
});
218258

219259
it("should successfully create, abort, and list upload", async () => {
220-
//create multipart upload
260+
onTestFailed(setTestFailed);
261+
262+
// create multipart upload
221263
const createResult = await client.createMultipartUpload({
222264
Bucket,
223265
Key: multipartObjectKey,
@@ -248,14 +290,18 @@ describe("@aws-sdk/client-s3", () => {
248290
jsrocks,13
249291
node4life,22
250292
esfuture,29`;
293+
251294
beforeEach(async () => {
252295
Key = `${Date.now()}`;
253296
await client.putObject({ Bucket, Key, Body: csvFile });
254297
});
298+
255299
afterEach(async () => {
256300
await client.deleteObject({ Bucket, Key });
257301
});
302+
258303
it("should succeed", async () => {
304+
onTestFailed(setTestFailed);
259305
const { Payload } = await client.selectObjectContent({
260306
Bucket,
261307
Key,
@@ -287,8 +333,9 @@ esfuture,29`;
287333
beforeEach(async () => {
288334
Key = `${Date.now()}`;
289335
});
290-
afterEach(async () => {});
336+
291337
it("should throw for aws-crt no available in browser", async () => {
338+
onTestFailed(setTestFailed);
292339
try {
293340
await client.listObjects({
294341
Bucket: mrapArn,
@@ -299,4 +346,4 @@ esfuture,29`;
299346
}
300347
});
301348
});
302-
});
349+
}, 60_000);

packages/middleware-sdk-s3/src/region-redirect-middleware.e2e.spec.ts

+44-8
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,32 @@
1-
import { S3 } from "@aws-sdk/client-s3";
1+
import { S3, S3ClientConfig, waitUntilBucketExists, waitUntilBucketNotExists } from "@aws-sdk/client-s3";
22
import { GetCallerIdentityCommandOutput, STS } from "@aws-sdk/client-sts";
3-
import { afterAll, beforeAll, describe, expect, test as it } from "vitest";
3+
import { afterAll, beforeAll, describe, expect, onTestFailed, test as it } from "vitest";
44

55
const testValue = "Hello S3 global client!";
66

77
describe("S3 Global Client Test", () => {
8+
const errors = [] as any[];
9+
let testFailed = false;
10+
const setTestFailed = () => {
11+
testFailed = true;
12+
};
13+
814
const regionConfigs = [
9-
{ region: "us-east-1", followRegionRedirects: true },
10-
{ region: "eu-west-1", followRegionRedirects: true },
11-
{ region: "us-west-2", followRegionRedirects: true },
12-
];
15+
{ region: "us-east-1", followRegionRedirects: true } as S3ClientConfig,
16+
{ region: "eu-west-1", followRegionRedirects: true } as S3ClientConfig,
17+
{ region: "us-west-2", followRegionRedirects: true } as S3ClientConfig,
18+
].map((config) => {
19+
config.logger = {
20+
trace() {},
21+
debug() {},
22+
info() {},
23+
warn() {},
24+
error(entry: any) {
25+
errors.push(entry);
26+
},
27+
};
28+
return config;
29+
});
1330
const s3Clients = regionConfigs.map((config) => new S3(config));
1431
const stsClient = new STS({});
1532

@@ -24,16 +41,33 @@ describe("S3 Global Client Test", () => {
2441
beforeAll(async () => {
2542
callerID = await stsClient.getCallerIdentity({});
2643
bucketNames = regionConfigs.map((config) => `${callerID.Account}-${randId}-redirect-${config.region}`);
27-
await Promise.all(bucketNames.map((bucketName, index) => deleteBucket(s3Clients[index], bucketName)));
28-
await Promise.all(bucketNames.map((bucketName, index) => s3Clients[index].createBucket({ Bucket: bucketName })));
44+
await Promise.all(
45+
bucketNames.map(async (bucketName, index) => {
46+
await deleteBucket(s3Clients[index], bucketName);
47+
return waitUntilBucketNotExists({ client: s3Clients[index], maxWaitTime: 60 }, { Bucket: bucketName });
48+
})
49+
);
50+
await Promise.all(
51+
bucketNames.map(async (bucketName, index) => {
52+
await s3Clients[index].createBucket({ Bucket: bucketName });
53+
return waitUntilBucketExists({ client: s3Clients[index], maxWaitTime: 60 }, { Bucket: bucketName });
54+
})
55+
);
2956
await Promise.all(bucketNames.map((bucketName, index) => s3Clients[index].headBucket({ Bucket: bucketName })));
3057
});
3158

3259
afterAll(async () => {
3360
await Promise.all(bucketNames.map((bucketName, index) => deleteBucket(s3Clients[index], bucketName)));
61+
if (testFailed) {
62+
console.info("Test failed, logging errors collecting during test.");
63+
for (const error of errors) {
64+
console.error(error);
65+
}
66+
}
3467
});
3568

3669
it("Should be able to put objects following region redirect", async () => {
70+
onTestFailed(setTestFailed);
3771
// Upload objects to each bucket
3872
for (const bucketName of bucketNames) {
3973
for (const s3Client of s3Clients) {
@@ -44,6 +78,7 @@ describe("S3 Global Client Test", () => {
4478
});
4579

4680
it("Should be able to get objects following region redirect", async () => {
81+
onTestFailed(setTestFailed);
4782
// Fetch and assert objects
4883
for (const bucketName of bucketNames) {
4984
for (const s3Client of s3Clients) {
@@ -57,6 +92,7 @@ describe("S3 Global Client Test", () => {
5792
});
5893

5994
it("Should delete objects following region redirect", async () => {
95+
onTestFailed(setTestFailed);
6096
for (const bucketName of bucketNames) {
6197
for (const s3Client of s3Clients) {
6298
const objKey = `object-from-${await s3Client.config.region()}-client`;

0 commit comments

Comments
 (0)