diff options
| author | Joe Gordon <joe.gordon0@gmail.com> | 2015-01-27 12:59:15 -0800 |
|---|---|---|
| committer | Joe Gordon <joe.gordon0@gmail.com> | 2015-01-27 13:06:06 -0800 |
| commit | 3561772f8b0cfee746af53fa228375b2ec7dfd9d (patch) | |
| tree | db17dcd13f893639354b48b9288cbbd407d56b0b /novaclient/tests/unit/fixture_data | |
| parent | 7544dcb4ea92247c1e8fa97b8f0aba566e33ca48 (diff) | |
| download | python-novaclient-3561772f8b0cfee746af53fa228375b2ec7dfd9d.tar.gz | |
Move unit tests into unit test directory
In order to pave the way for functional testing, move existing unit
tests into a directory labeled unit. A subsequent patch will add a
directory for functional tests.
Change-Id: I0adb8b9f14451acb382c725d31f5387b4b6d82bb
Diffstat (limited to 'novaclient/tests/unit/fixture_data')
22 files changed, 2116 insertions, 0 deletions
diff --git a/novaclient/tests/unit/fixture_data/__init__.py b/novaclient/tests/unit/fixture_data/__init__.py new file mode 100644 index 00000000..e69de29b --- /dev/null +++ b/novaclient/tests/unit/fixture_data/__init__.py diff --git a/novaclient/tests/unit/fixture_data/agents.py b/novaclient/tests/unit/fixture_data/agents.py new file mode 100644 index 00000000..46a0bb67 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/agents.py @@ -0,0 +1,54 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-agents' + + def setUp(self): + super(Fixture, self).setUp() + + post_os_agents = { + 'agent': { + 'url': '/xxx/xxx/xxx', + 'hypervisor': 'kvm', + 'md5hash': 'add6bb58e139be103324d04d82d8f546', + 'version': '7.0', + 'architecture': 'x86', + 'os': 'win', + 'id': 1 + } + } + + self.requests.register_uri('POST', self.url(), + json=post_os_agents, + headers=self.json_headers) + + put_os_agents_1 = { + "agent": { + "url": "/yyy/yyyy/yyyy", + "version": "8.0", + "md5hash": "add6bb58e139be103324d04d82d8f546", + 'id': 1 + } + } + + self.requests.register_uri('PUT', self.url(1), + json=put_os_agents_1, + headers=self.json_headers) + + self.requests.register_uri('DELETE', self.url(1), + headers=self.json_headers, + status_code=202) diff --git a/novaclient/tests/unit/fixture_data/aggregates.py b/novaclient/tests/unit/fixture_data/aggregates.py new file mode 100644 index 00000000..ed743ed1 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/aggregates.py @@ -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. + +from novaclient.tests.unit.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'}, + ]} + + self.requests.register_uri('GET', self.url(), + json=get_os_aggregates, + headers=self.json_headers) + + get_aggregates_1 = {'aggregate': get_os_aggregates['aggregates'][0]} + + self.requests.register_uri('POST', self.url(), + json=get_aggregates_1, + headers=self.json_headers) + + for agg_id in (1, 2): + for method in ('GET', 'PUT'): + self.requests.register_uri(method, self.url(agg_id), + json=get_aggregates_1, + headers=self.json_headers) + + self.requests.register_uri('POST', self.url(agg_id, 'action'), + json=get_aggregates_1, + headers=self.json_headers) + + self.requests.register_uri('DELETE', self.url(1), status_code=202) diff --git a/novaclient/tests/unit/fixture_data/availability_zones.py b/novaclient/tests/unit/fixture_data/availability_zones.py new file mode 100644 index 00000000..36659d70 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/availability_zones.py @@ -0,0 +1,91 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class V1(base.Fixture): + + base_url = 'os-availability-zone' + + zone_info_key = 'availabilityZoneInfo' + zone_name_key = 'zoneName' + zone_state_key = 'zoneState' + + def setUp(self): + super(V1, self).setUp() + + get_os_availability_zone = { + self.zone_info_key: [ + { + self.zone_name_key: "zone-1", + self.zone_state_key: {"available": True}, + "hosts": None + }, + { + self.zone_name_key: "zone-2", + self.zone_state_key: {"available": False}, + "hosts": None + } + ] + } + + self.requests.register_uri('GET', self.url(), + json=get_os_availability_zone, + headers=self.json_headers) + + get_os_zone_detail = { + self.zone_info_key: [ + { + self.zone_name_key: "zone-1", + self.zone_state_key: {"available": True}, + "hosts": { + "fake_host-1": { + "nova-compute": { + "active": True, + "available": True, + "updated_at": '2012-12-26 14:45:25' + } + } + } + }, + { + self.zone_name_key: "internal", + self.zone_state_key: {"available": True}, + "hosts": { + "fake_host-1": { + "nova-sched": { + "active": True, + "available": True, + "updated_at": '2012-12-26 14:45:25' + } + }, + "fake_host-2": { + "nova-network": { + "active": True, + "available": False, + "updated_at": '2012-12-26 14:45:24' + } + } + } + }, + { + self.zone_name_key: "zone-2", + self.zone_state_key: {"available": False}, + "hosts": None + } + ] + } + + self.requests.register_uri('GET', self.url('detail'), + json=get_os_zone_detail, + headers=self.json_headers) diff --git a/novaclient/tests/unit/fixture_data/base.py b/novaclient/tests/unit/fixture_data/base.py new file mode 100644 index 00000000..6a2e238b --- /dev/null +++ b/novaclient/tests/unit/fixture_data/base.py @@ -0,0 +1,40 @@ +# 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 +from six.moves.urllib import parse + +COMPUTE_URL = 'http://compute.host' + + +class Fixture(fixtures.Fixture): + + base_url = None + json_headers = {'Content-Type': 'application/json'} + + def __init__(self, requests, compute_url=COMPUTE_URL): + super(Fixture, self).__init__() + self.requests = requests + self.compute_url = compute_url + + def url(self, *args, **kwargs): + url_args = [self.compute_url] + + if self.base_url: + url_args.append(self.base_url) + + url = '/'.join(str(a).strip('/') for a in tuple(url_args) + args) + + if kwargs: + url += '?%s' % parse.urlencode(kwargs, doseq=True) + + return url diff --git a/novaclient/tests/unit/fixture_data/certs.py b/novaclient/tests/unit/fixture_data/certs.py new file mode 100644 index 00000000..1dedaa4a --- /dev/null +++ b/novaclient/tests/unit/fixture_data/certs.py @@ -0,0 +1,55 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-certificates' + + def get_os_certificates_root(self, **kw): + return ( + 200, + {}, + {'certificate': {'private_key': None, 'data': 'foo'}} + ) + + def post_os_certificates(self, **kw): + return ( + 200, + {}, + {'certificate': {'private_key': 'foo', 'data': 'bar'}} + ) + + def setUp(self): + super(Fixture, self).setUp() + + get_os_certificate = { + 'certificate': { + 'private_key': None, + 'data': 'foo' + } + } + self.requests.register_uri('GET', self.url('root'), + json=get_os_certificate, + headers=self.json_headers) + + post_os_certificates = { + 'certificate': { + 'private_key': 'foo', + 'data': 'bar' + } + } + self.requests.register_uri('POST', self.url(), + json=post_os_certificates, + headers=self.json_headers) diff --git a/novaclient/tests/unit/fixture_data/client.py b/novaclient/tests/unit/fixture_data/client.py new file mode 100644 index 00000000..c6ddad3b --- /dev/null +++ b/novaclient/tests/unit/fixture_data/client.py @@ -0,0 +1,65 @@ +# 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 +from keystoneclient.auth.identity import v2 +from keystoneclient import fixture +from keystoneclient import session + +from novaclient.v1_1 import client as v1_1client + +IDENTITY_URL = 'http://identityserver:5000/v2.0' +COMPUTE_URL = 'http://compute.host' + + +class V1(fixtures.Fixture): + + def __init__(self, requests, + 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.requests = requests + + self.token = fixture.V2Token() + self.token.set_scope() + + s = self.token.add_service('compute') + s.add_endpoint(self.compute_url) + + s = self.token.add_service('computev3') + s.add_endpoint(self.compute_url) + + def setUp(self): + super(V1, self).setUp() + + auth_url = '%s/tokens' % self.identity_url + headers = {'X-Content-Type': 'application/json'} + self.requests.register_uri('POST', auth_url, + json=self.token, + headers=headers) + 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 SessionV1(V1): + + def new_client(self): + self.session = session.Session() + self.session.auth = v2.Password(self.identity_url, 'xx', 'xx') + return v1_1client.Client(session=self.session) diff --git a/novaclient/tests/unit/fixture_data/cloudpipe.py b/novaclient/tests/unit/fixture_data/cloudpipe.py new file mode 100644 index 00000000..abe59056 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/cloudpipe.py @@ -0,0 +1,37 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-cloudpipe' + + def setUp(self): + super(Fixture, self).setUp() + + get_os_cloudpipe = {'cloudpipes': [{'project_id': 1}]} + self.requests.register_uri('GET', self.url(), + json=get_os_cloudpipe, + headers=self.json_headers) + + instance_id = '9d5824aa-20e6-4b9f-b967-76a699fc51fd' + post_os_cloudpipe = {'instance_id': instance_id} + self.requests.register_uri('POST', self.url(), + json=post_os_cloudpipe, + headers=self.json_headers, + status_code=202) + + self.requests.register_uri('PUT', self.url('configure-project'), + headers=self.json_headers, + status_code=202) diff --git a/novaclient/tests/unit/fixture_data/fixedips.py b/novaclient/tests/unit/fixture_data/fixedips.py new file mode 100644 index 00000000..fb677e91 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/fixedips.py @@ -0,0 +1,39 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-fixed-ips' + + def setUp(self): + super(Fixture, self).setUp() + + get_os_fixed_ips = { + "fixed_ip": { + 'cidr': '192.168.1.0/24', + 'address': '192.168.1.1', + 'hostname': 'foo', + 'host': 'bar' + } + } + + self.requests.register_uri('GET', self.url('192.168.1.1'), + json=get_os_fixed_ips, + headers=self.json_headers) + + self.requests.register_uri('POST', + self.url('192.168.1.1', 'action'), + headers=self.json_headers, + status_code=202) diff --git a/novaclient/tests/unit/fixture_data/floatingips.py b/novaclient/tests/unit/fixture_data/floatingips.py new file mode 100644 index 00000000..10772a79 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/floatingips.py @@ -0,0 +1,211 @@ +# 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. + +from oslo.serialization import jsonutils + +from novaclient.tests.unit import fakes +from novaclient.tests.unit.fixture_data import base + + +class FloatingFixture(base.Fixture): + + base_url = 'os-floating-ips' + + def setUp(self): + super(FloatingFixture, self).setUp() + + floating_ips = [{'id': 1, 'fixed_ip': '10.0.0.1', 'ip': '11.0.0.1'}, + {'id': 2, 'fixed_ip': '10.0.0.2', 'ip': '11.0.0.2'}] + + get_os_floating_ips = {'floating_ips': floating_ips} + self.requests.register_uri('GET', self.url(), + json=get_os_floating_ips, + headers=self.json_headers) + + for ip in floating_ips: + get_os_floating_ip = {'floating_ip': ip} + self.requests.register_uri('GET', self.url(ip['id']), + json=get_os_floating_ip, + headers=self.json_headers) + + self.requests.register_uri('DELETE', self.url(ip['id']), + headers=self.json_headers, + status_code=204) + + def post_os_floating_ips(request, context): + body = jsonutils.loads(request.body) + ip = floating_ips[0].copy() + ip['pool'] = body.get('pool') + return {'floating_ip': ip} + self.requests.register_uri('POST', self.url(), + json=post_os_floating_ips, + headers=self.json_headers) + + +class DNSFixture(base.Fixture): + + base_url = 'os-floating-ip-dns' + + def setUp(self): + super(DNSFixture, self).setUp() + + get_os_floating_ip_dns = { + 'domain_entries': [ + {'domain': 'example.org'}, + {'domain': 'example.com'} + ] + } + self.requests.register_uri('GET', self.url(), + json=get_os_floating_ip_dns, + headers=self.json_headers, + status_code=205) + + get_dns_testdomain_entries_testname = { + 'dns_entry': { + 'ip': "10.10.10.10", + 'name': 'testname', + 'type': "A", + 'domain': 'testdomain' + } + } + url = self.url('testdomain', 'entries', 'testname') + self.requests.register_uri('GET', url, + json=get_dns_testdomain_entries_testname, + headers=self.json_headers, + status_code=205) + + self.requests.register_uri('DELETE', self.url('testdomain')) + + url = self.url('testdomain', 'entries', 'testname') + self.requests.register_uri('DELETE', url) + + def put_dns_testdomain_entries_testname(request, context): + body = jsonutils.loads(request.body) + fakes.assert_has_keys(body['dns_entry'], + required=['ip', 'dns_type']) + context.status_code = 205 + return request.body + self.requests.register_uri('PUT', url, + text=put_dns_testdomain_entries_testname, + headers=self.json_headers) + + url = self.url('testdomain', 'entries') + self.requests.register_uri('GET', url, status_code=404) + + get_os_floating_ip_dns_testdomain = { + 'dns_entries': [ + { + 'dns_entry': { + 'ip': '1.2.3.4', + 'name': "host1", + 'type': "A", + 'domain': 'testdomain' + } + }, + { + 'dns_entry': { + 'ip': '1.2.3.4', + 'name': "host2", + 'type': "A", + 'domain': 'testdomain' + } + }, + ] + } + self.requests.register_uri('GET', url + '?ip=1.2.3.4', + json=get_os_floating_ip_dns_testdomain, + status_code=205, + headers=self.json_headers) + + def put_os_floating_ip_dns_testdomain(request, context): + body = jsonutils.loads(request.body) + if body['domain_entry']['scope'] == 'private': + fakes.assert_has_keys(body['domain_entry'], + required=['availability_zone', 'scope']) + elif body['domain_entry']['scope'] == 'public': + fakes.assert_has_keys(body['domain_entry'], + required=['project', 'scope']) + else: + fakes.assert_has_keys(body['domain_entry'], + required=['project', 'scope']) + + return request.body + + self.requests.register_uri('PUT', self.url('testdomain'), + text=put_os_floating_ip_dns_testdomain, + status_code=205, + headers=self.json_headers) + + +class BulkFixture(base.Fixture): + + base_url = 'os-floating-ips-bulk' + + def setUp(self): + super(BulkFixture, self).setUp() + + get_os_floating_ips_bulk = { + 'floating_ip_info': [ + {'id': 1, 'fixed_ip': '10.0.0.1', 'ip': '11.0.0.1'}, + {'id': 2, 'fixed_ip': '10.0.0.2', 'ip': '11.0.0.2'}, + ] + } + self.requests.register_uri('GET', self.url(), + json=get_os_floating_ips_bulk, + headers=self.json_headers) + self.requests.register_uri('GET', self.url('testHost'), + json=get_os_floating_ips_bulk, + headers=self.json_headers) + + def put_os_floating_ips_bulk_delete(request, context): + body = jsonutils.loads(request.body) + ip_range = body.get('ip_range') + return {'floating_ips_bulk_delete': ip_range} + + self.requests.register_uri('PUT', self.url('delete'), + json=put_os_floating_ips_bulk_delete, + headers=self.json_headers) + + def post_os_floating_ips_bulk(request, context): + body = jsonutils.loads(request.body) + params = body.get('floating_ips_bulk_create') + pool = params.get('pool', 'defaultPool') + interface = params.get('interface', 'defaultInterface') + return { + 'floating_ips_bulk_create': { + 'ip_range': '192.168.1.0/30', + 'pool': pool, + 'interface': interface + } + } + + self.requests.register_uri('POST', self.url(), + json=post_os_floating_ips_bulk, + headers=self.json_headers) + + +class PoolsFixture(base.Fixture): + + base_url = 'os-floating-ip-pools' + + def setUp(self): + super(PoolsFixture, self).setUp() + + get_os_floating_ip_pools = { + 'floating_ip_pools': [ + {'name': 'foo'}, + {'name': 'bar'} + ] + } + self.requests.register_uri('GET', self.url(), + json=get_os_floating_ip_pools, + headers=self.json_headers) diff --git a/novaclient/tests/unit/fixture_data/fping.py b/novaclient/tests/unit/fixture_data/fping.py new file mode 100644 index 00000000..6c6cd4f8 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/fping.py @@ -0,0 +1,46 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-fping' + + def setUp(self): + super(Fixture, self).setUp() + + get_os_fping_1 = { + 'server': { + "id": "1", + "project_id": "fake-project", + "alive": True, + } + } + self.requests.register_uri('GET', self.url(1), + json=get_os_fping_1, + headers=self.json_headers) + + get_os_fping = { + 'servers': [ + get_os_fping_1['server'], + { + "id": "2", + "project_id": "fake-project", + "alive": True, + }, + ] + } + self.requests.register_uri('GET', self.url(), + json=get_os_fping, + headers=self.json_headers) diff --git a/novaclient/tests/unit/fixture_data/hosts.py b/novaclient/tests/unit/fixture_data/hosts.py new file mode 100644 index 00000000..5c1ff60a --- /dev/null +++ b/novaclient/tests/unit/fixture_data/hosts.py @@ -0,0 +1,149 @@ +# 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. + +from oslo.serialization import jsonutils +from six.moves.urllib import parse + +from novaclient.tests.unit.fixture_data import base + + +class BaseFixture(base.Fixture): + + base_url = 'os-hosts' + + def setUp(self): + super(BaseFixture, self).setUp() + + get_os_hosts_host = { + 'host': [ + {'resource': {'project': '(total)', 'host': 'dummy', + 'cpu': 16, 'memory_mb': 32234, 'disk_gb': 128}}, + {'resource': {'project': '(used_now)', 'host': 'dummy', + 'cpu': 1, 'memory_mb': 2075, 'disk_gb': 45}}, + {'resource': {'project': '(used_max)', 'host': 'dummy', + 'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}}, + {'resource': {'project': 'admin', 'host': 'dummy', + 'cpu': 1, 'memory_mb': 2048, 'disk_gb': 30}} + ] + } + + headers = {'Content-Type': 'application/json'} + + self.requests.register_uri('GET', self.url('host'), + json=get_os_hosts_host, + headers=headers) + + def get_os_hosts(request, context): + host, query = parse.splitquery(request.url) + zone = 'nova1' + service = None + + if query: + qs = parse.parse_qs(query) + try: + zone = qs['zone'][0] + except Exception: + pass + + try: + service = qs['service'][0] + except Exception: + pass + + return { + 'hosts': [ + { + 'host': 'host1', + 'service': service or 'nova-compute', + 'zone': zone + }, + { + 'host': 'host1', + 'service': service or 'nova-cert', + 'zone': zone + } + ] + } + + self.requests.register_uri('GET', self.url(), + json=get_os_hosts, + headers=headers) + + get_os_hosts_sample_host = { + 'host': [ + {'resource': {'host': 'sample_host'}} + ], + } + self.requests.register_uri('GET', self.url('sample_host'), + json=get_os_hosts_sample_host, + headers=headers) + + self.requests.register_uri('PUT', self.url('sample_host', 1), + json=self.put_host_1(), + headers=headers) + + self.requests.register_uri('PUT', self.url('sample_host', 2), + json=self.put_host_2(), + headers=headers) + + self.requests.register_uri('PUT', self.url('sample_host', 3), + json=self.put_host_3(), + headers=headers) + + self.requests.register_uri('GET', self.url('sample_host', 'reboot'), + json=self.get_host_reboot(), + headers=headers) + + self.requests.register_uri('GET', self.url('sample_host', 'startup'), + json=self.get_host_startup(), + headers=headers) + + self.requests.register_uri('GET', self.url('sample_host', 'shutdown'), + json=self.get_host_shutdown(), + headers=headers) + + def put_os_hosts_sample_host(request, context): + result = {'host': 'dummy'} + result.update(jsonutils.loads(request.body)) + return result + + self.requests.register_uri('PUT', self.url('sample_host'), + json=put_os_hosts_sample_host, + headers=headers) + + +class V1(BaseFixture): + + def put_host_1(self): + return {'host': 'sample-host_1', + 'status': 'enabled'} + + def put_host_2(self): + return {'host': 'sample-host_2', + 'maintenance_mode': 'on_maintenance'} + + def put_host_3(self): + return {'host': 'sample-host_3', + 'status': 'enabled', + 'maintenance_mode': 'on_maintenance'} + + def get_host_reboot(self): + return {'host': 'sample_host', + 'power_action': 'reboot'} + + def get_host_startup(self): + return {'host': 'sample_host', + 'power_action': 'startup'} + + def get_host_shutdown(self): + return {'host': 'sample_host', + 'power_action': 'shutdown'} diff --git a/novaclient/tests/unit/fixture_data/hypervisors.py b/novaclient/tests/unit/fixture_data/hypervisors.py new file mode 100644 index 00000000..62952f08 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/hypervisors.py @@ -0,0 +1,182 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class V1(base.Fixture): + + base_url = 'os-hypervisors' + + def setUp(self): + super(V1, self).setUp() + + get_os_hypervisors = { + 'hypervisors': [ + {'id': 1234, 'hypervisor_hostname': 'hyper1'}, + {'id': 5678, 'hypervisor_hostname': 'hyper2'}, + ] + } + + self.headers = {'Content-Type': 'application/json'} + + self.requests.register_uri('GET', self.url(), + json=get_os_hypervisors, + headers=self.headers) + + get_os_hypervisors_detail = { + 'hypervisors': [ + { + 'id': 1234, + 'service': { + 'id': 1, + 'host': 'compute1', + }, + 'vcpus': 4, + 'memory_mb': 10 * 1024, + 'local_gb': 250, + 'vcpus_used': 2, + 'memory_mb_used': 5 * 1024, + 'local_gb_used': 125, + 'hypervisor_type': 'xen', + 'hypervisor_version': 3, + 'hypervisor_hostname': 'hyper1', + 'free_ram_mb': 5 * 1024, + 'free_disk_gb': 125, + 'current_workload': 2, + 'running_vms': 2, + 'cpu_info': 'cpu_info', + 'disk_available_least': 100 + }, + { + 'id': 2, + 'service': { + 'id': 2, + 'host': 'compute2', + }, + 'vcpus': 4, + 'memory_mb': 10 * 1024, + 'local_gb': 250, + 'vcpus_used': 2, + 'memory_mb_used': 5 * 1024, + 'local_gb_used': 125, + 'hypervisor_type': 'xen', + 'hypervisor_version': 3, + 'hypervisor_hostname': 'hyper2', + 'free_ram_mb': 5 * 1024, + 'free_disk_gb': 125, + 'current_workload': 2, + 'running_vms': 2, + 'cpu_info': 'cpu_info', + 'disk_available_least': 100 + } + ] + } + + self.requests.register_uri('GET', self.url('detail'), + json=get_os_hypervisors_detail, + headers=self.headers) + + get_os_hypervisors_stats = { + 'hypervisor_statistics': { + 'count': 2, + 'vcpus': 8, + 'memory_mb': 20 * 1024, + 'local_gb': 500, + 'vcpus_used': 4, + 'memory_mb_used': 10 * 1024, + 'local_gb_used': 250, + 'free_ram_mb': 10 * 1024, + 'free_disk_gb': 250, + 'current_workload': 4, + 'running_vms': 4, + 'disk_available_least': 200, + } + } + + self.requests.register_uri('GET', self.url('statistics'), + json=get_os_hypervisors_stats, + headers=self.headers) + + get_os_hypervisors_search = { + 'hypervisors': [ + {'id': 1234, 'hypervisor_hostname': 'hyper1'}, + {'id': 5678, 'hypervisor_hostname': 'hyper2'} + ] + } + + self.requests.register_uri('GET', self.url('hyper', 'search'), + json=get_os_hypervisors_search, + headers=self.headers) + + get_hyper_server = { + 'hypervisors': [ + { + 'id': 1234, + 'hypervisor_hostname': 'hyper1', + 'servers': [ + {'name': 'inst1', 'uuid': 'uuid1'}, + {'name': 'inst2', 'uuid': 'uuid2'} + ] + }, + { + 'id': 5678, + 'hypervisor_hostname': 'hyper2', + 'servers': [ + {'name': 'inst3', 'uuid': 'uuid3'}, + {'name': 'inst4', 'uuid': 'uuid4'} + ] + } + ] + } + + self.requests.register_uri('GET', self.url('hyper', 'servers'), + json=get_hyper_server, + headers=self.headers) + + get_os_hypervisors_1234 = { + 'hypervisor': { + 'id': 1234, + 'service': {'id': 1, 'host': 'compute1'}, + 'vcpus': 4, + 'memory_mb': 10 * 1024, + 'local_gb': 250, + 'vcpus_used': 2, + 'memory_mb_used': 5 * 1024, + 'local_gb_used': 125, + 'hypervisor_type': 'xen', + 'hypervisor_version': 3, + 'hypervisor_hostname': 'hyper1', + 'free_ram_mb': 5 * 1024, + 'free_disk_gb': 125, + 'current_workload': 2, + 'running_vms': 2, + 'cpu_info': 'cpu_info', + 'disk_available_least': 100 + } + } + + self.requests.register_uri('GET', self.url(1234), + json=get_os_hypervisors_1234, + headers=self.headers) + + get_os_hypervisors_uptime = { + 'hypervisor': { + 'id': 1234, + 'hypervisor_hostname': 'hyper1', + 'uptime': 'fake uptime' + } + } + + self.requests.register_uri('GET', self.url(1234, 'uptime'), + json=get_os_hypervisors_uptime, + headers=self.headers) diff --git a/novaclient/tests/unit/fixture_data/images.py b/novaclient/tests/unit/fixture_data/images.py new file mode 100644 index 00000000..02f35966 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/images.py @@ -0,0 +1,113 @@ +# 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. + +from oslo.serialization import jsonutils + +from novaclient.tests.unit import fakes +from novaclient.tests.unit.fixture_data import base + + +class V1(base.Fixture): + + base_url = 'images' + + def setUp(self): + super(V1, self).setUp() + + get_images = { + 'images': [ + {'id': 1, 'name': 'CentOS 5.2'}, + {'id': 2, 'name': 'My Server Backup'} + ] + } + + headers = {'Content-Type': 'application/json'} + + self.requests.register_uri('GET', self.url(), + json=get_images, + headers=headers) + + image_1 = { + 'id': 1, + 'name': 'CentOS 5.2', + "updated": "2010-10-10T12:00:00Z", + "created": "2010-08-10T12:00:00Z", + "status": "ACTIVE", + "metadata": { + "test_key": "test_value", + }, + "links": {}, + } + + image_2 = { + "id": 2, + "name": "My Server Backup", + "serverId": 1234, + "updated": "2010-10-10T12:00:00Z", + "created": "2010-08-10T12:00:00Z", + "status": "SAVING", + "progress": 80, + "links": {}, + } + + self.requests.register_uri('GET', self.url('detail'), + json={'images': [image_1, image_2]}, + headers=headers) + + self.requests.register_uri('GET', self.url(1), + json={'image': image_1}, + headers=headers) + + self.requests.register_uri('GET', self.url(2), + json={'image': image_2}, + headers=headers) + + self.requests.register_uri('GET', self.url(456), + json={'image': image_2}, + headers=headers) + + def post_images(request, context): + body = jsonutils.loads(request.body) + assert list(body) == ['image'] + fakes.assert_has_keys(body['image'], required=['serverId', 'name']) + return images_1 + + self.requests.register_uri('POST', self.url(), + json=post_images, + headers=headers, + status_code=202) + + def post_images_1_metadata(request, context): + body = jsonutils.loads(request.body) + assert list(body) == ['metadata'] + fakes.assert_has_keys(body['metadata'], required=['test_key']) + return {'metadata': image_1['metadata']} + + self.requests.register_uri('POST', self.url(1, 'metadata'), + json=post_images_1_metadata, + headers=headers) + + for u in (1, 2, '1/metadata/test_key'): + self.requests.register_uri('DELETE', self.url(u), status_code=204) + + image_headers = {'x-image-meta-id': '1', + 'x-image-meta-name': 'CentOS 5.2', + 'x-image-meta-updated': '2010-10-10T12:00:00Z', + 'x-image-meta-created': '2010-10-10T12:00:00Z', + 'x-image-meta-status': 'ACTIVE', + 'x-image-meta-property-test-key': 'test_value'} + self.requests.register_uri('HEAD', self.url(1), headers=image_headers) + + +class V3(V1): + + base_url = 'v1/images' diff --git a/novaclient/tests/unit/fixture_data/keypairs.py b/novaclient/tests/unit/fixture_data/keypairs.py new file mode 100644 index 00000000..9314c58a --- /dev/null +++ b/novaclient/tests/unit/fixture_data/keypairs.py @@ -0,0 +1,47 @@ +# 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. + +from oslo.serialization import jsonutils + +from novaclient.tests.unit import fakes +from novaclient.tests.unit.fixture_data import base + + +class V1(base.Fixture): + + base_url = 'os-keypairs' + + def setUp(self): + super(V1, self).setUp() + keypair = {'fingerprint': 'FAKE_KEYPAIR', 'name': 'test'} + + headers = {'Content-Type': 'application/json'} + + self.requests.register_uri('GET', self.url(), + json={'keypairs': [keypair]}, + headers=headers) + + self.requests.register_uri('GET', self.url('test'), + json={'keypair': keypair}, + headers=headers) + + self.requests.register_uri('DELETE', self.url('test'), status_code=202) + + def post_os_keypairs(request, context): + body = jsonutils.loads(request.body) + assert list(body) == ['keypair'] + fakes.assert_has_keys(body['keypair'], required=['name']) + return {'keypair': keypair} + + self.requests.register_uri('POST', self.url(), + json=post_os_keypairs, + headers=headers) diff --git a/novaclient/tests/unit/fixture_data/limits.py b/novaclient/tests/unit/fixture_data/limits.py new file mode 100644 index 00000000..55d324d9 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/limits.py @@ -0,0 +1,80 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'limits' + + def setUp(self): + super(Fixture, self).setUp() + + get_limits = { + "limits": { + "rate": [ + { + "uri": "*", + "regex": ".*", + "limit": [ + { + "value": 10, + "verb": "POST", + "remaining": 2, + "unit": "MINUTE", + "next-available": "2011-12-15T22:42:45Z" + }, + { + "value": 10, + "verb": "PUT", + "remaining": 2, + "unit": "MINUTE", + "next-available": "2011-12-15T22:42:45Z" + }, + { + "value": 100, + "verb": "DELETE", + "remaining": 100, + "unit": "MINUTE", + "next-available": "2011-12-15T22:42:45Z" + } + ] + }, + { + "uri": "*/servers", + "regex": "^/servers", + "limit": [ + { + "verb": "POST", + "value": 25, + "remaining": 24, + "unit": "DAY", + "next-available": "2011-12-15T22:42:45Z" + } + ] + } + ], + "absolute": { + "maxTotalRAMSize": 51200, + "maxServerMeta": 5, + "maxImageMeta": 5, + "maxPersonality": 5, + "maxPersonalitySize": 10240 + }, + }, + } + + headers = {'Content-Type': 'application/json'} + self.requests.register_uri('GET', self.url(), + json=get_limits, + headers=headers) diff --git a/novaclient/tests/unit/fixture_data/networks.py b/novaclient/tests/unit/fixture_data/networks.py new file mode 100644 index 00000000..9ef692c3 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/networks.py @@ -0,0 +1,62 @@ +# 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. + +from oslo.serialization import jsonutils + +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-networks' + + def setUp(self): + super(Fixture, self).setUp() + + get_os_networks = { + 'networks': [ + { + "label": "1", + "cidr": "10.0.0.0/24", + 'project_id': '4ffc664c198e435e9853f2538fbcd7a7', + 'id': '1' + } + ] + } + + headers = {'Content-Type': 'application/json'} + + self.requests.register_uri('GET', self.url(), + json=get_os_networks, + headers=headers) + + def post_os_networks(request, context): + body = jsonutils.loads(request.body) + return {'network': body} + + self.requests.register_uri("POST", self.url(), + json=post_os_networks, + headers=headers) + + get_os_networks_1 = {'network': {"label": "1", "cidr": "10.0.0.0/24"}} + + self.requests.register_uri('GET', self.url(1), + json=get_os_networks_1, + headers=headers) + + self.requests.register_uri('DELETE', + self.url('networkdelete'), + status_code=202) + + for u in ('add', 'networkdisassociate/action', 'networktest/action', + '1/action', '2/action'): + self.requests.register_uri('POST', self.url(u), status_code=202) diff --git a/novaclient/tests/unit/fixture_data/quotas.py b/novaclient/tests/unit/fixture_data/quotas.py new file mode 100644 index 00000000..83f448f4 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/quotas.py @@ -0,0 +1,66 @@ +# 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. + +from novaclient.tests.unit.fixture_data import base + + +class V1(base.Fixture): + + base_url = 'os-quota-sets' + + def setUp(self): + super(V1, self).setUp() + + uuid = '97f4c221-bff4-4578-b030-0df4ef119353' + uuid2 = '97f4c221bff44578b0300df4ef119353' + test_json = {'quota_set': self.test_quota('test')} + self.headers = {'Content-Type': 'application/json'} + + for u in ('test', 'tenant-id', 'tenant-id/defaults', + '%s/defaults' % uuid2): + self.requests.register_uri('GET', self.url(u), + json=test_json, + headers=self.headers) + + self.requests.register_uri('PUT', self.url(uuid), + json={'quota_set': self.test_quota(uuid)}, + headers=self.headers) + + self.requests.register_uri('GET', self.url(uuid), + json={'quota_set': self.test_quota(uuid)}, + headers=self.headers) + + self.requests.register_uri('PUT', self.url(uuid2), + json={'quota_set': self.test_quota(uuid2)}, + headers=self.headers) + self.requests.register_uri('GET', self.url(uuid2), + json={'quota_set': self.test_quota(uuid2)}, + headers=self.headers) + + for u in ('test', uuid2): + self.requests.register_uri('DELETE', self.url(u), status_code=202) + + def test_quota(self, tenant_id='test'): + return { + 'tenant_id': tenant_id, + 'metadata_items': [], + 'injected_file_content_bytes': 1, + 'injected_file_path_bytes': 1, + 'ram': 1, + 'floating_ips': 1, + 'instances': 1, + 'injected_files': 1, + 'cores': 1, + 'keypairs': 1, + 'security_groups': 1, + 'security_group_rules': 1 + } diff --git a/novaclient/tests/unit/fixture_data/security_group_rules.py b/novaclient/tests/unit/fixture_data/security_group_rules.py new file mode 100644 index 00000000..5f1d2fad --- /dev/null +++ b/novaclient/tests/unit/fixture_data/security_group_rules.py @@ -0,0 +1,58 @@ +# 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. + +from oslo.serialization import jsonutils + +from novaclient.tests.unit import fakes +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-security-group-rules' + + def setUp(self): + super(Fixture, self).setUp() + + rule = { + 'id': 1, + 'parent_group_id': 1, + 'group_id': 2, + 'ip_protocol': 'TCP', + 'from_port': '22', + 'to_port': 22, + 'cidr': '10.0.0.0/8' + } + + headers = {'Content-Type': 'application/json'} + + self.requests.register_uri('GET', self.url(), + json={'security_group_rules': [rule]}, + headers=headers) + + for u in (1, 11, 12): + self.requests.register_uri('DELETE', self.url(u), status_code=202) + + def post_rules(request, context): + body = jsonutils.loads(request.body) + assert list(body) == ['security_group_rule'] + fakes.assert_has_keys(body['security_group_rule'], + required=['parent_group_id'], + optional=['group_id', 'ip_protocol', + 'from_port', 'to_port', 'cidr']) + + return {'security_group_rule': rule} + + self.requests.register_uri('POST', self.url(), + json=post_rules, + headers=headers, + status_code=202) diff --git a/novaclient/tests/unit/fixture_data/security_groups.py b/novaclient/tests/unit/fixture_data/security_groups.py new file mode 100644 index 00000000..ac5d182c --- /dev/null +++ b/novaclient/tests/unit/fixture_data/security_groups.py @@ -0,0 +1,100 @@ +# 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. + +from oslo.serialization import jsonutils + +from novaclient.tests.unit import fakes +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-security-groups' + + def setUp(self): + super(Fixture, self).setUp() + + security_group_1 = { + "name": "test", + "description": "FAKE_SECURITY_GROUP", + "tenant_id": "4ffc664c198e435e9853f2538fbcd7a7", + "id": 1, + "rules": [ + { + "id": 11, + "group": {}, + "ip_protocol": "TCP", + "from_port": 22, + "to_port": 22, + "parent_group_id": 1, + "ip_range": {"cidr": "10.0.0.0/8"} + }, + { + "id": 12, + "group": { + "tenant_id": "272bee4c1e624cd4a72a6b0ea55b4582", + "name": "test2" + }, + "ip_protocol": "TCP", + "from_port": 222, + "to_port": 222, + "parent_group_id": 1, + "ip_range": {} + } + ] + } + + security_group_2 = { + "name": "test2", + "description": "FAKE_SECURITY_GROUP2", + "tenant_id": "272bee4c1e624cd4a72a6b0ea55b4582", + "id": 2, + "rules": [] + } + + get_groups = {'security_groups': [security_group_1, security_group_2]} + headers = {'Content-Type': 'application/json'} + + self.requests.register_uri('GET', self.url(), + json=get_groups, + headers=headers) + + get_group_1 = {'security_group': security_group_1} + self.requests.register_uri('GET', self.url(1), + json=get_group_1, + headers=headers) + + self.requests.register_uri('DELETE', self.url(1), status_code=202) + + def post_os_security_groups(request, context): + body = jsonutils.loads(request.body) + assert list(body) == ['security_group'] + fakes.assert_has_keys(body['security_group'], + required=['name', 'description']) + return {'security_group': security_group_1} + + self.requests.register_uri('POST', self.url(), + json=post_os_security_groups, + headers=headers, + status_code=202) + + def put_os_security_groups_1(request, context): + body = jsonutils.loads(request.body) + assert list(body) == ['security_group'] + fakes.assert_has_keys(body['security_group'], + required=['name', 'description']) + return body + + self.requests.register_uri('PUT', self.url(1), + json=put_os_security_groups_1, + headers=headers, + status_code=205) diff --git a/novaclient/tests/unit/fixture_data/server_groups.py b/novaclient/tests/unit/fixture_data/server_groups.py new file mode 100644 index 00000000..1fcfdea5 --- /dev/null +++ b/novaclient/tests/unit/fixture_data/server_groups.py @@ -0,0 +1,74 @@ +# 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. + +from oslo.serialization import jsonutils + +from novaclient.tests.unit.fixture_data import base + + +class Fixture(base.Fixture): + + base_url = 'os-server-groups' + + def setUp(self): + super(Fixture, self).setUp() + + server_groups = [ + { + "members": [], + "metadata": {}, + "id": "2cbd51f4-fafe-4cdb-801b-cf913a6f288b", + "policies": [], + "name": "ig1" + }, + { + "members": [], + "metadata": {}, + "id": "4473bb03-4370-4bfb-80d3-dc8cffc47d94", + "policies": ["anti-affinity"], + "name": "ig2" + }, + { + "members": [], + "metadata": {"key": "value"}, + "id": "31ab9bdb-55e1-4ac3-b094-97eeb1b65cc4", + "policies": [], "name": "ig3" + }, + { + "members": ["2dccb4a1-02b9-482a-aa23-5799490d6f5d"], + "metadata": {}, + "id": "4890bb03-7070-45fb-8453-d34556c87d94", + "policies": ["anti-affinity"], + "name": "ig2" + } + ] + + headers = {'Content-Type': 'application/json'} + + self.requests.register_uri('GET', self.url(), + json={'server_groups': server_groups}, + headers=headers) + + server = server_groups[0] + server_j = jsonutils.dumps({'server_group': server}) + + def _register(method, *args): + self.requests.register_uri(method, self.url(*args), text=server_j) + + _register('POST') + _register('POST', server['id']) + _register('GET', server['id']) + _register('PUT', server['id']) + _register('POST', server['id'], '/action') + + self.requests.register_uri('DELETE', self.url(server['id']), + status_code=202) diff --git a/novaclient/tests/unit/fixture_data/servers.py b/novaclient/tests/unit/fixture_data/servers.py new file mode 100644 index 00000000..6e3dd46b --- /dev/null +++ b/novaclient/tests/unit/fixture_data/servers.py @@ -0,0 +1,495 @@ +# 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. + +from oslo.serialization import jsonutils + +from novaclient.tests.unit import fakes +from novaclient.tests.unit.fixture_data import base + + +class Base(base.Fixture): + + base_url = 'servers' + + def setUp(self): + super(Base, self).setUp() + + get_servers = { + "servers": [ + {'id': 1234, 'name': 'sample-server'}, + {'id': 5678, 'name': 'sample-server2'} + ] + } + + self.requests.register_uri('GET', self.url(), + json=get_servers, + headers=self.json_headers) + + self.server_1234 = { + "id": 1234, + "name": "sample-server", + "image": { + "id": 2, + "name": "sample image", + }, + "flavor": { + "id": 1, + "name": "256 MB Server", + }, + "hostId": "e4d909c290d0fb1ca068ffaddf22cbd0", + "status": "BUILD", + "progress": 60, + "addresses": { + "public": [ + { + "version": 4, + "addr": "1.2.3.4", + }, + { + "version": 4, + "addr": "5.6.7.8", + }], + "private": [{ + "version": 4, + "addr": "10.11.12.13", + }], + }, + "metadata": { + "Server Label": "Web Head 1", + "Image Version": "2.1" + }, + "OS-EXT-SRV-ATTR:host": "computenode1", + "security_groups": [{ + 'id': 1, 'name': 'securitygroup1', + 'description': 'FAKE_SECURITY_GROUP', + 'tenant_id': '4ffc664c198e435e9853f2538fbcd7a7' + }], + "OS-EXT-MOD:some_thing": "mod_some_thing_value", + } + + self.server_5678 = { + "id": 5678, + "name": "sample-server2", + "image": { + "id": 2, + "name": "sample image", + }, + "flavor": { + "id": 1, + "name": "256 MB Server", + }, + "hostId": "9e107d9d372bb6826bd81d3542a419d6", + "status": "ACTIVE", + "addresses": { + "public": [ + { + "version": 4, + "addr": "4.5.6.7", + }, + { + "version": 4, + "addr": "5.6.9.8", + }], + "private": [{ + "version": 4, + "addr": "10.13.12.13", + }], + }, + "metadata": { + "Server Label": "DB 1" + }, + "OS-EXT-SRV-ATTR:host": "computenode2", + "security_groups": [ + { + 'id': 1, 'name': 'securitygroup1', + 'description': 'FAKE_SECURITY_GROUP', + 'tenant_id': '4ffc664c198e435e9853f2538fbcd7a7' + }, + { + 'id': 2, 'name': 'securitygroup2', + 'description': 'ANOTHER_FAKE_SECURITY_GROUP', + 'tenant_id': '4ffc664c198e435e9853f2538fbcd7a7' + }], + } + + self.server_9012 = { + "id": 9012, + "name": "sample-server3", + "image": "", + "flavor": { + "id": 1, + "name": "256 MB Server", + }, + "hostId": "9e107d9d372bb6826bd81d3542a419d6", + "status": "ACTIVE", + "addresses": { + "public": [ + { + "version": 4, + "addr": "4.5.6.7", + }, + { + "version": 4, + "addr": "5.6.9.8", + }], + "private": [{ + "version": 4, + "addr": "10.13.12.13", + }], + }, + "metadata": { + "Server Label": "DB 1" + } + } + + servers = [self.server_1234, self.server_5678, self.server_9012] + get_servers_detail = {"servers": servers} + + self.requests.register_uri('GET', self.url('detail'), + json=get_servers_detail, + headers=self.json_headers) + + self.server_1235 = self.server_1234.copy() + self.server_1235['id'] = 1235 + self.server_1235['status'] = 'error' + self.server_1235['fault'] = {'message': 'something went wrong!'} + + for s in servers + [self.server_1235]: + self.requests.register_uri('GET', self.url(s['id']), + json={'server': s}, + headers=self.json_headers) + + for s in (1234, 5678): + self.requests.register_uri('DELETE', self.url(s), status_code=202) + + for k in ('test_key', 'key1', 'key2'): + self.requests.register_uri('DELETE', + self.url(1234, 'metadata', k), + status_code=204) + + metadata1 = {'metadata': {'test_key': 'test_value'}} + self.requests.register_uri('POST', self.url(1234, 'metadata'), + json=metadata1, + headers=self.json_headers) + self.requests.register_uri('PUT', + self.url(1234, 'metadata', 'test_key'), + json=metadata1, + headers=self.json_headers) + + self.diagnostic = {'data': 'Fake diagnostics'} + + metadata2 = {'metadata': {'key1': 'val1'}} + for u in ('uuid1', 'uuid2', 'uuid3', 'uuid4'): + self.requests.register_uri('POST', self.url(u, 'metadata'), + json=metadata2, status_code=204) + self.requests.register_uri('DELETE', + self.url(u, 'metadata', 'key1'), + json=self.diagnostic, + headers=self.json_headers) + + get_security_groups = { + "security_groups": [{ + 'id': 1, + 'name': 'securitygroup1', + 'description': 'FAKE_SECURITY_GROUP', + 'tenant_id': '4ffc664c198e435e9853f2538fbcd7a7', + 'rules': []}] + } + + self.requests.register_uri('GET', + self.url('1234', 'os-security-groups'), + json=get_security_groups) + + self.requests.register_uri('POST', self.url(), + json=self.post_servers, + headers=self.json_headers) + + self.requests.register_uri('POST', self.url('1234', 'action'), + json=self.post_servers_1234_action, + headers=self.json_headers) + + get_os_interface = { + "interfaceAttachments": [ + { + "port_state": "ACTIVE", + "net_id": "net-id-1", + "port_id": "port-id-1", + "mac_address": "aa:bb:cc:dd:ee:ff", + "fixed_ips": [{"ip_address": "1.2.3.4"}], + }, + { + "port_state": "ACTIVE", + "net_id": "net-id-1", + "port_id": "port-id-1", + "mac_address": "aa:bb:cc:dd:ee:ff", + "fixed_ips": [{"ip_address": "1.2.3.4"}], + } + ] + } + + self.requests.register_uri('GET', + self.url('1234', 'os-interface'), + json=get_os_interface, + headers=self.json_headers) + + interface_data = {'interfaceAttachment': {}} + self.requests.register_uri('POST', + self.url('1234', 'os-interface'), + json=interface_data, + headers=self.json_headers) + + def put_servers_1234(request, context): + body = jsonutils.loads(request.body) + assert list(body) == ['server'] + fakes.assert_has_keys(body['server'], + optional=['name', 'adminPass']) + return request.body + + self.requests.register_uri('PUT', self.url(1234), + text=put_servers_1234, + status_code=204, + headers=self.json_headers) + + def post_os_volumes_boot(request, context): + body = jsonutils.loads(request.body) + assert (set(body.keys()) <= + set(['server', 'os:scheduler_hints'])) + + fakes.assert_has_keys(body['server'], + required=['name', 'flavorRef'], + optional=['imageRef']) + + data = body['server'] + + # Require one, and only one, of the keys for bdm + if 'block_device_mapping' not in data: + if 'block_device_mapping_v2' not in data: + msg = "missing required keys: 'block_device_mapping'" + raise AssertionError(msg) + elif 'block_device_mapping_v2' in data: + msg = "found extra keys: 'block_device_mapping'" + raise AssertionError(msg) + + return {'server': self.server_9012} + + # NOTE(jamielennox): hack to make os_volumes mock go to the right place + base_url = self.base_url + self.base_url = None + self.requests.register_uri('POST', self.url('os-volumes_boot'), + json=post_os_volumes_boot, + status_code=202, + headers=self.json_headers) + self.base_url = base_url + + # + # Server password + # + + self.requests.register_uri('DELETE', + self.url(1234, 'os-server-password'), + status_code=202) + + +class V1(Base): + + def setUp(self): + super(V1, self).setUp() + + # + # Server Addresses + # + + add = self.server_1234['addresses'] + self.requests.register_uri('GET', self.url(1234, 'ips'), + json={'addresses': add}, + headers=self.json_headers) + + self.requests.register_uri('GET', self.url(1234, 'ips', 'public'), + json={'public': add['public']}, + headers=self.json_headers) + + self.requests.register_uri('GET', self.url(1234, 'ips', 'private'), + json={'private': add['private']}, + headers=self.json_headers) + + self.requests.register_uri('DELETE', + self.url(1234, 'ips', 'public', '1.2.3.4'), + status_code=202) + + self.requests.register_uri('GET', + self.url('1234', 'diagnostics'), + json=self.diagnostic) + + self.requests.register_uri('DELETE', + self.url('1234', 'os-interface', 'port-id')) + + # Testing with the following password and key + # + # Clear password: FooBar123 + # + # RSA Private Key: novaclient/tests/unit/idfake.pem + # + # Encrypted password + # OIuEuQttO8Rk93BcKlwHQsziDAnkAm/V6V8VPToA8ZeUaUBWwS0gwo2K6Y61Z96r + # qG447iRz0uTEEYq3RAYJk1mh3mMIRVl27t8MtIecR5ggVVbz1S9AwXJQypDKl0ho + # QFvhCBcMWPohyGewDJOhDbtuN1IoFI9G55ZvFwCm5y7m7B2aVcoLeIsJZE4PLsIw + # /y5a6Z3/AoJZYGG7IH5WN88UROU3B9JZGFB2qtPLQTOvDMZLUhoPRIJeHiVSlo1N + # tI2/++UsXVg3ow6ItqCJGgdNuGG5JB+bslDHWPxROpesEIHdczk46HCpHQN8f1sk + # Hi/fmZZNQQqj1Ijq0caOIw== + + get_server_password = { + 'password': + 'OIuEuQttO8Rk93BcKlwHQsziDAnkAm/V6V8VPToA8ZeUaUBWwS0gwo2K6Y61Z96r' + 'qG447iRz0uTEEYq3RAYJk1mh3mMIRVl27t8MtIecR5ggVVbz1S9AwXJQypDKl0ho' + 'QFvhCBcMWPohyGewDJOhDbtuN1IoFI9G55ZvFwCm5y7m7B2aVcoLeIsJZE4PLsIw' + '/y5a6Z3/AoJZYGG7IH5WN88UROU3B9JZGFB2qtPLQTOvDMZLUhoPRIJeHiVSlo1N' + 'tI2/++UsXVg3ow6ItqCJGgdNuGG5JB+bslDHWPxROpesEIHdczk46HCpHQN8f1sk' + 'Hi/fmZZNQQqj1Ijq0caOIw=='} + self.requests.register_uri('GET', + self.url(1234, 'os-server-password'), + json=get_server_password) + + def post_servers(self, request, context): + body = jsonutils.loads(request.body) + context.status_code = 202 + assert (set(body.keys()) <= + set(['server', 'os:scheduler_hints'])) + fakes.assert_has_keys(body['server'], + required=['name', 'imageRef', 'flavorRef'], + optional=['metadata', 'personality']) + if 'personality' in body['server']: + for pfile in body['server']['personality']: + fakes.assert_has_keys(pfile, required=['path', 'contents']) + if body['server']['name'] == 'some-bad-server': + body = self.server_1235 + else: + body = self.server_1234 + + return {'server': body} + + def post_servers_1234_action(self, request, context): + _body = '' + body = jsonutils.loads(request.body) + context.status_code = 202 + assert len(body.keys()) == 1 + action = list(body)[0] + if action == 'reboot': + assert list(body[action]) == ['type'] + assert body[action]['type'] in ['HARD', 'SOFT'] + elif action == 'rebuild': + body = body[action] + adminPass = body.get('adminPass', 'randompassword') + assert 'imageRef' in body + _body = self.server_1234.copy() + _body['adminPass'] = adminPass + elif action == 'resize': + keys = body[action].keys() + assert 'flavorRef' in keys + elif action == 'confirmResize': + assert body[action] is None + # This one method returns a different response code + context.status_code = 204 + return None + elif action == 'revertResize': + assert body[action] is None + elif action == 'migrate': + assert body[action] is None + elif action == 'os-stop': + assert body[action] is None + elif action == 'os-start': + assert body[action] is None + elif action == 'forceDelete': + assert body[action] is None + elif action == 'restore': + assert body[action] is None + elif action == 'pause': + assert body[action] is None + elif action == 'unpause': + assert body[action] is None + elif action == 'lock': + assert body[action] is None + elif action == 'unlock': + assert body[action] is None + elif action == 'rescue': + if body[action]: + keys = set(body[action].keys()) + assert not (keys - set(['adminPass', 'rescue_image_ref'])) + else: + assert body[action] is None + _body = {'adminPass': 'RescuePassword'} + elif action == 'unrescue': + assert body[action] is None + elif action == 'resume': + assert body[action] is None + elif action == 'suspend': + assert body[action] is None + elif action == 'lock': + assert body[action] is None + elif action == 'unlock': + assert body[action] is None + elif action == 'shelve': + assert body[action] is None + elif action == 'shelveOffload': + assert body[action] is None + elif action == 'unshelve': + assert body[action] is None + elif action == 'addFixedIp': + assert list(body[action]) == ['networkId'] + elif action == 'removeFixedIp': + assert list(body[action]) == ['address'] + elif action == 'addFloatingIp': + assert (list(body[action]) == ['address'] or + sorted(list(body[action])) == ['address', + 'fixed_address']) + elif action == 'removeFloatingIp': + assert list(body[action]) == ['address'] + elif action == 'createImage': + assert set(body[action].keys()) == set(['name', 'metadata']) + context.headers['location'] = "http://blah/images/456" + elif action == 'changePassword': + assert list(body[action]) == ['adminPass'] + elif action == 'os-getConsoleOutput': + assert list(body[action]) == ['length'] + context.status_code = 202 + return {'output': 'foo'} + elif action == 'os-getVNCConsole': + assert list(body[action]) == ['type'] + elif action == 'os-getSPICEConsole': + assert list(body[action]) == ['type'] + elif action == 'os-getRDPConsole': + assert list(body[action]) == ['type'] + elif action == 'os-getSerialConsole': + assert list(body[action]) == ['type'] + elif action == 'os-migrateLive': + assert set(body[action].keys()) == set(['host', + 'block_migration', + 'disk_over_commit']) + elif action == 'os-resetState': + assert list(body[action]) == ['state'] + elif action == 'resetNetwork': + assert body[action] is None + elif action == 'addSecurityGroup': + assert list(body[action]) == ['name'] + elif action == 'removeSecurityGroup': + assert list(body[action]) == ['name'] + elif action == 'createBackup': + assert set(body[action]) == set(['name', + 'backup_type', + 'rotation']) + elif action == 'evacuate': + keys = list(body[action]) + if 'adminPass' in keys: + keys.remove('adminPass') + assert set(keys) == set(['host', 'onSharedStorage']) + else: + raise AssertionError("Unexpected server action: %s" % action) + return {'server': _body} |
