Skip to content

test_s3 versioning multi object delete - add more versions for each object#687

Merged
cbodley merged 2 commits intoceph:masterfrom
BBoozmen:wip-72375
Sep 10, 2025
Merged

test_s3 versioning multi object delete - add more versions for each object#687
cbodley merged 2 commits intoceph:masterfrom
BBoozmen:wip-72375

Conversation

@BBoozmen
Copy link
Contributor

@BBoozmen BBoozmen commented Sep 3, 2025

Related ceph PR: ceph/ceph#64800 which changes the handling of the multi object delete for versioned buckets.

Related tracker: https://tracker.ceph.com/issues/72375

Ran the fix from ceph/ceph#64800 with this updated testcase:

$ S3TEST_CONF=./s3tests_vstart.conf tox -- s3tests_boto3/functional/test_s3.py::test_versioning_concurrent_multi_object_delete
...
collected 1 item

s3tests_boto3/functional/test_s3.py .
...
================================================================================================= 1 passed, 11 warnings in 3.04s ==================================================================================================
  py: OK (7.18=setup[3.74]+cmd[3.43] seconds)
  congratulations :) (7.24 seconds)

NOTE: Warnings are SyntaxWarning for some untouched lines.

Later added the 2nd commit to also check "Versions" key in the response dict for list_object API call as Contents is already not in:

>>> response = c.list_object_versions(Bucket="oozmen-yf2h37n9754h5ohsns2vaf-1")
>>> response
{'ResponseMetadata': {'RequestId': 'tx00000216387569507080c-0068b84fa6-4191-default', 'HostId': '', 'HTTPStatusCode': 200, 'HTTPHeaders': {'transfer-encoding': 'chunked', 'x-amz-request-id': 'tx00000216387569507080c-0068b84fa6-4191-default', 'content-type': 'application/xml', 'server': 'Ceph Object Gateway (tentacle)', 'date': 'Wed, 03 Sep 2025 14:24:38 GMT', 'connection': 'Keep-Alive'}, 'RetryAttempts': 0}, 'IsTruncated': False, 'KeyMarker': '', 'VersionIdMarker': '', 'Versions': [{'ETag': '"9a53cbcc7dbaf825c0f5309a57c63070"', 'Size': 5, 'StorageClass': 'STANDARD', 'Key': 'key_0', 'VersionId': 'KZbb840Zaq5GyWaDkqlrgaQzrmCmyyZ', 'IsLatest': True, 'LastModified': datetime.datetime(2025, 9, 2, 21, 17, 46, tzinfo=tzlocal()), 'Owner': {'DisplayName': 'M. Tester', 'ID': 'testid'}}, {'ETag': '"bcc0f76ba3ff7262fd88be8c1728708f"', 'Size': 5, 'StorageClass': 'STANDARD', 'Key': 'key_1', 'VersionId': 'fR7Dy7fUO9nffHhB6cLMGmCQOlPFson', 'IsLatest': True, 'LastModified': datetime.datetime(2025, 9, 2, 21, 17, 46, tzinfo=tzlocal()), 'Owner': {'DisplayName': 'M. Tester', 'ID': 'testid'}}, {'ETag': '"24fd6a24d80aabe2116d80b6c3dc89e2"', 'Size': 5, 'StorageClass': 'STANDARD', 'Key': 'key_2', 'VersionId': 'JBc.IaisMpk2DKpupsoXZpebQwDR4hy', 'IsLatest': True, 'LastModified': datetime.datetime(2025, 9, 2, 21, 17, 46, tzinfo=tzlocal()), 'Owner': {'DisplayName': 'M. Tester', 'ID': 'testid'}}, {'ETag': '"29e96a50c5e61e8f7ab39134d50e4b0b"', 'Size': 5, 'StorageClass': 'STANDARD', 'Key': 'key_3', 'VersionId': 'WWDX7WwClQaYGgkFTVl1HuSEZyNTGUk', 'IsLatest': True, 'LastModified': datetime.datetime(2025, 9, 2, 21, 17, 46, tzinfo=tzlocal()), 'Owner': {'DisplayName': 'M. Tester', 'ID': 'testid'}}, {'ETag': '"d261b2f59f6b454da23a5fd5444180c0"', 'Size': 5, 'StorageClass': 'STANDARD', 'Key': 'key_4', 'VersionId': 'kVyjR-AB6dJtAxFnAi-qp6MRAl2A9o7', 'IsLatest': True, 'LastModified': datetime.datetime(2025, 9, 2, 21, 17, 46, tzinfo=tzlocal()), 'Owner': {'DisplayName': 'M. Tester', 'ID': 'testid'}}], 'Name': 'oozmen-yf2h37n9754h5ohsns2vaf-1', 'Prefix': '', 'MaxKeys': 1000, 'EncodingType': 'url'}
>>> response.keys()
dict_keys(['ResponseMetadata', 'IsTruncated', 'KeyMarker', 'VersionIdMarker', 'Versions', 'Name', 'Prefix', 'MaxKeys', 'EncodingType'])

…bject

Signed-off-by: Oguzhan Ozmen <oozmen@bloomberg.net>
@BBoozmen
Copy link
Contributor Author

BBoozmen commented Sep 3, 2025

@cbodley - realizing that list_objects response output doesn't include any key 'Contents' but 'Versions' which is what the testcase uses already to retrieve objects/versions:

client = get_client()
versions = client.list_object_versions(Bucket=bucket_name)['Versions']

added a second commit to check for the 'Versions' key to verify bucket is indeed emptied.

…ersioning

Extend test_versioning_concurrent_multi_object_delete to also verify that
list_object_versions returns no Versions or DeleteMarkers after all objects
and their versions have been deleted. This ensures both list_objects and
list_object_versions reflect an empty bucket.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants