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: