Merge "s3api: Fix (async) multi-delete of MPUs"
This commit is contained in:
commit
b3c5a9a9e0
@ -17,6 +17,7 @@ import copy
|
||||
import json
|
||||
|
||||
from swift.common.constraints import MAX_OBJECT_NAME_LENGTH
|
||||
from swift.common.http import HTTP_NO_CONTENT
|
||||
from swift.common.utils import public, StreamingPile, get_swift_info
|
||||
|
||||
from swift.common.middleware.s3api.controllers.base import Controller, \
|
||||
@ -127,8 +128,11 @@ class MultiObjectDeleteController(Controller):
|
||||
|
||||
resp = req.get_response(self.app, method='DELETE', query=query,
|
||||
headers={'Accept': 'application/json'})
|
||||
# Have to read the response to actually do the SLO delete
|
||||
if query.get('multipart-manifest'):
|
||||
# If async segment cleanup is available, we expect to get
|
||||
# back a 204; otherwise, the delete is synchronous and we
|
||||
# have to read the response to actually do the SLO delete
|
||||
if query.get('multipart-manifest') and \
|
||||
resp.status_int != HTTP_NO_CONTENT:
|
||||
try:
|
||||
delete_result = json.loads(resp.body)
|
||||
if delete_result['Errors']:
|
||||
|
@ -62,14 +62,14 @@ class TestS3ApiMultiDelete(S3ApiTestCase):
|
||||
|
||||
@s3acl
|
||||
def test_object_multi_DELETE(self):
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/bucket/Key3',
|
||||
swob.HTTPOk,
|
||||
{'x-static-large-object': 'True'},
|
||||
None)
|
||||
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key1',
|
||||
swob.HTTPNoContent, {}, None)
|
||||
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key2',
|
||||
swob.HTTPNotFound, {}, None)
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/bucket/Key3',
|
||||
swob.HTTPOk,
|
||||
{'x-static-large-object': 'True'},
|
||||
None)
|
||||
slo_delete_resp = {
|
||||
'Number Not Found': 0,
|
||||
'Response Status': '200 OK',
|
||||
@ -79,9 +79,16 @@ class TestS3ApiMultiDelete(S3ApiTestCase):
|
||||
}
|
||||
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key3',
|
||||
swob.HTTPOk, {}, json.dumps(slo_delete_resp))
|
||||
self.swift.register('HEAD', '/v1/AUTH_test/bucket/Key4',
|
||||
swob.HTTPOk,
|
||||
{'x-static-large-object': 'True',
|
||||
'x-object-sysmeta-s3api-etag': 'some-etag'},
|
||||
None)
|
||||
self.swift.register('DELETE', '/v1/AUTH_test/bucket/Key4',
|
||||
swob.HTTPNoContent, {}, None)
|
||||
|
||||
elem = Element('Delete')
|
||||
for key in ['Key1', 'Key2', 'Key3']:
|
||||
for key in ['Key1', 'Key2', 'Key3', 'Key4']:
|
||||
obj = SubElement(elem, 'Object')
|
||||
SubElement(obj, 'Key').text = key
|
||||
body = tostring(elem, use_s3ns=False)
|
||||
@ -99,7 +106,8 @@ class TestS3ApiMultiDelete(S3ApiTestCase):
|
||||
self.assertEqual(status.split()[0], '200')
|
||||
|
||||
elem = fromstring(body)
|
||||
self.assertEqual(len(elem.findall('Deleted')), 3)
|
||||
self.assertEqual(len(elem.findall('Deleted')), 4)
|
||||
self.assertEqual(len(elem.findall('Error')), 0)
|
||||
self.assertEqual(self.swift.calls, [
|
||||
('HEAD', '/v1/AUTH_test/bucket'),
|
||||
('HEAD', '/v1/AUTH_test/bucket/Key1?symlink=get'),
|
||||
@ -108,6 +116,9 @@ class TestS3ApiMultiDelete(S3ApiTestCase):
|
||||
('DELETE', '/v1/AUTH_test/bucket/Key2'),
|
||||
('HEAD', '/v1/AUTH_test/bucket/Key3?symlink=get'),
|
||||
('DELETE', '/v1/AUTH_test/bucket/Key3?multipart-manifest=delete'),
|
||||
('HEAD', '/v1/AUTH_test/bucket/Key4?symlink=get'),
|
||||
('DELETE',
|
||||
'/v1/AUTH_test/bucket/Key4?async=on&multipart-manifest=delete'),
|
||||
])
|
||||
|
||||
@s3acl
|
||||
|
@ -1572,7 +1572,7 @@ class TestS3ApiObj(S3ApiTestCase):
|
||||
'x-object-sysmeta-s3api-etag': 's3-style-etag'},
|
||||
None)
|
||||
self.swift.register('DELETE', '/v1/AUTH_test/bucket/object',
|
||||
swob.HTTPOk, {}, '<SLO delete results>')
|
||||
swob.HTTPNoContent, {}, '')
|
||||
req = Request.blank('/bucket/object',
|
||||
environ={'REQUEST_METHOD': 'DELETE'},
|
||||
headers={'Authorization': 'AWS test:tester:hmac',
|
||||
|
Loading…
x
Reference in New Issue
Block a user