Convert aggregates testing to use httpretty
This is the first in the series and so contains some setup classes. In general the original data will not be able to be removed from fakes until the very end because testing shell depends on a lot of it. Change-Id: I499fe968923b9452f60c1b2ca50d5749e89827de blueprint: httpretty-testing
This commit is contained in:
parent
c9f4e085e2
commit
119a480fc1
0
novaclient/tests/fixture_data/__init__.py
Normal file
0
novaclient/tests/fixture_data/__init__.py
Normal file
52
novaclient/tests/fixture_data/aggregates.py
Normal file
52
novaclient/tests/fixture_data/aggregates.py
Normal file
@ -0,0 +1,52 @@
|
||||
# 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.
|
||||
|
||||
import httpretty
|
||||
|
||||
from novaclient.openstack.common import jsonutils
|
||||
from novaclient.tests.fixture_data import base
|
||||
|
||||
|
||||
class Fixture(base.Fixture):
|
||||
|
||||
base_url = 'os-aggregates'
|
||||
|
||||
def setUp(self):
|
||||
super(Fixture, self).setUp()
|
||||
|
||||
get_os_aggregates = {"aggregates": [
|
||||
{'id': '1',
|
||||
'name': 'test',
|
||||
'availability_zone': 'nova1'},
|
||||
{'id': '2',
|
||||
'name': 'test2',
|
||||
'availability_zone': 'nova1'},
|
||||
]}
|
||||
|
||||
httpretty.register_uri(httpretty.GET, self.url(),
|
||||
body=jsonutils.dumps(get_os_aggregates),
|
||||
content_type='application/json')
|
||||
|
||||
r = jsonutils.dumps({'aggregate': get_os_aggregates['aggregates'][0]})
|
||||
|
||||
httpretty.register_uri(httpretty.POST, self.url(), body=r,
|
||||
content_type='application/json')
|
||||
|
||||
for agg_id in (1, 2):
|
||||
for method in (httpretty.GET, httpretty.PUT):
|
||||
httpretty.register_uri(method, self.url(agg_id), body=r,
|
||||
content_type='application/json')
|
||||
|
||||
httpretty.register_uri(httpretty.POST, self.url(agg_id, 'action'),
|
||||
body=r, content_type='application/json')
|
||||
|
||||
httpretty.register_uri(httpretty.DELETE, self.url(1), status=202)
|
32
novaclient/tests/fixture_data/base.py
Normal file
32
novaclient/tests/fixture_data/base.py
Normal file
@ -0,0 +1,32 @@
|
||||
# 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.
|
||||
|
||||
import fixtures
|
||||
|
||||
COMPUTE_URL = 'http://compute.host'
|
||||
|
||||
|
||||
class Fixture(fixtures.Fixture):
|
||||
|
||||
base_url = None
|
||||
|
||||
def __init__(self, compute_url=COMPUTE_URL):
|
||||
super(Fixture, self).__init__()
|
||||
self.compute_url = compute_url
|
||||
|
||||
def url(self, *args):
|
||||
url_args = [self.compute_url]
|
||||
|
||||
if self.base_url:
|
||||
url_args.append(self.base_url)
|
||||
|
||||
return '/'.join(str(a).strip('/') for a in tuple(url_args) + args)
|
109
novaclient/tests/fixture_data/client.py
Normal file
109
novaclient/tests/fixture_data/client.py
Normal file
@ -0,0 +1,109 @@
|
||||
# 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.
|
||||
|
||||
import fixtures
|
||||
import httpretty
|
||||
|
||||
from novaclient.openstack.common import jsonutils
|
||||
from novaclient.v1_1 import client as v1_1client
|
||||
from novaclient.v3 import client as v3client
|
||||
|
||||
IDENTITY_URL = 'http://identityserver:5000/v2.0'
|
||||
COMPUTE_URL = 'http://compute.host'
|
||||
|
||||
|
||||
class V1(fixtures.Fixture):
|
||||
|
||||
def __init__(self, compute_url=COMPUTE_URL, identity_url=IDENTITY_URL):
|
||||
super(V1, self).__init__()
|
||||
self.identity_url = identity_url
|
||||
self.compute_url = compute_url
|
||||
self.client = None
|
||||
|
||||
self.token = {
|
||||
'access': {
|
||||
"token": {
|
||||
"id": "ab48a9efdfedb23ty3494",
|
||||
"expires": "2010-11-01T03:32:15-05:00",
|
||||
"tenant": {
|
||||
"id": "345",
|
||||
"name": "My Project"
|
||||
}
|
||||
},
|
||||
"user": {
|
||||
"id": "123",
|
||||
"name": "jqsmith",
|
||||
"roles": [
|
||||
{
|
||||
"id": "234",
|
||||
"name": "compute:admin",
|
||||
},
|
||||
{
|
||||
"id": "235",
|
||||
"name": "object-store:admin",
|
||||
"tenantId": "1",
|
||||
}
|
||||
],
|
||||
"roles_links": [],
|
||||
},
|
||||
"serviceCatalog": [
|
||||
{
|
||||
"name": "Cloud Servers",
|
||||
"type": "compute",
|
||||
"endpoints": [
|
||||
{
|
||||
"publicURL": self.compute_url,
|
||||
"internalURL": "https://compute1.host/v1/1",
|
||||
},
|
||||
],
|
||||
"endpoints_links": [],
|
||||
},
|
||||
{
|
||||
"name": "Cloud Servers",
|
||||
"type": "computev3",
|
||||
"endpoints": [
|
||||
{
|
||||
"publicURL": self.compute_url,
|
||||
"internalURL": "https://compute1.host/v1/1",
|
||||
},
|
||||
],
|
||||
"endpoints_links": [],
|
||||
},
|
||||
],
|
||||
}
|
||||
}
|
||||
|
||||
def setUp(self):
|
||||
super(V1, self).setUp()
|
||||
httpretty.enable()
|
||||
self.addCleanup(httpretty.disable)
|
||||
|
||||
auth_url = '%s/tokens' % self.identity_url
|
||||
httpretty.register_uri(httpretty.POST, auth_url,
|
||||
body=jsonutils.dumps(self.token),
|
||||
content_type='application/json')
|
||||
self.client = self.new_client()
|
||||
|
||||
def new_client(self):
|
||||
return v1_1client.Client(username='xx',
|
||||
api_key='xx',
|
||||
project_id='xx',
|
||||
auth_url=self.identity_url)
|
||||
|
||||
|
||||
class V3(V1):
|
||||
|
||||
def new_client(self):
|
||||
return v3client.Client(username='xx',
|
||||
password='xx',
|
||||
project_id='xx',
|
||||
auth_url=self.identity_url)
|
@ -14,9 +14,13 @@
|
||||
import os
|
||||
|
||||
import fixtures
|
||||
import httpretty
|
||||
import requests
|
||||
import six
|
||||
import testtools
|
||||
|
||||
from novaclient.openstack.common import jsonutils
|
||||
|
||||
AUTH_URL = "http://localhost:5002/auth_url"
|
||||
AUTH_URL_V1 = "http://localhost:5002/auth_url/v1.0"
|
||||
AUTH_URL_V2 = "http://localhost:5002/auth_url/v2.0"
|
||||
@ -39,6 +43,40 @@ class TestCase(testtools.TestCase):
|
||||
self.useFixture(fixtures.MonkeyPatch('sys.stderr', stderr))
|
||||
|
||||
|
||||
class FixturedTestCase(TestCase):
|
||||
|
||||
client_fixture_class = None
|
||||
data_fixture_class = None
|
||||
|
||||
def setUp(self):
|
||||
super(FixturedTestCase, self).setUp()
|
||||
|
||||
httpretty.reset()
|
||||
self.data_fixture = None
|
||||
self.client_fixture = None
|
||||
self.cs = None
|
||||
|
||||
if self.client_fixture_class:
|
||||
self.client_fixture = self.useFixture(self.client_fixture_class())
|
||||
self.cs = self.client_fixture.client
|
||||
|
||||
if self.data_fixture_class:
|
||||
self.data_fixture = self.useFixture(self.data_fixture_class())
|
||||
|
||||
def assert_called(self, method, path, body=None):
|
||||
self.assertEqual(httpretty.last_request().method, method)
|
||||
self.assertEqual(httpretty.last_request().path, path)
|
||||
|
||||
if body:
|
||||
req_data = httpretty.last_request().body
|
||||
if isinstance(req_data, six.binary_type):
|
||||
req_data = req_data.decode('utf-8')
|
||||
if not isinstance(body, six.string_types):
|
||||
# json load if the input body to match against is not a string
|
||||
req_data = jsonutils.loads(req_data)
|
||||
self.assertEqual(req_data, body)
|
||||
|
||||
|
||||
class TestResponse(requests.Response):
|
||||
"""
|
||||
Class used to wrap requests.Response and provide some
|
||||
|
@ -13,51 +13,45 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from novaclient.tests.fixture_data import aggregates as data
|
||||
from novaclient.tests.fixture_data import client
|
||||
from novaclient.tests import utils
|
||||
from novaclient.tests.v1_1 import fakes
|
||||
from novaclient.v1_1 import aggregates
|
||||
|
||||
|
||||
class AggregatesTest(utils.TestCase):
|
||||
def setUp(self):
|
||||
super(AggregatesTest, self).setUp()
|
||||
self.cs = self._get_fake_client()
|
||||
self.aggregate_type = self._get_aggregate_type()
|
||||
class AggregatesTest(utils.FixturedTestCase):
|
||||
|
||||
def _get_fake_client(self):
|
||||
return fakes.FakeClient()
|
||||
|
||||
def _get_aggregate_type(self):
|
||||
return aggregates.Aggregate
|
||||
client_fixture_class = client.V1
|
||||
data_fixture_class = data.Fixture
|
||||
|
||||
def test_list_aggregates(self):
|
||||
result = self.cs.aggregates.list()
|
||||
self.cs.assert_called('GET', '/os-aggregates')
|
||||
self.assert_called('GET', '/os-aggregates')
|
||||
for aggregate in result:
|
||||
self.assertIsInstance(aggregate, aggregates.Aggregate)
|
||||
|
||||
def test_create_aggregate(self):
|
||||
body = {"aggregate": {"name": "test", "availability_zone": "nova1"}}
|
||||
aggregate = self.cs.aggregates.create("test", "nova1")
|
||||
self.cs.assert_called('POST', '/os-aggregates', body)
|
||||
self.assert_called('POST', '/os-aggregates', body)
|
||||
self.assertIsInstance(aggregate, aggregates.Aggregate)
|
||||
|
||||
def test_get(self):
|
||||
aggregate = self.cs.aggregates.get("1")
|
||||
self.cs.assert_called('GET', '/os-aggregates/1')
|
||||
self.assert_called('GET', '/os-aggregates/1')
|
||||
self.assertIsInstance(aggregate, aggregates.Aggregate)
|
||||
|
||||
aggregate2 = self.cs.aggregates.get(aggregate)
|
||||
self.cs.assert_called('GET', '/os-aggregates/1')
|
||||
self.assert_called('GET', '/os-aggregates/1')
|
||||
self.assertIsInstance(aggregate2, aggregates.Aggregate)
|
||||
|
||||
def test_get_details(self):
|
||||
aggregate = self.cs.aggregates.get_details("1")
|
||||
self.cs.assert_called('GET', '/os-aggregates/1')
|
||||
self.assert_called('GET', '/os-aggregates/1')
|
||||
self.assertIsInstance(aggregate, aggregates.Aggregate)
|
||||
|
||||
aggregate2 = self.cs.aggregates.get_details(aggregate)
|
||||
self.cs.assert_called('GET', '/os-aggregates/1')
|
||||
self.assert_called('GET', '/os-aggregates/1')
|
||||
self.assertIsInstance(aggregate2, aggregates.Aggregate)
|
||||
|
||||
def test_update(self):
|
||||
@ -66,11 +60,11 @@ class AggregatesTest(utils.TestCase):
|
||||
body = {"aggregate": values}
|
||||
|
||||
result1 = aggregate.update(values)
|
||||
self.cs.assert_called('PUT', '/os-aggregates/1', body)
|
||||
self.assert_called('PUT', '/os-aggregates/1', body)
|
||||
self.assertIsInstance(result1, aggregates.Aggregate)
|
||||
|
||||
result2 = self.cs.aggregates.update(2, values)
|
||||
self.cs.assert_called('PUT', '/os-aggregates/2', body)
|
||||
self.assert_called('PUT', '/os-aggregates/2', body)
|
||||
self.assertIsInstance(result2, aggregates.Aggregate)
|
||||
|
||||
def test_update_with_availability_zone(self):
|
||||
@ -79,7 +73,7 @@ class AggregatesTest(utils.TestCase):
|
||||
body = {"aggregate": values}
|
||||
|
||||
result3 = self.cs.aggregates.update(aggregate, values)
|
||||
self.cs.assert_called('PUT', '/os-aggregates/1', body)
|
||||
self.assert_called('PUT', '/os-aggregates/1', body)
|
||||
self.assertIsInstance(result3, aggregates.Aggregate)
|
||||
|
||||
def test_add_host(self):
|
||||
@ -88,15 +82,15 @@ class AggregatesTest(utils.TestCase):
|
||||
body = {"add_host": {"host": "host1"}}
|
||||
|
||||
result1 = aggregate.add_host(host)
|
||||
self.cs.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assertIsInstance(result1, aggregates.Aggregate)
|
||||
|
||||
result2 = self.cs.aggregates.add_host("2", host)
|
||||
self.cs.assert_called('POST', '/os-aggregates/2/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/2/action', body)
|
||||
self.assertIsInstance(result2, aggregates.Aggregate)
|
||||
|
||||
result3 = self.cs.aggregates.add_host(aggregate, host)
|
||||
self.cs.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assertIsInstance(result3, aggregates.Aggregate)
|
||||
|
||||
def test_remove_host(self):
|
||||
@ -105,15 +99,15 @@ class AggregatesTest(utils.TestCase):
|
||||
body = {"remove_host": {"host": "host1"}}
|
||||
|
||||
result1 = aggregate.remove_host(host)
|
||||
self.cs.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assertIsInstance(result1, aggregates.Aggregate)
|
||||
|
||||
result2 = self.cs.aggregates.remove_host("2", host)
|
||||
self.cs.assert_called('POST', '/os-aggregates/2/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/2/action', body)
|
||||
self.assertIsInstance(result2, aggregates.Aggregate)
|
||||
|
||||
result3 = self.cs.aggregates.remove_host(aggregate, host)
|
||||
self.cs.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assertIsInstance(result3, aggregates.Aggregate)
|
||||
|
||||
def test_set_metadata(self):
|
||||
@ -122,24 +116,24 @@ class AggregatesTest(utils.TestCase):
|
||||
body = {"set_metadata": {"metadata": metadata}}
|
||||
|
||||
result1 = aggregate.set_metadata(metadata)
|
||||
self.cs.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assertIsInstance(result1, aggregates.Aggregate)
|
||||
|
||||
result2 = self.cs.aggregates.set_metadata(2, metadata)
|
||||
self.cs.assert_called('POST', '/os-aggregates/2/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/2/action', body)
|
||||
self.assertIsInstance(result2, aggregates.Aggregate)
|
||||
|
||||
result3 = self.cs.aggregates.set_metadata(aggregate, metadata)
|
||||
self.cs.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assert_called('POST', '/os-aggregates/1/action', body)
|
||||
self.assertIsInstance(result3, aggregates.Aggregate)
|
||||
|
||||
def test_delete_aggregate(self):
|
||||
aggregate = self.cs.aggregates.list()[0]
|
||||
aggregate.delete()
|
||||
self.cs.assert_called('DELETE', '/os-aggregates/1')
|
||||
self.assert_called('DELETE', '/os-aggregates/1')
|
||||
|
||||
self.cs.aggregates.delete('1')
|
||||
self.cs.assert_called('DELETE', '/os-aggregates/1')
|
||||
self.assert_called('DELETE', '/os-aggregates/1')
|
||||
|
||||
self.cs.aggregates.delete(aggregate)
|
||||
self.cs.assert_called('DELETE', '/os-aggregates/1')
|
||||
self.assert_called('DELETE', '/os-aggregates/1')
|
||||
|
@ -12,19 +12,9 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
from novaclient.tests.fixture_data import client
|
||||
from novaclient.tests.v1_1 import test_aggregates
|
||||
from novaclient.tests.v3 import fakes
|
||||
from novaclient.v3 import aggregates
|
||||
|
||||
|
||||
class AggregatesTest(test_aggregates.AggregatesTest):
|
||||
def setUp(self):
|
||||
super(AggregatesTest, self).setUp()
|
||||
self.cs = self._get_fake_client()
|
||||
self.aggregate_type = self._get_aggregate_type()
|
||||
|
||||
def _get_fake_client(self):
|
||||
return fakes.FakeClient()
|
||||
|
||||
def _get_aggregate_type(self):
|
||||
return aggregates.Aggregate
|
||||
client_fixture = client.V3
|
||||
|
@ -3,6 +3,7 @@ hacking>=0.8.0,<0.9
|
||||
coverage>=3.6
|
||||
discover
|
||||
fixtures>=0.3.14
|
||||
httpretty>=0.8.0
|
||||
keyring>=2.1
|
||||
mock>=1.0
|
||||
sphinx>=1.1.2,<1.2
|
||||
|
Loading…
x
Reference in New Issue
Block a user