From ad7f2d73267741338d166cc502f5fb79a72ca313 Mon Sep 17 00:00:00 2001 From: Kefu Chai Date: Wed, 5 Nov 2025 14:08:26 +0800 Subject: [PATCH] nuke_bucket: Abort multipart uploads before bucket deletion The nuke_bucket cleanup function was failing to delete buckets that had ongoing multipart uploads because it only deleted objects but didn't abort the uploads. This caused test teardown to fail with BucketNotEmpty errors when tests left multipart uploads incomplete. Add logic to list and abort all multipart uploads in a bucket before attempting to delete it. This ensures clean test teardown even when tests fail or don't complete their uploads. This change is necessary for S3 implementations that correctly enforce the requirement that buckets with ongoing multipart uploads cannot be deleted, while still supporting deferred cleanup of part data (where AbortMultipartUpload removes metadata immediately but storage cleanup happens asynchronously). Signed-off-by: Kefu Chai --- s3tests/functional/__init__.py | 12 ++++++++++++ 1 file changed, 12 insertions(+) diff --git a/s3tests/functional/__init__.py b/s3tests/functional/__init__.py index fbea948e5..e8d938445 100644 --- a/s3tests/functional/__init__.py +++ b/s3tests/functional/__init__.py @@ -136,6 +136,18 @@ def nuke_bucket(client, bucket): Delete={'Objects': objects, 'Quiet': True}, BypassGovernanceRetention=True) + # abort any ongoing multipart uploads before deleting the bucket + try: + uploads = client.list_multipart_uploads(Bucket=bucket) + for upload in uploads.get('Uploads', []): + client.abort_multipart_upload( + Bucket=bucket, + Key=upload['Key'], + UploadId=upload['UploadId'] + ) + except ClientError: + pass # bucket might not exist or have no uploads + client.delete_bucket(Bucket=bucket) def nuke_prefixed_buckets(prefix, client=None):