1- import { S3 } from "@aws-sdk/client-s3" ;
1+ import { ChecksumAlgorithm , S3 } from "@aws-sdk/client-s3" ;
22import { Upload } from "@aws-sdk/lib-storage" ;
33import { randomBytes } from "crypto" ;
44import { Readable } from "stream" ;
@@ -10,128 +10,126 @@ describe("@aws-sdk/lib-storage", () => {
1010 describe . each ( [ undefined , "WHEN_REQUIRED" , "WHEN_SUPPORTED" ] ) (
1111 "requestChecksumCalculation: %s" ,
1212 ( requestChecksumCalculation ) => {
13- let Key : string ;
14- let client : S3 ;
15- let data : Uint8Array ;
16- let dataString : string ;
17- let Bucket : string ;
18- let region : string ;
19-
20- beforeAll ( async ( ) => {
21- const integTestResourcesEnv = await getIntegTestResources ( ) ;
22- Object . assign ( process . env , integTestResourcesEnv ) ;
23-
24- region = process ?. env ?. AWS_SMOKE_TEST_REGION as string ;
25- Bucket = process ?. env ?. AWS_SMOKE_TEST_BUCKET as string ;
26-
27- Key = `` ;
28- data = randomBytes ( 20_240_000 ) ;
29- dataString = data . toString ( ) ;
30-
31- // @ts -expect-error: Types of property 'requestChecksumCalculation' are incompatible
32- client = new S3 ( {
33- region,
34- requestChecksumCalculation,
13+ describe . each ( [
14+ undefined ,
15+ ChecksumAlgorithm . SHA1 ,
16+ ChecksumAlgorithm . SHA256 ,
17+ ChecksumAlgorithm . CRC32 ,
18+ ChecksumAlgorithm . CRC32C ,
19+ ] ) ( "ChecksumAlgorithm: %s" , ( ChecksumAlgorithm ) => {
20+ let Key : string ;
21+ let client : S3 ;
22+ let data : Uint8Array ;
23+ let dataString : string ;
24+ let Bucket : string ;
25+ let region : string ;
26+
27+ beforeAll ( async ( ) => {
28+ const integTestResourcesEnv = await getIntegTestResources ( ) ;
29+ Object . assign ( process . env , integTestResourcesEnv ) ;
30+
31+ region = process ?. env ?. AWS_SMOKE_TEST_REGION as string ;
32+ Bucket = process ?. env ?. AWS_SMOKE_TEST_BUCKET as string ;
33+
34+ Key = `` ;
35+ data = randomBytes ( 20_240_000 ) ;
36+ dataString = data . toString ( ) ;
37+
38+ // @ts -expect-error: Types of property 'requestChecksumCalculation' are incompatible
39+ client = new S3 ( {
40+ region,
41+ requestChecksumCalculation,
42+ } ) ;
43+ Key = `multi-part-file-${ requestChecksumCalculation } -${ ChecksumAlgorithm } -${ Date . now ( ) } ` ;
3544 } ) ;
36- Key = `multi-part-file-${ requestChecksumCalculation } -${ Date . now ( ) } ` ;
37- } ) ;
38-
39- afterAll ( async ( ) => {
40- await client . deleteObject ( { Bucket, Key } ) ;
41- } ) ;
4245
43- it ( "should upload in parts for input type bytes" , async ( ) => {
44- const s3Upload = new Upload ( {
45- client,
46- params : { Bucket, Key, Body : data } ,
46+ afterAll ( async ( ) => {
47+ await client . deleteObject ( { Bucket, Key } ) ;
4748 } ) ;
48- await s3Upload . done ( ) ;
4949
50- const object = await client . getObject ( { Bucket, Key } ) ;
51- expect ( await object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ;
52- } ) ;
50+ it ( "should upload in parts for input type bytes" , async ( ) => {
51+ const s3Upload = new Upload ( {
52+ client,
53+ params : { Bucket, Key, Body : data , ChecksumAlgorithm } ,
54+ } ) ;
55+ await s3Upload . done ( ) ;
5356
54- it ( "should upload in parts for input type string" , async ( ) => {
55- const s3Upload = new Upload ( {
56- client,
57- params : { Bucket, Key, Body : dataString } ,
57+ const object = await client . getObject ( { Bucket, Key } ) ;
58+ expect ( await object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ;
5859 } ) ;
59- await s3Upload . done ( ) ;
6060
61- const object = await client . getObject ( { Bucket, Key } ) ;
62- expect ( await object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ;
63- } ) ;
61+ it ( "should upload in parts for input type string" , async ( ) => {
62+ const s3Upload = new Upload ( {
63+ client,
64+ params : { Bucket, Key, Body : dataString , ChecksumAlgorithm } ,
65+ } ) ;
66+ await s3Upload . done ( ) ;
6467
65- it ( "should upload in parts for input type Readable" , async ( ) => {
66- const s3Upload = new Upload ( {
67- client,
68- params : { Bucket, Key, Body : Readable . from ( data ) } ,
68+ const object = await client . getObject ( { Bucket, Key } ) ;
69+ expect ( await object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ;
6970 } ) ;
70- await s3Upload . done ( ) ;
71-
72- const object = await client . getObject ( { Bucket, Key } ) ;
73- expect ( await object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ;
74- } ) ;
7571
76- it ( "should call AbortMultipartUpload if unable to complete a multipart upload." , async ( ) => {
77- class MockFailureS3 extends S3 {
78- public counter = 0 ;
79- async send ( command : any , ...rest : any [ ] ) {
80- if ( command ?. constructor ?. name === "UploadPartCommand" && this . counter ++ % 3 === 0 ) {
81- throw new Error ( "simulated upload part error" ) ;
82- }
83- return super . send ( command , ...rest ) ;
84- }
85- }
72+ it ( "should upload in parts for input type Readable" , async ( ) => {
73+ const s3Upload = new Upload ( {
74+ client,
75+ params : { Bucket, Key, Body : Readable . from ( data ) , ChecksumAlgorithm } ,
76+ } ) ;
77+ await s3Upload . done ( ) ;
8678
87- const client = new MockFailureS3 ( {
88- region ,
79+ const object = await client . getObject ( { Bucket , Key } ) ;
80+ expect ( await object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ;
8981 } ) ;
9082
91- const requestLog = [ ] as string [ ] ;
92-
93- client . middlewareStack . add (
94- ( next , context ) => async ( args ) => {
95- const result = await next ( args ) ;
96- requestLog . push (
97- [ context . clientName , context . commandName , result . output . $metadata . httpStatusCode ] . join ( " " )
98- ) ;
99- return result ;
100- } ,
101- {
102- name : "E2eRequestLog" ,
103- step : "build" ,
104- override : true ,
83+ it ( "should call AbortMultipartUpload if unable to complete a multipart upload." , async ( ) => {
84+ class MockFailureS3 extends S3 {
85+ public counter = 0 ;
86+ async send ( command : any , ...rest : any [ ] ) {
87+ if ( command ?. constructor ?. name === "UploadPartCommand" && this . counter ++ % 3 === 0 ) {
88+ throw new Error ( "simulated upload part error" ) ;
89+ }
90+ return super . send ( command , ...rest ) ;
91+ }
10592 }
106- ) ;
107-
108- const s3Upload = new Upload ( {
109- client,
110- params : {
111- Bucket,
112- Key,
113- Body : data ,
114- } ,
93+
94+ const client = new MockFailureS3 ( { region } ) ;
95+
96+ const requestLog = [ ] as string [ ] ;
97+
98+ client . middlewareStack . add (
99+ ( next , context ) => async ( args ) => {
100+ const result = await next ( args ) ;
101+ requestLog . push (
102+ [ context . clientName , context . commandName , result . output . $metadata . httpStatusCode ] . join ( " " )
103+ ) ;
104+ return result ;
105+ } ,
106+ {
107+ name : "E2eRequestLog" ,
108+ step : "build" ,
109+ override : true ,
110+ }
111+ ) ;
112+
113+ const s3Upload = new Upload ( {
114+ client,
115+ params : { Bucket, Key, Body : data , ChecksumAlgorithm } ,
116+ } ) ;
117+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
118+ await s3Upload . done ( ) . catch ( ( ignored ) => { } ) ;
119+
120+ const uploadStatus = await client
121+ . listParts ( { Bucket, Key, UploadId : s3Upload . uploadId } )
122+ . then ( ( listParts ) => listParts . $metadata . httpStatusCode )
123+ . catch ( ( err ) => err . toString ( ) ) ;
124+
125+ expect ( uploadStatus ) . toMatch ( / N o S u c h U p l o a d : ( .* ?) a b o r t e d o r c o m p l e t e d \. / ) ;
126+ expect ( requestLog ) . toEqual ( [
127+ "S3Client CreateMultipartUploadCommand 200" ,
128+ "S3Client UploadPartCommand 200" ,
129+ "S3Client UploadPartCommand 200" ,
130+ "S3Client AbortMultipartUploadCommand 204" ,
131+ ] ) ;
115132 } ) ;
116- // eslint-disable-next-line @typescript-eslint/no-unused-vars
117- await s3Upload . done ( ) . catch ( ( ignored ) => { } ) ;
118-
119- const uploadStatus = await client
120- . listParts ( {
121- Bucket,
122- Key,
123- UploadId : s3Upload . uploadId ,
124- } )
125- . then ( ( listParts ) => listParts . $metadata . httpStatusCode )
126- . catch ( ( err ) => err . toString ( ) ) ;
127-
128- expect ( uploadStatus ) . toMatch ( / N o S u c h U p l o a d : ( .* ?) a b o r t e d o r c o m p l e t e d \. / ) ;
129- expect ( requestLog ) . toEqual ( [
130- "S3Client CreateMultipartUploadCommand 200" ,
131- "S3Client UploadPartCommand 200" ,
132- "S3Client UploadPartCommand 200" ,
133- "S3Client AbortMultipartUploadCommand 204" ,
134- ] ) ;
135133 } ) ;
136134 }
137135 ) ;
0 commit comments