Merge "Add test for copy using a Range header"
This commit is contained in:
commit
7973bf8e9d
@ -1275,7 +1275,17 @@ class TestFile(Base):
|
||||
self.assertTrue(file_item.copy(
|
||||
'%s%s' % (prefix, cont), dest_filename, hdrs=extra_hdrs))
|
||||
|
||||
self.assertIn(dest_filename, cont.files())
|
||||
# verify container listing for copy
|
||||
listing = cont.files(parms={'format': 'json'})
|
||||
for obj in listing:
|
||||
if obj['name'] == dest_filename:
|
||||
break
|
||||
else:
|
||||
self.fail('Failed to find %s in listing' % dest_filename)
|
||||
|
||||
self.assertEqual(file_item.size, obj['bytes'])
|
||||
self.assertEqual(file_item.etag, obj['hash'])
|
||||
self.assertEqual(file_item.content_type, obj['content_type'])
|
||||
|
||||
file_copy = cont.file(dest_filename)
|
||||
|
||||
@ -1315,6 +1325,19 @@ class TestFile(Base):
|
||||
self.assertIn(k.lower(), resp_headers)
|
||||
self.assertEqual(v, resp_headers[k.lower()])
|
||||
|
||||
# verify container listing for copy
|
||||
listing = cont.files(parms={'format': 'json'})
|
||||
for obj in listing:
|
||||
if obj['name'] == dest_filename:
|
||||
break
|
||||
else:
|
||||
self.fail('Failed to find %s in listing' % dest_filename)
|
||||
|
||||
self.assertEqual(file_item.size, obj['bytes'])
|
||||
self.assertEqual(file_item.etag, obj['hash'])
|
||||
self.assertEqual(
|
||||
'application/test-changed', obj['content_type'])
|
||||
|
||||
# repeat copy with X-Fresh-Metadata header - existing user
|
||||
# metadata should not be copied, new completely replaces it.
|
||||
extra_hdrs = {'Content-Type': 'application/test-updated',
|
||||
@ -1337,6 +1360,63 @@ class TestFile(Base):
|
||||
for k in ('Content-Disposition', 'Content-Encoding'):
|
||||
self.assertNotIn(k.lower(), resp_headers)
|
||||
|
||||
# verify container listing for copy
|
||||
listing = cont.files(parms={'format': 'json'})
|
||||
for obj in listing:
|
||||
if obj['name'] == dest_filename:
|
||||
break
|
||||
else:
|
||||
self.fail('Failed to find %s in listing' % dest_filename)
|
||||
|
||||
self.assertEqual(file_item.size, obj['bytes'])
|
||||
self.assertEqual(file_item.etag, obj['hash'])
|
||||
self.assertEqual(
|
||||
'application/test-updated', obj['content_type'])
|
||||
|
||||
def testCopyRange(self):
|
||||
# makes sure to test encoded characters
|
||||
source_filename = 'dealde%2Fl04 011e%204c8df/flash.png'
|
||||
file_item = self.env.container.file(source_filename)
|
||||
|
||||
metadata = {Utils.create_ascii_name(): Utils.create_name()}
|
||||
|
||||
data = file_item.write_random(1024)
|
||||
file_item.sync_metadata(metadata)
|
||||
file_item.initialize()
|
||||
|
||||
dest_cont = self.env.account.container(Utils.create_name())
|
||||
self.assertTrue(dest_cont.create())
|
||||
|
||||
expected_body = data[100:201]
|
||||
expected_etag = hashlib.md5(expected_body)
|
||||
# copy both from within and across containers
|
||||
for cont in (self.env.container, dest_cont):
|
||||
# copy both with and without initial slash
|
||||
for prefix in ('', '/'):
|
||||
dest_filename = Utils.create_name()
|
||||
|
||||
file_item.copy('%s%s' % (prefix, cont), dest_filename,
|
||||
hdrs={'Range': 'bytes=100-200'})
|
||||
self.assertEqual(201, file_item.conn.response.status)
|
||||
|
||||
# verify container listing for copy
|
||||
listing = cont.files(parms={'format': 'json'})
|
||||
for obj in listing:
|
||||
if obj['name'] == dest_filename:
|
||||
break
|
||||
else:
|
||||
self.fail('Failed to find %s in listing' % dest_filename)
|
||||
|
||||
self.assertEqual(101, obj['bytes'])
|
||||
self.assertEqual(expected_etag.hexdigest(), obj['hash'])
|
||||
self.assertEqual(file_item.content_type, obj['content_type'])
|
||||
|
||||
# verify copy object
|
||||
copy_file_item = cont.file(dest_filename)
|
||||
self.assertEqual(expected_body, copy_file_item.read())
|
||||
self.assertTrue(copy_file_item.initialize())
|
||||
self.assertEqual(metadata, copy_file_item.metadata)
|
||||
|
||||
def testCopyAccount(self):
|
||||
# makes sure to test encoded characters
|
||||
source_filename = 'dealde%2Fl04 011e%204c8df/flash.png'
|
||||
@ -1427,10 +1507,9 @@ class TestFile(Base):
|
||||
|
||||
# invalid destination container
|
||||
file_item = self.env.container.file(source_filename)
|
||||
self.assertTrue(
|
||||
not file_item.copy(
|
||||
'%s%s' % (prefix, Utils.create_name()),
|
||||
Utils.create_name()))
|
||||
self.assertFalse(file_item.copy(
|
||||
'%s%s' % (prefix, Utils.create_name()),
|
||||
Utils.create_name()))
|
||||
|
||||
def testCopyAccount404s(self):
|
||||
acct = self.env.conn.account_name
|
||||
|
@ -1410,6 +1410,30 @@ class TestServerSideCopyMiddleware(unittest.TestCase):
|
||||
self.assertEqual('Not Bar', req_headers.get('X-Foo'))
|
||||
self.assertIn('X-Fresh-Metadata', req_headers)
|
||||
|
||||
def test_COPY_with_single_range(self):
|
||||
# verify that source etag is not copied when copying a range
|
||||
self.app.register('GET', '/v1/a/c/o', swob.HTTPOk,
|
||||
{'etag': 'bogus etag'}, "abcdefghijklmnop")
|
||||
self.app.register('PUT', '/v1/a/c1/o', swob.HTTPCreated, {})
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='COPY',
|
||||
headers={'Destination': 'c1/o',
|
||||
'Range': 'bytes=5-10'})
|
||||
|
||||
status, headers, body = self.call_ssc(req)
|
||||
|
||||
self.assertEqual(status, '201 Created')
|
||||
calls = self.app.calls_with_headers
|
||||
self.assertEqual(2, len(calls))
|
||||
method, path, req_headers = calls[1]
|
||||
self.assertEqual('PUT', method)
|
||||
self.assertEqual('/v1/a/c1/o', path)
|
||||
self.assertNotIn('etag', (h.lower() for h in req_headers))
|
||||
self.assertEqual('6', req_headers['content-length'])
|
||||
req = swob.Request.blank('/v1/a/c1/o', method='GET')
|
||||
status, headers, body = self.call_ssc(req)
|
||||
self.assertEqual('fghijk', body)
|
||||
|
||||
|
||||
class TestServerSideCopyConfiguration(unittest.TestCase):
|
||||
|
||||
@ -1498,7 +1522,7 @@ class TestServerSideCopyMiddlewareWithEC(unittest.TestCase):
|
||||
self.policy = POLICIES.default
|
||||
self.app.container_info = dict(self.container_info)
|
||||
|
||||
def test_COPY_with_ranges(self):
|
||||
def test_COPY_with_single_range(self):
|
||||
req = swob.Request.blank(
|
||||
'/v1/a/c/o', method='COPY',
|
||||
headers={'Destination': 'c1/o',
|
||||
@ -1528,10 +1552,24 @@ class TestServerSideCopyMiddlewareWithEC(unittest.TestCase):
|
||||
'X-Obj-Metadata-Footer': 'yes',
|
||||
'X-Obj-Multiphase-Commit': 'yes'
|
||||
}
|
||||
|
||||
put_hdrs = []
|
||||
|
||||
def capture_conn(host, port, dev, part, method, path, *args, **kwargs):
|
||||
if method == 'PUT':
|
||||
put_hdrs.append(args[0])
|
||||
|
||||
with set_http_connect(*status_codes, body_iter=body_iter,
|
||||
headers=headers, expect_headers=expect_headers):
|
||||
headers=headers, expect_headers=expect_headers,
|
||||
give_connect=capture_conn):
|
||||
resp = req.get_response(self.ssc)
|
||||
|
||||
self.assertEqual(resp.status_int, 201)
|
||||
expected_puts = POLICIES.default.ec_ndata + POLICIES.default.ec_nparity
|
||||
self.assertEqual(expected_puts, len(put_hdrs))
|
||||
for hdrs in put_hdrs:
|
||||
# etag should not be copied from source
|
||||
self.assertNotIn('etag', (h.lower() for h in hdrs))
|
||||
|
||||
def test_COPY_with_invalid_ranges(self):
|
||||
# real body size is segment_size - 10 (just 1 segment)
|
||||
|
Loading…
Reference in New Issue
Block a user