-
Notifications
You must be signed in to change notification settings - Fork 587
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
fix(middleware-sdk-s3): bug fix for middleware and test refactor
- Loading branch information
Showing
5 changed files
with
111 additions
and
57 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
140 changes: 94 additions & 46 deletions
140
packages/middleware-sdk-s3/src/region-redirect-middleware.e2e.spec.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,58 +1,106 @@ | ||
import { | ||
CreateBucketCommand, | ||
DeleteBucketCommand, | ||
DeleteObjectCommand, | ||
GetObjectCommand, | ||
PutObjectCommand, | ||
S3Client, | ||
} from "@aws-sdk/client-s3"; | ||
import { STS } from "@aws-sdk/client-sts"; | ||
|
||
const regionConfigs = [ | ||
{ region: "us-east-1", followRegionRedirects: true }, | ||
{ region: "eu-west-1", followRegionRedirects: true }, | ||
{ region: "us-west-2", followRegionRedirects: true }, | ||
]; | ||
|
||
const s3Clients = regionConfigs.map((config) => new S3Client(config)); | ||
import { S3 } from "@aws-sdk/client-s3"; | ||
import { GetCallerIdentityCommandOutput, STS } from "@aws-sdk/client-sts"; | ||
|
||
const testValue = "Hello S3 global client!"; | ||
|
||
async function testS3GlobalClient() { | ||
describe("S3 Global Client Test", () => { | ||
const regionConfigs = [ | ||
{ region: "us-east-1", followRegionRedirects: true }, | ||
{ region: "eu-west-1", followRegionRedirects: true }, | ||
{ region: "us-west-2", followRegionRedirects: true }, | ||
]; | ||
const s3Clients = regionConfigs.map((config) => new S3(config)); | ||
const stsClient = new STS({}); | ||
|
||
const callerID = await stsClient.getCallerIdentity({}); | ||
|
||
const bucketNames = regionConfigs.map((config) => `${callerID.Account}-redirect-${config.region}`); | ||
await Promise.all( | ||
bucketNames.map((bucketName, index) => s3Clients[index].send(new CreateBucketCommand({ Bucket: bucketName }))) | ||
); | ||
// Upload objects to each bucket | ||
for (const bucketName of bucketNames) { | ||
for (const s3Client of s3Clients) { | ||
const objKey = `object-from-${await s3Client.config.region()}-client`; | ||
await s3Client.send(new PutObjectCommand({ Bucket: bucketName, Key: objKey, Body: testValue })); | ||
let callerID = null as unknown as GetCallerIdentityCommandOutput; | ||
let bucketNames = [] as string[]; | ||
|
||
beforeAll(async () => { | ||
jest.setTimeout(500000); | ||
callerID = await stsClient.getCallerIdentity({}); | ||
bucketNames = regionConfigs.map((config) => `${callerID.Account}-redirect-${config.region}`); | ||
await Promise.all(bucketNames.map((bucketName, index) => deleteBucket(s3Clients[index], bucketName))); | ||
await Promise.all(bucketNames.map((bucketName, index) => s3Clients[index].createBucket({ Bucket: bucketName }))); | ||
}); | ||
|
||
afterAll(async () => { | ||
await Promise.all(bucketNames.map((bucketName, index) => deleteBucket(s3Clients[index], bucketName))); | ||
}); | ||
|
||
it("Should be able to put objects following region redirect", async () => { | ||
// Upload objects to each bucket | ||
for (const bucketName of bucketNames) { | ||
for (const s3Client of s3Clients) { | ||
const objKey = `object-from-${await s3Client.config.region()}-client`; | ||
await s3Client.putObject({ Bucket: bucketName, Key: objKey, Body: testValue }); | ||
} | ||
} | ||
} | ||
}, 50000); | ||
|
||
// Fetch, assert, and delete objects | ||
for (const bucketName of bucketNames) { | ||
for (const s3Client of s3Clients) { | ||
const objKey = `object-from-${await s3Client.config.region()}-client`; | ||
const { Body } = await s3Client.send(new GetObjectCommand({ Bucket: bucketName, Key: objKey })); | ||
const data = await Body?.transformToString(); | ||
expect(data).toEqual(testValue); | ||
await s3Client.send(new DeleteObjectCommand({ Bucket: bucketName, Key: objKey })); | ||
it("Should be able to get objects following region redirect", async () => { | ||
// Fetch and assert objects | ||
for (const bucketName of bucketNames) { | ||
for (const s3Client of s3Clients) { | ||
const objKey = `object-from-${await s3Client.config.region()}-client`; | ||
const { Body } = await s3Client.getObject({ Bucket: bucketName, Key: objKey }); | ||
const data = await Body?.transformToString(); | ||
expect(data).toEqual(testValue); | ||
} | ||
} | ||
}, 50000); | ||
|
||
it("Should delete objects following region redirect", async () => { | ||
for (const bucketName of bucketNames) { | ||
for (const s3Client of s3Clients) { | ||
const objKey = `object-from-${await s3Client.config.region()}-client`; | ||
await s3Client.deleteObject({ Bucket: bucketName, Key: objKey }); | ||
} | ||
} | ||
}, 50000); | ||
}); | ||
|
||
async function deleteBucket(s3: S3, bucketName: string) { | ||
const Bucket = bucketName; | ||
|
||
try { | ||
await s3.headBucket({ | ||
Bucket, | ||
}); | ||
} catch (e) { | ||
return; | ||
} | ||
|
||
for (let i = 0; i < s3Clients.length; ++i) { | ||
await s3Clients[i].send(new DeleteBucketCommand({ Bucket: bucketNames[(i + 1) % bucketNames.length] })); | ||
const list = await s3 | ||
.listObjects({ | ||
Bucket, | ||
}) | ||
.catch((e) => { | ||
if (!String(e).includes("NoSuchBucket")) { | ||
throw e; | ||
} | ||
return { | ||
Contents: [], | ||
}; | ||
}); | ||
|
||
const promises = [] as any[]; | ||
for (const key of list.Contents ?? []) { | ||
promises.push( | ||
s3.deleteObject({ | ||
Bucket, | ||
Key: key.Key, | ||
}) | ||
); | ||
} | ||
} | ||
await Promise.all(promises); | ||
|
||
describe("S3 Global Client Test", () => { | ||
it("Can perform all operations cross-regionally by following region redirect", async () => { | ||
await testS3GlobalClient(); | ||
}, 50000); | ||
}); | ||
try { | ||
return await s3.deleteBucket({ | ||
Bucket, | ||
}); | ||
} catch (e) { | ||
if (!String(e).includes("NoSuchBucket")) { | ||
throw e; | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters