Skip to content

Commit c33ba90

Browse files
committed
fix(lib-storage): use input parameter object size information if available
1 parent ad1514d commit c33ba90

File tree

2 files changed

+72
-20
lines changed

2 files changed

+72
-20
lines changed

lib/lib-storage/src/Upload.spec.ts

Lines changed: 62 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,23 @@
1+
import {
2+
CompleteMultipartUploadCommand,
3+
CompleteMultipartUploadCommandOutput,
4+
CreateMultipartUploadCommand,
5+
PutObjectCommand,
6+
PutObjectTaggingCommand,
7+
S3,
8+
S3Client,
9+
UploadPartCommand,
10+
} from "@aws-sdk/client-s3";
11+
import { AbortController } from "@smithy/abort-controller";
12+
import { EventEmitter, Readable } from "stream";
113
import { afterAll, afterEach, beforeEach, describe, expect, test as it, vi } from "vitest";
214

15+
import { Progress, Upload } from "./index";
16+
317
/* eslint-disable no-var */
418
var hostname = "s3.region.amazonaws.com";
519
var port: number | undefined;
620

7-
import { EventEmitter, Readable } from "stream";
8-
921
vi.mock("@aws-sdk/client-s3", async () => {
1022
const sendMock = vi.fn().mockImplementation(async (x) => x);
1123
const endpointMock = vi.fn().mockImplementation(() => ({
@@ -61,24 +73,20 @@ vi.mock("@aws-sdk/client-s3", async () => {
6173
};
6274
});
6375

64-
import {
65-
CompleteMultipartUploadCommand,
66-
CompleteMultipartUploadCommandOutput,
67-
CreateMultipartUploadCommand,
68-
PutObjectCommand,
69-
PutObjectTaggingCommand,
70-
S3,
71-
S3Client,
72-
UploadPartCommand,
73-
} from "@aws-sdk/client-s3";
74-
import { AbortController } from "@smithy/abort-controller";
75-
76-
import { Progress, Upload } from "./index";
77-
7876
const DEFAULT_PART_SIZE = 1024 * 1024 * 5;
7977

78+
type Expose = {
79+
totalBytes: number | undefined;
80+
};
81+
type VisibleForTesting = Omit<Upload, keyof Expose> & Expose;
82+
8083
describe(Upload.name, () => {
81-
const s3MockInstance = new S3Client();
84+
const s3MockInstance = new S3Client({
85+
credentials: {
86+
accessKeyId: "UNIT",
87+
secretAccessKey: "UNIT",
88+
},
89+
});
8290

8391
beforeEach(() => {
8492
vi.clearAllMocks();
@@ -107,6 +115,43 @@ describe(Upload.name, () => {
107115
Body: "this-is-a-sample-payload",
108116
};
109117

118+
it("uses the input parameters for object length if provided", async () => {
119+
const falseFileStream = Object.assign(Readable.from("abcd"), {
120+
path: "/dev/null",
121+
});
122+
let upload = new Upload({
123+
params: {
124+
Bucket: "",
125+
Key: "",
126+
Body: falseFileStream,
127+
MpuObjectSize: 6 * 1024 * 1024,
128+
},
129+
client: s3MockInstance,
130+
}) as unknown as VisibleForTesting;
131+
expect(upload.totalBytes).toEqual(6 * 1024 * 1024);
132+
133+
upload = new Upload({
134+
params: {
135+
Bucket: "",
136+
Key: "",
137+
Body: falseFileStream,
138+
ContentLength: 6 * 1024 * 1024,
139+
},
140+
client: s3MockInstance,
141+
}) as unknown as VisibleForTesting;
142+
expect(upload.totalBytes).toEqual(6 * 1024 * 1024);
143+
144+
upload = new Upload({
145+
params: {
146+
Bucket: "",
147+
Key: "",
148+
Body: falseFileStream,
149+
},
150+
client: s3MockInstance,
151+
}) as unknown as VisibleForTesting;
152+
expect(upload.totalBytes).toEqual(0);
153+
});
154+
110155
it("correctly exposes the event emitter API", () => {
111156
const upload = new Upload({
112157
params,

lib/lib-storage/src/Upload.ts

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,15 +3,18 @@ import {
33
ChecksumAlgorithm,
44
CompletedPart,
55
CompleteMultipartUploadCommand,
6+
CompleteMultipartUploadCommandInput,
67
CompleteMultipartUploadCommandOutput,
78
CreateMultipartUploadCommand,
9+
CreateMultipartUploadCommandInput,
810
CreateMultipartUploadCommandOutput,
911
PutObjectCommand,
1012
PutObjectCommandInput,
1113
PutObjectTaggingCommand,
1214
S3Client,
1315
Tag,
1416
UploadPartCommand,
17+
UploadPartCommandInput,
1518
} from "@aws-sdk/client-s3";
1619
import { AbortController } from "@smithy/abort-controller";
1720
import {
@@ -52,7 +55,8 @@ export class Upload extends EventEmitter {
5255
private readonly tags: Tag[] = [];
5356

5457
private readonly client: S3Client;
55-
private readonly params: PutObjectCommandInput;
58+
private readonly params: PutObjectCommandInput &
59+
Partial<CreateMultipartUploadCommandInput & UploadPartCommandInput & CompleteMultipartUploadCommandInput>;
5660

5761
// used for reporting progress.
5862
private totalBytes?: number;
@@ -89,12 +93,15 @@ export class Upload extends EventEmitter {
8993
this.params = options.params;
9094

9195
// set progress defaults
92-
this.totalBytes = byteLength(this.params.Body);
96+
this.totalBytes = this.params.MpuObjectSize ?? this.params.ContentLength ?? byteLength(this.params.Body);
9397
this.bytesUploadedSoFar = 0;
9498
this.abortController = options.abortController ?? new AbortController();
9599

96100
this.partSize = Math.max(Upload.MIN_PART_SIZE, Math.floor((this.totalBytes || 0) / this.MAX_PARTS));
97-
this.expectedPartsCount = this.totalBytes !== undefined ? Math.ceil(this.totalBytes / this.partSize) : undefined;
101+
102+
if (this.totalBytes !== undefined) {
103+
this.expectedPartsCount = Math.ceil(this.totalBytes / this.partSize);
104+
}
98105

99106
this.__validateInput();
100107
}

0 commit comments

Comments
 (0)