From: Jacques Heunis Date: Mon, 16 Mar 2026 15:13:02 +0000 (+0000) Subject: s3: Add a test for attempting to complete an unstarted multipart upload X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=4fd31db4665803832104f4111461ce6b03d66233;p=s3-tests.git s3: Add a test for attempting to complete an unstarted multipart upload The AWS documentation for CompleteMultipartUpload specifies that the call will return a 404 with the text "NoSuchUpload" to indicate that the specified multipart upload does not exist. This could be the result of an invalid upload ID or a multipart upload that has been aborted or completed. Of particular significance is the requirement that this API call return a 400-series error (indicating a client-side problem) and not a 500-series error (indicating a server-size problem). At the time of writing, Ceph returns a 500 in this scenario which may be handled incorrectly by client SDKs and is likely to be misinterpreted by Ceph monitoring as an increase in errors that require operator intervention to fix. CompleteMultipartUpload docs available at: https://docs.aws.amazon.com/AmazonS3/latest/API/API_CompleteMultipartUpload.html Signed-off-by: Jacques Heunis (cherry picked from commit 5506af825b6dde397da7926cdcab889ff537c506) --- diff --git a/s3tests/functional/test_s3.py b/s3tests/functional/test_s3.py index d063caf3..f089642a 100644 --- a/s3tests/functional/test_s3.py +++ b/s3tests/functional/test_s3.py @@ -5975,6 +5975,25 @@ def test_multipart_upload_empty(): assert status == 400 assert error_code == 'MalformedXML' +@pytest.mark.fails_on_rgw # TODO: Remove fails_on_rgw when https://tracker.ceph.com/issues/75534 is fixed +def test_multipart_upload_complete_without_create(): + bucket_name = get_new_bucket() + client = get_client() + + parts = {} + upload_opts = { + 'Bucket': bucket_name, + 'Key': 'mymultipart', + 'UploadId': 'abc1234def', + 'MultipartUpload': {'Parts': [ + {'ETag': "1234", 'PartNumber': 1} + ]} + } + e = assert_raises(ClientError, client.complete_multipart_upload, **upload_opts) + status, error_code = _get_status_and_error_code(e.response) + assert status == 404 + assert error_code == 'NoSuchUpload' + @pytest.mark.fails_on_dbstore def test_multipart_upload_small(): bucket_name = get_new_bucket()