From 3de03a19d832e5ec5e08193e24e08be6761e04d4 Mon Sep 17 00:00:00 2001 From: Andrew Hutchings Date: Wed, 20 Feb 2013 10:07:26 +0000 Subject: [PATCH] Update to work with Novaclient 2.11.1 * Fixes problem with --debug option * Updated tests to work with 2.11.x usage of requests library Fixes bug #1130524 Change-Id: I0aa71dc379dbd768922a3b199eac1332fb9204e1 --- debian/changelog | 7 ++++ libraclient/__init__.py | 2 +- libraclient/libraapi.py | 16 +++++--- tests/test_lbaas_client.py | 76 +++++++++++++++++++++++++------------- tools/pip-requires | 3 +- tools/test-requires | 1 - 6 files changed, 70 insertions(+), 35 deletions(-) diff --git a/debian/changelog b/debian/changelog index 33978ba..6bb8d53 100644 --- a/debian/changelog +++ b/debian/changelog @@ -1,3 +1,10 @@ +python-libraclient (1.2.2-1) UNRELEASED; urgency=low + + * Allow newer versions of Novaclient again + * Fix tests for newer versions + + -- Andrew Hutchings Wed, 20 Feb 2013 08:52:39 +0000 + python-libraclient (1.2.1-1) UNRELEASED; urgency=low * Don't use broken version of Novaclient diff --git a/libraclient/__init__.py b/libraclient/__init__.py index 86bab4e..e40f81e 100644 --- a/libraclient/__init__.py +++ b/libraclient/__init__.py @@ -12,4 +12,4 @@ # License for the specific language governing permissions and limitations # under the License. -__version__ = "1.2.1" +__version__ = "1.2.2" diff --git a/libraclient/libraapi.py b/libraclient/libraapi.py index dd6cfa5..c02bc12 100644 --- a/libraclient/libraapi.py +++ b/libraclient/libraapi.py @@ -21,7 +21,7 @@ from novaclient import client # NOTE(LinuxJedi): Override novaclient's error handler as we send messages in # a slightly different format which causes novaclient's to throw an exception -def from_response(response, body): +def from_response(response, body, url, method=None): """ Return an instance of an ClientException or subclass based on an httplib2 response. @@ -33,19 +33,23 @@ def from_response(response, body): raise exception_from_response(resp, body) """ cls = novaclient.exceptions._code_map.get( - response.status, novaclient.exceptions.ClientException + response.status_code, novaclient.exceptions.ClientException ) - request_id = response.get('x-compute-request-id') + if response.headers: + request_id = response.get('x-compute-request-id') + else: + request_id = None if body: message = "n/a" details = "n/a" if hasattr(body, 'keys'): message = body.get('message', None) details = body.get('details', None) - return cls(code=response.status, message=message, details=details, - request_id=request_id) + return cls(code=response.status_code, message=message, details=details, + request_id=request_id, url=url, method=method) else: - return cls(code=response.status, request_id=request_id) + return cls(code=response.status_code, request_id=request_id, url=url, + method=method) novaclient.exceptions.from_response = from_response diff --git a/tests/test_lbaas_client.py b/tests/test_lbaas_client.py index 61da6da..5f5549e 100644 --- a/tests/test_lbaas_client.py +++ b/tests/test_lbaas_client.py @@ -1,6 +1,6 @@ import json import mock -import httplib2 +import requests import sys import novaclient import testtools @@ -30,6 +30,31 @@ class DummyModifyArgs(object): self.name = 'a-modified-loadbalancer' self.algorithm = 'LEAST_CONNECTIONS' +class TestResponse(requests.Response): + """ + Class used to wrap requests.Response and provide some + convenience to initialize with a dict + """ + + def __init__(self, data): + self._text = None + super(TestResponse, self) + if isinstance(data, dict): + self.status_code = data.get('status', None) + self.headers = data.get('headers', None) + # Fake the text attribute to streamline Response creation + self._text = data.get('text', None) + else: + self.status_code = data + + def __eq__(self, other): + return self.__dict__ == other.__dict__ + + @property + def text(self): + return self._text + + class MockLibraArgs(object): def __init__(self, username, password, tenant, auth_url, region): self.os_username=username @@ -62,14 +87,14 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): """ Fake a login with token """ super(TestLBaaSClientLibraAPI, self).setUp() self.api = MockLibraAPI('username', 'password', 'tenant', 'auth_test', 'region') - self.api.nova.management_url = "http://example.com" + self.api.nova.management_url = "auth_url/v1.0" self.api.nova.auth_token = "token" def testListLb(self): """ Test the table generated from the LIST function """ - fake_response = httplib2.Response({"status": '200'}) - fake_body = json.dumps({ - "loadBalancers":[ + fake_response = TestResponse({"status": 200, + "text": json.dumps({ + "loadBalancers":[ { "name":"lb-site1", "id":"71", @@ -90,11 +115,11 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): "created":"2010-11-30T03:23:42Z", "updated":"2010-11-30T03:23:44Z" } - ] + ]}) }) - mock_request = mock.Mock(return_value=(fake_response, fake_body)) + mock_request = mock.Mock(return_value=(fake_response)) - with mock.patch.object(httplib2.Http, "request", mock_request): + with mock.patch.object(requests, "request", mock_request): with mock.patch('time.time', mock.Mock(return_value=1234)): orig = sys.stdout try: @@ -116,8 +141,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): def testGetLb(self): """ Test the table generated from the STATUS function """ - fake_response = httplib2.Response({"status": '200'}) - fake_body = json.dumps({ + fake_response = TestResponse({"status": 200, + "text": json.dumps({ "id": "2000", "name":"sample-loadbalancer", "protocol":"HTTP", @@ -154,10 +179,10 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): "connectionThrottle":{ "maxRequestRate": "50", "rateInterval": "60" - } + }}) }) - mock_request = mock.Mock(return_value=(fake_response, fake_body)) - with mock.patch.object(httplib2.Http, "request", mock_request): + mock_request = mock.Mock(return_value=(fake_response)) + with mock.patch.object(requests, "request", mock_request): with mock.patch('time.time', mock.Mock(return_value=1234)): orig = sys.stdout try: @@ -175,10 +200,9 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): Test a failure of a DELETE function. We don't test a succeed yet since that has no response so nothing to assert on """ - fake_response = httplib2.Response({"status": '500'}) - fake_body = '' - mock_request = mock.Mock(return_value=(fake_response, fake_body)) - with mock.patch.object(httplib2.Http, "request", mock_request): + fake_response = TestResponse({"status": 500, "text": ""}) + mock_request = mock.Mock(return_value=(fake_response)) + with mock.patch.object(requests, "request", mock_request): with mock.patch('time.time', mock.Mock(return_value=1234)): args = DummyArgs() self.assertRaises(novaclient.exceptions.ClientException, @@ -190,8 +214,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): 1. We send the correct POST data 2. We create a table from the response correctly """ - fake_response = httplib2.Response({"status": '202'}) - fake_body = json.dumps({ + fake_response = TestResponse({"status": 202, + "text": json.dumps({ 'name': 'a-new-loadbalancer', 'id': '144', 'protocol': 'HTTP', @@ -218,6 +242,7 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): } ] }) + }) # This is what the POST data should look like based on the args passed post_compare = { "name": "a-new-loadbalancer", @@ -232,8 +257,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): } ] } - mock_request = mock.Mock(return_value=(fake_response, fake_body)) - with mock.patch.object(httplib2.Http, "request", mock_request): + mock_request = mock.Mock(return_value=(fake_response)) + with mock.patch.object(requests, "request", mock_request): with mock.patch('time.time', mock.Mock(return_value=1234)): orig = sys.stdout try: @@ -256,8 +281,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): Tests the CREATE function as above but adding a load balancer to a virtual IP """ - fake_response = httplib2.Response({"status": '202'}) - fake_body = json.dumps({ + fake_response = TestResponse({"status": 202, + "text": json.dumps({ 'name': 'a-new-loadbalancer', 'id': '144', 'protocol': 'HTTP', @@ -283,6 +308,7 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): } ] }) + }) # This is what the POST data should look like based on the args passed post_compare = { "name": "a-new-loadbalancer", @@ -300,8 +326,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase): } ] } - mock_request = mock.Mock(return_value=(fake_response, fake_body)) - with mock.patch.object(httplib2.Http, "request", mock_request): + mock_request = mock.Mock(return_value=(fake_response)) + with mock.patch.object(requests, "request", mock_request): with mock.patch('time.time', mock.Mock(return_value=1234)): orig = sys.stdout try: diff --git a/tools/pip-requires b/tools/pip-requires index 160ae42..e6d0ebe 100644 --- a/tools/pip-requires +++ b/tools/pip-requires @@ -1,2 +1 @@ -python_novaclient==2.10.0 -requests>=1.0.0 +python_novaclient>=2.11.1 diff --git a/tools/test-requires b/tools/test-requires index 8a222d0..cd2d418 100644 --- a/tools/test-requires +++ b/tools/test-requires @@ -1,6 +1,5 @@ pep8 mock -httplib2 sphinx>=1.1.2 testrepository>=0.0.8 testtools>=0.9.22