Skip to content

Commit a788cad

Browse files
committed
feat(lib-storage): s3TM constructor and add event listener tests
1 parent 79d394f commit a788cad

File tree

2 files changed

+137
-44
lines changed

2 files changed

+137
-44
lines changed
Lines changed: 137 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import { S3, S3Client } from "@aws-sdk/client-s3";
2+
import { TransferCompleteEvent, TransferEvent } from "@aws-sdk/lib-storage/dist-types/s3-transfer-manager/types";
13
import { beforeAll, describe, expect, test as it, vi } from "vitest";
24

35
import { S3TransferManager } from "./S3TransferManager";
@@ -13,11 +15,138 @@ import { S3TransferManager } from "./S3TransferManager";
1315
*/
1416

1517
describe("S3TransferManager Unit Tests", () => {
18+
let client: S3;
19+
let Bucket: string;
20+
let region: string;
21+
22+
beforeAll(async () => {
23+
region = "us-west-1";
24+
Bucket = "lukachad-us-west-2";
25+
26+
client = new S3({
27+
region,
28+
responseChecksumValidation: "WHEN_REQUIRED",
29+
});
30+
});
31+
describe("S3TransferManager Constructor", () => {
32+
it("Should create an instance of S3TransferManager with defaults given no parameters", () => {
33+
const defaultS3Client = new S3Client({
34+
requestChecksumCalculation: "WHEN_SUPPORTED",
35+
responseChecksumValidation: "WHEN_SUPPORTED",
36+
});
37+
const tm = new S3TransferManager() as any;
38+
39+
expect(tm.s3ClientInstance).toBeInstanceOf(S3Client);
40+
expect(tm.targetPartSizeBytes).toBe(8 * 1024 * 1024);
41+
expect(tm.multipartUploadThresholdBytes).toBe(16 * 1024 * 1024);
42+
expect(tm.checksumValidationEnabled).toBe(true);
43+
expect(tm.checksumAlgorithm).toBe("CRC32");
44+
expect(tm.multipartDownloadType).toBe("PART");
45+
expect(tm.eventListeners).toEqual({
46+
transferInitiated: [],
47+
bytesTransferred: [],
48+
transferComplete: [],
49+
transferFailed: [],
50+
});
51+
});
52+
53+
it("Should create an instance of S3TransferManager with all given parameters", () => {
54+
const eventListeners = {
55+
transferInitiated: [() => console.log("transferInitiated")],
56+
bytesTransferred: [() => console.log("bytesTransferred")],
57+
transferComplete: [() => console.log("transferComplete")],
58+
transferFailed: [() => console.log("transferFailed")],
59+
};
60+
const tm = new S3TransferManager({
61+
s3ClientInstance: client,
62+
targetPartSizeBytes: 8 * 1024 * 1024,
63+
checksumValidationEnabled: true,
64+
checksumAlgorithm: "CRC32",
65+
multipartDownloadType: "RANGE",
66+
eventListeners: eventListeners,
67+
}) as any;
68+
69+
expect(tm.s3ClientInstance).toBe(client);
70+
expect(tm.targetPartSizeBytes).toBe(8 * 1024 * 1024);
71+
expect(tm.checksumValidationEnabled).toBe(true);
72+
expect(tm.checksumAlgorithm).toBe("CRC32");
73+
expect(tm.multipartDownloadType).toBe("RANGE");
74+
expect(tm.eventListeners).toEqual(eventListeners);
75+
});
76+
77+
it("Should throw an error given targetPartSizeBytes smaller than minimum", () => {
78+
expect(() => {
79+
new S3TransferManager({
80+
targetPartSizeBytes: 2 * 1024 * 1024,
81+
});
82+
}).toThrow(`targetPartSizeBytes must be at least ${5 * 1024 * 1024} bytes`);
83+
});
84+
});
85+
86+
describe("EventListener functions", () => {
87+
let tm: S3TransferManager;
88+
89+
function initiated(event: TransferEvent) {
90+
return {
91+
request: event.request,
92+
snapshot: event.snapshot,
93+
};
94+
}
95+
function transferring(event: TransferEvent) {
96+
return {
97+
request: event.request,
98+
snapshot: event.snapshot,
99+
};
100+
}
101+
function completed(event: TransferCompleteEvent) {
102+
return {
103+
request: event.request,
104+
snapshot: event.snapshot,
105+
response: event.response,
106+
};
107+
}
108+
function failed(event: TransferEvent) {
109+
return {
110+
request: event.request,
111+
snapshot: event.snapshot,
112+
};
113+
}
114+
115+
beforeAll(async () => {
116+
tm = new S3TransferManager({
117+
s3ClientInstance: client,
118+
});
119+
});
120+
121+
describe("addEventListener", () => {
122+
it("Should add a new listener for each callback", () => {
123+
tm.addEventListener("transferInitiated", initiated);
124+
tm.addEventListener("bytesTransferred", transferring);
125+
tm.addEventListener("transferComplete", completed);
126+
tm.addEventListener("transferFailed", failed);
127+
128+
expect((tm as any).eventListeners).toEqual({
129+
transferInitiated: [initiated],
130+
bytesTransferred: [transferring],
131+
transferComplete: [completed],
132+
transferFailed: [failed],
133+
});
134+
});
135+
136+
it("Should append new listeners for a callback");
137+
});
138+
139+
describe.skip("dispatchEvent"), () => {};
140+
141+
describe.skip("removeEventListener"), () => {};
142+
});
143+
16144
describe("validateExpectedRanges()", () => {
17145
let tm: any;
18146
beforeAll(async () => {
19147
tm = new S3TransferManager() as any;
20148
}, 120_000);
149+
21150
it("Should pass correct sequential ranges without throwing an error", () => {
22151
const ranges = [
23152
"bytes 0-5242879/13631488",
@@ -31,6 +160,7 @@ describe("S3TransferManager Unit Tests", () => {
31160
}).not.toThrow();
32161
}
33162
});
163+
34164
it("Should throw error for incomplete download", () => {
35165
const ranges = [
36166
"bytes 0-5242879/13631488",
@@ -44,40 +174,15 @@ describe("S3TransferManager Unit Tests", () => {
44174
"Range validation failed: Final part did not cover total range of 13631488. Expected range of bytes 10485760-314572"
45175
);
46176
});
47-
it("Should throw error for non-sequential ranges", () => {
48-
const previousRange = "bytes 0-5242879/13631488";
49-
const invalidRange = "bytes 5242881-10485759/13631488"; // 1 byte off
50177

178+
it.each([
179+
["bytes 5242881-10485759/13631488", "Expected part 2 to start at 5242880 but got 5242881"], // 1 byte off
180+
["bytes 5242879-10485759/13631488", "Expected part 2 to start at 5242880 but got 5242879"], // overlap
181+
["bytes 0-5242879/13631488", "Expected part 2 to start at 5242880 but got 0"], // duplicate
182+
])("Should throw error for non-sequential range: %s", (invalidRange, expectedError) => {
51183
expect(() => {
52-
tm.validateExpectedRanges(previousRange, invalidRange, 2);
53-
}).toThrow("Expected part 2 to start at 5242880 but got 5242881");
54-
});
55-
it("Should throw error for non-sequential ranges", () => {
56-
const previousRange = "bytes 0-5242879/13631488";
57-
const invalidRange = "bytes 5242879-10485759/13631488";
58-
59-
expect(() => {
60-
tm.validateExpectedRanges(previousRange, invalidRange, 2);
61-
}).toThrow("Expected part 2 to start at 5242880 but got 5242879");
62-
});
63-
it("Should throw error for non-sequential ranges", () => {
64-
const previousRange = "bytes 0-5242879/13631488";
65-
const invalidRange = "bytes 0-5242879/13631488";
66-
67-
expect(() => {
68-
tm.validateExpectedRanges(previousRange, invalidRange, 2);
69-
}).toThrow("Expected part 2 to start at 5242880 but got 0");
70-
});
71-
it("Should throw error for non-sequential ranges", () => {
72-
const previousRange = "bytes 0-5242879/13631488";
73-
const invalidRange = "bytes 0-5242879/13631488";
74-
75-
expect(() => {
76-
tm.validateExpectedRanges(previousRange, invalidRange, 2);
77-
}).toThrow("Expected part 2 to start at 5242880 but got 0");
184+
tm.validateExpectedRanges("bytes 0-5242879/13631488", invalidRange, 2);
185+
}).toThrow(expectedError);
78186
});
79187
});
80-
// describe("EventTarget functions tests", () => {
81-
82-
// })
83188
});

lib/lib-storage/src/s3-transfer-manager/S3TransferManager.ts

Lines changed: 0 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -442,18 +442,6 @@ export class S3TransferManager implements IS3TransferManager {
442442
if (this.targetPartSizeBytes < S3TransferManager.MIN_PART_SIZE) {
443443
throw new Error(`targetPartSizeBytes must be at least ${S3TransferManager.MIN_PART_SIZE} bytes`);
444444
}
445-
446-
if (
447-
this.checksumAlgorithm != "CRC32" &&
448-
this.checksumAlgorithm != "CRC32C" &&
449-
this.checksumAlgorithm != "CRC64NVME" &&
450-
this.checksumAlgorithm != "SHA1" &&
451-
this.checksumAlgorithm != "SHA256"
452-
) {
453-
throw new Error(
454-
`Invalid checksumAlgorithm. Must be one of the following: CRC32, CRC32C, CRC64NVME, SHA1, SHA256`
455-
);
456-
}
457445
}
458446

459447
private dispatchTransferInitiatedEvent(request: DownloadRequest | UploadRequest, totalSize?: number): boolean {

0 commit comments

Comments
 (0)