summaryrefslogtreecommitdiff
path: root/tests/unit/test_swiftclient.py
diff options
context:
space:
mode:
Diffstat (limited to 'tests/unit/test_swiftclient.py')
-rw-r--r--tests/unit/test_swiftclient.py369
1 files changed, 307 insertions, 62 deletions
diff --git a/tests/unit/test_swiftclient.py b/tests/unit/test_swiftclient.py
index 0969f41..a51fe1a 100644
--- a/tests/unit/test_swiftclient.py
+++ b/tests/unit/test_swiftclient.py
@@ -17,7 +17,8 @@ import logging
import mock
import six
import socket
-import testtools
+import string
+import unittest
import warnings
import tempfile
from hashlib import md5
@@ -33,7 +34,7 @@ import swiftclient.utils
import swiftclient
-class TestClientException(testtools.TestCase):
+class TestClientException(unittest.TestCase):
def test_is_exception(self):
self.assertTrue(issubclass(c.ClientException, Exception))
@@ -50,6 +51,7 @@ class TestClientException(testtools.TestCase):
'status',
'reason',
'device',
+ 'response_content',
)
for value in test_kwargs:
kwargs = {
@@ -58,6 +60,26 @@ class TestClientException(testtools.TestCase):
exc = c.ClientException('test', **kwargs)
self.assertIn(value, str(exc))
+ def test_attrs(self):
+ test_kwargs = (
+ 'scheme',
+ 'host',
+ 'port',
+ 'path',
+ 'query',
+ 'status',
+ 'reason',
+ 'device',
+ 'response_content',
+ 'response_headers',
+ )
+ for value in test_kwargs:
+ key = 'http_%s' % value
+ kwargs = {key: value}
+ exc = c.ClientException('test', **kwargs)
+ self.assertIs(True, hasattr(exc, key))
+ self.assertEqual(getattr(exc, key), value)
+
class MockHttpResponse(object):
def __init__(self, status=0, headers=None, verify=False):
@@ -250,12 +272,12 @@ class TestGetAuth(MockHttpTest):
self.assertEqual(url, 'storageURL')
self.assertEqual(token, 'someauthtoken')
- e = self.assertRaises(c.ClientException, c.get_auth,
- 'http://www.test.com/invalid_cert',
- 'asdf', 'asdf', auth_version='1.0')
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.get_auth('http://www.test.com/invalid_cert',
+ 'asdf', 'asdf', auth_version='1.0')
# TODO: this test is really on validating the mock and not the
# the full plumbing into the requests's 'verify' option
- self.assertIn('invalid_certificate', str(e))
+ self.assertIn('invalid_certificate', str(exc_context.exception))
def test_auth_v1_timeout(self):
# this test has some overlap with
@@ -581,9 +603,12 @@ class TestHeadAccount(MockHttpTest):
def test_server_error(self):
body = 'c' * 65
- c.http_connection = self.fake_http_connection(500, body=body)
- e = self.assertRaises(c.ClientException, c.head_account,
- 'http://www.tests.com', 'asdf')
+ headers = {'foo': 'bar'}
+ c.http_connection = self.fake_http_connection(
+ StubResponse(500, body, headers))
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.head_account('http://www.tests.com', 'asdf')
+ e = exc_context.exception
self.assertEqual(e.http_response_content, body)
self.assertEqual(e.http_status, 500)
self.assertRequests([
@@ -595,6 +620,40 @@ class TestHeadAccount(MockHttpTest):
self.assertEqual(e.__str__()[-89:], new_body)
+class TestPostAccount(MockHttpTest):
+
+ def test_ok(self):
+ c.http_connection = self.fake_http_connection(200, headers={
+ 'X-Account-Meta-Color': 'blue',
+ }, body='foo')
+ resp_headers, body = c.post_account(
+ 'http://www.tests.com/path/to/account', 'asdf',
+ {'x-account-meta-shape': 'square'}, query_string='bar=baz',
+ data='some data')
+ self.assertEqual('blue', resp_headers.get('x-account-meta-color'))
+ self.assertEqual('foo', body)
+ self.assertRequests([
+ ('POST', 'http://www.tests.com/path/to/account?bar=baz',
+ 'some data', {'x-auth-token': 'asdf',
+ 'x-account-meta-shape': 'square'})
+ ])
+
+ def test_server_error(self):
+ body = 'c' * 65
+ c.http_connection = self.fake_http_connection(500, body=body)
+ with self.assertRaises(c.ClientException) as exc_mgr:
+ c.post_account('http://www.tests.com', 'asdf', {})
+ self.assertEqual(exc_mgr.exception.http_response_content, body)
+ self.assertEqual(exc_mgr.exception.http_status, 500)
+ self.assertRequests([
+ ('POST', 'http://www.tests.com', None, {'x-auth-token': 'asdf'})
+ ])
+ # TODO: this is a fairly brittle test of the __repr__ on the
+ # ClientException which should probably be in a targeted test
+ new_body = "[first 60 chars of response] " + body[0:60]
+ self.assertEqual(exc_mgr.exception.__str__()[-89:], new_body)
+
+
class TestGetContainer(MockHttpTest):
def test_no_content(self):
@@ -705,14 +764,18 @@ class TestHeadContainer(MockHttpTest):
def test_server_error(self):
body = 'c' * 60
- c.http_connection = self.fake_http_connection(500, body=body)
- e = self.assertRaises(c.ClientException, c.head_container,
- 'http://www.test.com', 'asdf', 'container')
+ headers = {'foo': 'bar'}
+ c.http_connection = self.fake_http_connection(
+ StubResponse(500, body, headers))
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.head_container('http://www.test.com', 'asdf', 'container')
+ e = exc_context.exception
self.assertRequests([
('HEAD', '/container', '', {'x-auth-token': 'asdf'}),
])
self.assertEqual(e.http_status, 500)
self.assertEqual(e.http_response_content, body)
+ self.assertEqual(e.http_response_headers, headers)
class TestPutContainer(MockHttpTest):
@@ -729,10 +792,13 @@ class TestPutContainer(MockHttpTest):
def test_server_error(self):
body = 'c' * 60
- c.http_connection = self.fake_http_connection(500, body=body)
- e = self.assertRaises(c.ClientException, c.put_container,
- 'http://www.test.com', 'token', 'container')
- self.assertEqual(e.http_response_content, body)
+ headers = {'foo': 'bar'}
+ c.http_connection = self.fake_http_connection(
+ StubResponse(500, body, headers))
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.put_container('http://www.test.com', 'token', 'container')
+ self.assertEqual(exc_context.exception.http_response_content, body)
+ self.assertEqual(exc_context.exception.http_response_headers, headers)
self.assertRequests([
('PUT', '/container', '', {
'x-auth-token': 'token',
@@ -755,9 +821,14 @@ class TestDeleteContainer(MockHttpTest):
class TestGetObject(MockHttpTest):
def test_server_error(self):
- c.http_connection = self.fake_http_connection(500)
- self.assertRaises(c.ClientException, c.get_object,
- 'http://www.test.com', 'asdf', 'asdf', 'asdf')
+ body = 'c' * 60
+ headers = {'foo': 'bar'}
+ c.http_connection = self.fake_http_connection(
+ StubResponse(500, body, headers))
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.get_object('http://www.test.com', 'asdf', 'asdf', 'asdf')
+ self.assertEqual(exc_context.exception.http_response_content, body)
+ self.assertEqual(exc_context.exception.http_response_headers, headers)
def test_query_string(self):
c.http_connection = self.fake_http_connection(200,
@@ -974,9 +1045,14 @@ class TestGetObject(MockHttpTest):
class TestHeadObject(MockHttpTest):
def test_server_error(self):
- c.http_connection = self.fake_http_connection(500)
- self.assertRaises(c.ClientException, c.head_object,
- 'http://www.test.com', 'asdf', 'asdf', 'asdf')
+ body = 'c' * 60
+ headers = {'foo': 'bar'}
+ c.http_connection = self.fake_http_connection(
+ StubResponse(500, body, headers))
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.head_object('http://www.test.com', 'asdf', 'asdf', 'asdf')
+ self.assertEqual(exc_context.exception.http_response_content, body)
+ self.assertEqual(exc_context.exception.http_response_headers, headers)
def test_request_headers(self):
c.http_connection = self.fake_http_connection(204)
@@ -1018,7 +1094,7 @@ class TestPutObject(MockHttpTest):
mock_file)
text = u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
headers = {'X-Header1': text,
- 'X-2': 1, 'X-3': {'a': 'b'}, 'a-b': '.x:yz mn:fg:lp'}
+ 'X-2': '1', 'X-3': "{'a': 'b'}", 'a-b': '.x:yz mn:fg:lp'}
resp = MockHttpResponse()
conn[1].getresponse = resp.fake_response
@@ -1053,10 +1129,15 @@ class TestPutObject(MockHttpTest):
def test_server_error(self):
body = 'c' * 60
- c.http_connection = self.fake_http_connection(500, body=body)
+ headers = {'foo': 'bar'}
+ c.http_connection = self.fake_http_connection(
+ StubResponse(500, body, headers))
args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', 'asdf')
- e = self.assertRaises(c.ClientException, c.put_object, *args)
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.put_object(*args)
+ e = exc_context.exception
self.assertEqual(e.http_response_content, body)
+ self.assertEqual(e.http_response_headers, headers)
self.assertEqual(e.http_status, 500)
self.assertRequests([
('PUT', '/asdf/asdf', 'asdf', {
@@ -1234,13 +1315,16 @@ class TestPostObject(MockHttpTest):
def test_ok(self):
c.http_connection = self.fake_http_connection(200)
+ delete_at = 2.1 # not str! we don't know what other devs will use!
args = ('http://www.test.com', 'token', 'container', 'obj',
- {'X-Object-Meta-Test': 'mymeta'})
+ {'X-Object-Meta-Test': 'mymeta',
+ 'X-Delete-At': delete_at})
c.post_object(*args)
self.assertRequests([
('POST', '/container/obj', '', {
'x-auth-token': 'token',
- 'X-Object-Meta-Test': 'mymeta'}),
+ 'X-Object-Meta-Test': 'mymeta',
+ 'X-Delete-At': delete_at}),
])
def test_unicode_ok(self):
@@ -1252,7 +1336,7 @@ class TestPostObject(MockHttpTest):
text = u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
headers = {'X-Header1': text,
b'X-Header2': 'value',
- 'X-2': '1', 'X-3': {'a': 'b'}, 'a-b': '.x:yz mn:kl:qr',
+ 'X-2': '1', 'X-3': "{'a': 'b'}", 'a-b': '.x:yz mn:kl:qr',
'X-Object-Meta-Header-not-encoded': text,
b'X-Object-Meta-Header-encoded': 'value'}
@@ -1273,10 +1357,14 @@ class TestPostObject(MockHttpTest):
def test_server_error(self):
body = 'c' * 60
- c.http_connection = self.fake_http_connection(500, body=body)
+ headers = {'foo': 'bar'}
+ c.http_connection = self.fake_http_connection(
+ StubResponse(500, body, headers))
args = ('http://www.test.com', 'token', 'container', 'obj', {})
- e = self.assertRaises(c.ClientException, c.post_object, *args)
- self.assertEqual(e.http_response_content, body)
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.post_object(*args)
+ self.assertEqual(exc_context.exception.http_response_content, body)
+ self.assertEqual(exc_context.exception.http_response_headers, headers)
self.assertRequests([
('POST', 'http://www.test.com/container/obj', '', {
'x-auth-token': 'token',
@@ -1296,9 +1384,14 @@ class TestDeleteObject(MockHttpTest):
])
def test_server_error(self):
- c.http_connection = self.fake_http_connection(500)
- self.assertRaises(c.ClientException, c.delete_object,
- 'http://www.test.com', 'asdf', 'asdf', 'asdf')
+ body = 'c' * 60
+ headers = {'foo': 'bar'}
+ c.http_connection = self.fake_http_connection(
+ StubResponse(500, body, headers))
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.delete_object('http://www.test.com', 'asdf', 'asdf', 'asdf')
+ self.assertEqual(exc_context.exception.http_response_content, body)
+ self.assertEqual(exc_context.exception.http_response_headers, headers)
def test_query_string(self):
c.http_connection = self.fake_http_connection(200,
@@ -1325,9 +1418,15 @@ class TestGetCapabilities(MockHttpTest):
self.assertTrue(http_conn[1].resp.has_been_read)
def test_server_error(self):
- conn = self.fake_http_connection(500)
+ body = 'c' * 60
+ headers = {'foo': 'bar'}
+ conn = self.fake_http_connection(
+ StubResponse(500, body, headers))
http_conn = conn('http://www.test.com/info')
- self.assertRaises(c.ClientException, c.get_capabilities, http_conn)
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.get_capabilities(http_conn)
+ self.assertEqual(exc_context.exception.http_response_content, body)
+ self.assertEqual(exc_context.exception.http_response_headers, headers)
def test_conn_get_capabilities_with_auth(self):
auth_headers = {
@@ -1430,17 +1529,23 @@ class TestHTTPConnection(MockHttpTest):
def test_bad_url_scheme(self):
url = u'www.test.com'
- exc = self.assertRaises(c.ClientException, c.http_connection, url)
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.http_connection(url)
+ exc = exc_context.exception
expected = u'Unsupported scheme "" in url "www.test.com"'
self.assertEqual(expected, str(exc))
url = u'://www.test.com'
- exc = self.assertRaises(c.ClientException, c.http_connection, url)
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.http_connection(url)
+ exc = exc_context.exception
expected = u'Unsupported scheme "" in url "://www.test.com"'
self.assertEqual(expected, str(exc))
url = u'blah://www.test.com'
- exc = self.assertRaises(c.ClientException, c.http_connection, url)
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.http_connection(url)
+ exc = exc_context.exception
expected = u'Unsupported scheme "blah" in url "blah://www.test.com"'
self.assertEqual(expected, str(exc))
@@ -1607,8 +1712,9 @@ class TestConnection(MockHttpTest):
}
c.http_connection = self.fake_http_connection(
*code_iter, headers=auth_resp_headers)
- e = self.assertRaises(c.ClientException, conn.head_account)
- self.assertIn('Account HEAD failed', str(e))
+ with self.assertRaises(c.ClientException) as exc_context:
+ conn.head_account()
+ self.assertIn('Account HEAD failed', str(exc_context.exception))
self.assertEqual(conn.attempts, conn.retries + 1)
# test default no-retry
@@ -1616,8 +1722,9 @@ class TestConnection(MockHttpTest):
200, 498,
headers=auth_resp_headers)
conn = c.Connection('http://www.test.com/auth/v1.0', 'asdf', 'asdf')
- e = self.assertRaises(c.ClientException, conn.head_account)
- self.assertIn('Account HEAD failed', str(e))
+ with self.assertRaises(c.ClientException) as exc_context:
+ conn.head_account()
+ self.assertIn('Account HEAD failed', str(exc_context.exception))
self.assertEqual(conn.attempts, 1)
def test_resp_read_on_server_error(self):
@@ -1887,9 +1994,10 @@ class TestConnection(MockHttpTest):
# v2 auth
timeouts = []
+ os_options = {'tenant_name': 'tenant', 'auth_token': 'meta-token'}
conn = c.Connection(
'http://auth.example.com', 'user', 'password', timeout=33.0,
- os_options=dict(tenant_name='tenant'), auth_version=2.0)
+ os_options=os_options, auth_version=2.0)
fake_ks = FakeKeystone(endpoint='http://some_url', token='secret')
with mock.patch('swiftclient.client._import_keystone_client',
_make_fake_import_keystone_client(fake_ks)):
@@ -1904,28 +2012,33 @@ class TestConnection(MockHttpTest):
# check timeout passed to HEAD for account
self.assertEqual(timeouts, [33.0])
+ # check token passed to keystone client
+ self.assertIn('token', fake_ks.calls[0])
+ self.assertEqual('meta-token', fake_ks.calls[0].get('token'))
+
def test_reset_stream(self):
class LocalContents(object):
def __init__(self, tell_value=0):
- self.already_read = False
+ self.data = six.BytesIO(string.ascii_letters.encode() * 10)
+ self.data.seek(tell_value)
+ self.reads = []
self.seeks = []
- self.tell_value = tell_value
+ self.tells = []
def tell(self):
- return self.tell_value
+ self.tells.append(self.data.tell())
+ return self.tells[-1]
- def seek(self, position):
- self.seeks.append(position)
- self.already_read = False
+ def seek(self, position, mode=0):
+ self.seeks.append((position, mode))
+ self.data.seek(position, mode)
def read(self, size=-1):
- if self.already_read:
- return ''
- else:
- self.already_read = True
- return 'abcdef'
+ read_data = self.data.read(size)
+ self.reads.append((size, read_data))
+ return read_data
class LocalConnection(object):
@@ -1936,7 +2049,7 @@ class TestConnection(MockHttpTest):
self.port = parsed_url.netloc
def putrequest(self, *args, **kwargs):
- self.send()
+ self.send('PUT', *args, **kwargs)
def putheader(self, *args, **kwargs):
return
@@ -1945,6 +2058,13 @@ class TestConnection(MockHttpTest):
return
def send(self, *args, **kwargs):
+ data = kwargs.get('data')
+ if data is not None:
+ if hasattr(data, 'read'):
+ data.read()
+ else:
+ for datum in data:
+ pass
raise socket.error('oops')
def request(self, *args, **kwargs):
@@ -1979,7 +2099,12 @@ class TestConnection(MockHttpTest):
conn.put_object('c', 'o', contents)
except socket.error as err:
exc = err
- self.assertEqual(contents.seeks, [0])
+ self.assertEqual(contents.tells, [0])
+ self.assertEqual(contents.seeks, [(0, 0)])
+ # four reads: two in the initial pass, two in the retry
+ self.assertEqual(4, len(contents.reads))
+ self.assertEqual((65536, b''), contents.reads[1])
+ self.assertEqual((65536, b''), contents.reads[3])
self.assertEqual(str(exc), 'oops')
contents = LocalContents(tell_value=123)
@@ -1988,9 +2113,29 @@ class TestConnection(MockHttpTest):
conn.put_object('c', 'o', contents)
except socket.error as err:
exc = err
- self.assertEqual(contents.seeks, [123])
+ self.assertEqual(contents.tells, [123])
+ self.assertEqual(contents.seeks, [(123, 0)])
+ # four reads: two in the initial pass, two in the retry
+ self.assertEqual(4, len(contents.reads))
+ self.assertEqual((65536, b''), contents.reads[1])
+ self.assertEqual((65536, b''), contents.reads[3])
self.assertEqual(str(exc), 'oops')
+ contents = LocalContents(tell_value=123)
+ wrapped_contents = swiftclient.utils.LengthWrapper(
+ contents, 6, md5=True)
+ exc = None
+ try:
+ conn.put_object('c', 'o', wrapped_contents)
+ except socket.error as err:
+ exc = err
+ self.assertEqual(contents.tells, [123])
+ self.assertEqual(contents.seeks, [(123, 0)])
+ self.assertEqual(contents.reads, [(6, b'tuvwxy')] * 2)
+ self.assertEqual(str(exc), 'oops')
+ self.assertEqual(md5(b'tuvwxy').hexdigest(),
+ wrapped_contents.get_md5sum())
+
contents = LocalContents()
contents.tell = None
exc = None
@@ -2060,7 +2205,8 @@ class TestResponseDict(MockHttpTest):
"""
Verify handling of optional response_dict argument.
"""
- calls = [('post_container', 'c', {}),
+ calls = [('post_account', {}),
+ ('post_container', 'c', {}),
('put_container', 'c'),
('delete_container', 'c'),
('post_object', 'c', 'o', {}),
@@ -2176,9 +2322,86 @@ class TestLogging(MockHttpTest):
def test_get_error(self):
c.http_connection = self.fake_http_connection(404)
- e = self.assertRaises(c.ClientException, c.get_object,
- 'http://www.test.com', 'asdf', 'asdf', 'asdf')
- self.assertEqual(e.http_status, 404)
+ with self.assertRaises(c.ClientException) as exc_context:
+ c.get_object('http://www.test.com', 'asdf', 'asdf', 'asdf')
+ self.assertEqual(exc_context.exception.http_status, 404)
+
+ def test_redact_token(self):
+ with mock.patch('swiftclient.client.logger.debug') as mock_log:
+ token_value = 'tkee96b40a8ca44fc5ad72ec5a7c90d9b'
+ token_encoded = token_value.encode('utf8')
+ unicode_token_value = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
+ u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
+ u'\u5929\u7a7a\u4e2d\u7684\u4e4c')
+ unicode_token_encoded = unicode_token_value.encode('utf8')
+ set_cookie_value = 'X-Auth-Token=%s' % token_value
+ set_cookie_encoded = set_cookie_value.encode('utf8')
+ c.http_log(
+ ['GET'],
+ {'headers': {
+ 'X-Auth-Token': token_encoded,
+ 'X-Storage-Token': unicode_token_encoded
+ }},
+ MockHttpResponse(
+ status=200,
+ headers={
+ 'X-Auth-Token': token_encoded,
+ 'X-Storage-Token': unicode_token_encoded,
+ 'Etag': b'mock_etag',
+ 'Set-Cookie': set_cookie_encoded
+ }
+ ),
+ ''
+ )
+ out = []
+ for _, args, kwargs in mock_log.mock_calls:
+ for arg in args:
+ out.append(u'%s' % arg)
+ output = u''.join(out)
+ self.assertIn('X-Auth-Token', output)
+ self.assertIn(token_value[:16] + '...', output)
+ self.assertIn('X-Storage-Token', output)
+ self.assertIn(unicode_token_value[:8] + '...', output)
+ self.assertIn('Set-Cookie', output)
+ self.assertIn(set_cookie_value[:16] + '...', output)
+ self.assertNotIn(token_value, output)
+ self.assertNotIn(unicode_token_value, output)
+ self.assertNotIn(set_cookie_value, output)
+
+ def test_show_token(self):
+ with mock.patch('swiftclient.client.logger.debug') as mock_log:
+ token_value = 'tkee96b40a8ca44fc5ad72ec5a7c90d9b'
+ token_encoded = token_value.encode('utf8')
+ unicode_token_value = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
+ u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91'
+ u'\u5929\u7a7a\u4e2d\u7684\u4e4c')
+ c.logger_settings['redact_sensitive_headers'] = False
+ unicode_token_encoded = unicode_token_value.encode('utf8')
+ c.http_log(
+ ['GET'],
+ {'headers': {
+ 'X-Auth-Token': token_encoded,
+ 'X-Storage-Token': unicode_token_encoded
+ }},
+ MockHttpResponse(
+ status=200,
+ headers=[
+ ('X-Auth-Token', token_encoded),
+ ('X-Storage-Token', unicode_token_encoded),
+ ('Etag', b'mock_etag')
+ ]
+ ),
+ ''
+ )
+ out = []
+ for _, args, kwargs in mock_log.mock_calls:
+ for arg in args:
+ out.append(u'%s' % arg)
+ output = u''.join(out)
+ self.assertIn('X-Auth-Token', output)
+ self.assertIn(token_value, output)
+ self.assertIn('X-Storage-Token', output)
+ self.assertIn(unicode_token_value, output)
class TestCloseConnection(MockHttpTest):
@@ -2374,6 +2597,28 @@ class TestServiceToken(MockHttpTest):
actual['full_path'])
self.assertEqual(conn.attempts, 1)
+ def test_service_token_get_container_full_listing(self):
+ # verify service token is sent with each request for a full listing
+ with mock.patch('swiftclient.client.http_connection',
+ self.fake_http_connection(200, 200)):
+ with mock.patch('swiftclient.client.parse_api_response') as resp:
+ resp.side_effect = ([{"name": "obj1"}], [])
+ conn = self.get_connection()
+ conn.get_container('container1', full_listing=True)
+ self.assertEqual(2, len(self.request_log), self.request_log)
+ expected_urls = iter((
+ 'http://storage_url.com/container1?format=json',
+ 'http://storage_url.com/container1?format=json&marker=obj1'
+ ))
+ for actual in self.iter_request_log():
+ self.assertEqual('GET', actual['method'])
+ actual_hdrs = actual['headers']
+ self.assertEqual('stoken', actual_hdrs.get('X-Service-Token'))
+ self.assertEqual('token', actual_hdrs['X-Auth-Token'])
+ self.assertEqual(next(expected_urls),
+ actual['full_path'])
+ self.assertEqual(conn.attempts, 1)
+
def test_service_token_head_container(self):
with mock.patch('swiftclient.client.http_connection',
self.fake_http_connection(200)):