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" ; 
@@ -7,153 +7,130 @@ import { afterAll, beforeAll, describe, expect, test as it } from "vitest";
77import  {  getIntegTestResources  }  from  "../../../tests/e2e/get-integ-test-resources" ; 
88
99describe ( "@aws-sdk/lib-storage" ,  ( )  =>  { 
10-   let  Key : string ; 
11-   let  client : S3 ; 
12-   let  data : Uint8Array ; 
13-   let  dataString : string ; 
14-   let  Bucket : string ; 
15-   let  region : string ; 
16- 
17-   beforeAll ( async  ( )  =>  { 
18-     const  integTestResourcesEnv  =  await  getIntegTestResources ( ) ; 
19-     Object . assign ( process . env ,  integTestResourcesEnv ) ; 
20- 
21-     region  =  process ?. env ?. AWS_SMOKE_TEST_REGION  as  string ; 
22-     Bucket  =  process ?. env ?. AWS_SMOKE_TEST_BUCKET  as  string ; 
23- 
24-     Key  =  `` ; 
25-     data  =  randomBytes ( 20_240_000 ) ; 
26-     dataString  =  data . toString ( ) ; 
27- 
28-     client  =  new  S3 ( { 
29-       region, 
30-       // ToDo(JS-5678): Remove this when default checksum is supported by Upload. 
31-       requestChecksumCalculation : "WHEN_REQUIRED" , 
32-     } ) ; 
33-   } ) ; 
34- 
35-   describe ( "Upload" ,  ( )  =>  { 
36-     beforeAll ( ( )  =>  { 
37-       Key  =  `multi-part-file-${ Date . now ( ) }  ; 
38-     } ) ; 
39-     afterAll ( async  ( )  =>  { 
40-       await  client . deleteObject ( {  Bucket,  Key } ) ; 
41-     } ) ; 
42- 
43-     it ( "should upload in parts for input type bytes" ,  async  ( )  =>  { 
44-       const  s3Upload  =  new  Upload ( { 
45-         client, 
46-         params : { 
47-           Bucket, 
48-           Key, 
49-           Body : data , 
50-         } , 
51-       } ) ; 
52-       await  s3Upload . done ( ) ; 
53- 
54-       const  object  =  await  client . getObject ( { 
55-         Bucket, 
56-         Key, 
57-       } ) ; 
58- 
59-       expect ( await  object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ; 
60-     } ) ; 
61- 
62-     it ( "should upload in parts for input type string" ,  async  ( )  =>  { 
63-       const  s3Upload  =  new  Upload ( { 
64-         client, 
65-         params : { 
66-           Bucket, 
67-           Key, 
68-           Body : dataString , 
69-         } , 
70-       } ) ; 
71-       await  s3Upload . done ( ) ; 
72- 
73-       const  object  =  await  client . getObject ( { 
74-         Bucket, 
75-         Key, 
76-       } ) ; 
77- 
78-       expect ( await  object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ; 
79-     } ) ; 
80- 
81-     it ( "should upload in parts for input type Readable" ,  async  ( )  =>  { 
82-       const  s3Upload  =  new  Upload ( { 
83-         client, 
84-         params : { 
85-           Bucket, 
86-           Key, 
87-           Body : Readable . from ( data ) , 
88-         } , 
89-       } ) ; 
90-       await  s3Upload . done ( ) ; 
91- 
92-       const  object  =  await  client . getObject ( { 
93-         Bucket, 
94-         Key, 
95-       } ) ; 
96- 
97-       expect ( await  object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ; 
98-     } ) ; 
99- 
100-     it ( "should call AbortMultipartUpload if unable to complete a multipart upload." ,  async  ( )  =>  { 
101-       class  MockFailureS3  extends  S3  { 
102-         public  counter  =  0 ; 
103-         async  send ( command : any ,  ...rest : any [ ] )  { 
104-           if  ( command ?. constructor ?. name  ===  "UploadPartCommand"  &&  this . counter ++  %  3  ===  0 )  { 
105-             throw  new  Error ( "simulated upload part error" ) ; 
10+   describe . each ( [ undefined ,  "WHEN_REQUIRED" ,  "WHEN_SUPPORTED" ] ) ( 
11+     "requestChecksumCalculation: %s" , 
12+     ( 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 ( ) }  ; 
44+         } ) ; 
45+ 
46+         afterAll ( async  ( )  =>  { 
47+           await  client . deleteObject ( {  Bucket,  Key } ) ; 
48+         } ) ; 
49+ 
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 ( ) ; 
56+ 
57+           const  object  =  await  client . getObject ( {  Bucket,  Key } ) ; 
58+           expect ( await  object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ; 
59+         } ) ; 
60+ 
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 ( ) ; 
67+ 
68+           const  object  =  await  client . getObject ( {  Bucket,  Key } ) ; 
69+           expect ( await  object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ; 
70+         } ) ; 
71+ 
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 ( ) ; 
78+ 
79+           const  object  =  await  client . getObject ( {  Bucket,  Key } ) ; 
80+           expect ( await  object . Body ?. transformToString ( ) ) . toEqual ( dataString ) ; 
81+         } ) ; 
82+ 
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+             } 
10692          } 
107-           return  super . send ( command ,  ...rest ) ; 
108-         } 
109-       } 
110- 
111-       const  client  =  new  MockFailureS3 ( { 
112-         region, 
113-       } ) ; 
11493
115-       const  requestLog  =  [ ]  as  string [ ] ; 
116- 
117-       client . middlewareStack . add ( 
118-         ( next ,  context )  =>  async  ( args )  =>  { 
119-           const  result  =  await  next ( args ) ; 
120-           requestLog . push ( [ context . clientName ,  context . commandName ,  result . output . $metadata . httpStatusCode ] . join ( " " ) ) ; 
121-           return  result ; 
122-         } , 
123-         { 
124-           name : "E2eRequestLog" , 
125-           step : "build" , 
126-           override : true , 
127-         } 
128-       ) ; 
129- 
130-       const  s3Upload  =  new  Upload ( { 
131-         client, 
132-         params : { 
133-           Bucket, 
134-           Key, 
135-           Body : data , 
136-         } , 
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+           ] ) ; 
132+         } ) ; 
137133      } ) ; 
138-       // eslint-disable-next-line @typescript-eslint/no-unused-vars 
139-       await  s3Upload . done ( ) . catch ( ( ignored )  =>  { } ) ; 
140- 
141-       const  uploadStatus  =  await  client 
142-         . listParts ( { 
143-           Bucket, 
144-           Key, 
145-           UploadId : s3Upload . uploadId , 
146-         } ) 
147-         . then ( ( listParts )  =>  listParts . $metadata . httpStatusCode ) 
148-         . catch ( ( err )  =>  err . toString ( ) ) ; 
149- 
150-       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 \. / ) ; 
151-       expect ( requestLog ) . toEqual ( [ 
152-         "S3Client CreateMultipartUploadCommand 200" , 
153-         "S3Client UploadPartCommand 200" , 
154-         "S3Client UploadPartCommand 200" , 
155-         "S3Client AbortMultipartUploadCommand 204" , 
156-       ] ) ; 
157-     } ) ; 
158-   } ) ; 
134+     } 
135+   ) ; 
159136} ,  45_000 ) ; 
0 commit comments