diff options
author | Christian Schwede <christian.schwede@enovance.com> | 2014-02-25 21:42:17 +0000 |
---|---|---|
committer | Chmouel Boudjnah <chmouel@enovance.com> | 2014-05-05 11:53:37 +0200 |
commit | eb94ac076dec7e08f4e6c4c55d7c6f60b1b1cbfd (patch) | |
tree | 07a9ccd6ff5c1382e13df5259940c0b2cd4a9c03 /tests/test_swiftclient.py | |
parent | 9ff3bad4e22fbd561d9253af2b6e38580124b450 (diff) | |
download | python-swiftclient-eb94ac076dec7e08f4e6c4c55d7c6f60b1b1cbfd.tar.gz |
Add functional tests for python-swiftclient
Coverage for swiftclient.client is 71% with these tests.
Unit tests have been moved into another subdirectory
to separate them from functional tests.
Change-Id: Ib8c4d78f7169cee893f82906f6388a5b06c45602
Diffstat (limited to 'tests/test_swiftclient.py')
-rw-r--r-- | tests/test_swiftclient.py | 1154 |
1 files changed, 0 insertions, 1154 deletions
diff --git a/tests/test_swiftclient.py b/tests/test_swiftclient.py deleted file mode 100644 index 4e83a2d..0000000 --- a/tests/test_swiftclient.py +++ /dev/null @@ -1,1154 +0,0 @@ -# Copyright (c) 2010-2012 OpenStack, LLC. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or -# implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -# TODO: More tests -import logging - -try: - from unittest import mock -except ImportError: - import mock - -import six -import socket -import types -import testtools -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 fake_http_connect, fake_get_keystoneclient_2_0 - -from swiftclient import client as c -import swiftclient.utils - - -class TestClientException(testtools.TestCase): - - def test_is_exception(self): - self.assertTrue(issubclass(c.ClientException, Exception)) - - def test_format(self): - exc = c.ClientException('something failed') - self.assertTrue('something failed' in str(exc)) - test_kwargs = ( - 'scheme', - 'host', - 'port', - 'path', - 'query', - 'status', - 'reason', - 'device', - ) - for value in test_kwargs: - kwargs = { - 'http_%s' % value: value, - } - exc = c.ClientException('test', **kwargs) - self.assertTrue(value in str(exc)) - - -class TestJsonImport(testtools.TestCase): - - def tearDown(self): - try: - import json - except ImportError: - pass - else: - reload_module(json) - - try: - import simplejson - except ImportError: - pass - else: - reload_module(simplejson) - super(TestJsonImport, self).tearDown() - - def test_any(self): - self.assertTrue(hasattr(c, 'json_loads')) - - def test_no_simplejson(self): - # break simplejson - try: - import simplejson - except ImportError: - # not installed, so we don't have to break it for these tests - pass - else: - delattr(simplejson, 'loads') - reload_module(c) - - try: - from json import loads - except ImportError: - # this case is stested in _no_json - pass - else: - self.assertEqual(loads, c.json_loads) - - -class MockHttpTest(testtools.TestCase): - - def setUp(self): - super(MockHttpTest, self).setUp() - - def fake_http_connection(*args, **kwargs): - _orig_http_connection = c.http_connection - return_read = kwargs.get('return_read') - query_string = kwargs.get('query_string') - storage_url = kwargs.get('storage_url') - - def wrapper(url, proxy=None, cacert=None, insecure=False, - ssl_compression=True): - if storage_url: - self.assertEqual(storage_url, url) - - parsed, _conn = _orig_http_connection(url, proxy=proxy) - conn = fake_http_connect(*args, **kwargs)() - - def request(method, url, *args, **kwargs): - if query_string: - self.assertTrue(url.endswith('?' + query_string)) - if url.endswith('invalid_cert') and not insecure: - from swiftclient import client as c - raise c.ClientException("invalid_certificate") - return - conn.request = request - - conn.has_been_read = False - _orig_read = conn.read - - def read(*args, **kwargs): - conn.has_been_read = True - return _orig_read(*args, **kwargs) - conn.read = return_read or read - - return parsed, conn - return wrapper - self.fake_http_connection = fake_http_connection - - def tearDown(self): - super(MockHttpTest, self).tearDown() - reload_module(c) - - -class MockHttpResponse(): - def __init__(self, status=0): - self.status = status - self.status_code = status - self.reason = "OK" - self.buffer = [] - self.requests_params = None - - class Raw: - def read(): - pass - self.raw = Raw() - - def read(self): - return "" - - def getheader(self, name, default): - return "" - - def getheaders(self): - return {"key1": "value1", "key2": "value2"} - - def fake_response(self): - return MockHttpResponse(self.status) - - def _fake_request(self, *arg, **kwarg): - self.status = 200 - self.requests_params = kwarg - # This simulate previous httplib implementation that would do a - # putrequest() and then use putheader() to send header. - for k, v in kwarg['headers'].items(): - self.buffer.append((k, v)) - return self.fake_response() - - -class TestHttpHelpers(MockHttpTest): - - def test_quote(self): - value = b'bytes\xff' - self.assertEqual('bytes%FF', c.quote(value)) - value = 'native string' - self.assertEqual('native%20string', c.quote(value)) - value = u'unicode string' - self.assertEqual('unicode%20string', c.quote(value)) - value = u'unicode:\xe9\u20ac' - self.assertEqual('unicode%3A%C3%A9%E2%82%AC', c.quote(value)) - - def test_http_connection(self): - url = 'http://www.test.com' - _junk, conn = c.http_connection(url) - self.assertTrue(isinstance(conn, c.HTTPConnection)) - url = 'https://www.test.com' - _junk, conn = c.http_connection(url) - self.assertTrue(isinstance(conn, c.HTTPConnection)) - url = 'ftp://www.test.com' - self.assertRaises(c.ClientException, c.http_connection, url) - - def test_set_user_agent_default(self): - _junk, conn = c.http_connection('http://www.example.com') - req_headers = {} - - def my_request_handler(*a, **kw): - req_headers.update(kw.get('headers', {})) - conn._request = my_request_handler - - # test the default - conn.request('GET', '/') - ua = req_headers.get('user-agent', 'XXX-MISSING-XXX') - self.assert_(ua.startswith('python-swiftclient-')) - - def test_set_user_agent_per_request_override(self): - _junk, conn = c.http_connection('http://www.example.com') - req_headers = {} - - def my_request_handler(*a, **kw): - req_headers.update(kw.get('headers', {})) - conn._request = my_request_handler - - # test if it's actually set - conn.request('GET', '/', headers={'User-Agent': 'Me'}) - ua = req_headers.get('user-agent', 'XXX-MISSING-XXX') - self.assertEqual(ua, 'Me', req_headers) - - def test_set_user_agent_default_override(self): - _junk, conn = c.http_connection( - 'http://www.example.com', - default_user_agent='a-new-default') - req_headers = {} - - def my_request_handler(*a, **kw): - req_headers.update(kw.get('headers', {})) - conn._request = my_request_handler - - # test setting a default - conn._request = my_request_handler - conn.request('GET', '/') - ua = req_headers.get('user-agent', 'XXX-MISSING-XXX') - self.assertEqual(ua, 'a-new-default') - -# TODO: following tests are placeholders, need more tests, better coverage - - -class TestGetAuth(MockHttpTest): - - def test_ok(self): - c.http_connection = self.fake_http_connection(200) - url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf') - self.assertEqual(url, None) - 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") - - def test_auth_v1(self): - c.http_connection = self.fake_http_connection(200, auth_v1=True) - url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf', - auth_version="1.0") - self.assertEqual(url, 'storageURL') - self.assertEqual(token, 'someauthtoken') - - def test_auth_v1_insecure(self): - c.http_connection = self.fake_http_connection(200, auth_v1=True) - url, token = c.get_auth('http://www.test.com/invalid_cert', - 'asdf', 'asdf', - auth_version='1.0', - insecure=True) - 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') - - def test_auth_v2(self): - os_options = {'tenant_name': 'asdf'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(os_options) - url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf', - os_options=os_options, - auth_version="2.0") - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - def test_auth_v2_no_tenant_name(self): - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0({}) - self.assertRaises(c.ClientException, c.get_auth, - 'http://www.tests.com', 'asdf', 'asdf', - os_options={}, - auth_version='2.0') - - def test_auth_v2_with_tenant_user_in_user(self): - tenant_option = {'tenant_name': 'foo'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(tenant_option) - url, token = c.get_auth('http://www.test.com', 'foo:bar', 'asdf', - os_options={}, - auth_version="2.0") - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - def test_auth_v2_tenant_name_no_os_options(self): - tenant_option = {'tenant_name': 'asdf'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(tenant_option) - url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf', - tenant_name='asdf', - os_options={}, - auth_version="2.0") - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - def test_auth_v2_with_os_options(self): - os_options = {'service_type': 'object-store', - 'endpoint_type': 'internalURL', - 'tenant_name': 'asdf'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(os_options) - url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf', - os_options=os_options, - auth_version="2.0") - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - def test_auth_v2_with_tenant_user_in_user_no_os_options(self): - tenant_option = {'tenant_name': 'foo'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(tenant_option) - url, token = c.get_auth('http://www.test.com', 'foo:bar', 'asdf', - auth_version="2.0") - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - def test_auth_v2_with_os_region_name(self): - os_options = {'region_name': 'good-region', - 'tenant_name': 'asdf'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0(os_options) - url, token = c.get_auth('http://www.test.com', 'asdf', 'asdf', - os_options=os_options, - auth_version="2.0") - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - def test_auth_v2_no_endpoint(self): - os_options = {'region_name': 'unknown_region', - 'tenant_name': 'asdf'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0( - os_options, c.ClientException) - self.assertRaises(c.ClientException, c.get_auth, - 'http://www.tests.com', 'asdf', 'asdf', - os_options=os_options, auth_version='2.0') - - def test_auth_v2_ks_exception(self): - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0( - {}, c.ClientException) - self.assertRaises(c.ClientException, c.get_auth, - 'http://www.tests.com', 'asdf', 'asdf', - os_options={}, - auth_version='2.0') - - def test_auth_v2_cacert(self): - os_options = {'tenant_name': 'foo'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0( - os_options, None) - - auth_url_secure = 'https://www.tests.com' - auth_url_insecure = 'https://www.tests.com/self-signed-certificate' - - url, token = c.get_auth(auth_url_secure, 'asdf', 'asdf', - os_options=os_options, auth_version='2.0', - insecure=False) - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - url, token = c.get_auth(auth_url_insecure, 'asdf', 'asdf', - os_options=os_options, auth_version='2.0', - cacert='ca.pem', insecure=False) - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - self.assertRaises(c.ClientException, c.get_auth, - auth_url_insecure, 'asdf', 'asdf', - os_options=os_options, auth_version='2.0') - self.assertRaises(c.ClientException, c.get_auth, - auth_url_insecure, 'asdf', 'asdf', - os_options=os_options, auth_version='2.0', - insecure=False) - - def test_auth_v2_insecure(self): - os_options = {'tenant_name': 'foo'} - c.get_keystoneclient_2_0 = fake_get_keystoneclient_2_0( - os_options, None) - - auth_url_secure = 'https://www.tests.com' - auth_url_insecure = 'https://www.tests.com/invalid-certificate' - - url, token = c.get_auth(auth_url_secure, 'asdf', 'asdf', - os_options=os_options, auth_version='2.0') - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - url, token = c.get_auth(auth_url_insecure, 'asdf', 'asdf', - os_options=os_options, auth_version='2.0', - insecure=True) - self.assertTrue(url.startswith("http")) - self.assertTrue(token) - - self.assertRaises(c.ClientException, c.get_auth, - auth_url_insecure, 'asdf', 'asdf', - os_options=os_options, auth_version='2.0') - self.assertRaises(c.ClientException, c.get_auth, - auth_url_insecure, 'asdf', 'asdf', - os_options=os_options, auth_version='2.0', - insecure=False) - - -class TestGetAccount(MockHttpTest): - - def test_no_content(self): - c.http_connection = self.fake_http_connection(204) - value = c.get_account('http://www.test.com', 'asdf')[1] - self.assertEqual(value, []) - - def test_param_marker(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&marker=marker") - c.get_account('http://www.test.com', 'asdf', marker='marker') - - def test_param_limit(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&limit=10") - c.get_account('http://www.test.com', 'asdf', limit=10) - - def test_param_prefix(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&prefix=asdf/") - c.get_account('http://www.test.com', 'asdf', prefix='asdf/') - - def test_param_end_marker(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&end_marker=end_marker") - c.get_account('http://www.test.com', 'asdf', end_marker='end_marker') - - -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) - - 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) - - -class TestGetContainer(MockHttpTest): - - def test_no_content(self): - c.http_connection = self.fake_http_connection(204) - value = c.get_container('http://www.test.com', 'asdf', 'asdf')[1] - self.assertEqual(value, []) - - def test_param_marker(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&marker=marker") - c.get_container('http://www.test.com', 'asdf', 'asdf', marker='marker') - - def test_param_limit(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&limit=10") - c.get_container('http://www.test.com', 'asdf', 'asdf', limit=10) - - def test_param_prefix(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&prefix=asdf/") - c.get_container('http://www.test.com', 'asdf', 'asdf', prefix='asdf/') - - def test_param_delimiter(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&delimiter=/") - c.get_container('http://www.test.com', 'asdf', 'asdf', delimiter='/') - - def test_param_end_marker(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&end_marker=end_marker") - c.get_container('http://www.test.com', 'asdf', 'asdf', - end_marker='end_marker') - - def test_param_path(self): - c.http_connection = self.fake_http_connection( - 204, - query_string="format=json&path=asdf") - c.get_container('http://www.test.com', 'asdf', 'asdf', - path='asdf') - - -class TestHeadContainer(MockHttpTest): - - 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) - - -class TestPutContainer(MockHttpTest): - - def test_ok(self): - c.http_connection = self.fake_http_connection(200) - value = c.put_container('http://www.test.com', 'asdf', 'asdf') - self.assertEqual(value, None) - - 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) - - -class TestDeleteContainer(MockHttpTest): - - def test_ok(self): - c.http_connection = self.fake_http_connection(200) - value = c.delete_container('http://www.test.com', 'asdf', 'asdf') - self.assertEqual(value, None) - - -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') - - def test_query_string(self): - c.http_connection = self.fake_http_connection(200, - query_string="hello=20") - c.get_object('http://www.test.com', 'asdf', 'asdf', 'asdf', - query_string="hello=20") - - 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 - 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') - - -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') - - -class TestPutObject(MockHttpTest): - - def test_ok(self): - c.http_connection = self.fake_http_connection(200) - args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', 'asdf') - value = c.put_object(*args) - self.assertTrue(isinstance(value, six.string_types)) - - def test_unicode_ok(self): - conn = c.http_connection(u'http://www.test.com/') - mock_file = six.StringIO(u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91') - args = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91', - '\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91', - u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91', - u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91', - 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'} - - resp = MockHttpResponse() - conn[1].getresponse = resp.fake_response - conn[1]._request = resp._fake_request - value = c.put_object(*args, headers=headers, http_conn=conn) - self.assertTrue(isinstance(value, six.string_types)) - # Test for RFC-2616 encoded symbols - self.assertIn((b"a-b", b".x:yz mn:fg:lp"), - resp.buffer) - # Test unicode header - self.assertIn((b'x-header1', text.encode('utf8')), - resp.buffer) - - def test_chunk_warning(self): - conn = c.http_connection('http://www.test.com/') - mock_file = six.StringIO('asdf') - args = ('asdf', 'asdf', 'asdf', 'asdf', mock_file) - resp = MockHttpResponse() - conn[1].getresponse = resp.fake_response - conn[1]._request = resp._fake_request - with warnings.catch_warnings(record=True) as w: - c.put_object(*args, chunk_size=20, headers={}, http_conn=conn) - self.assertEqual(len(w), 0) - - body = 'c' * 60 - c.http_connection = self.fake_http_connection(200, body=body) - args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', 'asdf') - with warnings.catch_warnings(record=True) as w: - c.put_object(*args, chunk_size=20) - self.assertEqual(len(w), 1) - self.assertTrue(issubclass(w[-1].category, UserWarning)) - - 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', '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) - - 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") - - def test_raw_upload(self): - # Raw upload happens when content_length is passed to put_object - conn = c.http_connection(u'http://www.test.com/') - resp = MockHttpResponse(status=200) - conn[1].getresponse = resp.fake_response - conn[1]._request = resp._fake_request - astring = 'asdf' - astring_len = len(astring) - mock_file = six.StringIO(astring) - - c.put_object(url='http://www.test.com', http_conn=conn, - contents=mock_file, content_length=astring_len) - self.assertTrue(isinstance(resp.requests_params['data'], - swiftclient.utils.LengthWrapper)) - self.assertEqual(astring_len, - len(resp.requests_params['data'].read())) - - mock_file = six.StringIO(astring) - c.put_object(url='http://www.test.com', http_conn=conn, - headers={'Content-Length': str(astring_len)}, - contents=mock_file) - self.assertTrue(isinstance(resp.requests_params['data'], - swiftclient.utils.LengthWrapper)) - self.assertEqual(astring_len, - len(resp.requests_params['data'].read())) - - def test_chunk_upload(self): - # Chunked upload happens when no content_length is passed to put_object - conn = c.http_connection(u'http://www.test.com/') - resp = MockHttpResponse(status=200) - conn[1].getresponse = resp.fake_response - conn[1]._request = resp._fake_request - raw_data = 'asdf' * 256 - chunk_size = 16 - mock_file = six.StringIO(raw_data) - - c.put_object(url='http://www.test.com', http_conn=conn, - contents=mock_file, chunk_size=chunk_size) - request_data = resp.requests_params['data'] - self.assertTrue(isinstance(request_data, types.GeneratorType)) - data = '' - for chunk in request_data: - self.assertEqual(chunk_size, len(chunk)) - data += chunk - self.assertEqual(data, raw_data) - - def test_params(self): - conn = c.http_connection(u'http://www.test.com/') - resp = MockHttpResponse(status=200) - conn[1].getresponse = resp.fake_response - conn[1]._request = resp._fake_request - - c.put_object(url='http://www.test.com', http_conn=conn, - etag='1234-5678', content_type='text/plain') - request_header = resp.requests_params['headers'] - self.assertTrue(request_header['etag'], '1234-5678') - self.assertTrue(request_header['content-type'], 'text/plain') - - -class TestPostObject(MockHttpTest): - - def test_ok(self): - c.http_connection = self.fake_http_connection(200) - args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', {}) - c.post_object(*args) - - def test_unicode_ok(self): - conn = c.http_connection(u'http://www.test.com/') - args = (u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91', - '\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91', - u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91', - u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91') - text = u'\u5929\u7a7a\u4e2d\u7684\u4e4c\u4e91' - headers = {'X-Header1': text, - 'X-2': '1', 'X-3': {'a': 'b'}, 'a-b': '.x:yz mn:kl:qr'} - - resp = MockHttpResponse() - conn[1].getresponse = resp.fake_response - conn[1]._request = resp._fake_request - c.post_object(*args, headers=headers, http_conn=conn) - # Test for RFC-2616 encoded symbols - self.assertTrue((b'a-b', b"a-b: .x:yz mn:kl:qr"), resp.buffer) - # Test unicode header - self.assertIn((b'x-header1', text.encode('utf8')), - resp.buffer) - - 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) - - -class TestDeleteObject(MockHttpTest): - - def test_ok(self): - c.http_connection = self.fake_http_connection(200) - c.delete_object('http://www.test.com', 'asdf', 'asdf', 'asdf') - - 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') - - def test_query_string(self): - c.http_connection = self.fake_http_connection(200, - query_string="hello=20") - c.delete_object('http://www.test.com', 'asdf', 'asdf', 'asdf', - query_string="hello=20") - - -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) - - 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) - - -class TestHTTPConnection(MockHttpTest): - - def test_ok_proxy(self): - conn = c.http_connection(u'http://www.test.com/', - proxy='http://localhost:8080') - self.assertEquals(conn[1].requests_args['proxies']['http'], - 'http://localhost:8080') - - def test_bad_proxy(self): - try: - c.http_connection(u'http://www.test.com/', proxy='localhost:8080') - except c.ClientException as e: - self.assertEqual(e.msg, "Proxy's missing scheme") - - def test_cacert(self): - conn = c.http_connection(u'http://www.test.com/', - cacert='/dev/urandom') - self.assertEquals(conn[1].requests_args['verify'], '/dev/urandom') - - def test_insecure(self): - conn = c.http_connection(u'http://www.test.com/', insecure=True) - self.assertEquals(conn[1].requests_args['verify'], False) - - -class TestConnection(MockHttpTest): - - def test_instance(self): - conn = c.Connection('http://www.test.com', 'asdf', 'asdf') - self.assertEqual(conn.retries, 5) - - def test_instance_kwargs(self): - args = {'user': 'ausername', - 'key': 'secretpass', - 'authurl': 'http://www.test.com', - 'tenant_name': 'atenant'} - conn = c.Connection(**args) - self.assertEqual(type(conn), c.Connection) - - def test_instance_kwargs_token(self): - args = {'preauthtoken': 'atoken123', - 'preauthurl': 'http://www.test.com:8080/v1/AUTH_123456'} - conn = c.Connection(**args) - self.assertEqual(type(conn), c.Connection) - - 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}) - method_signatures = ( - (conn.head_account, []), - (conn.get_account, []), - (conn.head_container, ('asdf',)), - (conn.get_container, ('asdf',)), - (conn.put_container, ('asdf',)), - (conn.delete_container, ('asdf',)), - (conn.head_object, ('asdf', 'asdf')), - (conn.get_object, ('asdf', 'asdf')), - (conn.put_object, ('asdf', 'asdf', 'asdf')), - (conn.post_object, ('asdf', 'asdf', {})), - (conn.delete_object, ('asdf', 'asdf')), - ) - - with mock.patch('swiftclient.client.get_auth_1_0') as mock_get_auth: - mock_get_auth.return_value = ('http://auth.storage.url', 'tToken') - - for method, args in method_signatures: - method(*args) - - def test_get_capabilities(self): - conn = c.Connection() - with mock.patch('swiftclient.client.get_capabilities') as get_cap: - conn.get_capabilities('http://storage2.test.com') - parsed = get_cap.call_args[0][0][0] - self.assertEqual(parsed.path, '/info') - self.assertEqual(parsed.netloc, 'storage2.test.com') - conn.get_auth = lambda: ('http://storage.test.com/v1/AUTH_test', - 'token') - conn.get_capabilities() - parsed = get_cap.call_args[0][0][0] - self.assertEqual(parsed.path, '/info') - 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') - 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', - retry_on_ratelimit=True) - self.assertRaises(c.ClientException, conn.head_account) - 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) - 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): - return 'http://www.new.com', 'new' - conn.get_auth = get_auth - self.url, self.token = conn.get_auth() - - method_signatures = ( - (conn.head_account, []), - (conn.get_account, []), - (conn.head_container, ('asdf',)), - (conn.get_container, ('asdf',)), - (conn.put_container, ('asdf',)), - (conn.delete_container, ('asdf',)), - (conn.head_object, ('asdf', 'asdf')), - (conn.get_object, ('asdf', 'asdf')), - (conn.put_object, ('asdf', 'asdf', 'asdf')), - (conn.post_object, ('asdf', 'asdf', {})), - (conn.delete_object, ('asdf', 'asdf')), - ) - - for method, args in method_signatures: - self.assertRaises(c.ClientException, method, *args) - try: - self.assertTrue(conn.http_conn[1].has_been_read) - except AssertionError: - 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)) - - def test_reauth(self): - c.http_connection = self.fake_http_connection(401) - - def get_auth(*args, **kwargs): - 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 - - conn = c.Connection('http://www.test.com', 'asdf', 'asdf', - preauthurl='http://www.old.com', - preauthtoken='old', - ) - - self.assertEqual(conn.attempts, 0) - self.assertEqual(conn.url, 'http://www.old.com') - self.assertEqual(conn.token, 'old') - - conn.head_account() - - self.assertTrue(self.swap_sleep_called) - self.assertEqual(conn.attempts, 2) - self.assertEqual(conn.url, 'http://www.new.com') - self.assertEqual(conn.token, 'new') - - def test_reset_stream(self): - - class LocalContents(object): - - def __init__(self, tell_value=0): - self.already_read = False - self.seeks = [] - self.tell_value = tell_value - - def tell(self): - return self.tell_value - - def seek(self, position): - self.seeks.append(position) - self.already_read = False - - def read(self, size=-1): - if self.already_read: - return '' - else: - self.already_read = True - return 'abcdef' - - class LocalConnection(object): - - def __init__(self, parsed_url=None): - self.reason = "" - if parsed_url: - self.host = parsed_url.netloc - self.port = parsed_url.netloc - - def putrequest(self, *args, **kwargs): - self.send() - - def putheader(self, *args, **kwargs): - return - - def endheaders(self, *args, **kwargs): - return - - def send(self, *args, **kwargs): - raise socket.error('oops') - - def request(self, *args, **kwargs): - return - - def getresponse(self, *args, **kwargs): - self.status = 200 - return self - - def getheader(self, *args, **kwargs): - return 'header' - - def getheaders(self): - return {"key1": "value1", "key2": "value2"} - - def read(self, *args, **kwargs): - return '' - - def local_http_connection(url, proxy=None, cacert=None, - insecure=False, ssl_compression=True): - parsed = urlparse(url) - return parsed, LocalConnection() - - orig_conn = c.http_connection - try: - c.http_connection = local_http_connection - conn = c.Connection('http://www.example.com', 'asdf', 'asdf', - retries=1, starting_backoff=.0001) - - contents = LocalContents() - exc = None - try: - conn.put_object('c', 'o', contents) - except socket.error as err: - exc = err - self.assertEqual(contents.seeks, [0]) - self.assertEqual(str(exc), 'oops') - - contents = LocalContents(tell_value=123) - exc = None - try: - conn.put_object('c', 'o', contents) - except socket.error as err: - exc = err - self.assertEqual(contents.seeks, [123]) - self.assertEqual(str(exc), 'oops') - - contents = LocalContents() - contents.tell = None - exc = None - try: - conn.put_object('c', 'o', contents) - except c.ClientException as err: - exc = err - self.assertEqual(contents.seeks, []) - self.assertEqual(str(exc), "put_object('c', 'o', ...) failure " - "and no ability to reset contents for reupload.") - finally: - c.http_connection = orig_conn - - -class TestLogging(MockHttpTest): - """ - Make sure all the lines in http_log are covered. - """ - - def setUp(self): - super(TestLogging, self).setUp() - self.swiftclient_logger = logging.getLogger("swiftclient") - self.log_level = self.swiftclient_logger.getEffectiveLevel() - self.swiftclient_logger.setLevel(logging.INFO) - - def tearDown(self): - self.swiftclient_logger.setLevel(self.log_level) - super(TestLogging, self).tearDown() - - def test_put_ok(self): - c.http_connection = self.fake_http_connection(200) - args = ('http://www.test.com', 'asdf', 'asdf', 'asdf', 'asdf') - value = c.put_object(*args) - self.assertTrue(isinstance(value, six.string_types)) - - def test_head_error(self): - c.http_connection = self.fake_http_connection(500) - self.assertRaises(c.ClientException, c.head_object, - '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) - - -class TestCloseConnection(MockHttpTest): - - def test_close_none(self): - c.http_connection = self.fake_http_connection(200) - conn = c.Connection('http://www.test.com', 'asdf', 'asdf') - self.assertEqual(conn.http_conn, None) - conn.close() - self.assertEqual(conn.http_conn, None) - - 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) - conn.close() - self.assertEqual(http_conn_obj.isclosed(), True) - self.assertEqual(conn.http_conn, None) - - -if __name__ == '__main__': - testtools.main() |