diff options
author | Stuart McLaren <stuart.mclaren@hp.com> | 2015-03-04 14:31:00 +0000 |
---|---|---|
committer | Alistair Coles <alistair.coles@hpe.com> | 2016-01-08 17:12:02 +0000 |
commit | 4af623bcf171a63240849b84b9359a4f74471455 (patch) | |
tree | 5d44a4d43577cb71fa74ba70fd9d5b1ff84c42b5 /tests/functional/test_swiftclient.py | |
parent | d1e310958801c1e058a933a43b2c7e9552e85772 (diff) | |
download | python-swiftclient-4af623bcf171a63240849b84b9359a4f74471455.tar.gz |
Retry download of object body
Currently the swift client retries establishing a connection to the server
(by default up to 5 times). However, when downloading an object, once
the connection has been established and the inital headers have been
returned, no attempt is made to retry.
So, for example, if 99MB of a 100MB object have been downloaded and the
connection is then lost, the download will fail. This patch changes the
behaviour to re-establish the connection and fetch the remaining bytes
using the 'Range' header to offset.
Data retry is not yet supported if the original request is for a subset
of the object data (ie uses the 'Range' header), or if resp_chunk_size
has not been set.
The object's etag is checked using If-Match to make sure the object data
hasn't changed since the start of the download.
Change-Id: Iab47f10081ff39f6d344dbc2479cbc3bfd1c5b29
Diffstat (limited to 'tests/functional/test_swiftclient.py')
-rw-r--r-- | tests/functional/test_swiftclient.py | 52 |
1 files changed, 52 insertions, 0 deletions
diff --git a/tests/functional/test_swiftclient.py b/tests/functional/test_swiftclient.py index ef1b9d5..5f9e271 100644 --- a/tests/functional/test_swiftclient.py +++ b/tests/functional/test_swiftclient.py @@ -333,6 +333,58 @@ class TestFunctional(testtools.TestCase): hdrs, body = self.conn.get_object(self.containername, self.objectname) self.assertEqual("should tolerate empty chunks", body) + def test_download_object_retry_chunked(self): + resp_chunk_size = 2 + hdrs, body = self.conn.get_object(self.containername, + self.objectname, + resp_chunk_size=resp_chunk_size) + data = next(body) + self.assertEqual(self.test_data[:resp_chunk_size], data) + self.assertTrue(1, self.conn.attempts) + for chunk in body.resp: + # Flush remaining data from underlying response + # (simulate a dropped connection) + pass + # Trigger the retry + for chunk in body: + data += chunk + self.assertEqual(self.test_data, data) + self.assertEqual(2, self.conn.attempts) + + def test_download_object_retry_chunked_auth_failure(self): + resp_chunk_size = 2 + self.conn.token = 'invalid' + hdrs, body = self.conn.get_object(self.containername, + self.objectname, + resp_chunk_size=resp_chunk_size) + self.assertEqual(2, self.conn.attempts) + for chunk in body.resp: + # Flush remaining data from underlying response + # (simulate a dropped connection) + pass + + self.conn.token = 'invalid' + data = next(body) + self.assertEqual(4, self.conn.attempts) + + for chunk in body: + data += chunk + + self.assertEqual(self.test_data, data) + self.assertEqual(4, self.conn.attempts) + + def test_download_object_non_chunked(self): + hdrs, body = self.conn.get_object(self.containername, self.objectname) + data = body + self.assertEqual(self.test_data, data) + self.assertTrue(1, self.conn.attempts) + + hdrs, body = self.conn.get_object(self.containername, self.objectname, + resp_chunk_size=0) + data = body + self.assertEqual(self.test_data, data) + self.assertTrue(1, self.conn.attempts) + def test_post_account(self): self.conn.post_account({'x-account-meta-data': 'Something'}) headers = self.conn.head_account() |