summaryrefslogtreecommitdiff
path: root/tests/unit/test_swiftclient.py
diff options
context:
space:
mode:
authorClay Gerrard <clay.gerrard@gmail.com>2014-10-24 01:02:53 -0700
committerpaul luse <paul.e.luse@intel.com>2014-12-17 05:53:56 -0700
commitfbe558885f29e2c545e3260927a625b1027995ec (patch)
treeb62ac1f265ade36710f70bdcc92c33347e364df7 /tests/unit/test_swiftclient.py
parentd59af8cc8b3f5ddf846046dd11029b84db4828ea (diff)
downloadpython-swiftclient-fbe558885f29e2c545e3260927a625b1027995ec.tar.gz
Make preauth params work
If you specify a token and storage url when creating a Connection, regardless of the auth api version the first request will be made directly to swift. You can either provide a preauthurl and preauthtoken or fall back to os_options' object_storage_url and auth_token keys (exposed as --os-storage-url and --os-auth-token on the command line or OS_STORAGE_URL and OS_AUTH_TOKEN in the environment). If a _retry wrapped request on a Connection fails because of invalid authentication (401) the Connection's cached token and url will be invalidated. If the Connection's retries attribute is > 0 the subsequent attempt will call get_auth to refresh the token, but the pre-configured storage_url will always be re-used. This is consistent with current auth v2 behavior and less surprising for auth v1. The pre-existing, but previously undocumented behavior/interface of get_auth would override the storage_url returned by the auth service if the 'os_storage_url' option was provided in the os_options dict. To ensure that this behavior is consistent across auth v1 and v2 from the command line and when using the Connection class as a library - the preauthurl is stashed in the os_options dict when provided. Improved Connection.get_capabilities storage_url handling to better support the consistent behavior of a preauthurl/object_storage_url on the connection regardless of auth version. Fixed up some test infrastructure to enable setting up and testing multiple requests/responses. Change-Id: I6950fb73f3e28fdddb62760cae9320e2f4336776
Diffstat (limited to 'tests/unit/test_swiftclient.py')
-rw-r--r--tests/unit/test_swiftclient.py513
1 files changed, 390 insertions, 123 deletions
diff --git a/tests/unit/test_swiftclient.py b/tests/unit/test_swiftclient.py
index 796f93c..0360016 100644
--- a/tests/unit/test_swiftclient.py
+++ b/tests/unit/test_swiftclient.py
@@ -13,8 +13,8 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-# TODO: More tests
import logging
+import json
try:
from unittest import mock
@@ -29,8 +29,7 @@ import warnings
from six.moves.urllib.parse import urlparse
from six.moves import reload_module
-# TODO: mock http connection class with more control over headers
-from .utils import MockHttpTest, fake_get_auth_keystone
+from .utils import MockHttpTest, fake_get_auth_keystone, StubResponse
from swiftclient import client as c
import swiftclient.utils
@@ -66,12 +65,7 @@ class TestClientException(testtools.TestCase):
class TestJsonImport(testtools.TestCase):
def tearDown(self):
- try:
- import json
- except ImportError:
- pass
- else:
- reload_module(json)
+ reload_module(json)
try:
import simplejson
@@ -84,7 +78,7 @@ class TestJsonImport(testtools.TestCase):
def test_any(self):
self.assertTrue(hasattr(c, 'json_loads'))
- def test_no_simplejson(self):
+ def test_no_simplejson_falls_back_to_stdlib_when_reloaded(self):
# break simplejson
try:
import simplejson
@@ -92,16 +86,10 @@ class TestJsonImport(testtools.TestCase):
# not installed, so we don't have to break it for these tests
pass
else:
- delattr(simplejson, 'loads')
- reload_module(c)
+ delattr(simplejson, 'loads') # break simple json
+ reload_module(c) # reload to repopulate json_loads
- try:
- from json import loads
- except ImportError:
- # this case is stested in _no_json
- pass
- else:
- self.assertEqual(loads, c.json_loads)
+ self.assertEqual(c.json_loads, json.loads)
class MockHttpResponse():
@@ -234,7 +222,6 @@ class TestGetAuth(MockHttpTest):
self.assertEqual(token, None)
def test_invalid_auth(self):
- c.http_connection = self.fake_http_connection(200)
self.assertRaises(c.ClientException, c.get_auth,
'http://www.tests.com', 'asdf', 'asdf',
auth_version="foo")
@@ -247,7 +234,7 @@ class TestGetAuth(MockHttpTest):
self.assertEqual(token, 'someauthtoken')
def test_auth_v1_insecure(self):
- c.http_connection = self.fake_http_connection(200, auth_v1=True)
+ c.http_connection = self.fake_http_connection(200, 200, auth_v1=True)
url, token = c.get_auth('http://www.test.com/invalid_cert',
'asdf', 'asdf',
auth_version='1.0',
@@ -255,10 +242,12 @@ class TestGetAuth(MockHttpTest):
self.assertEqual(url, 'storageURL')
self.assertEqual(token, 'someauthtoken')
- self.assertRaises(c.ClientException, c.get_auth,
- 'http://www.test.com/invalid_cert',
- 'asdf', 'asdf',
- auth_version='1.0')
+ e = self.assertRaises(c.ClientException, 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))
def test_auth_v2_with_tenant_name(self):
os_options = {'tenant_name': 'asdf'}
@@ -499,23 +488,29 @@ class TestGetAccount(MockHttpTest):
class TestHeadAccount(MockHttpTest):
def test_ok(self):
- c.http_connection = self.fake_http_connection(200)
- value = c.head_account('http://www.tests.com', 'asdf')
- # TODO: Hmm. This doesn't really test too much as it uses a fake that
- # always returns the same dict. I guess it "exercises" the code, so
- # I'll leave it for now.
- self.assertEqual(type(value), dict)
+ c.http_connection = self.fake_http_connection(200, headers={
+ 'x-account-meta-color': 'blue',
+ })
+ resp_headers = c.head_account('http://www.tests.com', 'asdf')
+ self.assertEqual(resp_headers['x-account-meta-color'], 'blue')
+ self.assertRequests([
+ ('HEAD', 'http://www.tests.com', '', {'x-auth-token': 'asdf'})
+ ])
def test_server_error(self):
body = 'c' * 65
c.http_connection = self.fake_http_connection(500, body=body)
- self.assertRaises(c.ClientException, c.head_account,
- 'http://www.tests.com', 'asdf')
- try:
- c.head_account('http://www.tests.com', 'asdf')
- except c.ClientException as e:
- new_body = "[first 60 chars of response] " + body[0:60]
- self.assertEqual(e.__str__()[-89:], new_body)
+ e = self.assertRaises(c.ClientException, c.head_account,
+ 'http://www.tests.com', 'asdf')
+ self.assertEqual(e.http_response_content, body)
+ self.assertEqual(e.http_status, 500)
+ self.assertRequests([
+ ('HEAD', 'http://www.tests.com', '', {'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(e.__str__()[-89:], new_body)
class TestGetContainer(MockHttpTest):
@@ -566,16 +561,29 @@ class TestGetContainer(MockHttpTest):
class TestHeadContainer(MockHttpTest):
+ def test_head_ok(self):
+ fake_conn = self.fake_http_connection(
+ 200, headers={'x-container-meta-color': 'blue'})
+ with mock.patch('swiftclient.client.http_connection',
+ new=fake_conn):
+ resp = c.head_container('https://example.com/v1/AUTH_test',
+ 'token', 'container')
+ self.assertEqual(resp['x-container-meta-color'], 'blue')
+ self.assertRequests([
+ ('HEAD', 'https://example.com/v1/AUTH_test/container', '',
+ {'x-auth-token': 'token'}),
+ ])
+
def test_server_error(self):
body = 'c' * 60
c.http_connection = self.fake_http_connection(500, body=body)
- self.assertRaises(c.ClientException, c.head_container,
- 'http://www.test.com', 'asdf', 'asdf',
- )
- try:
- c.head_container('http://www.test.com', 'asdf', 'asdf')
- except c.ClientException as e:
- self.assertEqual(e.http_response_content, body)
+ e = self.assertRaises(c.ClientException, c.head_container,
+ 'http://www.test.com', 'asdf', 'container')
+ self.assertRequests([
+ ('HEAD', '/container', '', {'x-auth-token': 'asdf'}),
+ ])
+ self.assertEqual(e.http_status, 500)
+ self.assertEqual(e.http_response_content, body)
class TestPutContainer(MockHttpTest):
@@ -588,13 +596,12 @@ class TestPutContainer(MockHttpTest):
def test_server_error(self):
body = 'c' * 60
c.http_connection = self.fake_http_connection(500, body=body)
- self.assertRaises(c.ClientException, c.put_container,
- 'http://www.test.com', 'asdf', 'asdf',
- )
- try:
- c.put_container('http://www.test.com', 'asdf', 'asdf')
- except c.ClientException as e:
- self.assertEqual(e.http_response_content, body)
+ e = self.assertRaises(c.ClientException, c.put_container,
+ 'http://www.test.com', 'token', 'container')
+ self.assertEqual(e.http_response_content, body)
+ self.assertRequests([
+ ('PUT', '/container', '', {'x-auth-token': 'token'}),
+ ])
class TestDeleteContainer(MockHttpTest):
@@ -617,26 +624,25 @@ class TestGetObject(MockHttpTest):
query_string="hello=20")
c.get_object('http://www.test.com', 'asdf', 'asdf', 'asdf',
query_string="hello=20")
+ for req in self.iter_request_log():
+ self.assertEqual(req['method'], 'GET')
+ self.assertEqual(req['parsed_path'].path, '/asdf/asdf')
+ self.assertEqual(req['parsed_path'].query, 'hello=20')
+ self.assertEqual(req['body'], '')
+ self.assertEqual(req['headers']['x-auth-token'], 'asdf')
def test_request_headers(self):
- request_args = {}
-
- def fake_request(method, url, body=None, headers=None):
- request_args['method'] = method
- request_args['url'] = url
- request_args['body'] = body
- request_args['headers'] = headers
- return
- conn = self.fake_http_connection(200)('http://www.test.com/')
- conn[1].request = fake_request
+ c.http_connection = self.fake_http_connection(200)
+ conn = c.http_connection('http://www.test.com')
headers = {'Range': 'bytes=1-2'}
c.get_object('url_is_irrelevant', 'TOKEN', 'container', 'object',
http_conn=conn, headers=headers)
- self.assertFalse(request_args['headers'] is None,
- "No headers in the request")
- self.assertTrue('Range' in request_args['headers'],
- "No Range header in the request")
- self.assertEqual(request_args['headers']['Range'], 'bytes=1-2')
+ self.assertRequests([
+ ('GET', '/container/object', '', {
+ 'x-auth-token': 'TOKEN',
+ 'range': 'bytes=1-2',
+ }),
+ ])
class TestHeadObject(MockHttpTest):
@@ -702,17 +708,23 @@ class TestPutObject(MockHttpTest):
body = 'c' * 60
c.http_connection = self.fake_http_connection(500, body=body)
args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', 'asdf')
- self.assertRaises(c.ClientException, c.put_object, *args)
- try:
- c.put_object(*args)
- except c.ClientException as e:
- self.assertEqual(e.http_response_content, body)
+ e = self.assertRaises(c.ClientException, c.put_object, *args)
+ self.assertEqual(e.http_response_content, body)
+ self.assertEqual(e.http_status, 500)
+ self.assertRequests([
+ ('PUT', '/asdf/asdf', 'asdf', {'x-auth-token': 'asdf'}),
+ ])
def test_query_string(self):
c.http_connection = self.fake_http_connection(200,
query_string="hello=20")
c.put_object('http://www.test.com', 'asdf', 'asdf', 'asdf',
query_string="hello=20")
+ for req in self.iter_request_log():
+ self.assertEqual(req['method'], 'PUT')
+ self.assertEqual(req['parsed_path'].path, '/asdf/asdf')
+ self.assertEqual(req['parsed_path'].query, 'hello=20')
+ self.assertEqual(req['headers']['x-auth-token'], 'asdf')
def test_raw_upload(self):
# Raw upload happens when content_length is passed to put_object
@@ -821,12 +833,14 @@ class TestPostObject(MockHttpTest):
def test_server_error(self):
body = 'c' * 60
c.http_connection = self.fake_http_connection(500, body=body)
- args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', {})
- self.assertRaises(c.ClientException, c.post_object, *args)
- try:
- c.post_object(*args)
- except c.ClientException as e:
- self.assertEqual(e.http_response_content, body)
+ args = ('http://www.test.com', 'token', 'container', 'obj', {})
+ e = self.assertRaises(c.ClientException, c.post_object, *args)
+ self.assertEqual(e.http_response_content, body)
+ self.assertRequests([
+ ('POST', 'http://www.test.com/container/obj', '', {
+ 'x-auth-token': 'token',
+ }),
+ ])
class TestDeleteObject(MockHttpTest):
@@ -852,14 +866,112 @@ class TestGetCapabilities(MockHttpTest):
def test_ok(self):
conn = self.fake_http_connection(200, body='{}')
http_conn = conn('http://www.test.com/info')
- self.assertEqual(type(c.get_capabilities(http_conn)), dict)
- self.assertTrue(http_conn[1].has_been_read)
+ info = c.get_capabilities(http_conn)
+ self.assertRequests([
+ ('GET', '/info'),
+ ])
+ self.assertEqual(info, {})
+ self.assertTrue(http_conn[1].resp.has_been_read)
def test_server_error(self):
conn = self.fake_http_connection(500)
http_conn = conn('http://www.test.com/info')
self.assertRaises(c.ClientException, c.get_capabilities, http_conn)
+ def test_conn_get_capabilities_with_auth(self):
+ auth_headers = {
+ 'x-auth-token': 'token',
+ 'x-storage-url': 'http://storage.example.com/v1/AUTH_test'
+ }
+ auth_v1_response = StubResponse(headers=auth_headers)
+ stub_info = {'swift': {'fake': True}}
+ info_response = StubResponse(body=json.dumps(stub_info))
+ fake_conn = self.fake_http_connection(auth_v1_response, info_response)
+
+ conn = c.Connection('http://auth.example.com/auth/v1.0',
+ 'user', 'key')
+ with mock.patch('swiftclient.client.http_connection',
+ new=fake_conn):
+ info = conn.get_capabilities()
+ self.assertEqual(info, stub_info)
+ self.assertRequests([
+ ('GET', '/auth/v1.0'),
+ ('GET', 'http://storage.example.com/info'),
+ ])
+
+ def test_conn_get_capabilities_with_os_auth(self):
+ fake_keystone = fake_get_auth_keystone(
+ storage_url='http://storage.example.com/v1/AUTH_test')
+ stub_info = {'swift': {'fake': True}}
+ info_response = StubResponse(body=json.dumps(stub_info))
+ fake_conn = self.fake_http_connection(info_response)
+
+ os_options = {'project_id': 'test'}
+ conn = c.Connection('http://keystone.example.com/v3.0',
+ 'user', 'key', os_options=os_options,
+ auth_version=3)
+ with mock.patch.multiple('swiftclient.client',
+ get_auth_keystone=fake_keystone,
+ http_connection=fake_conn):
+ info = conn.get_capabilities()
+ self.assertEqual(info, stub_info)
+ self.assertRequests([
+ ('GET', 'http://storage.example.com/info'),
+ ])
+
+ def test_conn_get_capabilities_with_url_param(self):
+ stub_info = {'swift': {'fake': True}}
+ info_response = StubResponse(body=json.dumps(stub_info))
+ fake_conn = self.fake_http_connection(info_response)
+
+ conn = c.Connection('http://auth.example.com/auth/v1.0',
+ 'user', 'key')
+ with mock.patch('swiftclient.client.http_connection',
+ new=fake_conn):
+ info = conn.get_capabilities(
+ 'http://other-storage.example.com/info')
+ self.assertEqual(info, stub_info)
+ self.assertRequests([
+ ('GET', 'http://other-storage.example.com/info'),
+ ])
+
+ def test_conn_get_capabilities_with_preauthurl_param(self):
+ stub_info = {'swift': {'fake': True}}
+ info_response = StubResponse(body=json.dumps(stub_info))
+ fake_conn = self.fake_http_connection(info_response)
+
+ storage_url = 'http://storage.example.com/v1/AUTH_test'
+ conn = c.Connection('http://auth.example.com/auth/v1.0',
+ 'user', 'key', preauthurl=storage_url)
+ with mock.patch('swiftclient.client.http_connection',
+ new=fake_conn):
+ info = conn.get_capabilities()
+ self.assertEqual(info, stub_info)
+ self.assertRequests([
+ ('GET', 'http://storage.example.com/info'),
+ ])
+
+ def test_conn_get_capabilities_with_os_options(self):
+ stub_info = {'swift': {'fake': True}}
+ info_response = StubResponse(body=json.dumps(stub_info))
+ fake_conn = self.fake_http_connection(info_response)
+
+ storage_url = 'http://storage.example.com/v1/AUTH_test'
+ os_options = {
+ 'project_id': 'test',
+ 'object_storage_url': storage_url,
+ }
+ conn = c.Connection('http://keystone.example.com/v3.0',
+ 'user', 'key', os_options=os_options,
+ auth_version=3)
+ with mock.patch('swiftclient.client.http_connection',
+ new=fake_conn):
+ info = conn.get_capabilities()
+ self.assertEqual(info, stub_info)
+ self.assertRequests([
+ ('GET', 'http://storage.example.com/info'),
+ ])
+
class TestHTTPConnection(MockHttpTest):
@@ -903,12 +1015,39 @@ class TestConnection(MockHttpTest):
args = {'preauthtoken': 'atoken123',
'preauthurl': 'http://www.test.com:8080/v1/AUTH_123456'}
conn = c.Connection(**args)
- self.assertEqual(type(conn), c.Connection)
+ self.assertEqual(conn.url, args['preauthurl'])
+ self.assertEqual(conn.token, args['preauthtoken'])
+
+ def test_instance_kwargs_os_token(self):
+ storage_url = 'http://storage.example.com/v1/AUTH_test'
+ token = 'token'
+ args = {
+ 'os_options': {
+ 'object_storage_url': storage_url,
+ 'auth_token': token,
+ }
+ }
+ conn = c.Connection(**args)
+ self.assertEqual(conn.url, storage_url)
+ self.assertEqual(conn.token, token)
+
+ def test_instance_kwargs_token_precedence(self):
+ storage_url = 'http://storage.example.com/v1/AUTH_test'
+ token = 'token'
+ args = {
+ 'preauthurl': storage_url,
+ 'preauthtoken': token,
+ 'os_options': {
+ 'auth_token': 'less-specific-token',
+ 'object_storage_url': 'less-specific-storage-url',
+ }
+ }
+ conn = c.Connection(**args)
+ self.assertEqual(conn.url, storage_url)
+ self.assertEqual(conn.token, token)
def test_storage_url_override(self):
static_url = 'http://overridden.storage.url'
- c.http_connection = self.fake_http_connection(
- 200, body='[]', storage_url=static_url)
conn = c.Connection('http://auth.url/', 'some_user', 'some_key',
os_options={
'object_storage_url': static_url})
@@ -930,7 +1069,15 @@ class TestConnection(MockHttpTest):
mock_get_auth.return_value = ('http://auth.storage.url', 'tToken')
for method, args in method_signatures:
+ c.http_connection = self.fake_http_connection(
+ 200, body='[]', storage_url=static_url)
method(*args)
+ self.assertEqual(len(self.request_log), 1)
+ for request in self.iter_request_log():
+ self.assertEqual(request['parsed_path'].netloc,
+ 'overridden.storage.url')
+ self.assertEqual(request['headers']['x-auth-token'],
+ 'tToken')
def test_get_capabilities(self):
conn = c.Connection()
@@ -947,35 +1094,46 @@ class TestConnection(MockHttpTest):
self.assertEqual(parsed.netloc, 'storage.test.com')
def test_retry(self):
- c.http_connection = self.fake_http_connection(500)
-
def quick_sleep(*args):
pass
c.sleep = quick_sleep
conn = c.Connection('http://www.test.com', 'asdf', 'asdf')
+ code_iter = [500] * (conn.retries + 1)
+ c.http_connection = self.fake_http_connection(*code_iter)
+
self.assertRaises(c.ClientException, conn.head_account)
self.assertEqual(conn.attempts, conn.retries + 1)
def test_retry_on_ratelimit(self):
- c.http_connection = self.fake_http_connection(498)
def quick_sleep(*args):
pass
c.sleep = quick_sleep
# test retries
- conn = c.Connection('http://www.test.com', 'asdf', 'asdf',
+ conn = c.Connection('http://www.test.com/auth/v1.0', 'asdf', 'asdf',
retry_on_ratelimit=True)
- self.assertRaises(c.ClientException, conn.head_account)
+ code_iter = [200] + [498] * (conn.retries + 1)
+ auth_resp_headers = {
+ 'x-auth-token': 'asdf',
+ 'x-storage-url': 'http://storage/v1/test',
+ }
+ 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))
self.assertEqual(conn.attempts, conn.retries + 1)
# test default no-retry
- conn = c.Connection('http://www.test.com', 'asdf', 'asdf')
- self.assertRaises(c.ClientException, conn.head_account)
+ c.http_connection = self.fake_http_connection(
+ 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))
self.assertEqual(conn.attempts, 1)
def test_resp_read_on_server_error(self):
- c.http_connection = self.fake_http_connection(500)
conn = c.Connection('http://www.test.com', 'asdf', 'asdf', retries=0)
def get_auth(*args, **kwargs):
@@ -998,25 +1156,28 @@ class TestConnection(MockHttpTest):
)
for method, args in method_signatures:
+ c.http_connection = self.fake_http_connection(500)
self.assertRaises(c.ClientException, method, *args)
- try:
- self.assertTrue(conn.http_conn[1].has_been_read)
- except AssertionError:
+ requests = list(self.iter_request_log())
+ self.assertEqual(len(requests), 1)
+ for req in requests:
msg = '%s did not read resp on server error' % method.__name__
- self.fail(msg)
- except Exception as e:
- raise e.__class__("%s - %s" % (method.__name__, e))
+ self.assertTrue(req['resp'].has_been_read, msg)
def test_reauth(self):
- c.http_connection = self.fake_http_connection(401)
+ c.http_connection = self.fake_http_connection(401, 200)
def get_auth(*args, **kwargs):
+ # this mock, and by extension this test are not
+ # represenative of the unit under test. The real get_auth
+ # method will always return the os_option dict's
+ # object_storage_url which will be overridden by the
+ # preauthurl paramater to Connection if it is provided.
return 'http://www.new.com', 'new'
def swap_sleep(*args):
self.swap_sleep_called = True
c.get_auth = get_auth
- c.http_connection = self.fake_http_connection(200)
c.sleep = swap_sleep
self.swap_sleep_called = False
@@ -1036,6 +1197,129 @@ class TestConnection(MockHttpTest):
self.assertEqual(conn.url, 'http://www.new.com')
self.assertEqual(conn.token, 'new')
+ def test_reauth_preauth(self):
+ conn = c.Connection(
+ 'http://auth.example.com', 'user', 'password',
+ preauthurl='http://storage.example.com/v1/AUTH_test',
+ preauthtoken='expired')
+ auth_v1_response = StubResponse(200, headers={
+ 'x-auth-token': 'token',
+ 'x-storage-url': 'http://storage.example.com/v1/AUTH_user',
+ })
+ fake_conn = self.fake_http_connection(401, auth_v1_response, 200)
+ with mock.patch.multiple('swiftclient.client',
+ http_connection=fake_conn,
+ sleep=mock.DEFAULT):
+ conn.head_account()
+ self.assertRequests([
+ ('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'expired'}),
+ ('GET', 'http://auth.example.com', '', {
+ 'x-auth-user': 'user',
+ 'x-auth-key': 'password'}),
+ ('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'token'}),
+ ])
+
+ def test_reauth_os_preauth(self):
+ os_preauth_options = {
+ 'tenant_name': 'demo',
+ 'object_storage_url': 'http://storage.example.com/v1/AUTH_test',
+ 'auth_token': 'expired',
+ }
+ conn = c.Connection('http://auth.example.com', 'user', 'password',
+ os_options=os_preauth_options, auth_version=2)
+ fake_keystone = fake_get_auth_keystone(os_preauth_options)
+ fake_conn = self.fake_http_connection(401, 200)
+ with mock.patch.multiple('swiftclient.client',
+ get_auth_keystone=fake_keystone,
+ http_connection=fake_conn,
+ sleep=mock.DEFAULT):
+ conn.head_account()
+ self.assertRequests([
+ ('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'expired'}),
+ ('HEAD', '/v1/AUTH_test', '', {'x-auth-token': 'token'}),
+ ])
+
+ def test_preauth_token_with_no_storage_url_requires_auth(self):
+ conn = c.Connection(
+ 'http://auth.example.com', 'user', 'password',
+ preauthtoken='expired')
+ auth_v1_response = StubResponse(200, headers={
+ 'x-auth-token': 'token',
+ 'x-storage-url': 'http://storage.example.com/v1/AUTH_user',
+ })
+ fake_conn = self.fake_http_connection(auth_v1_response, 200)
+ with mock.patch.multiple('swiftclient.client',
+ http_connection=fake_conn,
+ sleep=mock.DEFAULT):
+ conn.head_account()
+ self.assertRequests([
+ ('GET', 'http://auth.example.com', '', {
+ 'x-auth-user': 'user',
+ 'x-auth-key': 'password'}),
+ ('HEAD', '/v1/AUTH_user', '', {'x-auth-token': 'token'}),
+ ])
+
+ def test_os_preauth_token_with_no_storage_url_requires_auth(self):
+ os_preauth_options = {
+ 'tenant_name': 'demo',
+ 'auth_token': 'expired',
+ }
+ conn = c.Connection('http://auth.example.com', 'user', 'password',
+ os_options=os_preauth_options, auth_version=2)
+ storage_url = 'http://storage.example.com/v1/AUTH_user'
+ fake_keystone = fake_get_auth_keystone(storage_url=storage_url)
+ fake_conn = self.fake_http_connection(200)
+ with mock.patch.multiple('swiftclient.client',
+ get_auth_keystone=fake_keystone,
+ http_connection=fake_conn,
+ sleep=mock.DEFAULT):
+ conn.head_account()
+ self.assertRequests([
+ ('HEAD', '/v1/AUTH_user', '', {'x-auth-token': 'token'}),
+ ])
+
+ def test_preauth_url_trumps_auth_url(self):
+ storage_url = 'http://storage.example.com/v1/AUTH_pre_url'
+ conn = c.Connection(
+ 'http://auth.example.com', 'user', 'password',
+ preauthurl=storage_url)
+ auth_v1_response = StubResponse(200, headers={
+ 'x-auth-token': 'post_token',
+ 'x-storage-url': 'http://storage.example.com/v1/AUTH_post_url',
+ })
+ fake_conn = self.fake_http_connection(auth_v1_response, 200)
+ with mock.patch.multiple('swiftclient.client',
+ http_connection=fake_conn,
+ sleep=mock.DEFAULT):
+ conn.head_account()
+ self.assertRequests([
+ ('GET', 'http://auth.example.com', '', {
+ 'x-auth-user': 'user',
+ 'x-auth-key': 'password'}),
+ ('HEAD', '/v1/AUTH_pre_url', '', {'x-auth-token': 'post_token'}),
+ ])
+
+ def test_os_preauth_url_trumps_auth_url(self):
+ storage_url = 'http://storage.example.com/v1/AUTH_pre_url'
+ os_preauth_options = {
+ 'tenant_name': 'demo',
+ 'object_storage_url': storage_url,
+ }
+ conn = c.Connection('http://auth.example.com', 'user', 'password',
+ os_options=os_preauth_options, auth_version=2)
+ fake_keystone = fake_get_auth_keystone(
+ storage_url='http://storage.example.com/v1/AUTH_post_url',
+ token='post_token')
+ fake_conn = self.fake_http_connection(200)
+ with mock.patch.multiple('swiftclient.client',
+ get_auth_keystone=fake_keystone,
+ http_connection=fake_conn,
+ sleep=mock.DEFAULT):
+ conn.head_account()
+ self.assertRequests([
+ ('HEAD', '/v1/AUTH_pre_url', '', {'x-auth-token': 'post_token'}),
+ ])
+
def test_reset_stream(self):
class LocalContents(object):
@@ -1263,30 +1547,16 @@ class TestLogging(MockHttpTest):
'http://www.test.com', 'asdf', 'asdf', 'asdf')
def test_get_error(self):
- body = 'c' * 65
- conn = self.fake_http_connection(
- 404, body=body)('http://www.test.com/')
- request_args = {}
-
- def fake_request(method, url, body=None, headers=None):
- request_args['method'] = method
- request_args['url'] = url
- request_args['body'] = body
- request_args['headers'] = headers
- return
- conn[1].request = fake_request
- headers = {'Range': 'bytes=1-2'}
- self.assertRaises(
- c.ClientException,
- c.get_object,
- 'url_is_irrelevant', 'TOKEN', 'container', 'object',
- http_conn=conn, headers=headers)
+ 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)
class TestCloseConnection(MockHttpTest):
def test_close_none(self):
- c.http_connection = self.fake_http_connection(200)
+ c.http_connection = self.fake_http_connection()
conn = c.Connection('http://www.test.com', 'asdf', 'asdf')
self.assertEqual(conn.http_conn, None)
conn.close()
@@ -1294,15 +1564,12 @@ class TestCloseConnection(MockHttpTest):
def test_close_ok(self):
url = 'http://www.test.com'
- c.http_connection = self.fake_http_connection(200)
conn = c.Connection(url, 'asdf', 'asdf')
self.assertEqual(conn.http_conn, None)
-
conn.http_conn = c.http_connection(url)
self.assertEqual(type(conn.http_conn), tuple)
self.assertEqual(len(conn.http_conn), 2)
http_conn_obj = conn.http_conn[1]
- self.assertEqual(http_conn_obj.isclosed(), False)
+ self.assertIsInstance(http_conn_obj, c.HTTPConnection)
+ self.assertFalse(hasattr(http_conn_obj, 'close'))
conn.close()
- self.assertEqual(http_conn_obj.isclosed(), True)
- self.assertEqual(conn.http_conn, None)