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
This commit is contained in:
Andrew Hutchings
2013-02-20 10:07:26 +00:00
parent 70b2e2266d
commit 3de03a19d8
6 changed files with 70 additions and 35 deletions

7
debian/changelog vendored
View File

@@ -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 <andrew@linuxjedi.co.uk> Wed, 20 Feb 2013 08:52:39 +0000
python-libraclient (1.2.1-1) UNRELEASED; urgency=low python-libraclient (1.2.1-1) UNRELEASED; urgency=low
* Don't use broken version of Novaclient * Don't use broken version of Novaclient

View File

@@ -12,4 +12,4 @@
# License for the specific language governing permissions and limitations # License for the specific language governing permissions and limitations
# under the License. # under the License.
__version__ = "1.2.1" __version__ = "1.2.2"

View File

@@ -21,7 +21,7 @@ from novaclient import client
# NOTE(LinuxJedi): Override novaclient's error handler as we send messages in # NOTE(LinuxJedi): Override novaclient's error handler as we send messages in
# a slightly different format which causes novaclient's to throw an exception # 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 Return an instance of an ClientException or subclass
based on an httplib2 response. based on an httplib2 response.
@@ -33,19 +33,23 @@ def from_response(response, body):
raise exception_from_response(resp, body) raise exception_from_response(resp, body)
""" """
cls = novaclient.exceptions._code_map.get( cls = novaclient.exceptions._code_map.get(
response.status, novaclient.exceptions.ClientException response.status_code, novaclient.exceptions.ClientException
) )
if response.headers:
request_id = response.get('x-compute-request-id') request_id = response.get('x-compute-request-id')
else:
request_id = None
if body: if body:
message = "n/a" message = "n/a"
details = "n/a" details = "n/a"
if hasattr(body, 'keys'): if hasattr(body, 'keys'):
message = body.get('message', None) message = body.get('message', None)
details = body.get('details', None) details = body.get('details', None)
return cls(code=response.status, message=message, details=details, return cls(code=response.status_code, message=message, details=details,
request_id=request_id) request_id=request_id, url=url, method=method)
else: 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 novaclient.exceptions.from_response = from_response

View File

@@ -1,6 +1,6 @@
import json import json
import mock import mock
import httplib2 import requests
import sys import sys
import novaclient import novaclient
import testtools import testtools
@@ -30,6 +30,31 @@ class DummyModifyArgs(object):
self.name = 'a-modified-loadbalancer' self.name = 'a-modified-loadbalancer'
self.algorithm = 'LEAST_CONNECTIONS' 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): class MockLibraArgs(object):
def __init__(self, username, password, tenant, auth_url, region): def __init__(self, username, password, tenant, auth_url, region):
self.os_username=username self.os_username=username
@@ -62,13 +87,13 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
""" Fake a login with token """ """ Fake a login with token """
super(TestLBaaSClientLibraAPI, self).setUp() super(TestLBaaSClientLibraAPI, self).setUp()
self.api = MockLibraAPI('username', 'password', 'tenant', 'auth_test', 'region') 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" self.api.nova.auth_token = "token"
def testListLb(self): def testListLb(self):
""" Test the table generated from the LIST function """ """ Test the table generated from the LIST function """
fake_response = httplib2.Response({"status": '200'}) fake_response = TestResponse({"status": 200,
fake_body = json.dumps({ "text": json.dumps({
"loadBalancers":[ "loadBalancers":[
{ {
"name":"lb-site1", "name":"lb-site1",
@@ -90,11 +115,11 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
"created":"2010-11-30T03:23:42Z", "created":"2010-11-30T03:23:42Z",
"updated":"2010-11-30T03:23:44Z" "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)): with mock.patch('time.time', mock.Mock(return_value=1234)):
orig = sys.stdout orig = sys.stdout
try: try:
@@ -116,8 +141,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
def testGetLb(self): def testGetLb(self):
""" Test the table generated from the STATUS function """ """ Test the table generated from the STATUS function """
fake_response = httplib2.Response({"status": '200'}) fake_response = TestResponse({"status": 200,
fake_body = json.dumps({ "text": json.dumps({
"id": "2000", "id": "2000",
"name":"sample-loadbalancer", "name":"sample-loadbalancer",
"protocol":"HTTP", "protocol":"HTTP",
@@ -154,10 +179,10 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
"connectionThrottle":{ "connectionThrottle":{
"maxRequestRate": "50", "maxRequestRate": "50",
"rateInterval": "60" "rateInterval": "60"
} }})
}) })
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)): with mock.patch('time.time', mock.Mock(return_value=1234)):
orig = sys.stdout orig = sys.stdout
try: try:
@@ -175,10 +200,9 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
Test a failure of a DELETE function. We don't test a succeed yet Test a failure of a DELETE function. We don't test a succeed yet
since that has no response so nothing to assert on since that has no response so nothing to assert on
""" """
fake_response = httplib2.Response({"status": '500'}) fake_response = TestResponse({"status": 500, "text": ""})
fake_body = '' mock_request = mock.Mock(return_value=(fake_response))
mock_request = mock.Mock(return_value=(fake_response, fake_body)) with mock.patch.object(requests, "request", mock_request):
with mock.patch.object(httplib2.Http, "request", mock_request):
with mock.patch('time.time', mock.Mock(return_value=1234)): with mock.patch('time.time', mock.Mock(return_value=1234)):
args = DummyArgs() args = DummyArgs()
self.assertRaises(novaclient.exceptions.ClientException, self.assertRaises(novaclient.exceptions.ClientException,
@@ -190,8 +214,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
1. We send the correct POST data 1. We send the correct POST data
2. We create a table from the response correctly 2. We create a table from the response correctly
""" """
fake_response = httplib2.Response({"status": '202'}) fake_response = TestResponse({"status": 202,
fake_body = json.dumps({ "text": json.dumps({
'name': 'a-new-loadbalancer', 'name': 'a-new-loadbalancer',
'id': '144', 'id': '144',
'protocol': 'HTTP', 'protocol': 'HTTP',
@@ -218,6 +242,7 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
} }
] ]
}) })
})
# This is what the POST data should look like based on the args passed # This is what the POST data should look like based on the args passed
post_compare = { post_compare = {
"name": "a-new-loadbalancer", "name": "a-new-loadbalancer",
@@ -232,8 +257,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
} }
] ]
} }
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)): with mock.patch('time.time', mock.Mock(return_value=1234)):
orig = sys.stdout orig = sys.stdout
try: try:
@@ -256,8 +281,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
Tests the CREATE function as above but adding a load balancer to a Tests the CREATE function as above but adding a load balancer to a
virtual IP virtual IP
""" """
fake_response = httplib2.Response({"status": '202'}) fake_response = TestResponse({"status": 202,
fake_body = json.dumps({ "text": json.dumps({
'name': 'a-new-loadbalancer', 'name': 'a-new-loadbalancer',
'id': '144', 'id': '144',
'protocol': 'HTTP', 'protocol': 'HTTP',
@@ -283,6 +308,7 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
} }
] ]
}) })
})
# This is what the POST data should look like based on the args passed # This is what the POST data should look like based on the args passed
post_compare = { post_compare = {
"name": "a-new-loadbalancer", "name": "a-new-loadbalancer",
@@ -300,8 +326,8 @@ class TestLBaaSClientLibraAPI(testtools.TestCase):
} }
] ]
} }
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)): with mock.patch('time.time', mock.Mock(return_value=1234)):
orig = sys.stdout orig = sys.stdout
try: try:

View File

@@ -1,2 +1 @@
python_novaclient==2.10.0 python_novaclient>=2.11.1
requests>=1.0.0

View File

@@ -1,6 +1,5 @@
pep8 pep8
mock mock
httplib2
sphinx>=1.1.2 sphinx>=1.1.2
testrepository>=0.0.8 testrepository>=0.0.8
testtools>=0.9.22 testtools>=0.9.22