From b4c1c9f48258cfbf9236656724902162bb0bda41 Mon Sep 17 00:00:00 2001 From: Ken'ichi Ohmichi Date: Thu, 5 May 2016 16:38:01 -0700 Subject: [PATCH] Remove legacy v2 API tests which use wsgi_app() There is fakes.wsgi_app() for testing legacy v2 API code, but the method becomes unnecessary. So this patch removes the method and unit tests which used the method for legacy v2 API. NOTE: This patch just removes the test of createserverext extension which is not documented and not tested with Tempest. The extension is not implemented and seems unnecessary legacy. Let's remove the test. Partially implements blueprint remove-legacy-v2-api-code Change-Id: I0eaa0a9860af7d574a689722785d5d3d614eb0c1 --- .../openstack/compute/legacy_v2/test_auth.py | 59 - .../compute/legacy_v2/test_servers.py | 3321 ----------------- .../unit/api/openstack/compute/test_api.py | 18 +- .../openstack/compute/test_createserverext.py | 265 -- .../test_extended_availability_zone.py | 17 - .../openstack/compute/test_extended_ips.py | 16 - .../test_extended_server_attributes.py | 17 - .../openstack/compute/test_extended_status.py | 15 - .../compute/test_extended_volumes.py | 12 - .../openstack/compute/test_flavor_disabled.py | 9 - .../api/openstack/compute/test_flavor_rxtx.py | 6 - .../api/openstack/compute/test_flavor_swap.py | 9 - .../openstack/compute/test_flavorextradata.py | 7 - .../compute/test_hide_server_addresses.py | 10 - .../api/openstack/compute/test_image_size.py | 5 - .../openstack/compute/test_server_usage.py | 13 - .../unit/api/openstack/compute/test_urlmap.py | 13 +- .../api/openstack/compute/test_versions.py | 19 +- nova/tests/unit/api/openstack/fakes.py | 22 - 19 files changed, 12 insertions(+), 3841 deletions(-) delete mode 100644 nova/tests/unit/api/openstack/compute/legacy_v2/test_auth.py delete mode 100644 nova/tests/unit/api/openstack/compute/legacy_v2/test_servers.py delete mode 100644 nova/tests/unit/api/openstack/compute/test_createserverext.py diff --git a/nova/tests/unit/api/openstack/compute/legacy_v2/test_auth.py b/nova/tests/unit/api/openstack/compute/legacy_v2/test_auth.py deleted file mode 100644 index 659540854b..0000000000 --- a/nova/tests/unit/api/openstack/compute/legacy_v2/test_auth.py +++ /dev/null @@ -1,59 +0,0 @@ -# Copyright 2010 OpenStack Foundation -# All Rights Reserved. -# -# 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 webob -import webob.dec - -from nova import test -from nova.tests.unit.api.openstack import fakes - - -class TestNoAuthMiddleware(test.NoDBTestCase): - - def setUp(self): - super(TestNoAuthMiddleware, self).setUp() - fakes.stub_out_rate_limiting(self.stubs) - fakes.stub_out_networking(self) - - def test_authorize_user(self): - req = webob.Request.blank('/v2') - req.headers['X-Auth-User'] = 'user1' - req.headers['X-Auth-Key'] = 'user1_key' - req.headers['X-Auth-Project-Id'] = 'user1_project' - result = req.get_response(fakes.wsgi_app(use_no_auth=True)) - self.assertEqual('204 No Content', result.status) - self.assertEqual("http://localhost/v2/user1_project", - result.headers['X-Server-Management-Url']) - - def test_authorize_user_trailing_slash(self): - # make sure it works with trailing slash on the request - req = webob.Request.blank('/v2/') - req.headers['X-Auth-User'] = 'user1' - req.headers['X-Auth-Key'] = 'user1_key' - req.headers['X-Auth-Project-Id'] = 'user1_project' - result = req.get_response(fakes.wsgi_app(use_no_auth=True)) - self.assertEqual('204 No Content', result.status) - self.assertEqual("http://localhost/v2/user1_project", - result.headers['X-Server-Management-Url']) - - def test_auth_token_no_empty_headers(self): - req = webob.Request.blank('/v2') - req.headers['X-Auth-User'] = 'user1' - req.headers['X-Auth-Key'] = 'user1_key' - req.headers['X-Auth-Project-Id'] = 'user1_project' - result = req.get_response(fakes.wsgi_app(use_no_auth=True)) - self.assertEqual('204 No Content', result.status) - self.assertNotIn('X-CDN-Management-Url', result.headers) - self.assertNotIn('X-Storage-Url', result.headers) diff --git a/nova/tests/unit/api/openstack/compute/legacy_v2/test_servers.py b/nova/tests/unit/api/openstack/compute/legacy_v2/test_servers.py deleted file mode 100644 index e17978a170..0000000000 --- a/nova/tests/unit/api/openstack/compute/legacy_v2/test_servers.py +++ /dev/null @@ -1,3321 +0,0 @@ -# Copyright 2010-2011 OpenStack Foundation -# Copyright 2011 Piston Cloud Computing, Inc. -# All Rights Reserved. -# Copyright 2013 Red Hat, Inc. -# -# 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 base64 -import collections -import datetime -import urllib -import uuid - -import iso8601 -import mock -from oslo_policy import policy as oslo_policy -from oslo_serialization import jsonutils -from oslo_utils import timeutils -from six.moves import range -import six.moves.urllib.parse as urlparse -import testtools -import webob - -from nova.api.openstack.compute.legacy_v2 import ips -from nova.api.openstack.compute.legacy_v2 import servers -from nova.api.openstack.compute import views -from nova.api.openstack import extensions -from nova import availability_zones -from nova.compute import api as compute_api -from nova.compute import flavors -from nova.compute import task_states -from nova.compute import vm_states -import nova.conf -from nova import context -from nova import db -from nova.db.sqlalchemy import models -from nova import exception -from nova.image import glance -from nova.network import manager -from nova import objects -from nova.objects import instance as instance_obj -from nova import policy -from nova import test -from nova.tests.unit.api.openstack import fakes -from nova.tests.unit import fake_instance -from nova.tests.unit import fake_network -from nova.tests.unit.image import fake -from nova.tests.unit import matchers -from nova.tests.unit.objects import test_keypair -from nova.tests import uuidsentinel as uuids -from nova import utils as nova_utils - -CONF = nova.conf.CONF - -FAKE_UUID = fakes.FAKE_UUID -NS = "{http://docs.openstack.org/compute/api/v1.1}" -ATOMNS = "{http://www.w3.org/2005/Atom}" -XPATH_NS = { - 'atom': 'http://www.w3.org/2005/Atom', - 'ns': 'http://docs.openstack.org/compute/api/v1.1' -} - -INSTANCE_IDS = {FAKE_UUID: 1} - -FIELDS = instance_obj.INSTANCE_DEFAULT_FIELDS - - -def return_servers_empty(context, *args, **kwargs): - return objects.InstanceList(objects=[]) - - -def return_security_group(context, instance_id, security_group_id): - pass - - -def instance_update_and_get_original(context, instance_uuid, values, - columns_to_join=None, - ): - inst = fakes.stub_instance(INSTANCE_IDS.get(instance_uuid), - name=values.get('display_name')) - inst = dict(inst, **values) - return (inst, inst) - - -def instance_update(context, instance_uuid, values): - inst = fakes.stub_instance(INSTANCE_IDS.get(instance_uuid), - name=values.get('display_name')) - inst = dict(inst, **values) - return inst - - -def fake_compute_api(cls, req, id): - return True - - -class MockSetAdminPassword(object): - def __init__(self): - self.instance_id = None - self.password = None - - def __call__(self, context, instance_id, password): - self.instance_id = instance_id - self.password = password - - -class Base64ValidationTest(test.TestCase): - def setUp(self): - super(Base64ValidationTest, self).setUp() - self.ext_mgr = extensions.ExtensionManager() - self.ext_mgr.extensions = {} - self.controller = servers.Controller(self.ext_mgr) - - def test_decode_base64(self): - value = b"A random string" - result = self.controller._decode_base64(base64.b64encode(value)) - self.assertEqual(value, result) - - def test_decode_base64_binary(self): - value = b"\x00\x12\x75\x99" - result = self.controller._decode_base64(base64.b64encode(value)) - self.assertEqual(value, result) - - def test_decode_base64_whitespace(self): - value = b"A random string" - encoded = base64.b64encode(value).decode("ascii") - white = "\n \n%s\t%s\n" % (encoded[:2], encoded[2:]) - result = self.controller._decode_base64(white) - self.assertEqual(value, result) - - def test_decode_base64_invalid(self): - invalid = "A random string" - result = self.controller._decode_base64(invalid) - self.assertIsNone(result) - - def test_decode_base64_illegal_bytes(self): - value = b"A random string" - encoded = base64.b64encode(value).decode("ascii") - white = ">\x01%s*%s()" % (encoded[:2], encoded[2:]) - result = self.controller._decode_base64(white) - self.assertIsNone(result) - - -class ControllerTest(test.TestCase): - - def setUp(self): - super(ControllerTest, self).setUp() - self.flags(verbose=True, use_ipv6=False) - fakes.stub_out_rate_limiting(self.stubs) - fakes.stub_out_key_pair_funcs(self.stubs) - fake.stub_out_image_service(self) - return_server = fakes.fake_compute_get() - return_servers = fakes.fake_compute_get_all() - # Server sort keys extension is not enabled in v2 test so no sort - # data is passed to the instance API and the non-sorted DB API is - # invoked - self.stubs.Set(compute_api.API, 'get_all', - lambda api, *a, **k: return_servers(*a, **k)) - self.stubs.Set(compute_api.API, 'get', - lambda api, *a, **k: return_server(*a, **k)) - self.stub_out('nova.db.instance_add_security_group', - return_security_group) - self.stub_out('nova.db.instance_update_and_get_original', - instance_update_and_get_original) - - self.ext_mgr = extensions.ExtensionManager() - self.ext_mgr.extensions = {} - self.controller = servers.Controller(self.ext_mgr) - self.ips_controller = ips.Controller() - policy.reset() - policy.init() - fake_network.stub_out_nw_api_get_instance_nw_info(self) - - -class ServersControllerTest(ControllerTest): - def test_can_check_loaded_extensions(self): - self.ext_mgr.extensions = {'os-fake': None} - self.assertTrue(self.controller.ext_mgr.is_loaded('os-fake')) - self.assertFalse(self.controller.ext_mgr.is_loaded('os-not-loaded')) - - def test_requested_networks_prefix(self): - uuid = 'br-00000000-0000-0000-0000-000000000000' - requested_networks = [{'uuid': uuid}] - res = self.controller._get_requested_networks(requested_networks) - self.assertIn((uuid, None), res.as_tuples()) - - def test_requested_networks_neutronv2_enabled_with_port(self): - self.flags(use_neutron=True) - port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'port': port}] - res = self.controller._get_requested_networks(requested_networks) - self.assertEqual([(None, None, port, None)], res.as_tuples()) - - def test_requested_networks_neutronv2_enabled_with_network(self): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - requested_networks = [{'uuid': network}] - res = self.controller._get_requested_networks(requested_networks) - self.assertEqual([(network, None, None, None)], res.as_tuples()) - - def test_requested_networks_neutronv2_enabled_with_network_and_port(self): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'uuid': network, 'port': port}] - res = self.controller._get_requested_networks(requested_networks) - self.assertEqual([(None, None, port, None)], res.as_tuples()) - - def test_requested_networks_with_duplicate_networks(self): - # duplicate networks are allowed only for nova neutron v2.0 - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - requested_networks = [{'uuid': network}, {'uuid': network}] - self.assertRaises( - webob.exc.HTTPBadRequest, - self.controller._get_requested_networks, - requested_networks) - - def test_requested_networks_with_neutronv2_and_duplicate_networks(self): - # duplicate networks are allowed only for nova neutron v2.0 - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - requested_networks = [{'uuid': network}, {'uuid': network}] - res = self.controller._get_requested_networks(requested_networks) - self.assertEqual([(network, None, None, None), - (network, None, None, None)], res.as_tuples()) - - def test_requested_networks_neutronv2_disabled_with_port(self): - port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'port': port}] - self.assertRaises( - webob.exc.HTTPBadRequest, - self.controller._get_requested_networks, - requested_networks) - - def test_requested_networks_api_enabled_with_v2_subclass(self): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'uuid': network, 'port': port}] - res = self.controller._get_requested_networks(requested_networks) - self.assertEqual([(None, None, port, None)], res.as_tuples()) - - def test_get_server_by_uuid(self): - req = fakes.HTTPRequest.blank('/fake/servers/%s' % FAKE_UUID) - res_dict = self.controller.show(req, FAKE_UUID) - self.assertEqual(FAKE_UUID, res_dict['server']['id']) - - def test_unique_host_id(self): - """Create two servers with the same host and different - project_ids and check that the hostId's are unique. - """ - def return_instance_with_host(context, *args, **kwargs): - project_id = str(uuid.uuid4()) - self.assertIn('expected_attrs', kwargs) - self.assertEqual(['flavor', 'info_cache', 'metadata'], - kwargs['expected_attrs']) - return fakes.stub_instance_obj(context, id=1, uuid=FAKE_UUID, - project_id=project_id, - host='fake_host') - - req = fakes.HTTPRequest.blank('/fake/servers/%s' % FAKE_UUID) - with mock.patch.object(compute_api.API, 'get') as mock_get: - mock_get.side_effect = return_instance_with_host - server1 = self.controller.show(req, FAKE_UUID) - server2 = self.controller.show(req, FAKE_UUID) - - self.assertNotEqual(server1['server']['hostId'], - server2['server']['hostId']) - - def _get_server_data_dict(self, uuid, image_bookmark, flavor_bookmark, - status="ACTIVE", progress=100): - return { - "server": { - "id": uuid, - "user_id": "fake_user", - "tenant_id": "fake_project", - "updated": "2010-11-11T11:00:00Z", - "created": "2010-10-10T12:00:00Z", - "progress": progress, - "name": "server2", - "status": status, - "accessIPv4": "", - "accessIPv6": "", - "hostId": '', - "image": { - "id": "10", - "links": [ - { - "rel": "bookmark", - "href": image_bookmark, - }, - ], - }, - "flavor": { - "id": "2", - "links": [ - { - "rel": "bookmark", - "href": flavor_bookmark, - }, - ], - }, - "addresses": { - 'test1': [ - {'version': 4, 'addr': '192.168.1.100'}, - {'version': 6, 'addr': '2001:db8:0:1::1'} - ] - }, - "metadata": { - "seq": "2", - }, - "links": [ - { - "rel": "self", - "href": "http://localhost/v2/fake/servers/%s" % uuid, - }, - { - "rel": "bookmark", - "href": "http://localhost/fake/servers/%s" % uuid, - }, - ], - } - } - - def test_get_server_by_id(self): - self.flags(use_ipv6=True) - image_bookmark = "http://localhost/fake/images/10" - flavor_bookmark = "http://localhost/fake/flavors/2" - - uuid = FAKE_UUID - req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % uuid) - res_dict = self.controller.show(req, uuid) - - expected_server = self._get_server_data_dict(uuid, - image_bookmark, - flavor_bookmark, - status="BUILD", - progress=0) - expected_server['server']['name'] = 'server1' - expected_server['server']['metadata']['seq'] = '1' - self.assertThat(res_dict, matchers.DictMatches(expected_server)) - - def test_get_server_with_active_status_by_id(self): - image_bookmark = "http://localhost/fake/images/10" - flavor_bookmark = "http://localhost/fake/flavors/2" - - new_return_server = fakes.fake_compute_get( - id=2, vm_state=vm_states.ACTIVE, progress=100) - self.stubs.Set(compute_api.API, 'get', - lambda api, *a, **k: new_return_server(*a, **k)) - - uuid = FAKE_UUID - req = fakes.HTTPRequest.blank('/fake/servers/%s' % uuid) - res_dict = self.controller.show(req, uuid) - expected_server = self._get_server_data_dict(uuid, - image_bookmark, - flavor_bookmark) - self.assertThat(res_dict, matchers.DictMatches(expected_server)) - - def test_get_server_with_id_image_ref_by_id(self): - image_ref = "10" - image_bookmark = "http://localhost/fake/images/10" - flavor_id = "1" - flavor_bookmark = "http://localhost/fake/flavors/2" - - new_return_server = fakes.fake_compute_get( - id=2, vm_state=vm_states.ACTIVE, image_ref=image_ref, - flavor_id=flavor_id, progress=100) - self.stubs.Set(compute_api.API, 'get', - lambda api, *a, **k: new_return_server(*a, **k)) - - uuid = FAKE_UUID - req = fakes.HTTPRequest.blank('/fake/servers/%s' % uuid) - res_dict = self.controller.show(req, uuid) - expected_server = self._get_server_data_dict(uuid, - image_bookmark, - flavor_bookmark) - self.assertThat(res_dict, matchers.DictMatches(expected_server)) - - def test_get_server_addresses_from_cache(self): - pub0 = ('172.19.0.1', '172.19.0.2',) - pub1 = ('1.2.3.4',) - pub2 = ('b33f::fdee:ddff:fecc:bbaa',) - priv0 = ('192.168.0.3', '192.168.0.4',) - - def _ip(ip): - return {'address': ip, 'type': 'fixed'} - - nw_cache = [ - {'address': 'aa:aa:aa:aa:aa:aa', - 'id': 1, - 'network': {'bridge': 'br0', - 'id': 1, - 'label': 'public', - 'subnets': [{'cidr': '172.19.0.0/24', - 'ips': [_ip(ip) for ip in pub0]}, - {'cidr': '1.2.3.0/16', - 'ips': [_ip(ip) for ip in pub1]}, - {'cidr': 'b33f::/64', - 'ips': [_ip(ip) for ip in pub2]}]}}, - {'address': 'bb:bb:bb:bb:bb:bb', - 'id': 2, - 'network': {'bridge': 'br1', - 'id': 2, - 'label': 'private', - 'subnets': [{'cidr': '192.168.0.0/24', - 'ips': [_ip(ip) for ip in priv0]}]}}] - - return_server = fakes.fake_compute_get(nw_cache=nw_cache) - self.stubs.Set(compute_api.API, 'get', - lambda api, *a, **k: return_server(*a, **k)) - - req = fakes.HTTPRequest.blank('/fake/servers/%s/ips' % FAKE_UUID) - res_dict = self.ips_controller.index(req, FAKE_UUID) - - expected = { - 'addresses': { - 'private': [ - {'version': 4, 'addr': '192.168.0.3'}, - {'version': 4, 'addr': '192.168.0.4'}, - ], - 'public': [ - {'version': 4, 'addr': '172.19.0.1'}, - {'version': 4, 'addr': '172.19.0.2'}, - {'version': 4, 'addr': '1.2.3.4'}, - {'version': 6, 'addr': 'b33f::fdee:ddff:fecc:bbaa'}, - ], - }, - } - self.assertThat(res_dict, matchers.DictMatches(expected)) - # Make sure we kept the addresses in order - self.assertIsInstance(res_dict['addresses'], collections.OrderedDict) - labels = [vif['network']['label'] for vif in nw_cache] - for index, label in enumerate(res_dict['addresses'].keys()): - self.assertEqual(label, labels[index]) - - def test_get_server_addresses_nonexistent_network(self): - url = '/fake/servers/%s/ips/network_0' % FAKE_UUID - req = fakes.HTTPRequest.blank(url) - self.assertRaises(webob.exc.HTTPNotFound, self.ips_controller.show, - req, FAKE_UUID, 'network_0') - - def test_get_server_addresses_nonexistent_server(self): - def fake_instance_get(*args, **kwargs): - raise exception.InstanceNotFound(instance_id='fake') - - self.stubs.Set(compute_api.API, 'get', fake_instance_get) - - server_id = str(uuid.uuid4()) - req = fakes.HTTPRequest.blank('/fake/servers/%s/ips' % server_id) - self.assertRaises(webob.exc.HTTPNotFound, - self.ips_controller.index, req, server_id) - - def test_get_server_list_empty(self): - self.stubs.Set(compute_api.API, 'get_all', - return_servers_empty) - - req = fakes.HTTPRequest.blank('/fake/servers') - res_dict = self.controller.index(req) - - num_servers = len(res_dict['servers']) - self.assertEqual(0, num_servers) - - def test_get_server_list_with_reservation_id(self): - req = fakes.HTTPRequest.blank('/fake/servers?reservation_id=foo') - res_dict = self.controller.index(req) - - i = 0 - for s in res_dict['servers']: - self.assertEqual('server%d' % (i + 1), s.get('name')) - i += 1 - - def test_get_server_list_with_reservation_id_empty(self): - req = fakes.HTTPRequest.blank('/fake/servers/detail?' - 'reservation_id=foo') - res_dict = self.controller.detail(req) - - i = 0 - for s in res_dict['servers']: - self.assertEqual('server%d' % (i + 1), s.get('name')) - i += 1 - - def test_get_server_list_with_reservation_id_details(self): - req = fakes.HTTPRequest.blank('/fake/servers/detail?' - 'reservation_id=foo') - res_dict = self.controller.detail(req) - - i = 0 - for s in res_dict['servers']: - self.assertEqual('server%d' % (i + 1), s.get('name')) - i += 1 - - def test_get_server_list(self): - req = fakes.HTTPRequest.blank('/fake/servers') - res_dict = self.controller.index(req) - - self.assertEqual(5, len(res_dict['servers'])) - for i, s in enumerate(res_dict['servers']): - self.assertEqual(fakes.get_fake_uuid(i), s['id']) - self.assertEqual('server%d' % (i + 1), s['name']) - self.assertIsNone(s.get('image', None)) - - expected_links = [ - { - "rel": "self", - "href": "http://localhost/v2/fake/servers/%s" % s['id'], - }, - { - "rel": "bookmark", - "href": "http://localhost/fake/servers/%s" % s['id'], - }, - ] - - self.assertEqual(expected_links, s['links']) - - def test_get_servers_with_limit(self): - req = fakes.HTTPRequest.blank('/fake/servers?limit=3') - res_dict = self.controller.index(req) - - servers = res_dict['servers'] - self.assertEqual([fakes.get_fake_uuid(i) for i in range(len(servers))], - [s['id'] for s in servers]) - - servers_links = res_dict['servers_links'] - self.assertEqual('next', servers_links[0]['rel']) - href_parts = urlparse.urlparse(servers_links[0]['href']) - self.assertEqual('/v2/fake/servers', href_parts.path) - params = urlparse.parse_qs(href_parts.query) - expected_params = {'limit': ['3'], - 'marker': [fakes.get_fake_uuid(2)]} - self.assertThat(params, matchers.DictMatches(expected_params)) - - def test_get_servers_with_limit_bad_value(self): - req = fakes.HTTPRequest.blank('/fake/servers?limit=aaa') - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.index, req) - - def test_get_server_details_empty(self): - self.stubs.Set(compute_api.API, 'get_all', - return_servers_empty) - - req = fakes.HTTPRequest.blank('/fake/servers/detail') - res_dict = self.controller.detail(req) - - num_servers = len(res_dict['servers']) - self.assertEqual(0, num_servers) - - def test_get_server_details_with_limit(self): - req = fakes.HTTPRequest.blank('/fake/servers/detail?limit=3') - res = self.controller.detail(req) - - servers = res['servers'] - self.assertEqual([fakes.get_fake_uuid(i) for i in range(len(servers))], - [s['id'] for s in servers]) - - servers_links = res['servers_links'] - self.assertEqual('next', servers_links[0]['rel']) - - href_parts = urlparse.urlparse(servers_links[0]['href']) - self.assertEqual('/v2/fake/servers/detail', href_parts.path) - params = urlparse.parse_qs(href_parts.query) - expected = {'limit': ['3'], 'marker': [fakes.get_fake_uuid(2)]} - self.assertThat(params, matchers.DictMatches(expected)) - - def test_get_server_details_with_limit_bad_value(self): - req = fakes.HTTPRequest.blank('/fake/servers/detail?limit=aaa') - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.detail, req) - - def test_get_server_details_with_limit_and_other_params(self): - req = fakes.HTTPRequest.blank('/fake/servers/detail' - '?limit=3&blah=2:t' - '&sort_key=id1&sort_dir=asc') - res = self.controller.detail(req) - - servers = res['servers'] - self.assertEqual([fakes.get_fake_uuid(i) for i in range(len(servers))], - [s['id'] for s in servers]) - - servers_links = res['servers_links'] - self.assertEqual('next', servers_links[0]['rel']) - # Retrieve the parameters from the next link, they should contain the - # same limit, filter, and sort information as the original request as - # well as a marker; this ensures that the caller can simply use the - # "next" link and that they do not need to manually insert the limit - # and sort information. - href_parts = urlparse.urlparse(servers_links[0]['href']) - self.assertEqual('/v2/fake/servers/detail', href_parts.path) - params = urlparse.parse_qs(href_parts.query) - expected = {'limit': ['3'], 'blah': ['2:t'], - 'sort_key': ['id1'], 'sort_dir': ['asc'], - 'marker': [fakes.get_fake_uuid(2)]} - self.assertThat(params, matchers.DictMatches(expected)) - - def test_get_servers_with_too_big_limit(self): - req = fakes.HTTPRequest.blank('/fake/servers?limit=30') - res_dict = self.controller.index(req) - self.assertNotIn('servers_links', res_dict) - - def test_get_servers_with_bad_limit(self): - req = fakes.HTTPRequest.blank('/fake/servers?limit=asdf') - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.index, req) - - def test_get_servers_with_marker(self): - url = '/v2/fake/servers?marker=%s' % fakes.get_fake_uuid(2) - req = fakes.HTTPRequest.blank(url) - servers = self.controller.index(req)['servers'] - self.assertEqual(["server4", "server5"], [s['name'] for s in servers]) - - def test_get_servers_with_limit_and_marker(self): - url = '/v2/fake/servers?limit=2&marker=%s' % fakes.get_fake_uuid(1) - req = fakes.HTTPRequest.blank(url) - servers = self.controller.index(req)['servers'] - self.assertEqual(['server3', 'server4'], [s['name'] for s in servers]) - - def test_get_servers_with_bad_marker(self): - req = fakes.HTTPRequest.blank('/fake/servers?limit=2&marker=asdf') - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.index, req) - - @mock.patch('nova.compute.api.API.get_all') - def test_get_servers_with_sorting_enabled(self, mock_compute_get_all): - '''Sorting params honored if os-server-sort-keys is loaded.''' - self.ext_mgr.extensions = {'os-server-sort-keys': 'fake'} - req = fakes.HTTPRequest.blank('/fake/servers' - '?sort_key=id1&sort_dir=asc') - self.controller.index(req) - self.assertEqual(1, mock_compute_get_all.call_count) - # Ensure that sort_dirs and sort_dirs is correct - kwargs = mock_compute_get_all.call_args[1] - self.assertEqual(['id1'], kwargs['sort_keys']) - self.assertEqual(['asc'], kwargs['sort_dirs']) - - @mock.patch('nova.compute.api.API.get_all') - def test_get_servers_with_sorting_disabled(self, mock_compute_get_all): - '''Sorting params ignored if os-server-sort-keys is not loaded.''' - self.ext_mgr.extensions = {} - req = fakes.HTTPRequest.blank('/fake/servers' - '?sort_key=id1&sort_dir=asc') - self.controller.index(req) - self.assertEqual(1, mock_compute_get_all.call_count) - # Ensure that sort_dirs and sort_dirs is None - kwargs = mock_compute_get_all.call_args[1] - self.assertIsNone(kwargs['sort_keys']) - self.assertIsNone(kwargs['sort_dirs']) - - def test_get_servers_with_bad_option(self): - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - db_list = [fakes.stub_instance(100, uuid=server_uuid)] - return instance_obj._make_instance_list( - context, objects.InstanceList(), db_list, FIELDS) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?unknownoption=whee') - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_allows_image(self): - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - self.assertIn('image', search_opts) - self.assertEqual('12345', search_opts['image']) - db_list = [fakes.stub_instance(100, uuid=server_uuid)] - return instance_obj._make_instance_list( - context, objects.InstanceList(), db_list, FIELDS) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?image=12345') - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_all_tenants_param_normal(self): - def fake_get_all(context, search_opts=None, **kwargs): - self.assertNotIn('project_id', search_opts) - return [fakes.stub_instance_obj(100)] - - req = fakes.HTTPRequest.blank('/fake/servers?all_tenants', - use_admin_context=True) - with mock.patch.object(compute_api.API, 'get_all') as mock_get: - mock_get.side_effect = fake_get_all - servers = self.controller.index(req)['servers'] - self.assertEqual(1, len(servers)) - - def test_all_tenants_param_one(self): - def fake_get_all(api, context, search_opts=None, **kwargs): - return [fakes.stub_instance(100)] - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=1', - use_admin_context=True) - servers = self.controller.index(req)['servers'] - self.assertEqual(1, len(servers)) - - def test_all_tenants_param_zero(self): - def fake_get_all(api, context, search_opts=None, **kwargs): - self.assertNotIn('all_tenants', search_opts) - return [fakes.stub_instance(100)] - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=0', - use_admin_context=True) - servers = self.controller.index(req)['servers'] - self.assertEqual(1, len(servers)) - - def test_all_tenants_param_false(self): - def fake_get_all(api, context, search_opts=None, **kwargs): - self.assertNotIn('all_tenants', search_opts) - return [fakes.stub_instance(100)] - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=false', - use_admin_context=True) - servers = self.controller.index(req)['servers'] - self.assertEqual(1, len(servers)) - - def test_all_tenants_param_invalid(self): - def fake_get_all(api, context, search_opts=None, **kwargs): - self.assertNotIn('all_tenants', search_opts) - return [fakes.stub_instance(100)] - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=xxx', - use_admin_context=True) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.index, req) - - def test_admin_restricted_tenant(self): - def fake_get_all(api, context, search_opts=None, **kwargs): - self.assertIsNotNone(search_opts) - self.assertEqual('fake', search_opts['project_id']) - return [fakes.stub_instance(100)] - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers', - use_admin_context=True) - servers = self.controller.index(req)['servers'] - self.assertEqual(1, len(servers)) - - def test_all_tenants_pass_policy(self): - def fake_get_all(api, context, search_opts=None, **kwargs): - self.assertIsNotNone(search_opts) - self.assertNotIn('project_id', search_opts) - self.assertTrue(context.is_admin) - return [fakes.stub_instance(100)] - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - rules = { - "compute:get_all_tenants": "project_id:fake", - "compute:get_all": "project_id:fake", - } - - policy.set_rules(oslo_policy.Rules.from_dict(rules)) - - req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=1') - servers = self.controller.index(req)['servers'] - self.assertEqual(1, len(servers)) - - def test_all_tenants_fail_policy(self): - def fake_get_all(api, context, search_opts=None, **kwargs): - self.assertIsNotNone(search_opts) - return [fakes.stub_instance(100)] - - rules = { - "compute:get_all_tenants": "project_id:non_fake", - "compute:get_all": "project_id:fake", - } - - policy.set_rules(oslo_policy.Rules.from_dict(rules)) - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?all_tenants=1') - self.assertRaises(exception.PolicyNotAuthorized, - self.controller.index, req) - - def test_get_servers_allows_flavor(self): - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - self.assertIn('flavor', search_opts) - # flavor is an integer ID - self.assertEqual('12345', search_opts['flavor']) - db_list = [fakes.stub_instance(100, uuid=server_uuid)] - return instance_obj._make_instance_list( - context, objects.InstanceList(), db_list, FIELDS) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?flavor=12345') - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_with_bad_flavor(self): - req = fakes.HTTPRequest.blank('/fake/servers?flavor=abcde') - with mock.patch.object(compute_api.API, 'get_all') as mock_get: - mock_get.return_value = objects.InstanceList(objects=[]) - servers = self.controller.index(req)['servers'] - - self.assertEqual(0, len(servers)) - - def test_get_server_details_with_bad_flavor(self): - req = fakes.HTTPRequest.blank('/fake/servers/detail?flavor=abcde') - with mock.patch.object(compute_api.API, 'get_all') as mock_get: - mock_get.return_value = objects.InstanceList(objects=[]) - servers = self.controller.detail(req)['servers'] - - self.assertThat(servers, testtools.matchers.HasLength(0)) - - def test_get_servers_allows_status(self): - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - self.assertIn('vm_state', search_opts) - self.assertEqual(search_opts['vm_state'], [vm_states.ACTIVE]) - db_list = [fakes.stub_instance(100, uuid=server_uuid)] - return instance_obj._make_instance_list( - context, objects.InstanceList(), db_list, FIELDS) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?status=active') - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - @mock.patch.object(compute_api.API, 'get_all') - def test_get_servers_allows_multi_status(self, get_all_mock): - server_uuid0 = str(uuid.uuid4()) - server_uuid1 = str(uuid.uuid4()) - db_list = [fakes.stub_instance(100, uuid=server_uuid0), - fakes.stub_instance(101, uuid=server_uuid1)] - get_all_mock.return_value = instance_obj._make_instance_list( - context, instance_obj.InstanceList(), db_list, FIELDS) - - req = fakes.HTTPRequest.blank( - '/fake/servers?status=active&status=error') - servers = self.controller.index(req)['servers'] - self.assertEqual(2, len(servers)) - self.assertEqual(server_uuid0, servers[0]['id']) - self.assertEqual(server_uuid1, servers[1]['id']) - expected_search_opts = dict(deleted=False, - vm_state=[vm_states.ACTIVE, - vm_states.ERROR], - project_id='fake') - get_all_mock.assert_called_once_with(mock.ANY, - search_opts=expected_search_opts, limit=mock.ANY, - marker=mock.ANY, want_objects=mock.ANY, - expected_attrs=None, - sort_keys=mock.ANY, sort_dirs=mock.ANY) - - @mock.patch.object(compute_api.API, 'get_all') - def test_get_servers_system_metadata_filter(self, get_all_mock): - server_uuid0 = str(uuid.uuid4()) - server_uuid1 = str(uuid.uuid4()) - expected_system_metadata = u'{"some_value": "some_key"}' - db_list = [fakes.stub_instance(100, uuid=server_uuid0), - fakes.stub_instance(101, uuid=server_uuid1)] - get_all_mock.return_value = instance_obj._make_instance_list( - context, instance_obj.InstanceList(), db_list, FIELDS) - - req = fakes.HTTPRequest.blank( - '/fake/servers?status=active&status=error&system_metadata=' + - urllib.quote(expected_system_metadata), - use_admin_context=True) - servers = self.controller.index(req)['servers'] - self.assertEqual(2, len(servers)) - self.assertEqual(server_uuid0, servers[0]['id']) - self.assertEqual(server_uuid1, servers[1]['id']) - expected_search_opts = dict( - deleted=False, vm_state=[vm_states.ACTIVE, vm_states.ERROR], - system_metadata=expected_system_metadata, project_id='fake') - get_all_mock.assert_called_once_with(mock.ANY, - search_opts=expected_search_opts, limit=mock.ANY, - marker=mock.ANY, want_objects=mock.ANY, - expected_attrs=None, - sort_keys=mock.ANY, sort_dirs=mock.ANY) - - @mock.patch.object(compute_api.API, 'get_all') - def test_get_servers_flavor_not_found(self, get_all_mock): - get_all_mock.side_effect = exception.FlavorNotFound(flavor_id=1) - - req = fakes.HTTPRequest.blank( - '/fake/servers?status=active&flavor=abc') - servers = self.controller.index(req)['servers'] - self.assertEqual(0, len(servers)) - - @mock.patch.object(compute_api.API, 'get_all') - def test_get_servers_allows_invalid_status(self, get_all_mock): - server_uuid0 = str(uuid.uuid4()) - server_uuid1 = str(uuid.uuid4()) - db_list = [fakes.stub_instance(100, uuid=server_uuid0), - fakes.stub_instance(101, uuid=server_uuid1)] - get_all_mock.return_value = instance_obj._make_instance_list( - context, instance_obj.InstanceList(), db_list, FIELDS) - - req = fakes.HTTPRequest.blank( - '/fake/servers?status=active&status=invalid') - servers = self.controller.index(req)['servers'] - self.assertEqual(2, len(servers)) - self.assertEqual(server_uuid0, servers[0]['id']) - self.assertEqual(server_uuid1, servers[1]['id']) - expected_search_opts = dict(deleted=False, - vm_state=[vm_states.ACTIVE], - project_id='fake') - get_all_mock.assert_called_once_with(mock.ANY, - search_opts=expected_search_opts, limit=mock.ANY, - marker=mock.ANY, want_objects=mock.ANY, - expected_attrs=None, - sort_keys=mock.ANY, sort_dirs=mock.ANY) - - def test_get_servers_allows_task_status(self): - server_uuid = str(uuid.uuid4()) - task_state = task_states.REBOOTING - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - self.assertIn('task_state', search_opts) - self.assertEqual([task_states.REBOOT_PENDING, - task_states.REBOOT_STARTED, - task_states.REBOOTING], - search_opts['task_state']) - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid, - task_state=task_state)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/servers?status=reboot') - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_resize_status(self): - # Test when resize status, it maps list of vm states. - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIn('vm_state', search_opts) - self.assertEqual(search_opts['vm_state'], - [vm_states.ACTIVE, vm_states.STOPPED]) - - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?status=resize') - - servers = self.controller.detail(req)['servers'] - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_invalid_status(self): - # Test getting servers by invalid status. - req = fakes.HTTPRequest.blank('/fake/servers?status=baloney', - use_admin_context=False) - servers = self.controller.index(req)['servers'] - self.assertEqual(0, len(servers)) - - def test_get_servers_deleted_status_as_user(self): - req = fakes.HTTPRequest.blank('/fake/servers?status=deleted', - use_admin_context=False) - self.assertRaises(webob.exc.HTTPForbidden, - self.controller.detail, req) - - def test_get_servers_deleted_status_as_admin(self): - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIn('vm_state', search_opts) - self.assertEqual(['deleted'], search_opts['vm_state']) - - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?status=deleted', - use_admin_context=True) - - servers = self.controller.detail(req)['servers'] - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - @mock.patch.object(compute_api.API, 'get_all') - def test_get_servers_deleted_filter_str_to_bool(self, mock_get_all): - server_uuid = str(uuid.uuid4()) - - db_list = objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid, - vm_state='deleted')]) - mock_get_all.return_value = db_list - - req = fakes.HTTPRequest.blank('/fake/servers?deleted=true', - use_admin_context=True) - - servers = self.controller.detail(req)['servers'] - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - # Assert that 'deleted' filter value is converted to boolean - # while calling get_all() method. - expected_search_opts = {'deleted': True, 'project_id': 'fake'} - mock_get_all.assert_called_once_with( - mock.ANY, search_opts=expected_search_opts, limit=mock.ANY, - marker=mock.ANY, want_objects=mock.ANY, - expected_attrs=['flavor', 'info_cache', 'metadata'], - sort_keys=mock.ANY, sort_dirs=mock.ANY) - - @mock.patch.object(compute_api.API, 'get_all') - def test_get_servers_deleted_filter_invalid_str(self, mock_get_all): - server_uuid = str(uuid.uuid4()) - - db_list = objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - mock_get_all.return_value = db_list - - req = fakes.HTTPRequest.blank('/fake/servers?deleted=abc', - use_admin_context=True) - - servers = self.controller.detail(req)['servers'] - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - # Assert that invalid 'deleted' filter value is converted to boolean - # False while calling get_all() method. - expected_search_opts = {'deleted': False, 'project_id': 'fake'} - mock_get_all.assert_called_once_with( - mock.ANY, search_opts=expected_search_opts, limit=mock.ANY, - marker=mock.ANY, want_objects=mock.ANY, - expected_attrs=['flavor', 'info_cache', 'metadata'], - sort_keys=mock.ANY, sort_dirs=mock.ANY) - - def test_get_servers_allows_name(self): - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - self.assertIn('name', search_opts) - self.assertEqual('whee.*', search_opts['name']) - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?name=whee.*') - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_allows_changes_since(self): - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - self.assertIn('changes-since', search_opts) - changes_since = datetime.datetime(2011, 1, 24, 17, 8, 1, - tzinfo=iso8601.iso8601.UTC) - self.assertEqual(changes_since, search_opts['changes-since']) - self.assertNotIn('deleted', search_opts) - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - params = 'changes-since=2011-01-24T17:08:01Z' - req = fakes.HTTPRequest.blank('/fake/servers?%s' % params) - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_allows_changes_since_bad_value(self): - params = 'changes-since=asdf' - req = fakes.HTTPRequest.blank('/fake/servers?%s' % params) - self.assertRaises(webob.exc.HTTPBadRequest, self.controller.index, req) - - def test_get_servers_admin_filters_as_user(self): - """Test getting servers by admin-only or unknown options when - context is not admin. Make sure the admin and unknown options - are stripped before they get to compute_api.get_all() - """ - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - # Allowed by user - self.assertIn('name', search_opts) - self.assertIn('ip', search_opts) - # OSAPI converts status to vm_state - self.assertIn('vm_state', search_opts) - # Allowed only by admins with admin API on - self.assertNotIn('unknown_option', search_opts) - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - query_str = "name=foo&ip=10.*&status=active&unknown_option=meow" - req = fakes.HTTPRequest.blank('/fake/servers?%s' % query_str) - res = self.controller.index(req) - - servers = res['servers'] - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_admin_options_as_admin(self): - """Test getting servers by admin-only or unknown options when - context is admin. All options should be passed - """ - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - # Allowed by user - self.assertIn('name', search_opts) - # OSAPI converts status to vm_state - self.assertIn('vm_state', search_opts) - # Allowed only by admins with admin API on - self.assertIn('ip', search_opts) - self.assertIn('unknown_option', search_opts) - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - query_str = "name=foo&ip=10.*&status=active&unknown_option=meow" - req = fakes.HTTPRequest.blank('/fake/servers?%s' % query_str, - use_admin_context=True) - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_allows_ip(self): - """Test getting servers by ip.""" - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - self.assertIn('ip', search_opts) - self.assertEqual('10\..*', search_opts['ip']) - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?ip=10\..*') - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_servers_admin_allows_ip6(self): - """Test getting servers by ip6 with admin_api enabled and - admin context - """ - server_uuid = str(uuid.uuid4()) - - def fake_get_all(compute_self, context, search_opts=None, - limit=None, marker=None, want_objects=False, - sort_keys=None, sort_dirs=None, - expected_attrs=None): - self.assertIsNotNone(search_opts) - self.assertIn('ip6', search_opts) - self.assertEqual('ffff.*', search_opts['ip6']) - return objects.InstanceList( - objects=[fakes.stub_instance_obj(100, uuid=server_uuid)]) - - self.stubs.Set(compute_api.API, 'get_all', fake_get_all) - - req = fakes.HTTPRequest.blank('/fake/servers?ip6=ffff.*', - use_admin_context=True) - servers = self.controller.index(req)['servers'] - - self.assertEqual(1, len(servers)) - self.assertEqual(server_uuid, servers[0]['id']) - - def test_get_all_server_details(self): - expected_flavor = { - "id": "2", - "links": [ - { - "rel": "bookmark", - "href": 'http://localhost/fake/flavors/2', - }, - ], - } - expected_image = { - "id": "10", - "links": [ - { - "rel": "bookmark", - "href": 'http://localhost/fake/images/10', - }, - ], - } - req = fakes.HTTPRequest.blank('/fake/servers/detail') - res_dict = self.controller.detail(req) - - for i, s in enumerate(res_dict['servers']): - self.assertEqual(fakes.get_fake_uuid(i), s['id']) - self.assertEqual('', s['hostId']) - self.assertEqual('server%d' % (i + 1), s['name']) - self.assertEqual(expected_image, s['image']) - self.assertEqual(expected_flavor, s['flavor']) - self.assertEqual('BUILD', s['status']) - self.assertEqual(str(i + 1), s['metadata']['seq']) - - def test_get_all_server_details_with_host(self): - """We want to make sure that if two instances are on the same host, - then they return the same hostId. If two instances are on different - hosts, they should return different hostId's. In this test, there - are 5 instances - 2 on one host and 3 on another. - """ - - def return_servers_with_host(*args, **kwargs): - return objects.InstanceList( - objects=[fakes.stub_instance_obj(None, - id=i + 1, user_id='fake', - project_id='fake', - host=i % 2, - uuid=fakes.get_fake_uuid(i)) - for i in range(5)]) - - self.stubs.Set(self.controller.compute_api, 'get_all', - return_servers_with_host) - - req = fakes.HTTPRequest.blank('/fake/servers/detail') - res_dict = self.controller.detail(req) - - server_list = res_dict['servers'] - host_ids = [server_list[0]['hostId'], server_list[1]['hostId']] - self.assertTrue(host_ids[0] and host_ids[1]) - self.assertNotEqual(host_ids[0], host_ids[1]) - - for i, s in enumerate(server_list): - self.assertEqual(fakes.get_fake_uuid(i), s['id']) - self.assertEqual(host_ids[i % 2], s['hostId']) - self.assertEqual('server%d' % (i + 1), s['name']) - - @mock.patch.object(compute_api.API, 'get_all') - def test_get_servers_remove_non_search_options(self, get_all_mock): - req = fakes.HTTPRequest.blank('/fake/servers' - '?sort_key=id1&sort_dir=asc' - '&sort_key=id2&sort_dir=desc' - '&limit=1&marker=123', - use_admin_context=True) - self.controller.index(req) - kwargs = get_all_mock.call_args[1] - search_opts = kwargs['search_opts'] - for key in ('sort_key', 'sort_dir', 'limit', 'marker'): - self.assertNotIn(key, search_opts) - - -class ServersControllerUpdateTest(ControllerTest): - - def _get_request(self, body=None, content_type='json', options=None): - if options: - self.stubs.Set(compute_api.API, 'get', - fakes.fake_compute_get(**options)) - req = fakes.HTTPRequest.blank('/fake/servers/%s' % FAKE_UUID) - req.method = 'PUT' - req.content_type = 'application/%s' % content_type - req.body = jsonutils.dump_as_bytes(body) - return req - - @property - def wsgi_app(self): - with mock.patch.object(extensions.ExtensionManager, 'load_extension'): - # patch load_extension because it's expensive in fakes.wsgi_app - return fakes.wsgi_app(init_only=('servers',)) - - def test_update_server_all_attributes(self): - body = {'server': { - 'name': 'server_test', - 'accessIPv4': '0.0.0.0', - 'accessIPv6': 'beef::0123', - }} - req = self._get_request(body, {'name': 'server_test', - 'access_ipv4': '0.0.0.0', - 'access_ipv6': 'beef::0123'}) - res_dict = self.controller.update(req, FAKE_UUID, body) - - self.assertEqual(FAKE_UUID, res_dict['server']['id']) - self.assertEqual('server_test', res_dict['server']['name']) - self.assertEqual('0.0.0.0', res_dict['server']['accessIPv4']) - self.assertEqual('beef::123', res_dict['server']['accessIPv6']) - - def test_update_server_invalid_xml_raises_lookup(self): - body = """ - """ - req = self._get_request(body, content_type='xml') - res = req.get_response(self.wsgi_app) - self.assertEqual(415, res.status_int) - - def test_update_server_invalid_xml_raises_expat(self): - body = """ - """ - req = self._get_request(body, content_type='xml') - res = req.get_response(self.wsgi_app) - self.assertEqual(415, res.status_int) - - def test_update_server_name(self): - body = {'server': {'name': 'server_test'}} - req = self._get_request(body, {'name': 'server_test'}) - res_dict = self.controller.update(req, FAKE_UUID, body) - - self.assertEqual(FAKE_UUID, res_dict['server']['id']) - self.assertEqual('server_test', res_dict['server']['name']) - - def test_update_server_name_with_leading_trailing_spaces(self): - body = {'server': {'name': ' abc def '}} - req = self._get_request(body, {'name': 'server_test'}) - res_dict = self.controller.update(req, FAKE_UUID, body) - - self.assertEqual(FAKE_UUID, res_dict['server']['id']) - self.assertEqual('abc def', res_dict['server']['name']) - - def test_update_server_name_too_long(self): - body = {'server': {'name': 'x' * 256}} - req = self._get_request(body, {'name': 'server_test'}) - self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, - req, FAKE_UUID, body) - - def test_update_server_name_all_blank_spaces(self): - body = {'server': {'name': ' ' * 64}} - req = self._get_request(body, {'name': 'server_test'}) - self.assertRaises(webob.exc.HTTPBadRequest, self.controller.update, - req, FAKE_UUID, body) - - def test_update_server_name_with_spaces_in_the_middle(self): - body = {'server': {'name': 'abc def'}} - req = self._get_request(body) - self.controller.update(req, FAKE_UUID, body) - - def test_update_server_personality(self): - body = { - 'server': { - 'personality': [] - } - } - req = self._get_request(body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.update, req, FAKE_UUID, body) - - def test_update_server_adminPass_ignored(self): - inst_dict = dict(name='server_test', adminPass='bacon') - body = dict(server=inst_dict) - - def server_update(context, id, params): - filtered_dict = { - 'display_name': 'server_test', - } - self.assertEqual(filtered_dict, params) - filtered_dict['uuid'] = id - return filtered_dict - - self.stub_out('nova.db.instance_update', server_update) - # FIXME (comstud) - # self.stub_out('nova.db.instance_get', - # return_server_with_attributes(name='server_test')) - - req = fakes.HTTPRequest.blank('/fake/servers/%s' % FAKE_UUID) - req.method = 'PUT' - req.content_type = "application/json" - req.body = jsonutils.dump_as_bytes(body) - res_dict = self.controller.update(req, FAKE_UUID, body) - - self.assertEqual(FAKE_UUID, res_dict['server']['id']) - self.assertEqual('server_test', res_dict['server']['name']) - - def test_update_server_not_found(self): - def fake_get(*args, **kwargs): - raise exception.InstanceNotFound(instance_id='fake') - - self.stubs.Set(compute_api.API, 'get', fake_get) - body = {'server': {'name': 'server_test'}} - req = self._get_request(body) - self.assertRaises(webob.exc.HTTPNotFound, self.controller.update, - req, FAKE_UUID, body) - - def test_update_server_not_found_on_update(self): - def fake_update(*args, **kwargs): - raise exception.InstanceNotFound(instance_id='fake') - - self.stub_out('nova.db.instance_update_and_get_original', fake_update) - body = {'server': {'name': 'server_test'}} - req = self._get_request(body) - self.assertRaises(webob.exc.HTTPNotFound, self.controller.update, - req, FAKE_UUID, body) - - def test_update_server_policy_fail(self): - rule = {'compute:update': 'role:admin'} - policy.set_rules(oslo_policy.Rules.from_dict(rule)) - body = {'server': {'name': 'server_test'}} - req = self._get_request(body, {'name': 'server_test'}) - self.assertRaises(exception.PolicyNotAuthorized, - self.controller.update, req, FAKE_UUID, body) - - -class ServersControllerDeleteTest(ControllerTest): - - def setUp(self): - super(ServersControllerDeleteTest, self).setUp() - self.server_delete_called = False - - def fake_delete(api, context, instance): - if instance.uuid == uuids.non_existent_uuid: - raise exception.InstanceNotFound(instance_id=instance.uuid) - self.server_delete_called = True - - self.stubs.Set(compute_api.API, 'delete', fake_delete) - - def _create_delete_request(self, uuid): - fakes.stub_out_instance_quota(self, 0, 10) - req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % uuid) - req.method = 'DELETE' - return req - - def _delete_server_instance(self, uuid=FAKE_UUID): - req = self._create_delete_request(uuid) - fake_get = fakes.fake_compute_get(uuid=uuid, - vm_state=vm_states.ACTIVE) - self.stubs.Set(compute_api.API, 'get', - lambda api, *a, **k: fake_get(*a, **k)) - self.controller.delete(req, uuid) - - def test_delete_server_instance(self): - self._delete_server_instance() - self.assertTrue(self.server_delete_called) - - def test_delete_server_instance_not_found(self): - self.assertRaises(webob.exc.HTTPNotFound, - self._delete_server_instance, - uuid=uuids.non_existent_uuid) - - def test_delete_locked_server(self): - req = self._create_delete_request(FAKE_UUID) - self.stubs.Set(compute_api.API, 'soft_delete', - fakes.fake_actions_to_locked_server) - self.stubs.Set(compute_api.API, 'delete', - fakes.fake_actions_to_locked_server) - - self.assertRaises(webob.exc.HTTPConflict, self.controller.delete, - req, FAKE_UUID) - - def test_delete_server_instance_while_building(self): - fakes.stub_out_instance_quota(self, 0, 10) - request = self._create_delete_request(FAKE_UUID) - self.controller.delete(request, FAKE_UUID) - - self.assertTrue(self.server_delete_called) - - def test_delete_server_instance_while_deleting_host_up(self): - req = self._create_delete_request(FAKE_UUID) - return_server = fakes.fake_compute_get( - vm_state=vm_states.ACTIVE, - task_state=task_states.DELETING, - host='fake_host') - self.stubs.Set(compute_api.API, 'get', - lambda api, *a, **k: return_server(*a, **k)) - self.stubs.Set(objects.Instance, 'save', - lambda *args, **kwargs: None) - - @classmethod - def fake_get_by_compute_host(cls, context, host): - return {'updated_at': timeutils.utcnow()} - self.stubs.Set(objects.Service, 'get_by_compute_host', - fake_get_by_compute_host) - - self.controller.delete(req, FAKE_UUID) - - def test_delete_server_instance_while_deleting_host_down(self): - fake_network.stub_out_network_cleanup(self) - req = self._create_delete_request(FAKE_UUID) - self.stub_out('nova.db.instance_get_by_uuid', - fakes.fake_instance_get(vm_state=vm_states.ACTIVE, - task_state=task_states.DELETING, - host='fake_host')) - self.stubs.Set(objects.Instance, 'save', - lambda *args, **kwargs: None) - - @classmethod - def fake_get_by_compute_host(cls, context, host): - return {'updated_at': datetime.datetime.min} - self.stubs.Set(objects.Service, 'get_by_compute_host', - fake_get_by_compute_host) - - self.controller.delete(req, FAKE_UUID) - # Delete request would be ignored, because it's been accepted before - # but since the host is down, api should remove the instance anyway. - self.assertTrue(self.server_delete_called) - - def test_delete_server_instance_while_resize(self): - req = self._create_delete_request(FAKE_UUID) - self.stub_out('nova.db.instance_get_by_uuid', - fakes.fake_instance_get(vm_state=vm_states.ACTIVE, - task_state=task_states.RESIZE_PREP)) - - self.controller.delete(req, FAKE_UUID) - # Delete shoud be allowed in any case, even during resizing, - # because it may get stuck. - self.assertTrue(self.server_delete_called) - - def test_delete_server_instance_if_not_launched(self): - self.flags(reclaim_instance_interval=3600) - req = fakes.HTTPRequest.blank('/fake/servers/%s' % FAKE_UUID) - req.method = 'DELETE' - - self.server_delete_called = False - - fake_get = fakes.fake_compute_get(launched_at=None) - self.stubs.Set(compute_api.API, 'get', - lambda api, *a, **k: fake_get(*a, **k)) - - def instance_destroy_mock(*args, **kwargs): - self.server_delete_called = True - deleted_at = timeutils.utcnow() - return fake_instance.fake_db_instance(deleted_at=deleted_at) - self.stub_out('nova.db.instance_destroy', instance_destroy_mock) - - self.controller.delete(req, FAKE_UUID) - # delete() should be called for instance which has never been active, - # even if reclaim_instance_interval has been set. - self.assertTrue(self.server_delete_called) - - -class ServersControllerRebuildInstanceTest(ControllerTest): - image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - image_href = 'http://localhost/v2/fake/images/%s' % image_uuid - - def setUp(self): - super(ServersControllerRebuildInstanceTest, self).setUp() - return_server = fakes.fake_compute_get(vm_state=vm_states.ACTIVE) - self.stubs.Set(compute_api.API, 'get', - lambda api, *a, **k: return_server(*a, **k)) - self.body = { - 'rebuild': { - 'name': 'new_name', - 'imageRef': self.image_href, - 'metadata': { - 'open': 'stack', - }, - 'personality': [ - { - "path": "/etc/banner.txt", - "contents": "MQ==", - }, - ], - }, - } - self.req = fakes.HTTPRequest.blank('/fake/servers/a/action') - self.req.method = 'POST' - self.req.headers["content-type"] = "application/json" - - def test_rebuild_instance_with_blank_metadata_key(self): - self.body['rebuild']['accessIPv4'] = '0.0.0.0' - self.body['rebuild']['accessIPv6'] = 'fead::1234' - self.body['rebuild']['metadata'][''] = 'world' - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller._action_rebuild, - self.req, FAKE_UUID, self.body) - - def test_rebuild_instance_name_with_leading_trailing_spaces(self): - self.body['rebuild']['name'] = ' abc def ' - self.req.body = jsonutils.dump_as_bytes(self.body) - - def fake_rebuild(*args, **kwargs): - # NOTE(alex_xu): V2 API rebuild didn't strip the leading/trailing - # spaces. - self.assertEqual(' abc def ', kwargs['display_name']) - - with mock.patch.object(compute_api.API, 'rebuild') as mock_rebuild: - mock_rebuild.side_effect = fake_rebuild - self.controller._action_rebuild(self.req, FAKE_UUID, self.body) - - def test_rebuild_instance_name_with_spaces_in_middle(self): - self.body['rebuild']['name'] = 'abc def' - self.req.body = jsonutils.dump_as_bytes(self.body) - self.controller._action_rebuild(self.req, FAKE_UUID, self.body) - - def test_rebuild_instance_with_metadata_key_too_long(self): - self.body['rebuild']['accessIPv4'] = '0.0.0.0' - self.body['rebuild']['accessIPv6'] = 'fead::1234' - self.body['rebuild']['metadata'][('a' * 260)] = 'world' - - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, - self.controller._action_rebuild, - self.req, FAKE_UUID, self.body) - - def test_rebuild_instance_with_metadata_value_too_long(self): - self.body['rebuild']['accessIPv4'] = '0.0.0.0' - self.body['rebuild']['accessIPv6'] = 'fead::1234' - self.body['rebuild']['metadata']['key1'] = ('a' * 260) - - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, - self.controller._action_rebuild, - self.req, FAKE_UUID, self.body) - - def test_rebuild_instance_fails_when_min_ram_too_small(self): - # make min_ram larger than our instance ram size - def fake_get_image(self, context, image_href, **kwargs): - return dict(id='76fa36fc-c930-4bf3-8c8a-ea2a2420deb6', - name='public image', is_public=True, - status='active', properties={'key1': 'value1'}, - min_ram="4096", min_disk="10") - - self.stubs.Set(fake._FakeImageService, 'show', fake_get_image) - - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller._action_rebuild, - self.req, FAKE_UUID, self.body) - - def test_rebuild_instance_fails_when_min_disk_too_small(self): - # make min_disk larger than our instance disk size - def fake_get_image(self, context, image_href, **kwargs): - return dict(id='76fa36fc-c930-4bf3-8c8a-ea2a2420deb6', - name='public image', is_public=True, - status='active', properties={'key1': 'value1'}, - min_ram="128", min_disk="100000") - - self.stubs.Set(fake._FakeImageService, 'show', fake_get_image) - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller._action_rebuild, self.req, - FAKE_UUID, self.body) - - def test_rebuild_instance_image_too_large(self): - # make image size larger than our instance disk size - size = str(1000 * (1024 ** 3)) - - def fake_get_image(self, context, image_href, **kwargs): - return dict(id='76fa36fc-c930-4bf3-8c8a-ea2a2420deb6', - name='public image', is_public=True, - status='active', size=size) - - self.stubs.Set(fake._FakeImageService, 'show', fake_get_image) - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller._action_rebuild, self.req, FAKE_UUID, self.body) - - def test_rebuild_instance_with_deleted_image(self): - def fake_get_image(self, context, image_href, **kwargs): - return dict(id='76fa36fc-c930-4bf3-8c8a-ea2a2420deb6', - name='public image', is_public=True, - status='DELETED') - - self.stubs.Set(fake._FakeImageService, 'show', fake_get_image) - - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller._action_rebuild, self.req, FAKE_UUID, self.body) - - def test_rebuild_instance_onset_file_limit_over_quota(self): - def fake_get_image(self, context, image_href, **kwargs): - return dict(id='76fa36fc-c930-4bf3-8c8a-ea2a2420deb6', - name='public image', is_public=True, status='active') - - with test.nested( - mock.patch.object(fake._FakeImageService, 'show', - side_effect=fake_get_image), - mock.patch.object(self.controller.compute_api, 'rebuild', - side_effect=exception.OnsetFileLimitExceeded) - ) as ( - show_mock, rebuild_mock - ): - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPForbidden, - self.controller._action_rebuild, - self.req, FAKE_UUID, body=self.body) - - def test_rebuild_instance_with_null_image_ref(self): - self.body['rebuild']['imageRef'] = None - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller._action_rebuild, self.req, FAKE_UUID, - self.body) - - -class ServerStatusTest(test.TestCase): - - def setUp(self): - super(ServerStatusTest, self).setUp() - fakes.stub_out_nw_api(self) - - self.ext_mgr = extensions.ExtensionManager() - self.ext_mgr.extensions = {} - self.controller = servers.Controller(self.ext_mgr) - - def _get_with_state(self, vm_state, task_state=None): - request = fakes.HTTPRequest.blank('/fake/servers/%s' % FAKE_UUID) - with mock.patch.object(self.controller.compute_api, 'get') as get: - get.side_effect = fakes.fake_compute_get( - vm_state=vm_state, - task_state=task_state) - return self.controller.show(request, FAKE_UUID) - - def _req_with_policy_fail(self, policy_rule_name): - rule = {'compute:%s' % policy_rule_name: 'role:admin'} - policy.set_rules(oslo_policy.Rules.from_dict(rule)) - return fakes.HTTPRequest.blank('/fake/servers/1234/action') - - def test_active(self): - response = self._get_with_state(vm_states.ACTIVE) - self.assertEqual('ACTIVE', response['server']['status']) - - def test_reboot(self): - response = self._get_with_state(vm_states.ACTIVE, - task_states.REBOOTING) - self.assertEqual('REBOOT', response['server']['status']) - - def test_reboot_hard(self): - response = self._get_with_state(vm_states.ACTIVE, - task_states.REBOOTING_HARD) - self.assertEqual('HARD_REBOOT', response['server']['status']) - - @mock.patch.object(servers.Controller, "_get_server") - def test_reboot_resize_policy_fail(self, mock_get_server): - req = self._req_with_policy_fail('reboot') - self.assertRaises(exception.PolicyNotAuthorized, - self.controller._action_reboot, req, '1234', - {'reboot': {'type': 'HARD'}}) - - def test_rebuild(self): - response = self._get_with_state(vm_states.ACTIVE, - task_states.REBUILDING) - self.assertEqual('REBUILD', response['server']['status']) - - def test_rebuild_error(self): - response = self._get_with_state(vm_states.ERROR) - self.assertEqual('ERROR', response['server']['status']) - - def test_resize(self): - response = self._get_with_state(vm_states.ACTIVE, - task_states.RESIZE_PREP) - self.assertEqual('RESIZE', response['server']['status']) - - @mock.patch.object(servers.Controller, "_get_server") - def test_confirm_resize_policy_fail(self, mock_get_server): - req = self._req_with_policy_fail('confirm_resize') - self.assertRaises(exception.PolicyNotAuthorized, - self.controller._action_confirm_resize, req, '1234', {}) - - def test_verify_resize(self): - response = self._get_with_state(vm_states.RESIZED, None) - self.assertEqual('VERIFY_RESIZE', response['server']['status']) - - def test_revert_resize(self): - response = self._get_with_state(vm_states.RESIZED, - task_states.RESIZE_REVERTING) - self.assertEqual('REVERT_RESIZE', response['server']['status']) - - @mock.patch.object(servers.Controller, "_get_server") - def test_revert_resize_policy_fail(self, mock_get_server): - req = self._req_with_policy_fail('revert_resize') - self.assertRaises(exception.PolicyNotAuthorized, - self.controller._action_revert_resize, req, '1234', {}) - - def test_password_update(self): - response = self._get_with_state(vm_states.ACTIVE, - task_states.UPDATING_PASSWORD) - self.assertEqual('PASSWORD', response['server']['status']) - - def test_stopped(self): - response = self._get_with_state(vm_states.STOPPED) - self.assertEqual('SHUTOFF', response['server']['status']) - - -class ServersControllerCreateTest(test.TestCase): - image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - flavor_ref = 'http://localhost/123/flavors/3' - - def setUp(self): - """Shared implementation for tests below that create instance.""" - super(ServersControllerCreateTest, self).setUp() - - self.flags(verbose=True, - enable_instance_password=True) - self.instance_cache_num = 0 - self.instance_cache_by_id = {} - self.instance_cache_by_uuid = {} - - fakes.stub_out_nw_api(self) - - self.ext_mgr = extensions.ExtensionManager() - self.ext_mgr.extensions = {} - self.controller = servers.Controller(self.ext_mgr) - - self.volume_id = 'fake' - - def instance_create(context, inst): - inst_type = flavors.get_flavor_by_flavor_id(3) - image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - def_image_ref = 'http://localhost/images/%s' % image_uuid - self.instance_cache_num += 1 - instance = fake_instance.fake_db_instance(**{ - 'id': self.instance_cache_num, - 'display_name': inst['display_name'] or 'test', - 'uuid': inst['uuid'], - 'instance_type': inst_type, - 'access_ip_v4': '1.2.3.4', - 'access_ip_v6': 'fead::1234', - 'image_ref': inst.get('image_ref', def_image_ref), - 'user_id': 'fake', - 'project_id': 'fake', - 'reservation_id': inst['reservation_id'], - "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), - "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), - "config_drive": None, - "progress": 0, - "fixed_ips": [], - "task_state": "", - "vm_state": "", - "root_device_name": inst.get('root_device_name', 'vda'), - "security_groups": inst['security_groups'], - }) - - self.instance_cache_by_id[instance['id']] = instance - self.instance_cache_by_uuid[instance['uuid']] = instance - return instance - - def instance_get(context, instance_id): - """Stub for compute/api create() pulling in instance after - scheduling - """ - return self.instance_cache_by_id[instance_id] - - def instance_update(context, uuid, values): - instance = self.instance_cache_by_uuid[uuid] - instance.update(values) - return instance - - def server_update_and_get_original( - context, instance_uuid, params, columns_to_join=None): - inst = self.instance_cache_by_uuid[instance_uuid] - inst.update(params) - return (inst, inst) - - def fake_method(*args, **kwargs): - pass - - def project_get_networks(context, user_id): - return dict(id='1', host='localhost') - - fakes.stub_out_rate_limiting(self.stubs) - fakes.stub_out_key_pair_funcs(self.stubs) - fake.stub_out_image_service(self) - self.stub_out('nova.db.instance_add_security_group', - return_security_group) - self.stub_out('nova.db.project_get_networks', project_get_networks) - self.stub_out('nova.db.instance_create', instance_create) - self.stub_out('nova.db.instance_system_metadata_update', fake_method) - self.stub_out('nova.db.instance_get', instance_get) - self.stub_out('nova.db.instance_update', instance_update) - self.stub_out('nova.db.instance_update_and_get_original', - server_update_and_get_original) - self.stubs.Set(manager.VlanManager, 'allocate_fixed_ip', - fake_method) - self.body = { - 'server': { - 'min_count': 2, - 'name': 'server_test', - 'imageRef': self.image_uuid, - 'flavorRef': self.flavor_ref, - 'metadata': { - 'hello': 'world', - 'open': 'stack', - }, - 'personality': [ - { - "path": "/etc/banner.txt", - "contents": "MQ==", - }, - ], - }, - } - self.bdm = [{'delete_on_termination': 1, - 'device_name': 123, - 'volume_size': 1, - 'volume_id': '11111111-1111-1111-1111-111111111111'}] - - self.req = fakes.HTTPRequest.blank('/fake/servers') - self.req.method = 'POST' - self.req.headers["content-type"] = "application/json" - - def _check_admin_pass_len(self, server_dict): - """utility function - check server_dict for adminPass length.""" - self.assertEqual(CONF.password_length, - len(server_dict["adminPass"])) - - def _check_admin_pass_missing(self, server_dict): - """utility function - check server_dict for absence of adminPass.""" - self.assertNotIn("adminPass", server_dict) - - def _test_create_instance(self, flavor=2): - image_uuid = 'c905cedb-7281-47e4-8a62-f26bc5fc4c77' - self.body['server']['imageRef'] = image_uuid - self.body['server']['flavorRef'] = flavor - self.req.body = jsonutils.dump_as_bytes(self.body) - server = self.controller.create(self.req, self.body).obj['server'] - self._check_admin_pass_len(server) - instance = self.instance_cache_by_uuid.values()[0] - self.assertEqual(instance['uuid'], server['id']) - return server - - def test_create_instance_private_flavor(self): - values = { - 'name': 'fake_name', - 'memory_mb': 512, - 'vcpus': 1, - 'root_gb': 10, - 'ephemeral_gb': 10, - 'flavorid': '1324', - 'swap': 0, - 'rxtx_factor': 0.5, - 'vcpu_weight': 1, - 'disabled': False, - 'is_public': False, - } - db.flavor_create(context.get_admin_context(), values) - self.assertRaises(webob.exc.HTTPBadRequest, self._test_create_instance, - flavor=1324) - - def test_create_server_bad_image_href(self): - image_href = 1 - self.body['server']['imageRef'] = image_href, - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, - self.req, self.body) - - def test_create_server_with_invalid_networks_parameter(self): - self.ext_mgr.extensions = {'os-networks': 'fake'} - self.body['server']['networks'] = { - 'uuid': '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6'} - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, - self.req, - self.body) - - def test_create_server_with_deleted_image(self): - image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - # Get the fake image service so we can set the status to deleted - (image_service, image_id) = glance.get_remote_image_service( - context, '') - image_service.update(context, image_uuid, {'status': 'DELETED'}) - self.addCleanup(image_service.update, context, image_uuid, - {'status': 'active'}) - - self.body['server']['flavorRef'] = 2 - self.req.body = jsonutils.dump_as_bytes(self.body) - with testtools.ExpectedException( - webob.exc.HTTPBadRequest, - 'Image 76fa36fc-c930-4bf3-8c8a-ea2a2420deb6 is not active.'): - self.controller.create(self.req, self.body) - - def test_create_server_image_too_large(self): - image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - # Get the fake image service so we can update the size of the image - (image_service, image_id) = glance.get_remote_image_service(context, - image_uuid) - image = image_service.show(context, image_id) - orig_size = image['size'] - new_size = str(1000 * (1024 ** 3)) - image_service.update(context, image_uuid, {'size': new_size}) - - self.addCleanup(image_service.update, context, image_uuid, - {'size': orig_size}) - - self.body['server']['flavorRef'] = 2 - self.req.body = jsonutils.dump_as_bytes(self.body) - with testtools.ExpectedException( - webob.exc.HTTPBadRequest, - "Flavor's disk is too small for requested image."): - self.controller.create(self.req, self.body) - - def test_create_multiple_instances(self): - """Test creating multiple instances but not asking for - reservation_id - """ - self.ext_mgr.extensions = {'os-multiple-create': 'fake'} - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - instance_uuids = self.instance_cache_by_uuid.keys() - self.assertIn(res["server"]["id"], instance_uuids) - self._check_admin_pass_len(res["server"]) - - def test_create_multiple_instances_pass_disabled(self): - """Test creating multiple instances but not asking for - reservation_id - """ - self.ext_mgr.extensions = {'os-multiple-create': 'fake'} - self.flags(enable_instance_password=False) - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - instance_uuids = self.instance_cache_by_uuid.keys() - self.assertIn(res["server"]["id"], instance_uuids) - self._check_admin_pass_missing(res["server"]) - - def test_create_multiple_instances_resv_id_return(self): - """Test creating multiple instances with asking for - reservation_id - """ - self.ext_mgr.extensions = {'os-multiple-create': 'fake'} - self.body['server']['return_reservation_id'] = True - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body) - reservation_id = res.obj.get('reservation_id') - self.assertNotEqual(reservation_id, "") - self.assertIsNotNone(reservation_id) - self.assertTrue(len(reservation_id) > 1) - - def test_create_multiple_instances_with_multiple_volume_bdm(self): - """Test that a BadRequest is raised if multiple instances - are requested with a list of block device mappings for volumes. - """ - self.ext_mgr.extensions = {'os-multiple-create': 'fake'} - min_count = 2 - bdm = [{'device_name': 'foo1', 'volume_id': 'vol-xxxx'}, - {'device_name': 'foo2', 'volume_id': 'vol-yyyy'} - ] - params = { - 'block_device_mapping': bdm, - 'min_count': min_count - } - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertEqual(2, kwargs['min_count']) - self.assertEqual(2, len(kwargs['block_device_mapping'])) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params, no_image=True) - - def test_create_instance_image_ref_is_bookmark(self): - image_href = 'http://localhost/fake/images/%s' % self.image_uuid - self.body['server']['imageRef'] = image_href - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - server = res['server'] - instance = self.instance_cache_by_uuid.values()[0] - self.assertEqual(instance['uuid'], server['id']) - - def test_create_instance_image_ref_is_invalid(self): - image_uuid = 'this_is_not_a_valid_uuid' - image_href = 'http://localhost/fake/images/%s' % image_uuid - self.body['server']['imageRef'] = image_href - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, - self.req, self.body) - - def test_create_instance_no_key_pair(self): - fakes.stub_out_key_pair_funcs(self.stubs, have_key_pair=False) - self._test_create_instance() - - def _test_create_extra(self, params, no_image=False): - self.body['server']['flavorRef'] = 2 - if no_image: - self.body['server'].pop('imageRef', None) - self.body['server'].update(params) - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertIn('server', - self.controller.create(self.req, self.body).obj) - - def test_create_instance_with_security_group_enabled(self): - self.ext_mgr.extensions = {'os-security-groups': 'fake'} - group = 'foo' - old_create = compute_api.API.create - - def sec_group_get(ctx, proj, name): - if name == group: - return True - else: - raise exception.SecurityGroupNotFoundForProject( - project_id=proj, security_group_id=name) - - def create(*args, **kwargs): - self.assertEqual(kwargs['security_group'], [group]) - return old_create(*args, **kwargs) - - self.stub_out('nova.db.security_group_get_by_name', sec_group_get) - # negative test - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, - {'security_groups': [{'name': 'bogus'}]}) - # positive test - extra assert in create path - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra({'security_groups': [{'name': group}]}) - - def test_create_instance_with_non_unique_secgroup_name(self): - self.flags(use_neutron=True) - network = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'uuid': network}] - params = {'networks': requested_networks, - 'security_groups': [{'name': 'dup'}, {'name': 'dup'}]} - - def fake_create(*args, **kwargs): - raise exception.NoUniqueMatch("No Unique match found for ...") - - self.stubs.Set(compute_api.API, 'create', fake_create) - self.assertRaises(webob.exc.HTTPConflict, - self._test_create_extra, params) - - def test_create_instance_sg_with_leading_trailing_spaces(self): - self.flags(use_neutron=True) - network = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'uuid': network}] - params = {'networks': requested_networks, - 'security_groups': [{'name': ' sg '}]} - - def fake_create(*args, **kwargs): - self.assertEqual([' sg '], kwargs['security_group']) - return (objects.InstanceList(objects=[fakes.stub_instance_obj( - self.req.environ['nova.context'])]), None) - - self.stubs.Set(compute_api.API, 'create', fake_create) - self.ext_mgr.extensions = {'os-security-groups'} - self._test_create_extra(params) - - def test_create_instance_with_port_with_no_fixed_ips(self): - self.flags(use_neutron=True) - port_id = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'port': port_id}] - params = {'networks': requested_networks} - - def fake_create(*args, **kwargs): - raise exception.PortRequiresFixedIP(port_id=port_id) - - self.stubs.Set(compute_api.API, 'create', fake_create) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params) - - @mock.patch.object(compute_api.API, 'create') - def test_create_instance_raise_user_data_too_large(self, mock_create): - mock_create.side_effect = exception.InstanceUserDataTooLarge( - maxsize=1, length=2) - - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, - self.req, self.body) - - @mock.patch.object(compute_api.API, 'create') - def test_create_instance_raise_auto_disk_config_exc(self, mock_create): - mock_create.side_effect = exception.AutoDiskConfigDisabledByImage( - image='dummy') - - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, - self.req, self.body) - - @mock.patch.object(compute_api.API, 'create', - side_effect=exception.InstanceExists( - name='instance-name')) - def test_create_instance_raise_instance_exists(self, mock_create): - self.assertRaises(webob.exc.HTTPConflict, - self.controller.create, - self.req, self.body) - - def test_create_instance_with_network_with_no_subnet(self): - self.flags(use_neutron=True) - network = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'uuid': network}] - params = {'networks': requested_networks} - - def fake_create(*args, **kwargs): - raise exception.NetworkRequiresSubnet(network_uuid=network) - - self.stubs.Set(compute_api.API, 'create', fake_create) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params) - - def test_create_instance_name_all_blank_spaces(self): - self.body['server']['name'] = ' ' * 64 - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_name_with_spaces_in_middle(self): - self.body['server']['name'] = 'abc def' - self.req.body = jsonutils.dump_as_bytes(self.body) - self.controller.create(self.req, self.body) - - def test_create_instance_name_too_long(self): - self.body['server']['name'] = 'X' * 256 - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, self.controller.create, - self.req, self.body) - - def test_create_instance_name_with_leading_trailing_spaces(self): - self.body['server']['name'] = ' abc def ' - self.req.body = jsonutils.dump_as_bytes(self.body) - server = self._test_create_instance() - self.assertEqual( - self.body['server']['name'].strip(), - self.instance_cache_by_uuid[server['id']]['display_name']) - - def test_create_instance_az_with_leading_trailing_spaces(self): - self.body['server']['availability_zone'] = ' zone1 ' - self.req.body = jsonutils.dump_as_bytes(self.body) - with mock.patch.object(availability_zones, 'get_availability_zones', - return_value=[' zone1 ']): - self._test_create_instance() - - def test_create_instance(self): - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - - server = res['server'] - self._check_admin_pass_len(server) - instance = self.instance_cache_by_uuid.values()[0] - self.assertEqual(instance['uuid'], server['id']) - - def test_create_instance_pass_disabled(self): - self.flags(enable_instance_password=False) - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - - server = res['server'] - self._check_admin_pass_missing(server) - instance = self.instance_cache_by_uuid.values()[0] - self.assertEqual(instance['uuid'], server['id']) - - @mock.patch('nova.virt.hardware.numa_get_constraints') - def test_create_instance_numa_topology_wrong(self, numa_constraints_mock): - numa_constraints_mock.side_effect = ( - exception.ImageNUMATopologyIncomplete) - image_href = 'http://localhost/v2/images/%s' % self.image_uuid - self.body['server']['imageRef'] = image_href - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_too_much_metadata(self): - self.flags(quota_metadata_items=1) - self.body['server']['metadata']['vote'] = 'fiddletown' - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPForbidden, - self.controller.create, self.req, self.body) - - def test_create_instance_metadata_key_too_long(self): - self.flags(quota_metadata_items=1) - self.body['server']['metadata'] = {('a' * 260): '12345'} - - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, - self.controller.create, self.req, self.body) - - def test_create_instance_metadata_value_too_long(self): - self.flags(quota_metadata_items=1) - self.body['server']['metadata'] = {'key1': ('a' * 260)} - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPRequestEntityTooLarge, - self.controller.create, self.req, self.body) - - def test_create_instance_metadata_key_blank(self): - self.flags(quota_metadata_items=1) - self.body['server']['metadata'] = {'': 'abcd'} - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_metadata_not_dict(self): - self.flags(quota_metadata_items=1) - self.body['server']['metadata'] = 'string' - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_metadata_key_not_string(self): - self.flags(quota_metadata_items=1) - self.body['server']['metadata'] = {1: 'test'} - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_metadata_value_not_string(self): - self.flags(quota_metadata_items=1) - self.body['server']['metadata'] = {'test': ['a', 'list']} - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_user_data_malformed_bad_request(self): - self.ext_mgr.extensions = {'os-user-data': 'fake'} - params = {'user_data': 'u1234!'} - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params) - - @mock.patch('nova.compute.api.API.create', - side_effect=exception.KeypairNotFound(name='nonexistentkey', - user_id=1)) - def test_create_instance_invalid_key_name(self, mock_create): - self.body['server']['key_name'] = 'nonexistentkey' - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - @mock.patch('nova.compute.api.API.create', - side_effect=exception.KeypairNotFound(name='', - user_id=1)) - def test_create_instance_empty_key_name(self, mock_create): - self.body['server']['key_name'] = '' - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_valid_key_name(self): - self.body['server']['key_name'] = 'key' - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - - instance = self.instance_cache_by_uuid.values()[0] - self.assertEqual(instance['uuid'], res["server"]["id"]) - self._check_admin_pass_len(res["server"]) - - def test_create_instance_invalid_flavor_href(self): - flavor_ref = 'http://localhost/v2/flavors/asdf' - self.body['server']['flavorRef'] = flavor_ref - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_invalid_flavor_id_int(self): - flavor_ref = -1 - self.body['server']['flavorRef'] = flavor_ref - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_invalid_flavor_id_empty(self): - flavor_ref = "" - self.body['server']['flavorRef'] = flavor_ref - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_bad_flavor_href(self): - flavor_ref = 'http://localhost/v2/flavors/17' - self.body['server']['flavorRef'] = flavor_ref - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_with_config_drive(self): - self.ext_mgr.extensions = {'os-config-drive': 'fake'} - self.body['server']['config_drive'] = "true" - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - server = res['server'] - instance = self.instance_cache_by_uuid.values()[0] - self.assertEqual(instance['uuid'], server['id']) - - def test_create_instance_with_bad_config_drive(self): - self.ext_mgr.extensions = {'os-config-drive': 'fake'} - self.body['server']['config_drive'] = 'adcd' - self.req.body = jsonutils.dump_as_bytes(self.body) - - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_without_config_drive(self): - self.ext_mgr.extensions = {'os-config-drive': 'fake'} - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - server = res['server'] - instance = self.instance_cache_by_uuid.values()[0] - self.assertEqual(instance['uuid'], server['id']) - - def test_create_instance_with_config_drive_disabled(self): - config_drive = [{'config_drive': 'foo'}] - params = {'config_drive': config_drive} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertIsNone(kwargs['config_drive']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_bad_href(self): - image_href = 'asdf' - self.body['server']['imageRef'] = image_href - self.req.body = jsonutils.dump_as_bytes(self.body) - - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_instance_local_href(self): - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - - server = res['server'] - instance = self.instance_cache_by_uuid.values()[0] - self.assertEqual(instance['uuid'], server['id']) - - def test_create_instance_admin_pass(self): - self.body['server']['flavorRef'] = 3, - self.body['server']['adminPass'] = 'testpass' - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - - server = res['server'] - self.assertEqual(self.body['server']['adminPass'], server['adminPass']) - - def test_create_instance_admin_pass_pass_disabled(self): - self.flags(enable_instance_password=False) - self.body['server']['flavorRef'] = 3, - self.body['server']['adminPass'] = 'testpass' - self.req.body = jsonutils.dump_as_bytes(self.body) - res = self.controller.create(self.req, self.body).obj - - server = res['server'] - self.assertIn('adminPass', self.body['server']) - self.assertNotIn('adminPass', server) - - def test_create_instance_admin_pass_empty(self): - self.body['server']['flavorRef'] = 3, - self.body['server']['adminPass'] = '' - self.req.body = jsonutils.dump_as_bytes(self.body) - - # The fact that the action doesn't raise is enough validation - self.controller.create(self.req, self.body) - - def test_create_instance_with_security_group_disabled(self): - group = 'foo' - params = {'security_groups': [{'name': group}]} - old_create = compute_api.API.create - - def create(*args, **kwargs): - # NOTE(vish): if the security groups extension is not - # enabled, then security groups passed in - # are ignored. - self.assertEqual(['default'], kwargs['security_group']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_disk_config_enabled(self): - self.ext_mgr.extensions = {'OS-DCF': 'fake'} - # NOTE(vish): the extension converts OS-DCF:disk_config into - # auto_disk_config, so we are testing with - # the_internal_value - params = {'auto_disk_config': 'AUTO'} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertEqual('AUTO', kwargs['auto_disk_config']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_disk_config_disabled(self): - params = {'auto_disk_config': True} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertFalse(kwargs['auto_disk_config']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_scheduler_hints_enabled(self): - self.ext_mgr.extensions = {'OS-SCH-HNT': 'fake'} - hints = {'a': 'b'} - params = {'scheduler_hints': hints} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertEqual(hints, kwargs['scheduler_hints']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_scheduler_hints_disabled(self): - hints = {'a': 'b'} - params = {'scheduler_hints': hints} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertEqual({}, kwargs['scheduler_hints']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_volumes_enabled_no_image(self): - """Test that the create will fail if there is no image - and no bdms supplied in the request - """ - self.ext_mgr.extensions = {'os-volumes': 'fake'} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertNotIn('imageRef', kwargs) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, {}, no_image=True) - - def test_create_instance_with_bdm_v2_enabled_no_image(self): - self.ext_mgr.extensions = {'os-block-device-mapping-v2-boot': 'fake'} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertNotIn('imageRef', kwargs) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, {}, no_image=True) - - def test_create_instance_with_user_data_enabled(self): - self.ext_mgr.extensions = {'os-user-data': 'fake'} - user_data = 'fake' - params = {'user_data': user_data} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertEqual(user_data, kwargs['user_data']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_user_data_disabled(self): - user_data = 'fake' - params = {'user_data': user_data} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertIsNone(kwargs['user_data']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_keypairs_enabled(self): - self.ext_mgr.extensions = {'os-keypairs': 'fake'} - key_name = 'green' - - params = {'key_name': key_name} - old_create = compute_api.API.create - - # NOTE(sdague): key pair goes back to the database, - # so we need to stub it out for tests - def key_pair_get(context, user_id, name): - return dict(test_keypair.fake_keypair, - public_key='FAKE_KEY', - fingerprint='FAKE_FINGERPRINT', - name=name) - - def create(*args, **kwargs): - self.assertEqual(key_name, kwargs['key_name']) - return old_create(*args, **kwargs) - - self.stub_out('nova.db.key_pair_get', key_pair_get) - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_keypairs_disabled(self): - key_name = 'green' - - params = {'key_name': key_name} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertIsNone(kwargs['key_name']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_availability_zone_enabled(self): - self.ext_mgr.extensions = {'os-availability-zone': 'fake'} - availability_zone = 'fake' - params = {'availability_zone': availability_zone} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertEqual(availability_zone, kwargs['availability_zone']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - - try: - self._test_create_extra(params) - except webob.exc.HTTPBadRequest as e: - expected = 'The requested availability zone is not available' - self.assertEqual(expected, e.explanation) - admin_context = context.get_admin_context() - db.service_create(admin_context, {'host': 'host1_zones', - 'binary': "nova-compute", - 'topic': 'compute', - 'report_count': 0}) - agg = db.aggregate_create(admin_context, - {'name': 'agg1'}, {'availability_zone': availability_zone}) - db.aggregate_host_add(admin_context, agg['id'], 'host1_zones') - self._test_create_extra(params) - - def test_create_instance_with_availability_zone_disabled(self): - availability_zone = 'fake' - params = {'availability_zone': availability_zone} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertIsNone(kwargs['availability_zone']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_networks_enabled(self): - self.ext_mgr.extensions = {'os-networks': 'fake'} - net_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - requested_networks = [{'uuid': net_uuid}] - params = {'networks': requested_networks} - old_create = compute_api.API.create - - def create(*args, **kwargs): - result = [('76fa36fc-c930-4bf3-8c8a-ea2a2420deb6', None)] - self.assertEqual(result, kwargs['requested_networks'].as_tuples()) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_neutronv2_port_in_use(self): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'uuid': network, 'port': port}] - params = {'networks': requested_networks} - - def fake_create(*args, **kwargs): - raise exception.PortInUse(port_id=port) - - self.stubs.Set(compute_api.API, 'create', fake_create) - self.assertRaises(webob.exc.HTTPConflict, - self._test_create_extra, params) - - def test_create_instance_with_neutronv2_not_found_network(self): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - requested_networks = [{'uuid': network}] - params = {'networks': requested_networks} - - def fake_create(*args, **kwargs): - raise exception.NetworkNotFound(network_id=network) - - self.stubs.Set(compute_api.API, 'create', fake_create) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params) - - def test_create_instance_with_neutronv2_port_not_found(self): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - requested_networks = [{'uuid': network, 'port': port}] - params = {'networks': requested_networks} - - def fake_create(*args, **kwargs): - raise exception.PortNotFound(port_id=port) - - self.stubs.Set(compute_api.API, 'create', fake_create) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params) - - @mock.patch.object(compute_api.API, 'create') - def test_create_multiple_instance_with_specified_ip_neutronv2(self, - _api_mock): - _api_mock.side_effect = exception.InvalidFixedIpAndMaxCountRequest( - reason="") - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - address = '10.0.0.1' - self.body['server']['max_count'] = 2 - requested_networks = [{'uuid': network, 'fixed_ip': address, - 'port': port}] - params = {'networks': requested_networks} - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params) - - def test_create_multiple_instance_with_neutronv2_port(self): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - port = 'eeeeeeee-eeee-eeee-eeee-eeeeeeeeeeee' - self.body['server']['max_count'] = 2 - requested_networks = [{'uuid': network, 'port': port}] - params = {'networks': requested_networks} - - def fake_create(*args, **kwargs): - msg = ("Unable to launch multiple instances with" - " a single configured port ID. Please launch your" - " instance one by one with different ports.") - raise exception.MultiplePortsNotApplicable(reason=msg) - - self.stubs.Set(compute_api.API, 'create', fake_create) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params) - - def test_create_instance_with_networks_disabled_neutronv2(self): - self.flags(use_neutron=True) - net_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - requested_networks = [{'uuid': net_uuid}] - params = {'networks': requested_networks} - old_create = compute_api.API.create - - def create(*args, **kwargs): - result = [('76fa36fc-c930-4bf3-8c8a-ea2a2420deb6', None, - None, None)] - self.assertEqual(result, kwargs['requested_networks'].as_tuples()) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_with_networks_disabled(self): - self.ext_mgr.extensions = {} - net_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - requested_networks = [{'uuid': net_uuid}] - params = {'networks': requested_networks} - old_create = compute_api.API.create - - def create(*args, **kwargs): - self.assertIsNone(kwargs['requested_networks']) - return old_create(*args, **kwargs) - - self.stubs.Set(compute_api.API, 'create', create) - self._test_create_extra(params) - - def test_create_instance_invalid_personality(self): - - def fake_create(*args, **kwargs): - codec = 'utf8' - content = 'b25zLiINCg0KLVJpY2hhcmQgQ$$%QQmFjaA==' - start_position = 19 - end_position = 20 - msg = 'invalid start byte' - raise UnicodeDecodeError(codec, content, start_position, - end_position, msg) - self.stubs.Set(compute_api.API, 'create', fake_create) - self.body['server']['personality'] = [ - { - "path": "/etc/banner.txt", - "contents": "b25zLiINCg0KLVJpY2hhcmQgQ$$%QQmFjaA==", - }, - ] - self.req.body = jsonutils.dump_as_bytes(self.body) - self.assertRaises(webob.exc.HTTPBadRequest, - self.controller.create, self.req, self.body) - - def test_create_location(self): - image_href = 'http://localhost/v2/images/%s' % self.image_uuid - self.body['server']['imageRef'] = image_href - self.req.body = jsonutils.dump_as_bytes(self.body) - robj = self.controller.create(self.req, self.body) - instance = self.instance_cache_by_uuid.values()[0] - selfhref = 'http://localhost/v2/fake/servers/%s' % instance['uuid'] - self.assertEqual(selfhref, robj['Location']) - - def _do_test_create_instance_above_quota(self, resource, allowed, quota, - expected_msg): - fakes.stub_out_instance_quota(self, allowed, quota, resource) - self.body['server']['flavorRef'] = 3 - self.req.body = jsonutils.dump_as_bytes(self.body) - try: - self.controller.create(self.req, self.body).obj['server'] - self.fail('expected quota to be exceeded') - except webob.exc.HTTPForbidden as e: - self.assertEqual(expected_msg, e.explanation) - - def test_create_instance_above_quota_instances(self): - msg = ('Quota exceeded for instances: Requested 1, but' - ' already used 10 of 10 instances') - self._do_test_create_instance_above_quota('instances', 0, 10, msg) - - def test_create_instance_above_quota_ram(self): - msg = ('Quota exceeded for ram: Requested 4096, but' - ' already used 8192 of 10240 ram') - self._do_test_create_instance_above_quota('ram', 2048, 10 * 1024, msg) - - def test_create_instance_above_quota_cores(self): - msg = ('Quota exceeded for cores: Requested 2, but' - ' already used 9 of 10 cores') - self._do_test_create_instance_above_quota('cores', 1, 10, msg) - - def test_create_instance_above_quota_group_members(self): - ctxt = self.req.environ['nova.context'] - fake_group = objects.InstanceGroup(ctxt) - fake_group.project_id = ctxt.project_id - fake_group.user_id = ctxt.user_id - fake_group.create() - - def fake_count(context, name, group, user_id): - self.assertEqual("server_group_members", name) - self.assertEqual(fake_group.uuid, group.uuid) - self.assertEqual(self.req.environ['nova.context'].user_id, - user_id) - return 10 - - def fake_limit_check(context, **kwargs): - if 'server_group_members' in kwargs: - raise exception.OverQuota(overs={}) - - def fake_instance_destroy(context, uuid, constraint): - return fakes.stub_instance(1) - - self.stubs.Set(fakes.QUOTAS, 'count', fake_count) - self.stubs.Set(fakes.QUOTAS, 'limit_check', fake_limit_check) - self.stub_out('nova.db.instance_destroy', fake_instance_destroy) - self.ext_mgr.extensions = {'OS-SCH-HNT': 'fake', - 'os-server-group-quotas': 'fake'} - self.body['server']['scheduler_hints'] = {'group': fake_group.uuid} - self.req.body = jsonutils.dump_as_bytes(self.body) - - expected_msg = "Quota exceeded, too many servers in group" - - try: - self.controller.create(self.req, self.body).obj['server'] - self.fail('expected quota to be exceeded') - except webob.exc.HTTPForbidden as e: - self.assertEqual(expected_msg, e.explanation) - - def test_create_instance_with_group_hint(self): - ctxt = self.req.environ['nova.context'] - test_group = objects.InstanceGroup(ctxt) - test_group.project_id = ctxt.project_id - test_group.user_id = ctxt.user_id - test_group.create() - - def fake_instance_destroy(context, uuid, constraint): - return fakes.stub_instance(1) - - self.stub_out('nova.db.instance_destroy', fake_instance_destroy) - self.ext_mgr.extensions = {'OS-SCH-HNT': 'fake', - 'os-server-group-quotas': 'fake'} - self.body['server']['scheduler_hints'] = {'group': test_group.uuid} - self.req.body = jsonutils.dump_as_bytes(self.body) - server = self.controller.create(self.req, self.body).obj['server'] - - test_group = objects.InstanceGroup.get_by_uuid(ctxt, test_group.uuid) - self.assertIn(server['id'], test_group.members) - - def test_resolve_exception(self): - class AA(object): - pass - - class BB(AA): - pass - - class CC(BB): - pass - - list1 = [AA, BB, CC] - list2 = [BB, AA, CC] - list3 = [CC, AA] - list4 = [CC, BB, AA] - for test_list in [list1, list2, list3, list4]: - result = self.controller._resolve_exception(test_list) - # Since CC is the most specific, we always expect that returned. - self.assertEqual(CC, result) - - -class ServersControllerCreateTestWithMock(test.TestCase): - image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' - flavor_ref = 'http://localhost/123/flavors/3' - - def setUp(self): - """Shared implementation for tests below that create instance.""" - super(ServersControllerCreateTestWithMock, self).setUp() - - self.flags(verbose=True, - enable_instance_password=True) - self.instance_cache_num = 0 - self.instance_cache_by_id = {} - self.instance_cache_by_uuid = {} - - self.ext_mgr = extensions.ExtensionManager() - self.ext_mgr.extensions = {} - self.controller = servers.Controller(self.ext_mgr) - - self.volume_id = 'fake' - - self.body = { - 'server': { - 'min_count': 2, - 'name': 'server_test', - 'imageRef': self.image_uuid, - 'flavorRef': self.flavor_ref, - 'metadata': { - 'hello': 'world', - 'open': 'stack', - }, - 'personality': [ - { - "path": "/etc/banner.txt", - "contents": "MQ==", - }, - ], - }, - } - - self.req = fakes.HTTPRequest.blank('/fake/servers') - self.req.method = 'POST' - self.req.headers["content-type"] = "application/json" - - def _test_create_extra(self, params, no_image=False): - self.body['server']['flavorRef'] = 2 - if no_image: - self.body['server'].pop('imageRef', None) - self.body['server'].update(params) - self.req.body = jsonutils.dump_as_bytes(self.body) - self.controller.create(self.req, self.body).obj['server'] - - @mock.patch.object(compute_api.API, 'create') - def test_create_instance_with_neutronv2_fixed_ip_already_in_use(self, - create_mock): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - address = '10.0.2.3' - requested_networks = [{'uuid': network, 'fixed_ip': address}] - params = {'networks': requested_networks} - create_mock.side_effect = exception.FixedIpAlreadyInUse( - address=address, - instance_uuid=network) - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, params) - self.assertEqual(1, len(create_mock.call_args_list)) - - @mock.patch.object(compute_api.API, 'create') - def test_create_instance_with_neutronv2_invalid_fixed_ip(self, - create_mock): - self.flags(use_neutron=True) - network = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - address = '999.0.2.3' - requested_networks = [{'uuid': network, 'fixed_ip': address}] - params = {'networks': requested_networks} - try: - self._test_create_extra(params) - self.fail() - except webob.exc.HTTPBadRequest as ex: - self.assertEqual('Invalid fixed IP address (%s)' % address, - ex.explanation) - self.assertFalse(create_mock.called) - - @mock.patch.object(compute_api.API, 'create', - side_effect=exception.InvalidVolume(reason='error')) - def test_create_instance_with_invalid_volume_error(self, create_mock): - # Tests that InvalidVolume is translated to a 400 error. - self.assertRaises(webob.exc.HTTPBadRequest, - self._test_create_extra, {}) - - -class ServersViewBuilderTest(test.TestCase): - - image_bookmark = "http://localhost/fake/images/5" - flavor_bookmark = "http://localhost/fake/flavors/1" - - def setUp(self): - super(ServersViewBuilderTest, self).setUp() - self.flags(use_ipv6=True) - db_inst = fakes.stub_instance( - id=1, - image_ref="5", - uuid="deadbeef-feed-edee-beef-d0ea7beefedd", - display_name="test_server", - include_fake_metadata=False) - - privates = ['172.19.0.1'] - publics = ['192.168.0.3'] - public6s = ['b33f::fdee:ddff:fecc:bbaa'] - - def nw_info(*args, **kwargs): - return [(None, {'label': 'public', - 'ips': [dict(ip=ip) for ip in publics], - 'ip6s': [dict(ip=ip) for ip in public6s]}), - (None, {'label': 'private', - 'ips': [dict(ip=ip) for ip in privates]})] - - fakes.stub_out_nw_api_get_instance_nw_info(self, nw_info) - - self.uuid = db_inst['uuid'] - self.view_builder = views.servers.ViewBuilder() - self.request = fakes.HTTPRequest.blank("/v2/fake") - self.request.context = context.RequestContext('fake', 'fake') - self.instance = fake_instance.fake_instance_obj( - self.request.context, - expected_attrs=instance_obj.INSTANCE_DEFAULT_FIELDS, - **db_inst) - self.self_link = "http://localhost/v2/fake/servers/%s" % self.uuid - self.bookmark_link = "http://localhost/fake/servers/%s" % self.uuid - self.expected_detailed_server = { - "server": { - "id": self.uuid, - "user_id": "fake_user", - "tenant_id": "fake_project", - "updated": "2010-11-11T11:00:00Z", - "created": "2010-10-10T12:00:00Z", - "progress": 0, - "name": "test_server", - "status": "BUILD", - "accessIPv4": "", - "accessIPv6": "", - "hostId": '', - "image": { - "id": "5", - "links": [ - { - "rel": "bookmark", - "href": self.image_bookmark, - }, - ], - }, - "flavor": { - "id": "1", - "links": [ - { - "rel": "bookmark", - "href": self.flavor_bookmark, - }, - ], - }, - "addresses": { - 'test1': [ - {'version': 4, 'addr': '192.168.1.100'}, - {'version': 6, 'addr': '2001:db8:0:1::1'} - ] - }, - "metadata": {}, - "links": [ - { - "rel": "self", - "href": self.self_link, - }, - { - "rel": "bookmark", - "href": self.bookmark_link, - }, - ], - } - } - - self.expected_server = { - "server": { - "id": self.uuid, - "name": "test_server", - "links": [ - { - "rel": "self", - "href": self.self_link, - }, - { - "rel": "bookmark", - "href": self.bookmark_link, - }, - ], - } - } - - def test_get_flavor_valid_flavor(self): - expected = {"id": "1", - "links": [{"rel": "bookmark", - "href": self.flavor_bookmark}]} - result = self.view_builder._get_flavor(self.request, self.instance) - self.assertEqual(expected, result) - - def test_build_server(self): - output = self.view_builder.basic(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_server)) - - def test_build_server_with_project_id(self): - - output = self.view_builder.basic(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_server)) - - def test_build_server_detail(self): - - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_detailed_server)) - - def test_build_server_no_image(self): - self.instance["image_ref"] = "" - output = self.view_builder.show(self.request, self.instance) - self.assertEqual("", output['server']['image']) - - def test_build_server_detail_with_fault(self): - self.instance['vm_state'] = vm_states.ERROR - self.instance['fault'] = fake_instance.fake_fault_obj( - self.request.context, self.uuid) - - self.expected_detailed_server["server"]["status"] = "ERROR" - self.expected_detailed_server["server"]["fault"] = { - "code": 404, - "created": "2010-10-10T12:00:00Z", - "message": "HTTPNotFound", - "details": "Stock details for test", - } - del self.expected_detailed_server["server"]["progress"] - - self.request.context = context.RequestContext('fake', 'fake') - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_detailed_server)) - - def test_build_server_detail_with_fault_that_has_been_deleted(self): - self.instance['deleted'] = 1 - self.instance['vm_state'] = vm_states.ERROR - fault = fake_instance.fake_fault_obj(self.request.context, - self.uuid, code=500, - message="No valid host was found") - self.instance['fault'] = fault - - # Regardless of the vm_state deleted servers sholud have DELETED status - self.expected_detailed_server["server"]["status"] = "DELETED" - self.expected_detailed_server["server"]["fault"] = { - "code": 500, - "created": "2010-10-10T12:00:00Z", - "message": "No valid host was found", - } - del self.expected_detailed_server["server"]["progress"] - - self.request.context = context.RequestContext('fake', 'fake') - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_detailed_server)) - - def test_build_server_detail_with_fault_no_details_not_admin(self): - self.instance['vm_state'] = vm_states.ERROR - self.instance['fault'] = fake_instance.fake_fault_obj( - self.request.context, - self.uuid, - code=500, - message='Error') - - expected_fault = {"code": 500, - "created": "2010-10-10T12:00:00Z", - "message": "Error"} - - self.request.context = context.RequestContext('fake', 'fake') - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output['server']['fault'], - matchers.DictMatches(expected_fault)) - - def test_build_server_detail_with_fault_admin(self): - self.instance['vm_state'] = vm_states.ERROR - self.instance['fault'] = fake_instance.fake_fault_obj( - self.request.context, - self.uuid, - code=500, - message='Error') - - expected_fault = {"code": 500, - "created": "2010-10-10T12:00:00Z", - "message": "Error", - 'details': 'Stock details for test'} - - self.request.environ['nova.context'].is_admin = True - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output['server']['fault'], - matchers.DictMatches(expected_fault)) - - def test_build_server_detail_with_fault_no_details_admin(self): - self.instance['vm_state'] = vm_states.ERROR - self.instance['fault'] = fake_instance.fake_fault_obj( - self.request.context, - self.uuid, - code=500, - message='Error', - details='') - - expected_fault = {"code": 500, - "created": "2010-10-10T12:00:00Z", - "message": "Error"} - - self.request.environ['nova.context'].is_admin = True - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output['server']['fault'], - matchers.DictMatches(expected_fault)) - - def test_build_server_detail_with_fault_but_active(self): - self.instance['vm_state'] = vm_states.ACTIVE - self.instance['progress'] = 100 - self.instance['fault'] = fake_instance.fake_fault_obj( - self.request.context, self.uuid) - - output = self.view_builder.show(self.request, self.instance) - self.assertNotIn('fault', output['server']) - - def test_build_server_detail_active_status(self): - # set the power state of the instance to running - self.instance['vm_state'] = vm_states.ACTIVE - self.instance['progress'] = 100 - - self.expected_detailed_server["server"]["status"] = "ACTIVE" - self.expected_detailed_server["server"]["progress"] = 100 - - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_detailed_server)) - - def test_build_server_detail_with_accessipv4(self): - - access_ip_v4 = '1.2.3.4' - self.instance['access_ip_v4'] = access_ip_v4 - - self.expected_detailed_server["server"]["accessIPv4"] = access_ip_v4 - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_detailed_server)) - - def test_build_server_detail_with_accessipv6(self): - - access_ip_v6 = 'fead::1234' - self.instance['access_ip_v6'] = access_ip_v6 - - self.expected_detailed_server["server"]["accessIPv6"] = access_ip_v6 - - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_detailed_server)) - - def test_build_server_detail_with_metadata(self): - - metadata = [] - metadata.append(models.InstanceMetadata(key="Open", value="Stack")) - metadata = nova_utils.metadata_to_dict(metadata) - self.instance['metadata'] = metadata - - self.expected_detailed_server["server"]["metadata"] = {"Open": "Stack"} - output = self.view_builder.show(self.request, self.instance) - self.assertThat(output, - matchers.DictMatches(self.expected_detailed_server)) diff --git a/nova/tests/unit/api/openstack/compute/test_api.py b/nova/tests/unit/api/openstack/compute/test_api.py index de8bf79966..2d0bf66152 100644 --- a/nova/tests/unit/api/openstack/compute/test_api.py +++ b/nova/tests/unit/api/openstack/compute/test_api.py @@ -13,7 +13,6 @@ # License for the specific language governing permissions and limitations # under the License. -import mock from oslo_serialization import jsonutils import six import webob @@ -21,7 +20,6 @@ import webob.dec import webob.exc from nova.api import openstack as openstack_api -from nova.api.openstack import extensions from nova.api.openstack import wsgi from nova import exception from nova import test @@ -35,12 +33,9 @@ class APITest(test.NoDBTestCase): @property def wsgi_app(self): - with mock.patch.object(extensions.ExtensionManager, 'load_extension'): - # patch load_extension because it's expensive in fakes.wsgi_app - return fakes.wsgi_app(init_only=('versions',)) + return fakes.wsgi_app_v21(init_only=('versions',)) def _wsgi_app(self, inner_app): - # simpler version of the app than fakes.wsgi_app return openstack_api.FaultWrapper(inner_app) def test_malformed_json(self): @@ -172,14 +167,3 @@ class APITest(test.NoDBTestCase): api = self._wsgi_app(fail) resp = webob.Request.blank('/').get_response(api) self.assertEqual(500, resp.status_int) - - -class APITestV21(APITest): - - @property - def wsgi_app(self): - return fakes.wsgi_app_v21(init_only=('versions',)) - - # TODO(alex_xu): Get rid of the case translate NovaException to - # HTTPException after V2 api code removed. Because V2.1 API required raise - # HTTPException explicitly, so V2.1 API needn't such translation. diff --git a/nova/tests/unit/api/openstack/compute/test_createserverext.py b/nova/tests/unit/api/openstack/compute/test_createserverext.py deleted file mode 100644 index 14e66ef137..0000000000 --- a/nova/tests/unit/api/openstack/compute/test_createserverext.py +++ /dev/null @@ -1,265 +0,0 @@ -# Copyright 2010-2011 OpenStack Foundation -# All Rights Reserved. -# -# 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 base64 - -from oslo_serialization import jsonutils -import webob - -from nova.compute import api as compute_api -from nova import exception -from nova import test -from nova.tests.unit.api.openstack import fakes -from nova.tests import uuidsentinel as uuids - -FAKE_UUID = fakes.FAKE_UUID - -FAKE_NETWORKS = [('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', '10.0.1.12'), - ('bbbbbbbb-bbbb-bbbb-bbbb-bbbbbbbbbbbb', '10.0.2.12')] - -DUPLICATE_NETWORKS = [('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', '10.0.1.12'), - ('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', '10.0.1.12')] - -INVALID_NETWORKS = [('invalid', 'invalid-ip-address')] - - -def return_security_group_non_existing(context, project_id, group_name): - raise exception.SecurityGroupNotFoundForProject(project_id=project_id, - security_group_id=group_name) - - -def return_security_group_get_by_name(context, project_id, group_name): - return {'id': 1, 'name': group_name} - - -def return_security_group_get(context, security_group_id, session): - return {'id': security_group_id} - - -def return_instance_add_security_group(context, instance_id, - security_group_id): - pass - - -class CreateserverextTest(test.TestCase): - def setUp(self): - super(CreateserverextTest, self).setUp() - - self.security_group = None - self.injected_files = None - self.networks = None - self.user_data = None - - def create(*args, **kwargs): - if 'security_group' in kwargs: - self.security_group = kwargs['security_group'] - else: - self.security_group = None - if 'injected_files' in kwargs: - self.injected_files = kwargs['injected_files'] - else: - self.injected_files = None - - if 'requested_networks' in kwargs: - self.networks = kwargs['requested_networks'] - else: - self.networks = None - - if 'user_data' in kwargs: - self.user_data = kwargs['user_data'] - - resv_id = None - - return ([{'id': '1234', 'display_name': 'fakeinstance', - 'uuid': FAKE_UUID, - 'user_id': 'fake', - 'project_id': 'fake', - 'created_at': "", - 'updated_at': "", - 'fixed_ips': [], - 'progress': 0}], resv_id) - - self.stubs.Set(compute_api.API, 'create', create) - self.flags( - osapi_compute_extension=[ - 'nova.api.openstack.compute.contrib.select_extensions'], - osapi_compute_ext_list=['Createserverext', 'User_data', - 'Security_groups', 'Os_networks']) - - def _create_security_group_request_dict(self, security_groups): - server = {} - server['name'] = 'new-server-test' - server['imageRef'] = 'cedef40a-ed67-4d10-800e-17455edce175' - server['flavorRef'] = 1 - if security_groups is not None: - sg_list = [] - for name in security_groups: - sg_list.append({'name': name}) - server['security_groups'] = sg_list - return {'server': server} - - def _create_networks_request_dict(self, networks): - server = {} - server['name'] = 'new-server-test' - server['imageRef'] = 'cedef40a-ed67-4d10-800e-17455edce175' - server['flavorRef'] = 1 - if networks is not None: - network_list = [] - for uuid, fixed_ip in networks: - network_list.append({'uuid': uuid, 'fixed_ip': fixed_ip}) - server['networks'] = network_list - return {'server': server} - - def _create_user_data_request_dict(self, user_data): - server = {} - server['name'] = 'new-server-test' - server['imageRef'] = 'cedef40a-ed67-4d10-800e-17455edce175' - server['flavorRef'] = 1 - server['user_data'] = user_data - return {'server': server} - - def _get_create_request_json(self, body_dict): - req = webob.Request.blank('/v2/fake/os-create-server-ext') - req.headers['Content-Type'] = 'application/json' - req.method = 'POST' - req.body = jsonutils.dump_as_bytes(body_dict) - return req - - def _create_instance_with_networks_json(self, networks): - body_dict = self._create_networks_request_dict(networks) - request = self._get_create_request_json(body_dict) - response = request.get_response(fakes.wsgi_app( - init_only=('servers', 'os-create-server-ext'))) - return request, response, self.networks - - def _create_instance_with_user_data_json(self, networks): - body_dict = self._create_user_data_request_dict(networks) - request = self._get_create_request_json(body_dict) - response = request.get_response(fakes.wsgi_app( - init_only=('servers', 'os-create-server-ext'))) - return request, response, self.user_data - - def test_create_instance_with_no_networks(self): - _create_inst = self._create_instance_with_networks_json - request, response, networks = _create_inst(networks=None) - self.assertEqual(response.status_int, 202) - self.assertIsNone(networks) - - def test_create_instance_with_one_network(self): - _create_inst = self._create_instance_with_networks_json - request, response, networks = _create_inst([FAKE_NETWORKS[0]]) - self.assertEqual(response.status_int, 202) - self.assertEqual([FAKE_NETWORKS[0]], networks.as_tuples()) - - def test_create_instance_with_two_networks(self): - _create_inst = self._create_instance_with_networks_json - request, response, networks = _create_inst(FAKE_NETWORKS) - self.assertEqual(response.status_int, 202) - self.assertEqual(FAKE_NETWORKS, networks.as_tuples()) - - def test_create_instance_with_duplicate_networks(self): - _create_inst = self._create_instance_with_networks_json - request, response, networks = _create_inst(DUPLICATE_NETWORKS) - self.assertEqual(response.status_int, 400) - self.assertIsNone(networks) - - def test_create_instance_with_network_no_id(self): - body_dict = self._create_networks_request_dict([FAKE_NETWORKS[0]]) - del body_dict['server']['networks'][0]['uuid'] - request = self._get_create_request_json(body_dict) - response = request.get_response(fakes.wsgi_app( - init_only=('servers', 'os-create-server-ext'))) - self.assertEqual(response.status_int, 400) - self.assertIsNone(self.networks) - - def test_create_instance_with_network_invalid_id(self): - _create_inst = self._create_instance_with_networks_json - request, response, networks = _create_inst(INVALID_NETWORKS) - self.assertEqual(response.status_int, 400) - self.assertIsNone(networks) - - def test_create_instance_with_network_empty_fixed_ip(self): - networks = [('1', '')] - _create_inst = self._create_instance_with_networks_json - request, response, networks = _create_inst(networks) - self.assertEqual(response.status_int, 400) - self.assertIsNone(networks) - - def test_create_instance_with_network_non_string_fixed_ip(self): - networks = [('1', 12345)] - _create_inst = self._create_instance_with_networks_json - request, response, networks = _create_inst(networks) - self.assertEqual(response.status_int, 400) - self.assertIsNone(networks) - - def test_create_instance_with_network_no_fixed_ip(self): - body_dict = self._create_networks_request_dict([FAKE_NETWORKS[0]]) - del body_dict['server']['networks'][0]['fixed_ip'] - request = self._get_create_request_json(body_dict) - response = request.get_response(fakes.wsgi_app( - init_only=('servers', 'os-create-server-ext'))) - self.assertEqual(response.status_int, 202) - self.assertEqual([('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', None)], - self.networks.as_tuples()) - - def test_create_instance_with_userdata(self): - user_data_contents = '#!/bin/bash\necho "Oh no!"\n' - user_data_contents = base64.b64encode(user_data_contents) - _create_inst = self._create_instance_with_user_data_json - request, response, user_data = _create_inst(user_data_contents) - self.assertEqual(response.status_int, 202) - self.assertEqual(user_data, user_data_contents) - - def test_create_instance_with_userdata_none(self): - user_data_contents = None - _create_inst = self._create_instance_with_user_data_json - request, response, user_data = _create_inst(user_data_contents) - self.assertEqual(response.status_int, 202) - self.assertEqual(user_data, user_data_contents) - - def test_create_instance_with_userdata_with_non_b64_content(self): - user_data_contents = '#!/bin/bash\necho "Oh no!"\n' - _create_inst = self._create_instance_with_user_data_json - request, response, user_data = _create_inst(user_data_contents) - self.assertEqual(response.status_int, 400) - self.assertIsNone(user_data) - - def test_create_instance_with_security_group_json(self): - security_groups = ['test', 'test1'] - self.stub_out('nova.db.security_group_get_by_name', - return_security_group_get_by_name) - self.stub_out('nova.db.instance_add_security_group', - return_instance_add_security_group) - body_dict = self._create_security_group_request_dict(security_groups) - request = self._get_create_request_json(body_dict) - response = request.get_response(fakes.wsgi_app( - init_only=('servers', 'os-create-server-ext'))) - self.assertEqual(response.status_int, 202) - self.assertJsonEqual(self.security_group, security_groups) - - def test_get_server_by_id_verify_security_groups_json(self): - self.stub_out('nova.db.instance_get', fakes.fake_instance_get()) - self.stub_out('nova.db.instance_get_by_uuid', - fakes.fake_instance_get()) - req = webob.Request.blank('/v2/fake/os-create-server-ext/' + - uuids.server) - req.headers['Content-Type'] = 'application/json' - response = req.get_response(fakes.wsgi_app( - init_only=('os-create-server-ext', 'servers'))) - self.assertEqual(response.status_int, 200) - res_dict = jsonutils.loads(response.body) - expected_security_group = [{"name": "test"}] - self.assertEqual(res_dict['server'].get('security_groups'), - expected_security_group) diff --git a/nova/tests/unit/api/openstack/compute/test_extended_availability_zone.py b/nova/tests/unit/api/openstack/compute/test_extended_availability_zone.py index 0f9c6fae15..1c1d64a9a2 100644 --- a/nova/tests/unit/api/openstack/compute/test_extended_availability_zone.py +++ b/nova/tests/unit/api/openstack/compute/test_extended_availability_zone.py @@ -149,20 +149,3 @@ class ExtendedAvailabilityZoneTestV21(test.TestCase): res = self._make_request(url) self.assertEqual(res.status_int, 404) - - -class ExtendedAvailabilityZoneTestV2(ExtendedAvailabilityZoneTestV21): - - def setUp(self): - super(ExtendedAvailabilityZoneTestV2, self).setUp() - - self.flags( - osapi_compute_extension=[ - 'nova.api.openstack.compute.contrib.select_extensions'], - osapi_compute_ext_list=['Extended_availability_zone']) - - def _make_request(self, url): - req = webob.Request.blank(url) - req.headers['Accept'] = self.content_type - res = req.get_response(fakes.wsgi_app(init_only=('servers',))) - return res diff --git a/nova/tests/unit/api/openstack/compute/test_extended_ips.py b/nova/tests/unit/api/openstack/compute/test_extended_ips.py index ee53e6a420..b2b176c5d0 100644 --- a/nova/tests/unit/api/openstack/compute/test_extended_ips.py +++ b/nova/tests/unit/api/openstack/compute/test_extended_ips.py @@ -147,19 +147,3 @@ class ExtendedIpsTestV21(test.TestCase): self.assertEqual(res.status_int, 200) for i, server in enumerate(self._get_servers(res.body)): self.assertServerStates(server) - - -class ExtendedIpsTestV2(ExtendedIpsTestV21): - - def setUp(self): - super(ExtendedIpsTestV2, self).setUp() - self.flags( - osapi_compute_extension=[ - 'nova.api.openstack.compute.contrib.select_extensions'], - osapi_compute_ext_list=['Extended_ips']) - - def _make_request(self, url): - req = webob.Request.blank(url) - req.headers['Accept'] = self.content_type - res = req.get_response(fakes.wsgi_app(init_only=('servers',))) - return res diff --git a/nova/tests/unit/api/openstack/compute/test_extended_server_attributes.py b/nova/tests/unit/api/openstack/compute/test_extended_server_attributes.py index 834044fbcd..0a5517d08d 100644 --- a/nova/tests/unit/api/openstack/compute/test_extended_server_attributes.py +++ b/nova/tests/unit/api/openstack/compute/test_extended_server_attributes.py @@ -15,7 +15,6 @@ from oslo_config import cfg from oslo_serialization import jsonutils -import webob from nova.api.openstack import wsgi as os_wsgi from nova import compute @@ -142,22 +141,6 @@ class ExtendedServerAttributesTestV21(test.TestCase): self.assertEqual(res.status_int, 404) -class ExtendedServerAttributesTestV2(ExtendedServerAttributesTestV21): - - def setUp(self): - super(ExtendedServerAttributesTestV2, self).setUp() - self.flags( - osapi_compute_extension=[ - 'nova.api.openstack.compute.contrib.select_extensions'], - osapi_compute_ext_list=['Extended_server_attributes']) - - def _make_request(self, url): - req = webob.Request.blank(url) - req.headers['Accept'] = self.content_type - res = req.get_response(fakes.wsgi_app(init_only=('servers',))) - return res - - class ExtendedServerAttributesTestV23(ExtendedServerAttributesTestV21): wsgi_api_version = '2.3' diff --git a/nova/tests/unit/api/openstack/compute/test_extended_status.py b/nova/tests/unit/api/openstack/compute/test_extended_status.py index b5888941ad..44780d9b33 100644 --- a/nova/tests/unit/api/openstack/compute/test_extended_status.py +++ b/nova/tests/unit/api/openstack/compute/test_extended_status.py @@ -117,18 +117,3 @@ class ExtendedStatusTestV21(test.TestCase): res = self._make_request(url) self.assertEqual(res.status_int, 404) - - -class ExtendedStatusTestV2(ExtendedStatusTestV21): - - def _set_flags(self): - self.flags( - osapi_compute_extension=[ - 'nova.api.openstack.compute.contrib.select_extensions'], - osapi_compute_ext_list=['Extended_status']) - - def _make_request(self, url): - req = webob.Request.blank(url) - req.headers['Accept'] = self.content_type - res = req.get_response(fakes.wsgi_app(init_only=('servers',))) - return res diff --git a/nova/tests/unit/api/openstack/compute/test_extended_volumes.py b/nova/tests/unit/api/openstack/compute/test_extended_volumes.py index 9f34a7a257..5922d6cd44 100644 --- a/nova/tests/unit/api/openstack/compute/test_extended_volumes.py +++ b/nova/tests/unit/api/openstack/compute/test_extended_volumes.py @@ -148,18 +148,6 @@ class ExtendedVolumesTestV21(test.TestCase): self.assertEqual(self.exp_volumes_detail[i], actual) -class ExtendedVolumesTestV2(ExtendedVolumesTestV21): - - def _setup_app(self): - return fakes.wsgi_app(init_only=('servers',)) - - def _setUp(self): - self.flags( - osapi_compute_extension=['nova.api.openstack.compute.' - 'contrib.select_extensions'], - osapi_compute_ext_list=['Extended_volumes']) - - class ExtendedVolumesTestV23(ExtendedVolumesTestV21): exp_volumes_show = [ diff --git a/nova/tests/unit/api/openstack/compute/test_flavor_disabled.py b/nova/tests/unit/api/openstack/compute/test_flavor_disabled.py index 4bf70bdc97..062e99225b 100644 --- a/nova/tests/unit/api/openstack/compute/test_flavor_disabled.py +++ b/nova/tests/unit/api/openstack/compute/test_flavor_disabled.py @@ -103,12 +103,3 @@ class FlavorDisabledTestV21(test.NoDBTestCase): flavors = self._get_flavors(res.body) self.assertFlavorDisabled(flavors[0], 'False') self.assertFlavorDisabled(flavors[1], 'True') - - -class FlavorDisabledTestV2(FlavorDisabledTestV21): - - def _make_request(self, url): - req = webob.Request.blank(url) - req.headers['Accept'] = self.content_type - res = req.get_response(fakes.wsgi_app(init_only=('flavors',))) - return res diff --git a/nova/tests/unit/api/openstack/compute/test_flavor_rxtx.py b/nova/tests/unit/api/openstack/compute/test_flavor_rxtx.py index 87663907c4..c987fb2d10 100644 --- a/nova/tests/unit/api/openstack/compute/test_flavor_rxtx.py +++ b/nova/tests/unit/api/openstack/compute/test_flavor_rxtx.py @@ -108,9 +108,3 @@ class FlavorRxtxTestV21(test.NoDBTestCase): flavors = self._get_flavors(res.body) self.assertFlavorRxtx(flavors[0], '1.0') self.assertFlavorRxtx(flavors[1], '') - - -class FlavorRxtxTestV20(FlavorRxtxTestV21): - - def _get_app(self): - return fakes.wsgi_app(init_only=('flavors',)) diff --git a/nova/tests/unit/api/openstack/compute/test_flavor_swap.py b/nova/tests/unit/api/openstack/compute/test_flavor_swap.py index 8fb0859329..b2ea13687d 100644 --- a/nova/tests/unit/api/openstack/compute/test_flavor_swap.py +++ b/nova/tests/unit/api/openstack/compute/test_flavor_swap.py @@ -104,12 +104,3 @@ class FlavorSwapTestV21(test.NoDBTestCase): flavors = self._get_flavors(res.body) self.assertFlavorSwap(flavors[0], '512') self.assertFlavorSwap(flavors[1], '') - - -class FlavorSwapTestV2(FlavorSwapTestV21): - - def _make_request(self, url): - req = webob.Request.blank(url) - req.headers['Accept'] = self.content_type - res = req.get_response(fakes.wsgi_app(init_only=('flavors',))) - return res diff --git a/nova/tests/unit/api/openstack/compute/test_flavorextradata.py b/nova/tests/unit/api/openstack/compute/test_flavorextradata.py index b584e4b315..33f7a4cfb2 100644 --- a/nova/tests/unit/api/openstack/compute/test_flavorextradata.py +++ b/nova/tests/unit/api/openstack/compute/test_flavorextradata.py @@ -119,10 +119,3 @@ class FlavorExtraDataTestV21(test.NoDBTestCase): body = jsonutils.loads(res.body) for i, flavor in enumerate(body['flavors']): self._verify_flavor_response(flavor, expected[i]) - - -class FlavorExtraDataTestV2(FlavorExtraDataTestV21): - - @property - def app(self): - return fakes.wsgi_app(init_only=('flavors',)) diff --git a/nova/tests/unit/api/openstack/compute/test_hide_server_addresses.py b/nova/tests/unit/api/openstack/compute/test_hide_server_addresses.py index fd7a0d45a3..24cc0956be 100644 --- a/nova/tests/unit/api/openstack/compute/test_hide_server_addresses.py +++ b/nova/tests/unit/api/openstack/compute/test_hide_server_addresses.py @@ -137,13 +137,3 @@ class HideServerAddressesTestV21(test.TestCase): res = self._make_request(self.base_url + '/' + fakes.get_fake_uuid()) self.assertEqual(res.status_int, 404) - - -class HideServerAddressesTestV2(HideServerAddressesTestV21): - - def _setup_wsgi(self): - self.flags( - osapi_compute_extension=[ - 'nova.api.openstack.compute.contrib.select_extensions'], - osapi_compute_ext_list=['Hide_server_addresses']) - self.wsgi_app = fakes.wsgi_app(init_only=('servers',)) diff --git a/nova/tests/unit/api/openstack/compute/test_image_size.py b/nova/tests/unit/api/openstack/compute/test_image_size.py index 381181adab..6b921fc3c9 100644 --- a/nova/tests/unit/api/openstack/compute/test_image_size.py +++ b/nova/tests/unit/api/openstack/compute/test_image_size.py @@ -116,8 +116,3 @@ class ImageSizeTestV21(test.NoDBTestCase): images = self._get_images(res.body) self.assertImageSize(images[0], 12345678) self.assertImageSize(images[1], 87654321) - - -class ImageSizeTestV2(ImageSizeTestV21): - def _get_app(self): - return fakes.wsgi_app(init_only=('images',)) diff --git a/nova/tests/unit/api/openstack/compute/test_server_usage.py b/nova/tests/unit/api/openstack/compute/test_server_usage.py index 34a090763b..2ff5ebe280 100644 --- a/nova/tests/unit/api/openstack/compute/test_server_usage.py +++ b/nova/tests/unit/api/openstack/compute/test_server_usage.py @@ -130,16 +130,3 @@ class ServerUsageTestV21(test.TestCase): res = self._make_request(url) self.assertEqual(res.status_int, 404) - - -class ServerUsageTestV20(ServerUsageTestV21): - - def setUp(self): - super(ServerUsageTestV20, self).setUp() - self.flags( - osapi_compute_extension=[ - 'nova.api.openstack.compute.contrib.select_extensions'], - osapi_compute_ext_list=['Server_usage']) - - def _get_app(self): - return fakes.wsgi_app(init_only=('servers',)) diff --git a/nova/tests/unit/api/openstack/compute/test_urlmap.py b/nova/tests/unit/api/openstack/compute/test_urlmap.py index 0e1732a9bc..751450aa64 100644 --- a/nova/tests/unit/api/openstack/compute/test_urlmap.py +++ b/nova/tests/unit/api/openstack/compute/test_urlmap.py @@ -35,7 +35,8 @@ class UrlmapTest(test.NoDBTestCase): # Test URL path specifying v2 returns v2 content. req = webob.Request.blank('/v2/') req.accept = "application/json" - res = req.get_response(fakes.wsgi_app(init_only=('versions',))) + res = req.get_response(fakes.wsgi_app_v21(init_only=('versions',), + v2_compatible=True)) self.assertEqual(200, res.status_int) self.assertEqual("application/json", res.content_type) body = jsonutils.loads(res.body) @@ -46,7 +47,8 @@ class UrlmapTest(test.NoDBTestCase): req = webob.Request.blank('/') req.content_type = "application/json;version=2" req.accept = "application/json" - res = req.get_response(fakes.wsgi_app(init_only=('versions',))) + res = req.get_response(fakes.wsgi_app_v21(init_only=('versions',), + v2_compatible=True)) self.assertEqual(200, res.status_int) self.assertEqual("application/json", res.content_type) body = jsonutils.loads(res.body) @@ -56,7 +58,8 @@ class UrlmapTest(test.NoDBTestCase): # Test Accept header specifying v2 returns v2 content. req = webob.Request.blank('/') req.accept = "application/json;version=2" - res = req.get_response(fakes.wsgi_app(init_only=('versions',))) + res = req.get_response(fakes.wsgi_app_v21(init_only=('versions',), + v2_compatible=True)) self.assertEqual(200, res.status_int) self.assertEqual("application/json", res.content_type) body = jsonutils.loads(res.body) @@ -67,7 +70,7 @@ class UrlmapTest(test.NoDBTestCase): url = '/v2/fake/images/cedef40a-ed67-4d10-800e-17455edce175.json' req = webob.Request.blank(url) req.accept = "application/xml" - res = req.get_response(fakes.wsgi_app(init_only=('images',))) + res = req.get_response(fakes.wsgi_app_v21(init_only=('images',))) self.assertEqual(200, res.status_int) self.assertEqual("application/json", res.content_type) body = jsonutils.loads(res.body) @@ -79,7 +82,7 @@ class UrlmapTest(test.NoDBTestCase): url = '/v2/fake/images/cedef40a-ed67-4d10-800e-17455edce175' req = webob.Request.blank(url) req.accept = "application/xml;q=0.8, application/json" - res = req.get_response(fakes.wsgi_app(init_only=('images',))) + res = req.get_response(fakes.wsgi_app_v21(init_only=('images',))) self.assertEqual(200, res.status_int) self.assertEqual("application/json", res.content_type) body = jsonutils.loads(res.body) diff --git a/nova/tests/unit/api/openstack/compute/test_versions.py b/nova/tests/unit/api/openstack/compute/test_versions.py index 7b28565efa..3c5929c83c 100644 --- a/nova/tests/unit/api/openstack/compute/test_versions.py +++ b/nova/tests/unit/api/openstack/compute/test_versions.py @@ -16,13 +16,11 @@ import copy import uuid as stdlib_uuid -import mock from oslo_serialization import jsonutils import webob from nova.api.openstack import api_version_request as avr from nova.api.openstack.compute import views -from nova.api.openstack import extensions from nova import test from nova.tests.unit.api.openstack import fakes from nova.tests.unit import matchers @@ -103,13 +101,11 @@ def _get_self_href(response): return '' -class VersionsTestV20(test.NoDBTestCase): +class VersionsTestV21WithV2CompatibleWrapper(test.NoDBTestCase): @property def wsgi_app(self): - with mock.patch.object(extensions.ExtensionManager, 'load_extension'): - # patch load_extension because it's expensive in fakes.wsgi_app - return fakes.wsgi_app(init_only=('servers', 'images', 'versions')) + return fakes.wsgi_app_v21(v2_compatible=True, init_only=('versions',)) def test_get_version_list(self): req = webob.Request.blank('/') @@ -517,9 +513,7 @@ class VersionBehindSslTestCase(test.NoDBTestCase): @property def wsgi_app(self): - with mock.patch.object(extensions.ExtensionManager, 'load_extension'): - # patch load_extension because it's expensive in fakes.wsgi_app - return fakes.wsgi_app(init_only=('versions',)) + return fakes.wsgi_app_v21(v2_compatible=True, init_only=('versions',)) def test_versions_without_headers(self): req = wsgi.Request.blank('/') @@ -537,10 +531,3 @@ class VersionBehindSslTestCase(test.NoDBTestCase): self.assertEqual(200, res.status_int) href = _get_self_href(res) self.assertTrue(href.startswith('https://')) - - -class VersionsTestV21WithV2CompatibleWrapper(VersionsTestV20): - - @property - def wsgi_app(self): - return fakes.wsgi_app_v21(v2_compatible=True, init_only=('versions',)) diff --git a/nova/tests/unit/api/openstack/fakes.py b/nova/tests/unit/api/openstack/fakes.py index 372d94c192..44f3c0abc0 100644 --- a/nova/tests/unit/api/openstack/fakes.py +++ b/nova/tests/unit/api/openstack/fakes.py @@ -65,28 +65,6 @@ def fake_wsgi(self, req): return self.application -def wsgi_app(inner_app_v2=None, fake_auth_context=None, - use_no_auth=False, ext_mgr=None, init_only=None): - if not inner_app_v2: - inner_app_v2 = compute.APIRouter(ext_mgr, init_only) - - if use_no_auth: - api_v2 = openstack_api.FaultWrapper(auth.NoAuthMiddleware( - limits.RateLimitingMiddleware(inner_app_v2))) - else: - if fake_auth_context is not None: - ctxt = fake_auth_context - else: - ctxt = context.RequestContext('fake', 'fake', auth_token=True) - api_v2 = openstack_api.FaultWrapper(api_auth.InjectContext(ctxt, - limits.RateLimitingMiddleware(inner_app_v2))) - - mapper = urlmap.URLMap() - mapper['/v2'] = api_v2 - mapper['/'] = openstack_api.FaultWrapper(versions.Versions()) - return mapper - - def wsgi_app_v21(inner_app_v21=None, fake_auth_context=None, use_no_auth=False, ext_mgr=None, init_only=None, v2_compatible=False): if not inner_app_v21: