@@ -580,113 +580,107 @@ describe('Object Part Copy', () => {
580580 } ) ;
581581 } ) ;
582582
583- it ( 'should not corrupt object if overwriting an existing part by copying a part ' +
583+ it . only ( 'should not corrupt object if overwriting an existing part by copying a part ' +
584584 'while the MPU is being completed' , async ( ) => {
585- const finalObjETag = '"db77ebbae9e9f5a244a26b86193ad818-1"' ;
586- process . stdout . write ( 'Putting first part in MPU test"' ) ;
587- const randomDestObjName = `copycatobject${ Math . floor ( Math . random ( ) * 100000 ) } ` ;
585+ const finalObjETag = '"db77ebbae9e9f5a244a26b86193ad818-1"' ;
586+ process . stdout . write ( 'Putting first part in MPU test"' ) ;
587+ const randomDestObjName = `copycatobject${ Math . floor ( Math . random ( ) * 100000 ) } ` ;
588588
589- const initiateRes = await s3
590- . createMultipartUpload ( {
589+ const initiateRes = await s3
590+ . createMultipartUpload ( {
591591 Bucket : destBucketName ,
592592 Key : randomDestObjName ,
593- } )
594- . promise ( ) ;
595- const uploadId = initiateRes . UploadId ;
593+ } )
594+ . promise ( ) ;
595+ const uploadId = initiateRes . UploadId ;
596596
597- const res = await s3
598- . uploadPartCopy ( {
597+ const res = await s3
598+ . uploadPartCopy ( {
599599 Bucket : destBucketName ,
600600 Key : randomDestObjName ,
601601 CopySource : `${ sourceBucketName } /${ sourceObjName } ` ,
602602 PartNumber : 1 ,
603603 UploadId : uploadId ,
604- } )
605- . promise ( ) ;
606- assert . strictEqual ( res . ETag , etag ) ;
607- assert ( res . LastModified ) ;
604+ } )
605+ . promise ( ) ;
606+ assert . strictEqual ( res . ETag , etag ) ;
607+ assert ( res . LastModified ) ;
608608
609- process . stdout . write (
610- 'Overwriting first part in MPU test and completing MPU at the same time' ,
611- ) ;
609+ process . stdout . write (
610+ 'Overwriting first part in MPU test and completing MPU at the same time' ,
611+ ) ;
612612
613- const completeMPU = ( ) => s3
614- . completeMultipartUpload ( {
615- Bucket : destBucketName ,
616- Key : randomDestObjName ,
617- UploadId : uploadId ,
618- MultipartUpload : {
619- Parts : [ { ETag : etag , PartNumber : 1 } ] ,
620- } ,
621- } ) . promise ( ) ;
622-
623- const [ completeRes , uploadRes ] = await Promise . all ( [
624- completeMPU ( )
613+ const [ completeRes , uploadRes ] = await Promise . all ( [
614+ s3
615+ . completeMultipartUpload ( {
616+ Bucket : destBucketName ,
617+ Key : randomDestObjName ,
618+ UploadId : uploadId ,
619+ MultipartUpload : {
620+ Parts : [ { ETag : etag , PartNumber : 1 } ] ,
621+ } ,
622+ } ) . promise ( )
625623 . catch ( async err => {
626- // The completeMPU delete part in a 2 steps
627- // (first mark it as deletion with `delete: true` in Mongo, then delete it).
628- // At the same time, the uploadPartCopy update the same data in Mongo.
629- // In that case, the completeMPU fail with an InternalError (DeleteConflict in the logs)
630- const raceConditionOccurred = err && err . code === 'InternalError' ;
631-
632- if ( raceConditionOccurred ) {
633- process . stdout . write ( 'Retrying the complete MPU' ) ;
634-
635- try {
636- await completeMPU ( ) ;
637- } catch ( e ) {
638- if ( e . code === 'NoSuchUpload' ) {
639- process . stdout . write ( 'Race condition done' ) ;
624+ // The completeMPU delete part in a 2 steps
625+ // (first mark it as deletion with `delete: true` in Mongo, then delete it).
626+ // At the same time, the uploadPartCopy update the same data in Mongo.
627+ // In that case, the completeMPU fail with an InternalError (DeleteConflict in the logs)
628+ const raceConditionOccurred = err ?. code === 'InternalError'
629+ && err ?. message === 'conflict deleting MPU parts metadata' ;
630+
631+ console . info ( {
632+ raceConditionOccurred,
633+ err,
634+ message : err ?. message ,
635+ description : err . description ,
636+ code : err ?. code ,
637+ } ) ;
638+
639+ if ( raceConditionOccurred ) {
640640 return Promise . resolve ( null ) ;
641- }
642-
643- throw e ;
644641 }
645-
646- throw new Error ( 'Expected error on the retry of complete MPU' ) ;
647- }
648642
649- throw err ;
643+ throw err ;
650644 } ) ,
651- s3
645+ s3
652646 . uploadPartCopy ( {
653- Bucket : destBucketName ,
654- Key : randomDestObjName ,
655- CopySource : `${ sourceBucketName } /${ sourceObjName } ` ,
656- PartNumber : 1 ,
657- UploadId : uploadId ,
647+ Bucket : destBucketName ,
648+ Key : randomDestObjName ,
649+ CopySource : `${ sourceBucketName } /${ sourceObjName } ` ,
650+ PartNumber : 1 ,
651+ UploadId : uploadId ,
658652 } )
659653 . promise ( )
660654 . catch ( err => {
661- const completeMPUFinishedEarlier =
662- err && err . code === 'NoSuchKey' ;
663- if ( completeMPUFinishedEarlier ) {
664- return Promise . resolve ( null ) ;
665- }
655+ const completeMPUFinishedEarlier = err && err . code === 'NoSuchKey' ;
656+ if ( completeMPUFinishedEarlier ) {
657+ return Promise . resolve ( null ) ;
658+ }
666659
667- throw err ;
660+ throw err ;
668661 } ) ,
669- ] ) ;
662+ ] ,
663+ ) ;
670664
671- if ( uploadRes !== null ) {
672- assert . strictEqual ( uploadRes . ETag , etag ) ;
673- assert ( uploadRes . LastModified ) ;
674- }
665+ if ( uploadRes !== null ) {
666+ assert . strictEqual ( uploadRes . ETag , etag ) ;
667+ assert ( uploadRes . LastModified ) ;
668+ }
675669
676- if ( completeRes !== null ) {
677- assert . strictEqual ( completeRes . Bucket , destBucketName ) ;
678- assert . strictEqual ( completeRes . Key , randomDestObjName ) ;
679- assert . strictEqual ( completeRes . ETag , finalObjETag ) ;
680- }
670+ if ( completeRes !== null ) {
671+ assert . strictEqual ( completeRes . Bucket , destBucketName ) ;
672+ assert . strictEqual ( completeRes . Key , randomDestObjName ) ;
673+ assert . strictEqual ( completeRes . ETag , finalObjETag ) ;
674+ }
681675
682- process . stdout . write ( 'Getting object put by MPU with overwrite part' ) ;
683- const resGet = await s3
684- . getObject ( {
676+ process . stdout . write ( 'Getting object put by MPU with overwrite part' ) ;
677+ const resGet = await s3
678+ . getObject ( {
685679 Bucket : destBucketName ,
686680 Key : randomDestObjName ,
687- } )
688- . promise ( ) ;
689- assert . strictEqual ( resGet . ETag , finalObjETag ) ;
681+ } )
682+ . promise ( ) ;
683+ assert . strictEqual ( resGet . ETag , finalObjETag ) ;
690684 } ) ;
691685 } ) ;
692686
0 commit comments