@@ -124,6 +124,21 @@ describe('abortMultipartUpload', () => {
124124 } , abortRequest ) ;
125125 } ) ;
126126 } ) ;
127+
128+ it ( 'should return error if data backend fails to abort' , done => {
129+ const testError = new Error ( 'Data backend abort failed' ) ;
130+ // This stub is now more explicit to avoid side-effects.
131+ data . abortMPU . callsFake ( ( objKey , upId , loc , bucket , req , destB , locCheckFn , log , cb ) => {
132+ cb ( testError ) ;
133+ } ) ;
134+ createBucketAndMPU ( false , ( err , uploadId ) => {
135+ assert . ifError ( err ) ;
136+ abortMultipartUpload ( authInfo , bucketName , objectKey , uploadId , log , err => {
137+ assert . deepStrictEqual ( err , testError ) ;
138+ done ( ) ;
139+ } , { ...abortRequest , query : { uploadId } } ) ;
140+ } ) ;
141+ } ) ;
127142 } ) ;
128143
129144 describe ( 'with multipart upload parts' , ( ) => {
@@ -182,6 +197,45 @@ describe('abortMultipartUpload', () => {
182197 } ) ;
183198 } ) ;
184199
200+ it ( 'should NOT search for orphans on non-versioned bucket with mismatched master uploadId' , done => {
201+ const standardMetadataValidateStub = sinon . stub ( metadataUtils , 'standardMetadataValidateBucketAndObj' ) ;
202+ const mockBucket = {
203+ isVersioningEnabled : ( ) => false ,
204+ getOwner : ( ) => 'testCanonicalId' ,
205+ getName : ( ) => bucketName ,
206+ } ;
207+ const mockMasterMD = { 'uploadId' : 'master-id' } ;
208+ standardMetadataValidateStub . yields ( null , mockBucket , mockMasterMD ) ;
209+
210+ abortMultipartUpload ( authInfo , bucketName , objectKey , 'abort-id' , log , err => {
211+ assert . ifError ( err ) ;
212+ sinon . assert . notCalled ( findObjectVersionStub ) ;
213+ done ( ) ;
214+ } , { ...abortRequest , query : { uploadId : 'abort-id' } } ) ;
215+ } ) ;
216+
217+ it ( 'should proceed without cleanup if finding object version fails' , done => {
218+ const testError = new Error ( 'Find version failed' ) ;
219+ findObjectVersionStub . yields ( testError ) ;
220+ const deleteObjectMDStub = sinon . stub ( metadata , 'deleteObjectMD' ) . yields ( null ) ;
221+
222+ const standardMetadataValidateStub = sinon . stub ( metadataUtils , 'standardMetadataValidateBucketAndObj' ) ;
223+ const mockBucket = {
224+ isVersioningEnabled : ( ) => true ,
225+ getOwner : ( ) => 'testCanonicalId' ,
226+ getName : ( ) => bucketName ,
227+ } ;
228+ const mockMasterMD = { 'uploadId' : 'master-id' } ;
229+ standardMetadataValidateStub . yields ( null , mockBucket , mockMasterMD ) ;
230+
231+ abortMultipartUpload ( authInfo , bucketName , objectKey , 'abort-id' , log , err => {
232+ assert . ifError ( err ) ;
233+ sinon . assert . calledOnce ( findObjectVersionStub ) ;
234+ sinon . assert . notCalled ( deleteObjectMDStub ) ;
235+ done ( ) ;
236+ } , { ...abortRequest , query : { uploadId : 'abort-id' } } ) ;
237+ } ) ;
238+
185239 it ( 'should delete the correct orphaned object version' , done => {
186240 const deleteObjectMDStub = sinon . stub ( metadata , 'deleteObjectMD' ) . yields ( null ) ;
187241 findObjectVersionStub . yields ( null , { uploadId : 'abort-id' , versionId : 'orphan-vid' } ) ;
@@ -192,9 +246,7 @@ describe('abortMultipartUpload', () => {
192246 getOwner : ( ) => 'testCanonicalId' ,
193247 getName : ( ) => bucketName ,
194248 } ;
195- const mockMasterMD = {
196- 'uploadId' : 'master-id' ,
197- } ;
249+ const mockMasterMD = { 'uploadId' : 'master-id' } ;
198250 standardMetadataValidateStub . yields ( null , mockBucket , mockMasterMD ) ;
199251
200252 abortMultipartUpload ( authInfo , bucketName , objectKey , 'abort-id' , log , err => {
@@ -204,5 +256,25 @@ describe('abortMultipartUpload', () => {
204256 done ( ) ;
205257 } , { ...abortRequest , query : { uploadId : 'abort-id' } } ) ;
206258 } ) ;
259+
260+ it ( 'should proceed if orphaned object version is already deleted (NoSuchKey)' , done => {
261+ const deleteObjectMDStub = sinon . stub ( metadata , 'deleteObjectMD' ) . yields ( errors . NoSuchKey ) ;
262+ findObjectVersionStub . yields ( null , { uploadId : 'abort-id' , versionId : 'orphan-vid' } ) ;
263+
264+ const standardMetadataValidateStub = sinon . stub ( metadataUtils , 'standardMetadataValidateBucketAndObj' ) ;
265+ const mockBucket = {
266+ isVersioningEnabled : ( ) => true ,
267+ getOwner : ( ) => 'testCanonicalId' ,
268+ getName : ( ) => bucketName ,
269+ } ;
270+ const mockMasterMD = { 'uploadId' : 'master-id' } ;
271+ standardMetadataValidateStub . yields ( null , mockBucket , mockMasterMD ) ;
272+
273+ abortMultipartUpload ( authInfo , bucketName , objectKey , 'abort-id' , log , err => {
274+ assert . ifError ( err ) ;
275+ sinon . assert . calledOnce ( deleteObjectMDStub ) ;
276+ done ( ) ;
277+ } , { ...abortRequest , query : { uploadId : 'abort-id' } } ) ;
278+ } ) ;
207279 } ) ;
208280} ) ;
0 commit comments