diff options
| author | Chris Behrens <cbehrens@codestud.com> | 2012-02-17 00:42:10 +0000 |
|---|---|---|
| committer | Chris Behrens <cbehrens@codestud.com> | 2012-02-22 23:36:50 +0000 |
| commit | 08fa534a0d28fa1be48aef927584161becb936c7 (patch) | |
| tree | d872447d9d266df831c0f077afd09a3bd5e90d32 | |
| parent | 9196e1c7b07be8d3f9dbe7947cace9fd4e862f9c (diff) | |
| download | nova-08fa534a0d28fa1be48aef927584161becb936c7.tar.gz nova-08fa534a0d28fa1be48aef927584161becb936c7.tar.xz nova-08fa534a0d28fa1be48aef927584161becb936c7.zip | |
Remove network_api fallback for info_cache from APIs
Fixes bug 932395
OS API and EC2 would query the network API when instance['info_cache']
had no network info.. or network info was an empty list. The ideal was
to fall back to querying the network IP in case the cache was busted.
However, reality says this case is extremely common as it is the case
when instances are freshly built and haven't had network info assigned
yet. The calls to network API are expensive and goes against the whole
idea of this "cache".
So, this patch removes the fallback to querying the network API. In its
place, it adds a periodic task to the compute manager to periodically
sync the cache entry.
Since I had to fix a number of tests, I consolidated some things there
as well with regards to instance stubbing.
Change-Id: I493f811bcba4e99ac6a5756bcab473557d5c0104
| -rw-r--r-- | nova/api/ec2/ec2utils.py | 32 | ||||
| -rw-r--r-- | nova/api/openstack/common.py | 32 | ||||
| -rw-r--r-- | nova/compute/manager.py | 58 | ||||
| -rw-r--r-- | nova/tests/api/openstack/compute/contrib/test_createserverext.py | 38 | ||||
| -rw-r--r-- | nova/tests/api/openstack/compute/test_server_actions.py | 95 | ||||
| -rw-r--r-- | nova/tests/api/openstack/compute/test_servers.py | 375 | ||||
| -rw-r--r-- | nova/tests/api/openstack/fakes.py | 70 | ||||
| -rw-r--r-- | nova/tests/api/openstack/test_common.py | 10 | ||||
| -rw-r--r-- | nova/tests/test_compute.py | 91 | ||||
| -rw-r--r-- | nova/tests/test_metadata.py | 1 |
10 files changed, 332 insertions, 470 deletions
diff --git a/nova/api/ec2/ec2utils.py b/nova/api/ec2/ec2utils.py index d0e9e81d9..e0f336d4c 100644 --- a/nova/api/ec2/ec2utils.py +++ b/nova/api/ec2/ec2utils.py @@ -83,33 +83,15 @@ def get_ip_info_for_instance_from_nw_info(nw_info): return ip_info -def get_ip_info_for_instance_from_cache(instance): - if (not instance.get('info_cache') or - not instance['info_cache'].get('network_info')): - # NOTE(jkoelker) Raising ValueError so that we trigger the - # fallback lookup - raise ValueError - - cached_info = instance['info_cache']['network_info'] - nw_info = network_model.NetworkInfo.hydrate(cached_info) - - return get_ip_info_for_instance_from_nw_info(nw_info) - - def get_ip_info_for_instance(context, instance): - """Return a list of all fixed IPs for an instance""" + """Return a dictionary of IP information for an instance""" - try: - return get_ip_info_for_instance_from_cache(instance) - except (ValueError, KeyError, AttributeError): - # NOTE(jkoelker) If the json load (ValueError) or the - # sqlalchemy FK (KeyError, AttributeError) - # fail fall back to calling out to he - # network api - network_api = network.API() - - nw_info = network_api.get_instance_nw_info(context, instance) - return get_ip_info_for_instance_from_nw_info(nw_info) + cached_nwinfo = instance['info_cache']['network_info'] + # Make sure empty response is turned into [] + if not cached_nwinfo: + cached_nwinfo = [] + nw_info = network_model.NetworkInfo.hydrate(cached_nwinfo) + return get_ip_info_for_instance_from_nw_info(nw_info) def get_availability_zone_by_host(services, host): diff --git a/nova/api/openstack/common.py b/nova/api/openstack/common.py index 4305de950..575c58fac 100644 --- a/nova/api/openstack/common.py +++ b/nova/api/openstack/common.py @@ -304,18 +304,6 @@ def get_networks_for_instance_from_nw_info(nw_info): return networks -def get_networks_for_instance_from_cache(instance): - if (not instance.get('info_cache') or - not instance['info_cache'].get('network_info')): - # NOTE(jkoelker) Raising ValueError so that we trigger the - # fallback lookup - raise ValueError - - cached_info = instance['info_cache']['network_info'] - nw_info = network_model.NetworkInfo.hydrate(cached_info) - return get_networks_for_instance_from_nw_info(nw_info) - - def get_networks_for_instance(context, instance): """Returns a prepared nw_info list for passing into the view builders @@ -328,22 +316,10 @@ def get_networks_for_instance(context, instance): ...} """ - try: - return get_networks_for_instance_from_cache(instance) - except (ValueError, KeyError, AttributeError): - # NOTE(jkoelker) If the json load (ValueError) or the - # sqlalchemy FK (KeyError, AttributeError) - # fail fall back to calling out the the - # network api - pass - - network_api = network.API() - - try: - nw_info = network_api.get_instance_nw_info(context, instance) - except exception.InstanceNotFound: - nw_info = [] - + cached_nwinfo = instance['info_cache']['network_info'] + if not cached_nwinfo: + return {} + nw_info = network_model.NetworkInfo.hydrate(cached_nwinfo) return get_networks_for_instance_from_nw_info(nw_info) diff --git a/nova/compute/manager.py b/nova/compute/manager.py index fa02447c7..77452ee94 100644 --- a/nova/compute/manager.py +++ b/nova/compute/manager.py @@ -118,6 +118,10 @@ compute_opts = [ default=3600, help="Number of periodic scheduler ticks to wait between " "runs of the image cache manager."), + cfg.IntOpt("heal_instance_info_cache_interval", + default=60, + help="Number of seconds between instance info_cache self " + "healing updates") ] FLAGS = flags.FLAGS @@ -205,6 +209,7 @@ class ComputeManager(manager.SchedulerDependentManager): self.network_manager = utils.import_object(FLAGS.network_manager) self._last_host_check = 0 self._last_bw_usage_poll = 0 + self._last_info_cache_heal = 0 super(ComputeManager, self).__init__(service_name="compute", *args, **kwargs) @@ -2088,6 +2093,59 @@ class ComputeManager(manager.SchedulerDependentManager): block_device_info) @manager.periodic_task + def _heal_instance_info_cache(self, context): + """Called periodically. On every call, try to update the + info_cache's network information for another instance by + calling to the network manager. + + This is implemented by keeping a cache of uuids of instances + that live on this host. On each call, we pop one off of a + list, pull the DB record, and try the call to the network API. + If anything errors, we don't care. It's possible the instance + has been deleted, etc. + """ + heal_interval = FLAGS.heal_instance_info_cache_interval + if not heal_interval: + return + curr_time = time.time() + if self._last_info_cache_heal + heal_interval > curr_time: + return + self._last_info_cache_heal = curr_time + + instance_uuids = getattr(self, '_instance_uuids_to_heal', None) + instance = None + + while not instance or instance['host'] != self.host: + if instance_uuids: + try: + instance = self.db.instance_get_by_uuid(context, + instance_uuids.pop(0)) + except exception.InstanceNotFound: + # Instance is gone. Try to grab another. + continue + else: + # No more in our copy of uuids. Pull from the DB. + db_instances = self.db.instance_get_all_by_host( + context, self.host) + if not db_instances: + # None.. just return. + return + instance = db_instances.pop(0) + instance_uuids = [inst['uuid'] for inst in db_instances] + self._instance_uuids_to_heal = instance_uuids + + # We have an instance now and it's ours + try: + # Call to network API to get instance info.. this will + # force an update to the instance's info_cache + self.network_api.get_instance_nw_info(context, instance) + LOG.debug(_("Updated the info_cache for instance %s") % + instance['uuid']) + except Exception: + # We don't care about any failures + pass + + @manager.periodic_task def _poll_rebooting_instances(self, context): if FLAGS.reboot_timeout > 0: self.driver.poll_rebooting_instances(FLAGS.reboot_timeout) diff --git a/nova/tests/api/openstack/compute/contrib/test_createserverext.py b/nova/tests/api/openstack/compute/contrib/test_createserverext.py index 1e2266f87..e78f8cfd1 100644 --- a/nova/tests/api/openstack/compute/contrib/test_createserverext.py +++ b/nova/tests/api/openstack/compute/contrib/test_createserverext.py @@ -16,7 +16,6 @@ # under the License. import base64 -import datetime import json from xml.dom import minidom @@ -32,7 +31,7 @@ from nova.tests.api.openstack import fakes FLAGS = flags.FLAGS -FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' +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')] @@ -42,27 +41,6 @@ DUPLICATE_NETWORKS = [('aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa', '10.0.1.12'), INVALID_NETWORKS = [('invalid', 'invalid-ip-address')] -INSTANCE = { - "id": 1, - "name": "fake", - "display_name": "test_server", - "uuid": FAKE_UUID, - "user_id": 'fake_user_id', - "tenant_id": 'fake_tenant_id', - "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), - "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), - "security_groups": [{"id": 1, "name": "test"}], - "progress": 0, - "image_ref": 'http://foo.com/123', - "fixed_ips": [], - "instance_type": {"flavorid": '124'}, - } - - -def return_server_by_id(context, id, session=None): - INSTANCE['id'] = id - return INSTANCE - def return_security_group_non_existing(context, project_id, group_name): raise exception.SecurityGroupNotFoundForProject(project_id=project_id, @@ -138,9 +116,6 @@ class CreateserverextTest(test.TestCase): self._make_stub_method(compute_api)) return compute_api - def _setup_mock_network_api(self): - fakes.stub_out_nw_api(self.stubs) - def _create_security_group_request_dict(self, security_groups): server = {} server['name'] = 'new-server-test' @@ -182,7 +157,6 @@ class CreateserverextTest(test.TestCase): def _run_create_instance_with_mock_compute_api(self, request): compute_api = self._setup_mock_compute_api() - self._setup_mock_network_api() response = request.get_response(fakes.wsgi_app()) return compute_api, response @@ -395,7 +369,6 @@ class CreateserverextTest(test.TestCase): return_security_group_get_by_name) self.stubs.Set(nova.db, 'instance_add_security_group', return_instance_add_security_group) - self._setup_mock_network_api() body_dict = self._create_security_group_request_dict(security_groups) request = self._get_create_request_json(body_dict) _run_create_inst = self._run_create_instance_with_mock_compute_api @@ -403,8 +376,7 @@ class CreateserverextTest(test.TestCase): self.assertEquals(response.status_int, 202) def test_get_server_by_id_verify_security_groups_json(self): - self.stubs.Set(nova.db, 'instance_get', return_server_by_id) - self._setup_mock_network_api() + self.stubs.Set(nova.db, 'instance_get', fakes.fake_instance_get()) req = webob.Request.blank('/v2/fake/os-create-server-ext/1') req.headers['Content-Type'] = 'application/json' response = req.get_response(fakes.wsgi_app()) @@ -415,8 +387,7 @@ class CreateserverextTest(test.TestCase): expected_security_group) def test_get_server_by_id_verify_security_groups_xml(self): - self.stubs.Set(nova.db, 'instance_get', return_server_by_id) - self._setup_mock_network_api() + self.stubs.Set(nova.db, 'instance_get', fakes.fake_instance_get()) req = webob.Request.blank('/v2/fake/os-create-server-ext/1') req.headers['Accept'] = 'application/xml' response = req.get_response(fakes.wsgi_app()) @@ -425,5 +396,4 @@ class CreateserverextTest(test.TestCase): server = dom.childNodes[0] sec_groups = server.getElementsByTagName('security_groups')[0] sec_group = sec_groups.getElementsByTagName('security_group')[0] - self.assertEqual(INSTANCE['security_groups'][0]['name'], - sec_group.getAttribute("name")) + self.assertEqual('test', sec_group.getAttribute("name")) diff --git a/nova/tests/api/openstack/compute/test_server_actions.py b/nova/tests/api/openstack/compute/test_server_actions.py index d0b020b39..ffb612b74 100644 --- a/nova/tests/api/openstack/compute/test_server_actions.py +++ b/nova/tests/api/openstack/compute/test_server_actions.py @@ -14,7 +14,6 @@ # under the License. import base64 -import datetime import mox import stubout @@ -22,7 +21,6 @@ import webob from nova.api.openstack.compute import servers from nova.compute import vm_states -from nova.compute import instance_types from nova import context import nova.db from nova import exception @@ -33,7 +31,7 @@ from nova import utils FLAGS = flags.FLAGS -FAKE_UUID = "aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa" +FAKE_UUID = fakes.FAKE_UUID def return_server_not_found(context, uuid): @@ -41,76 +39,7 @@ def return_server_not_found(context, uuid): def instance_update(context, instance_id, kwargs): - return stub_instance(instance_id) - - -def return_server_with_attributes(**kwargs): - def _return_server(context, uuid): - return stub_instance(1, **kwargs) - return _return_server - - -def stub_instance(id, metadata=None, image_ref="10", flavor_id="1", - name=None, vm_state=None, task_state=None, uuid=None, - access_ip_v4="", access_ip_v6=""): - if metadata is not None: - metadata_items = [{'key':k, 'value':v} for k, v in metadata.items()] - else: - metadata_items = [{'key':'seq', 'value':id}] - - if uuid is None: - uuid = FAKE_UUID - - inst_type = instance_types.get_instance_type_by_flavor_id(int(flavor_id)) - - instance = { - "id": int(id), - "name": str(id), - "created_at": datetime.datetime(2010, 10, 10, 12, 0, 0), - "updated_at": datetime.datetime(2010, 11, 11, 11, 0, 0), - "admin_pass": "", - "user_id": "fake", - "project_id": "fake", - "image_ref": image_ref, - "kernel_id": "", - "ramdisk_id": "", - "launch_index": 0, - "key_name": "", - "key_data": "", - "vm_state": vm_state or vm_states.ACTIVE, - "task_state": task_state, - "memory_mb": 0, - "vcpus": 0, - "root_gb": 0, - "hostname": "", - "host": "fake_host", - "instance_type": dict(inst_type), - "user_data": "", - "reservation_id": "", - "mac_address": "", - "scheduled_at": utils.utcnow(), - "launched_at": utils.utcnow(), - "terminated_at": utils.utcnow(), - "availability_zone": "", - "display_name": name or "server%s" % id, - "display_description": "", - "locked": False, - "metadata": metadata_items, - "access_ip_v4": access_ip_v4, - "access_ip_v6": access_ip_v6, - "uuid": uuid, - "virtual_interfaces": [], - "progress": 0, - } - - instance["fixed_ips"] = [{"address": '192.168.0.1', - "network": - {'label': 'public', 'cidr_v6': None}, - "virtual_interface": - {'address': 'aa:aa:aa:aa:aa:aa'}, - "floating_ips": []}] - - return instance + return fakes.stub_instance(instance_id) class MockSetAdminPassword(object): @@ -131,8 +60,9 @@ class ServerActionsControllerTest(test.TestCase): self.stubs = stubout.StubOutForTesting() fakes.stub_out_auth(self.stubs) - return_server = return_server_with_attributes() - self.stubs.Set(nova.db, 'instance_get_by_uuid', return_server) + self.stubs.Set(nova.db, 'instance_get_by_uuid', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE, + host='fake_host')) self.stubs.Set(nova.db, 'instance_update', instance_update) fakes.stub_out_glance(self.stubs) @@ -261,7 +191,8 @@ class ServerActionsControllerTest(test.TestCase): req, FAKE_UUID, body) def test_rebuild_accepted_minimum(self): - return_server = return_server_with_attributes(image_ref='2') + return_server = fakes.fake_instance_get(image_ref='2', + vm_state=vm_states.ACTIVE, host='fake_host') self.stubs.Set(nova.db, 'instance_get_by_uuid', return_server) self_href = 'http://localhost/v2/fake/servers/%s' % FAKE_UUID @@ -286,7 +217,8 @@ class ServerActionsControllerTest(test.TestCase): # is missing from response. See lp bug 921814 self.flags(enable_instance_password=False) - return_server = return_server_with_attributes(image_ref='2') + return_server = fakes.fake_instance_get(image_ref='2', + vm_state=vm_states.ACTIVE, host='fake_host') self.stubs.Set(nova.db, 'instance_get_by_uuid', return_server) self_href = 'http://localhost/v2/fake/servers/%s' % FAKE_UUID @@ -325,7 +257,8 @@ class ServerActionsControllerTest(test.TestCase): def test_rebuild_accepted_with_metadata(self): metadata = {'new': 'metadata'} - return_server = return_server_with_attributes(metadata=metadata) + return_server = fakes.fake_instance_get(metadata=metadata, + vm_state=vm_states.ACTIVE, host='fake_host') self.stubs.Set(nova.db, 'instance_get_by_uuid', return_server) body = { @@ -398,7 +331,8 @@ class ServerActionsControllerTest(test.TestCase): self.assertTrue('personality' not in body['server']) def test_rebuild_admin_pass(self): - return_server = return_server_with_attributes(image_ref='2') + return_server = fakes.fake_instance_get(image_ref='2', + vm_state=vm_states.ACTIVE, host='fake_host') self.stubs.Set(nova.db, 'instance_get_by_uuid', return_server) body = { @@ -419,7 +353,8 @@ class ServerActionsControllerTest(test.TestCase): # is missing from response. See lp bug 921814 self.flags(enable_instance_password=False) - return_server = return_server_with_attributes(image_ref='2') + return_server = fakes.fake_instance_get(image_ref='2', + vm_state=vm_states.ACTIVE, host='fake_host') self.stubs.Set(nova.db, 'instance_get_by_uuid', return_server) body = { diff --git a/nova/tests/api/openstack/compute/test_servers.py b/nova/tests/api/openstack/compute/test_servers.py index e9607bd7c..ca2fdbc04 100644 --- a/nova/tests/api/openstack/compute/test_servers.py +++ b/nova/tests/api/openstack/compute/test_servers.py @@ -19,7 +19,6 @@ import datetime import json import urlparse -import uuid import iso8601 from lxml import etree @@ -47,7 +46,6 @@ from nova import utils FLAGS = flags.FLAGS FAKE_UUID = fakes.FAKE_UUID -FAKE_UUIDS = {0: FAKE_UUID} NS = "{http://docs.openstack.org/compute/api/v1.1}" ATOMNS = "{http://www.w3.org/2005/Atom}" XPATH_NS = { @@ -56,64 +54,13 @@ XPATH_NS = { } -def get_fake_uuid(token=0): - if not token in FAKE_UUIDS: - FAKE_UUIDS[token] = str(utils.gen_uuid()) - return FAKE_UUIDS[token] - - def fake_gen_uuid(): return FAKE_UUID -def return_server_by_id(context, id): - return fakes.stub_instance(id, project_id='fake_project') - - -def return_server_by_uuid(context, uuid): - id = 1 - return fakes.stub_instance(id, uuid=uuid, - project_id='fake_project') - - -def return_server_with_attributes(**kwargs): - def _return_server(context, instance_id): - return fakes.stub_instance(instance_id, **kwargs) - return _return_server - - -def return_server_with_attributes_by_uuid(**kwargs): - def _return_server(context, uuid): - return fakes.stub_instance(1, uuid=uuid, **kwargs) - return _return_server - - -def return_server_with_state(vm_state, task_state=None): - def _return_server(context, uuid): - return fakes.stub_instance(1, uuid=uuid, vm_state=vm_state, - task_state=task_state) - return _return_server - - -def return_server_with_uuid_and_state(vm_state, task_state): - def _return_server(context, id): - return fakes.stub_instance(id, - uuid=FAKE_UUID, - vm_state=vm_state, - task_state=task_state) - return _return_server - - -def return_servers(context, *args, **kwargs): - servers_list = [] - for i in xrange(5): - server = fakes.stub_instance(i, 'fake', 'fake', uuid=get_fake_uuid(i)) - servers_list.append(server) - return servers_list - - def return_servers_by_reservation(context, reservation_id=""): - return [fakes.stub_instance(i, reservation_id) for i in xrange(5)] + return [fakes.stub_instance(i + 1, + reservation_id=reservation_id) for i in xrange(5)] def return_servers_by_reservation_empty(context, reservation_id=""): @@ -150,11 +97,12 @@ class ServersControllerTest(test.TestCase): fakes.stub_out_rate_limiting(self.stubs) fakes.stub_out_key_pair_funcs(self.stubs) fakes.stub_out_image_service(self.stubs) + return_server = fakes.fake_instance_get() + return_servers = fakes.fake_instance_get_all_by_filters() self.stubs.Set(nova.db, 'instance_get_all_by_filters', return_servers) - self.stubs.Set(nova.db, 'instance_get', return_server_by_id) self.stubs.Set(nova.db, 'instance_get_by_uuid', - return_server_by_uuid) + return_server) self.stubs.Set(nova.db, 'instance_get_all_by_project', return_servers) self.stubs.Set(nova.db, 'instance_add_security_group', @@ -178,7 +126,7 @@ class ServersControllerTest(test.TestCase): """Create two servers with the same host and different project_ids and check that the hostId's are unique""" def return_instance_with_host(self, *args): - project_id = str(uuid.uuid4()) + project_id = str(utils.gen_uuid()) return fakes.stub_instance(id=1, uuid=FAKE_UUID, project_id=project_id, host='fake_host') @@ -207,7 +155,7 @@ class ServersControllerTest(test.TestCase): expected_server = { "server": { "id": uuid, - "user_id": "fake", + "user_id": "fake_user", "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", @@ -265,11 +213,8 @@ class ServersControllerTest(test.TestCase): image_bookmark = "http://localhost/fake/images/10" flavor_bookmark = "http://localhost/fake/flavors/1" - new_return_server = return_server_with_attributes( - vm_state=vm_states.ACTIVE, progress=100) - self.stubs.Set(nova.db, 'instance_get', new_return_server) - new_return_server = return_server_with_attributes_by_uuid( - vm_state=vm_states.ACTIVE, progress=100) + new_return_server = fakes.fake_instance_get( + vm_state=vm_states.ACTIVE, progress=100) self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server) uuid = FAKE_UUID @@ -278,8 +223,8 @@ class ServersControllerTest(test.TestCase): expected_server = { "server": { "id": uuid, - "user_id": "fake", - "tenant_id": "fake", + "user_id": "fake_user", + "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", "progress": 100, @@ -338,13 +283,9 @@ class ServersControllerTest(test.TestCase): flavor_id = "1" flavor_bookmark = "http://localhost/fake/flavors/1" - new_return_server = return_server_with_attributes( - vm_state=vm_states.ACTIVE, image_ref=image_ref, - flavor_id=flavor_id, progress=100) - self.stubs.Set(nova.db, 'instance_get', new_return_server) - new_return_server = return_server_with_attributes_by_uuid( - vm_state=vm_states.ACTIVE, image_ref=image_ref, - flavor_id=flavor_id, progress=100) + new_return_server = fakes.fake_instance_get( + vm_state=vm_states.ACTIVE, image_ref=image_ref, + flavor_id=flavor_id, progress=100) self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server) uuid = FAKE_UUID @@ -353,8 +294,8 @@ class ServersControllerTest(test.TestCase): expected_server = { "server": { "id": uuid, - "user_id": "fake", - "tenant_id": "fake", + "user_id": "fake_user", + "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", "progress": 100, @@ -407,60 +348,6 @@ class ServersControllerTest(test.TestCase): self.assertDictMatch(res_dict, expected_server) - # NOTE(bcwaldon): lp830817 - def test_get_server_by_id_malformed_networks(self): - def fake_instance_get(context, instance_uuid): - instance = return_server_by_uuid(context, instance_uuid) - instance['fixed_ips'] = [dict(network=None, address='1.2.3.4')] - return instance - - self.stubs.Set(nova.db, 'instance_get_by_uuid', fake_instance_get) - - req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) - res_dict = self.controller.show(req, FAKE_UUID) - - self.assertEqual(res_dict['server']['id'], FAKE_UUID) - self.assertEqual(res_dict['server']['name'], 'server1') - - def test_get_server_by_id_malformed_vif(self): - def fake_instance_get(context, uuid): - instance = return_server_by_uuid(context, uuid) - instance['fixed_ips'] = [dict(network={'label': 'meow'}, - address='1.2.3.4', virtual_interface=None)] - return instance - - self.stubs.Set(nova.db, 'instance_get_by_uuid', fake_instance_get) - - req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) - res_dict = self.controller.show(req, FAKE_UUID) - - self.assertEqual(res_dict['server']['id'], FAKE_UUID) - self.assertEqual(res_dict['server']['name'], 'server1') - - def test_get_server_addresses_from_nw_info(self): - self.flags(use_ipv6=True) - - new_return_server = return_server_with_attributes_by_uuid() - fake_network.fake_get_instance_nw_info(self.stubs, num_networks=2, - spectacular=True) - floaters = [] - fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs, - floaters) - self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server) - - req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID) - res_dict = self.ips_controller.index(req, FAKE_UUID) - - expected = { - 'addresses': { - 'test1': [ - {'version': 4, 'addr': '192.168.1.100'}, - {'version': 6, 'addr': '2001:db8:0:1::1'} - ] - }, - } - self.assertDictMatch(res_dict, expected) - def test_get_server_addresses_from_cache(self): pub0 = ('172.19.0.1', '172.19.0.2',) pub1 = ('1.2.3.4',) @@ -490,9 +377,8 @@ class ServersControllerTest(test.TestCase): 'subnets': [{'cidr': '192.168.0.0/24', 'ips': [_ip(ip) for ip in priv0]}]}}] - kwargs = {'nw_cache': nw_cache} - new_return_server = return_server_with_attributes_by_uuid(**kwargs) - self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server) + return_server = fakes.fake_instance_get(nw_cache=nw_cache) + self.stubs.Set(nova.db, 'instance_get_by_uuid', return_server) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID) res_dict = self.ips_controller.index(req, FAKE_UUID) @@ -513,51 +399,6 @@ class ServersControllerTest(test.TestCase): } self.assertDictMatch(res_dict, expected) - def test_get_server_addresses_with_floating_from_nwinfo(self): - new_return_server = return_server_with_attributes_by_uuid() - self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server) - - fake_network.stub_out_nw_api_get_instance_nw_info(self.stubs, - floating_ips_per_fixed_ip=1, - spectacular=True) - req = fakes.HTTPRequest.blank('/v2/fake/servers/%s/ips' % FAKE_UUID) - res_dict = self.ips_controller.index(req, FAKE_UUID) - - expected = { - 'addresses': { - 'test1': [ - {'version': 4, 'addr': '192.168.1.100'}, - {'version': 6, 'addr': '2001:db8:0:1::1'}, - {'version': 4, 'addr': '10.10.10.100'}, - ], - }, - } - self.assertDictMatch(res_dict, expected) - - def test_get_server_addresses_single_network_from_nwinfo(self): - self.flags(use_ipv6=True) - - def floaters(*args, **kwargs): - return [] - - new_return_server = return_server_with_attributes_by_uuid() - fake_network.fake_get_instance_nw_info(self.stubs, num_networks=1) - fakes.stub_out_nw_api_get_floating_ips_by_fixed_address(self.stubs, - floaters) - self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server) - - url = '/v2/fake/servers/%s/ips/test1' % FAKE_UUID - req = fakes.HTTPRequest.blank(url) - res_dict = self.ips_controller.show(req, FAKE_UUID, 'test1') - - expected = { - 'test1': [ - {'version': 4, 'addr': '192.168.1.100'}, - {'version': 6, 'addr': '2001:db8:0:1::1'} - ] - } - self.assertDictMatch(res_dict, expected) - def test_get_server_addresses_nonexistant_network(self): url = '/v2/fake/servers/%s/ips/network_0' % FAKE_UUID req = fakes.HTTPRequest.blank(url) @@ -584,12 +425,8 @@ class ServersControllerTest(test.TestCase): i = 0 for s in res_dict['servers']: - if '_is_precooked' in s: - self.assertEqual(s.get('reservation_id'), 'child') - else: - print s - self.assertEqual(s.get('name'), 'server%d' % i) - i += 1 + self.assertEqual(s.get('name'), 'server%d' % (i + 1)) + i += 1 def test_get_server_list_with_reservation_id_empty(self): self.stubs.Set(nova.db, 'instance_get_all_by_reservation', @@ -601,11 +438,8 @@ class ServersControllerTest(test.TestCase): i = 0 for s in res_dict['servers']: - if '_is_precooked' in s: - self.assertEqual(s.get('reservation_id'), 'child') - else: - self.assertEqual(s.get('name'), 'server%d' % i) - i += 1 + self.assertEqual(s.get('name'), 'server%d' % (i + 1)) + i += 1 def test_get_server_list_with_reservation_id_details(self): self.stubs.Set(nova.db, 'instance_get_all_by_reservation', @@ -617,11 +451,8 @@ class ServersControllerTest(test.TestCase): i = 0 for s in res_dict['servers']: - if '_is_precooked' in s: - self.assertEqual(s.get('reservation_id'), 'child') - else: - self.assertEqual(s.get('name'), 'server%d' % i) - i += 1 + self.assertEqual(s.get('name'), 'server%d' % (i + 1)) + i += 1 def test_get_server_list(self): req = fakes.HTTPRequest.blank('/v2/fake/servers') @@ -629,8 +460,8 @@ class ServersControllerTest(test.TestCase): self.assertEqual(len(res_dict['servers']), 5) for i, s in enumerate(res_dict['servers']): - self.assertEqual(s['id'], get_fake_uuid(i)) - self.assertEqual(s['name'], 'server%d' % i) + self.assertEqual(s['id'], fakes.get_fake_uuid(i)) + self.assertEqual(s['name'], 'server%d' % (i + 1)) self.assertEqual(s.get('image', None), None) expected_links = [ @@ -652,14 +483,15 @@ class ServersControllerTest(test.TestCase): servers = res_dict['servers'] self.assertEqual([s['id'] for s in servers], - [get_fake_uuid(i) for i in xrange(len(servers))]) + [fakes.get_fake_uuid(i) for i in xrange(len(servers))]) servers_links = res_dict['servers_links'] self.assertEqual(servers_links[0]['rel'], 'next') 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': [get_fake_uuid(2)]} + expected_params = {'limit': ['3'], + 'marker': [fakes.get_fake_uuid(2)]} self.assertDictMatch(expected_params, params) def test_get_servers_with_limit_bad_value(self): @@ -673,7 +505,7 @@ class ServersControllerTest(test.TestCase): servers = res['servers'] self.assertEqual([s['id'] for s in servers], - [get_fake_uuid(i) for i in xrange(len(servers))]) + [fakes.get_fake_uuid(i) for i in xrange(len(servers))]) servers_links = res['servers_links'] self.assertEqual(servers_links[0]['rel'], 'next') @@ -681,7 +513,7 @@ class ServersControllerTest(test.TestCase): href_parts = urlparse.urlparse(servers_links[0]['href']) self.assertEqual('/v2/fake/servers', href_parts.path) params = urlparse.parse_qs(href_parts.query) - expected = {'limit': ['3'], 'marker': [get_fake_uuid(2)]} + expected = {'limit': ['3'], 'marker': [fakes.get_fake_uuid(2)]} self.assertDictMatch(expected, params) def test_get_server_details_with_limit_bad_value(self): @@ -696,7 +528,7 @@ class ServersControllerTest(test.TestCase): servers = res['servers'] self.assertEqual([s['id'] for s in servers], - [get_fake_uuid(i) for i in xrange(len(servers))]) + [fakes.get_fake_uuid(i) for i in xrange(len(servers))]) servers_links = res['servers_links'] self.assertEqual(servers_links[0]['rel'], 'next') @@ -706,7 +538,7 @@ class ServersControllerTest(test.TestCase): params = urlparse.parse_qs(href_parts.query) self.assertDictMatch({'limit': ['3'], 'blah': ['2:t'], - 'marker': [get_fake_uuid(2)]}, params) + 'marker': [fakes.get_fake_uuid(2)]}, params) def test_get_servers_with_too_big_limit(self): req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=30') @@ -719,16 +551,16 @@ class ServersControllerTest(test.TestCase): self.controller.index, req) def test_get_servers_with_marker(self): - url = '/v2/fake/servers?marker=%s' % get_fake_uuid(2) + url = '/v2/fake/servers?marker=%s' % fakes.get_fake_uuid(2) req = fakes.HTTPRequest.blank(url) servers = self.controller.index(req)['servers'] - self.assertEqual([s['name'] for s in servers], ["server3", "server4"]) + self.assertEqual([s['name'] for s in servers], ["server4", "server5"]) def test_get_servers_with_limit_and_marker(self): - url = '/v2/fake/servers?limit=2&marker=%s' % get_fake_uuid(1) + 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([s['name'] for s in servers], ['server2', 'server3']) + self.assertEqual([s['name'] for s in servers], ['server3', 'server4']) def test_get_servers_with_bad_marker(self): req = fakes.HTTPRequest.blank('/v2/fake/servers?limit=2&marker=asdf') @@ -1016,9 +848,9 @@ class ServersControllerTest(test.TestCase): def test_update_server_all_attributes(self): self.stubs.Set(nova.db, 'instance_get', - return_server_with_attributes(name='server_test', - access_ipv4='0.0.0.0', - access_ipv6='beef::0123')) + fakes.fake_instance_get(name='server_test', + access_ipv4='0.0.0.0', + access_ipv6='beef::0123')) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'PUT' req.content_type = 'application/json' @@ -1037,7 +869,7 @@ class ServersControllerTest(test.TestCase): def test_update_server_name(self): self.stubs.Set(nova.db, 'instance_get', - return_server_with_attributes(name='server_test')) + fakes.fake_instance_get(name='server_test')) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'PUT' req.content_type = 'application/json' @@ -1050,7 +882,7 @@ class ServersControllerTest(test.TestCase): def test_update_server_access_ipv4(self): self.stubs.Set(nova.db, 'instance_get', - return_server_with_attributes(access_ipv4='0.0.0.0')) + fakes.fake_instance_get(access_ipv4='0.0.0.0')) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'PUT' req.content_type = 'application/json' @@ -1063,7 +895,7 @@ class ServersControllerTest(test.TestCase): def test_update_server_access_ipv4_bad_format(self): self.stubs.Set(nova.db, 'instance_get', - return_server_with_attributes(access_ipv4='0.0.0.0')) + fakes.fake_instance_get(access_ipv4='0.0.0.0')) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'PUT' req.content_type = 'application/json' @@ -1074,7 +906,7 @@ class ServersControllerTest(test.TestCase): def test_update_server_access_ipv6(self): self.stubs.Set(nova.db, 'instance_get', - return_server_with_attributes(access_ipv6='beef::0123')) + fakes.fake_instance_get(access_ipv6='beef::0123')) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'PUT' req.content_type = 'application/json' @@ -1087,7 +919,7 @@ class ServersControllerTest(test.TestCase): def test_update_server_access_ipv6_bad_format(self): self.stubs.Set(nova.db, 'instance_get', - return_server_with_attributes(access_ipv6='beef::0123')) + fakes.fake_instance_get(access_ipv6='beef::0123')) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'PUT' req.content_type = 'application/json' @@ -1109,8 +941,9 @@ class ServersControllerTest(test.TestCase): return filtered_dict self.stubs.Set(nova.db, 'instance_update', server_update) - self.stubs.Set(nova.db, 'instance_get', - return_server_with_attributes(name='server_test')) + # FIXME (comstud) + # self.stubs.Set(nova.db, 'instance_get', + # return_server_with_attributes(name='server_test')) req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) req.method = 'PUT' @@ -1122,11 +955,8 @@ class ServersControllerTest(test.TestCase): self.assertEqual(res_dict['server']['name'], 'server_test') def test_rebuild_instance_with_access_ipv4_bad_format(self): - - def fake_get_instance(*args, **kwargs): - return fakes.stub_instance(1, vm_state=vm_states.ACTIVE) - - self.stubs.Set(nova.db, 'instance_get', fake_get_instance) + self.stubs.Set(nova.db, 'instance_get', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE)) # proper local hrefs must start with 'http://localhost/v2/' image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' image_href = 'http://localhost/v2/fake/images/%s' % image_uuid @@ -1156,15 +986,11 @@ class ServersControllerTest(test.TestCase): req.body = json.dumps(body) req.headers["content-type"] = "application/json" self.assertRaises(webob.exc.HTTPBadRequest, - self.controller._action_rebuild, req, 1, body) + self.controller._action_rebuild, req, FAKE_UUID, body) def test_rebuild_instance_with_access_ipv6_bad_format(self): - - def fake_get_instance(*args, **kwargs): - return fakes.stub_instance(1, vm_state=vm_states.ACTIVE, - project_id='fake_project') - - self.stubs.Set(nova.db, 'instance_get', fake_get_instance) + self.stubs.Set(nova.db, 'instance_get_by_uuid', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE)) # proper local hrefs must start with 'http://localhost/v2/' image_uuid = '76fa36fc-c930-4bf3-8c8a-ea2a2420deb6' image_href = 'http://localhost/v2/fake/images/%s' % image_uuid @@ -1194,7 +1020,7 @@ class ServersControllerTest(test.TestCase): req.body = json.dumps(body) req.headers["content-type"] = "application/json" self.assertRaises(webob.exc.HTTPBadRequest, - self.controller._action_rebuild, req, 1, body) + self.controller._action_rebuild, req, FAKE_UUID, body) def test_get_all_server_details(self): expected_flavor = { @@ -1219,13 +1045,13 @@ class ServersControllerTest(test.TestCase): res_dict = self.controller.detail(req) for i, s in enumerate(res_dict['servers']): - self.assertEqual(s['id'], get_fake_uuid(i)) + self.assertEqual(s['id'], fakes.get_fake_uuid(i)) self.assertEqual(s['hostId'], '') - self.assertEqual(s['name'], 'server%d' % i) + self.assertEqual(s['name'], 'server%d' % (i + 1)) self.assertEqual(s['image'], expected_image) self.assertEqual(s['flavor'], expected_flavor) self.assertEqual(s['status'], 'BUILD') - self.assertEqual(s['metadata']['seq'], str(i)) + self.assertEqual(s['metadata']['seq'], str(i + 1)) def test_get_all_server_details_with_host(self): ''' @@ -1236,12 +1062,12 @@ class ServersControllerTest(test.TestCase): ''' def return_servers_with_host(context, *args, **kwargs): - return [fakes.stub_instance(i, 'fake', 'fake', i % 2, - uuid=get_fake_uuid(i)) + return [fakes.stub_instance(i + 1, 'fake', 'fake', host=i % 2, + uuid=fakes.get_fake_uuid(i)) for i in xrange(5)] self.stubs.Set(nova.db, 'instance_get_all_by_filters', - return_servers_with_host) + return_servers_with_host) req = fakes.HTTPRequest.blank('/v2/fake/servers/detail') res_dict = self.controller.detail(req) @@ -1252,9 +1078,9 @@ class ServersControllerTest(test.TestCase): self.assertNotEqual(host_ids[0], host_ids[1]) for i, s in enumerate(server_list): - self.assertEqual(s['id'], get_fake_uuid(i)) + self.assertEqual(s['id'], fakes.get_fake_uuid(i)) self.assertEqual(s['hostId'], host_ids[i % 2]) - self.assertEqual(s['name'], 'server%d' % i) + self.assertEqual(s['name'], 'server%d' % (i + 1)) def test_delete_server_instance(self): req = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) @@ -1262,9 +1088,8 @@ class ServersControllerTest(test.TestCase): self.server_delete_called = False - new_return_server = return_server_with_attributes( - vm_state=vm_states.ACTIVE) - self.stubs.Set(nova.db, 'instance_get', new_return_server) + self.stubs.Set(nova.db, 'instance_get_by_uuid', + fakes.fake_instance_get(vm_state=vm_states.ACTIVE)) def instance_destroy_mock(context, id): self.server_delete_called = True @@ -1280,10 +1105,6 @@ class ServersControllerTest(test.TestCase): self.server_delete_called = False - new_return_server = return_server_with_attributes( - vm_state=vm_states.BUILDING) - self.stubs.Set(nova.db, 'instance_get', new_return_server) - def instance_destroy_mock(context, id): self.server_delete_called = True self.stubs.Set(nova.db, 'instance_destroy', instance_destroy_mock) @@ -1298,12 +1119,8 @@ class ServersControllerTest(test.TestCase): self.server_delete_called = False - new_return_server = return_server_with_attributes( - vm_state=vm_states.RESIZING) - self.stubs.Set(nova.db, 'instance_get', new_return_server) - new_return_server = return_server_with_attributes_by_uuid( - vm_state=vm_states.RESIZING) - self.stubs.Set(nova.db, 'instance_get_by_uuid', new_return_server) + self.stubs.Set(nova.db, 'instance_get_by_uuid', + fakes.fake_instance_get(vm_state=vm_states.RESIZING)) def instance_destroy_mock(context, id): self.server_delete_called = True @@ -1324,9 +1141,9 @@ class ServerStatusTest(test.TestCase): self.controller = servers.Controller() def _get_with_state(self, vm_state, task_state=None): - new_server = return_server_with_state(vm_state, task_state) - self.stubs.Set(nova.db, 'instance_get_by_uuid', new_server) - self.stubs.Set(nova.db, 'instance_get', new_server) + self.stubs.Set(nova.db, 'instance_get_by_uuid', + fakes.fake_instance_get(vm_state=vm_state, + task_state=task_state)) request = fakes.HTTPRequest.blank('/v2/fake/servers/%s' % FAKE_UUID) return self.controller.show(request, FAKE_UUID) @@ -2745,8 +2562,8 @@ class ServersViewBuilderTest(test.TestCase): expected_server = { "server": { "id": self.uuid, - "user_id": "fake", - "tenant_id": "fake", + "user_id": "fake_user", + "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", "progress": 0, @@ -2815,8 +2632,8 @@ class ServersViewBuilderTest(test.TestCase): expected_server = { "server": { "id": self.uuid, - "user_id": "fake", - "tenant_id": "fake", + "user_id": "fake_user", + "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", "name": "test_server", @@ -2939,6 +2756,12 @@ class ServersViewBuilderTest(test.TestCase): 'details': "Stock details for test", 'created_at': datetime.datetime(2010, 10, 10, 12, 0, 0), } + + image_bookmark = "http://localhost/fake/images/5" + flavor_bookmark = "http://localhost/fake/flavors/1" + self_link = "http://localhost/v2/fake/servers/%s" % self.uuid + bookmark_link = "http://localhost/fake/servers/%s" % self.uuid + output = self.view_builder.show(self.request, self.instance) self.assertFalse('fault' in output['server']) @@ -2953,8 +2776,8 @@ class ServersViewBuilderTest(test.TestCase): expected_server = { "server": { "id": self.uuid, - "user_id": "fake", - "tenant_id": "fake", + "user_id": "fake_user", + "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", "progress": 100, @@ -3017,8 +2840,8 @@ class ServersViewBuilderTest(test.TestCase): expected_server = { "server": { "id": self.uuid, - "user_id": "fake", - "tenant_id": "fake", + "user_id": "fake_user", + "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", "progress": 0, @@ -3081,8 +2904,8 @@ class ServersViewBuilderTest(test.TestCase): expected_server = { "server": { "id": self.uuid, - "user_id": "fake", - "tenant_id": "fake", + "user_id": "fake_user", + "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", "progress": 0, @@ -3147,8 +2970,8 @@ class ServersViewBuilderTest(test.TestCase): expected_server = { "server": { "id": self.uuid, - "user_id": "fake", - "tenant_id": "fake", + "user_id": "fake_user", + "tenant_id": "fake_project", "updated": "2010-11-11T11:00:00Z", "created": "2010-10-10T12:00:00Z", "progress": 0, @@ -3557,15 +3380,15 @@ class ServerXMLSerializationTest(test.TestCase): def test_index(self): serializer = servers.MinimalServersTemplate() - uuid1 = get_fake_uuid(1) - uuid2 = get_fake_uuid(2) + uuid1 = fakes.get_fake_uuid(1) + uuid2 = fakes.get_fake_uuid(2) expected_server_href = 'http://localhost/v2/servers/%s' % uuid1 expected_server_bookmark = 'http://localhost/servers/%s' % uuid1 expected_server_href_2 = 'http://localhost/v2/servers/%s' % uuid2 expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2 fixture = {"servers": [ { - "id": get_fake_uuid(1), + "id": fakes.get_fake_uuid(1), "name": "test_server", 'links': [ { @@ -3579,7 +3402,7 @@ class ServerXMLSerializationTest(test.TestCase): ], }, { - "id": get_fake_uuid(2), + "id": fakes.get_fake_uuid(2), "name": "test_server_2", 'links': [ { @@ -3614,8 +3437,8 @@ class ServerXMLSerializationTest(test.TestCase): def test_index_with_servers_links(self): serializer = servers.MinimalServersTemplate() - uuid1 = get_fake_uuid(1) - uuid2 = get_fake_uuid(2) + uuid1 = fakes.get_fake_uuid(1) + uuid2 = fakes.get_fake_uuid(2) expected_server_href = 'http://localhost/v2/servers/%s' % uuid1 expected_server_next = self.SERVER_NEXT % (2, 2) expected_server_bookmark = 'http://localhost/servers/%s' % uuid1 @@ -3623,7 +3446,7 @@ class ServerXMLSerializationTest(test.TestCase): expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2 fixture = {"servers": [ { - "id": get_fake_uuid(1), + "id": fakes.get_fake_uuid(1), "name": "test_server", 'links': [ { @@ -3637,7 +3460,7 @@ class ServerXMLSerializationTest(test.TestCase): ], }, { - "id": get_fake_uuid(2), + "id": fakes.get_fake_uuid(2), "name": "test_server_2", 'links': [ { @@ -3684,18 +3507,18 @@ class ServerXMLSerializationTest(test.TestCase): def test_detail(self): serializer = servers.ServersTemplate() - uuid1 = get_fake_uuid(1) + uuid1 = fakes.get_fake_uuid(1) expected_server_href = 'http://localhost/v2/servers/%s' % uuid1 expected_server_bookmark = 'http://localhost/servers/%s' % uuid1 expected_image_bookmark = self.IMAGE_BOOKMARK expected_flavor_bookmark = self.FLAVOR_BOOKMARK - uuid2 = get_fake_uuid(2) + uuid2 = fakes.get_fake_uuid(2) expected_server_href_2 = 'http://localhost/v2/servers/%s' % uuid2 expected_server_bookmark_2 = 'http://localhost/servers/%s' % uuid2 fixture = {"servers": [ { - "id": get_fake_uuid(1), + "id": fakes.get_fake_uuid(1), "user_id": "fake", "tenant_id": "fake", 'created': self.TIMESTAMP, @@ -3751,7 +3574,7 @@ class ServerXMLSerializationTest(test.TestCase): ], }, { - "id": get_fake_uuid(2), + "id": fakes.get_fake_uuid(2), "user_id": 'fake', "tenant_id": 'fake', 'created': self.TIMESTAMP, diff --git a/nova/tests/api/openstack/fakes.py b/nova/tests/api/openstack/fakes.py index de42c859a..140353222 100644 --- a/nova/tests/api/openstack/fakes.py +++ b/nova/tests/api/openstack/fakes.py @@ -28,7 +28,6 @@ from nova.api import auth as api_auth from nova.api import openstack as openstack_api from nova.api.openstack import compute from nova.api.openstack import auth -from nova.api.openstack.compute import extensions from nova.api.openstack.compute import limits from nova.api.openstack import urlmap from nova.api.openstack.compute import versions @@ -46,6 +45,10 @@ from nova import utils from nova import wsgi +FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' +FAKE_UUIDS = {} + + class Context(object): pass @@ -447,12 +450,25 @@ class FakeRateLimiter(object): return self.application -FAKE_UUID = 'aaaaaaaa-aaaa-aaaa-aaaa-aaaaaaaaaaaa' - - def create_info_cache(nw_cache): if nw_cache is None: - return {} + pub0 = ('192.168.1.100',) + pub1 = ('2001:db8:0:1::1',) + + 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': 'test1', + 'subnets': [{'cidr': '192.168.1.0/24', + 'ips': [_ip(ip) for ip in pub0]}, + {'cidr': 'b33f::/64', + 'ips': [_ip(ip) for ip in pub1]}]}}] + return {"info_cache": {"network_info": nw_cache}} if not isinstance(nw_cache, basestring): nw_cache = utils.dumps(nw_cache) @@ -460,15 +476,47 @@ def create_info_cache(nw_cache): return {"info_cache": {"network_info": nw_cache}} -def stub_instance(id, user_id='fake', project_id='fake', host=None, +def get_fake_uuid(token=0): + if not token in FAKE_UUIDS: + FAKE_UUIDS[token] = str(utils.gen_uuid()) + return FAKE_UUIDS[token] + + +def fake_instance_get(**kwargs): + def _return_server(context, uuid): + return stub_instance(1, **kwargs) + return _return_server + + +def fake_instance_get_all_by_filters(num_servers=5, **kwargs): + def _return_servers(context, *args, **kwargs): + servers_list = [] + for i in xrange(num_servers): + server = stub_instance(id=i + 1, uuid=get_fake_uuid(i), + **kwargs) + servers_list.append(server) + return servers_list + return _return_servers + + +def stub_instance(id, user_id=None, project_id=None, host=None, vm_state=None, task_state=None, reservation_id="", uuid=FAKE_UUID, image_ref="10", flavor_id="1", name=None, key_name='', access_ipv4=None, access_ipv6=None, progress=0, auto_disk_config=False, display_name=None, include_fake_metadata=True, - power_state=None, nw_cache=None): - if include_fake_metadata: + power_state=None, nw_cache=None, metadata=None, + security_groups=None): + + if user_id is None: + user_id = 'fake_user' + if project_id is None: + project_id = 'fake_project' + + if metadata: + metadata = [{'key':k, 'value':v} for k, v in metadata.items()] + elif include_fake_metadata: metadata = [models.InstanceMetadata(key='seq', value=str(id))] else: metadata = [] @@ -483,6 +531,9 @@ def stub_instance(id, user_id='fake', project_id='fake', host=None, else: key_data = '' + if security_groups is None: + security_groups = [{"id": 1, "name": "test"}] + # ReservationID isn't sent back, hack it in there. server_name = name or "server%s" % id if reservation_id != "": @@ -532,7 +583,8 @@ def stub_instance(id, user_id='fake', project_id='fake', host=None, "auto_disk_config": auto_disk_config, "name": "instance-%s" % id, "shutdown_terminate": True, - "disable_terminate": False} + "disable_terminate": False, + "security_groups": security_groups} instance.update(info_cache) diff --git a/nova/tests/api/openstack/test_common.py b/nova/tests/api/openstack/test_common.py index 6103b6d13..f64a63024 100644 --- a/nova/tests/api/openstack/test_common.py +++ b/nova/tests/api/openstack/test_common.py @@ -329,16 +329,6 @@ class MiscFunctionsTest(test.TestCase): else: self.fail("webob.exc.HTTPConflict was not raised") - def test_get_networks_for_instance_handles_instance_not_found(self): - - def raise_not_found(*args, **kwargs): - raise exception.InstanceNotFound(instance_id='abcd') - - self.stubs.Set(network.API, 'get_instance_nw_info', raise_not_found) - - networks = common.get_networks_for_instance(context={}, instance={}) - self.assertEqual(networks, {}) - class MetadataXMLDeserializationTest(test.TestCase): diff --git a/nova/tests/test_compute.py b/nova/tests/test_compute.py index 17f8beeed..5e15b95e7 100644 --- a/nova/tests/test_compute.py +++ b/nova/tests/test_compute.py @@ -19,7 +19,7 @@ """ Tests For Compute """ -from copy import copy +import copy import datetime import sys import time @@ -1604,6 +1604,81 @@ class ComputeTestCase(BaseTestCase): val = self.compute._running_deleted_instances('context') self.assertEqual(val, [instance1]) + def test_heal_instance_info_cache(self): + # Update on every call for the test + self.flags(heal_instance_info_cache_interval=-1) + ctxt = context.get_admin_context() + + instance_map = {} + instances = [] + for x in xrange(5): + uuid = 'fake-uuid-%s' % x + instance_map[uuid] = {'uuid': uuid, 'host': FLAGS.host} + instances.append(instance_map[uuid]) + + call_info = {'get_all_by_host': 0, 'get_by_uuid': 0, + 'get_nw_info': 0, 'expected_instance': None} + + def fake_instance_get_all_by_host(context, host): + call_info['get_all_by_host'] += 1 + return instances[:] + + def fake_instance_get_by_uuid(context, instance_uuid): + if instance_uuid not in instance_map: + raise exception.InstanceNotFound + call_info['get_by_uuid'] += 1 + return instance_map[instance_uuid] + + def fake_get_instance_nw_info(context, instance): + # Note that this exception gets caught in compute/manager + # and is ignored. However, the below increment of + # 'get_nw_info' won't happen, and you'll get an assert + # failure checking it below. + self.assertEqual(instance, call_info['expected_instance']) + call_info['get_nw_info'] += 1 + + self.stubs.Set(db, 'instance_get_all_by_host', + fake_instance_get_all_by_host) + self.stubs.Set(db, 'instance_get_by_uuid', + fake_instance_get_by_uuid) + self.stubs.Set(self.compute.network_api, 'get_instance_nw_info', + fake_get_instance_nw_info) + + call_info['expected_instance'] = instances[0] + self.compute._heal_instance_info_cache(ctxt) + self.assertEqual(call_info['get_all_by_host'], 1) + self.assertEqual(call_info['get_by_uuid'], 0) + self.assertEqual(call_info['get_nw_info'], 1) + + call_info['expected_instance'] = instances[1] + self.compute._heal_instance_info_cache(ctxt) + self.assertEqual(call_info['get_all_by_host'], 1) + self.assertEqual(call_info['get_by_uuid'], 1) + self.assertEqual(call_info['get_nw_info'], 2) + + # Make an instance switch hosts + instances[2]['host'] = 'not-me' + # Make an instance disappear + instance_map.pop(instances[3]['uuid']) + # '2' and '3' should be skipped.. + call_info['expected_instance'] = instances[4] + self.compute._heal_instance_info_cache(ctxt) + self.assertEqual(call_info['get_all_by_host'], 1) + # Incremented for '2' and '4'.. '3' caused a raise above. + self.assertEqual(call_info['get_by_uuid'], 3) + self.assertEqual(call_info['get_nw_info'], 3) + # Should be no more left. + self.assertEqual(len(self.compute._instance_uuids_to_heal), 0) + + # This should cause a DB query now so we get first instance + # back again + call_info['expected_instance'] = instances[0] + self.compute._heal_instance_info_cache(ctxt) + self.assertEqual(call_info['get_all_by_host'], 2) + # Stays the same, beacuse the instance came from the DB + self.assertEqual(call_info['get_by_uuid'], 3) + self.assertEqual(call_info['get_nw_info'], 4) + class ComputeAPITestCase(BaseTestCase): @@ -1638,7 +1713,7 @@ class ComputeAPITestCase(BaseTestCase): inst_type['memory_mb'] = 1 def fake_show(*args): - img = copy(self.fake_image) + img = copy.copy(self.fake_image) img['min_ram'] = 2 return img self.stubs.Set(fake_image._FakeImageService, 'show', fake_show) @@ -1659,7 +1734,7 @@ class ComputeAPITestCase(BaseTestCase): inst_type['root_gb'] = 1 def fake_show(*args): - img = copy(self.fake_image) + img = copy.copy(self.fake_image) img['min_disk'] = 2 return img self.stubs.Set(fake_image._FakeImageService, 'show', fake_show) @@ -1681,7 +1756,7 @@ class ComputeAPITestCase(BaseTestCase): inst_type['memory_mb'] = 2 def fake_show(*args): - img = copy(self.fake_image) + img = copy.copy(self.fake_image) img['min_ram'] = 2 img['min_disk'] = 2 return img @@ -1699,7 +1774,7 @@ class ComputeAPITestCase(BaseTestCase): inst_type['memory_mb'] = 1 def fake_show(*args): - return copy(self.fake_image) + return copy.copy(self.fake_image) self.stubs.Set(fake_image._FakeImageService, 'show', fake_show) (refs, resv_id) = self.compute_api.create(self.context, @@ -2143,7 +2218,7 @@ class ComputeAPITestCase(BaseTestCase): """ def fake_show(*args): - img = copy(self.fake_image) + img = copy.copy(self.fake_image) img['disk_format'] = 'vhd' return img self.stubs.Set(fake_image._FakeImageService, 'show', fake_show) @@ -2175,7 +2250,7 @@ class ComputeAPITestCase(BaseTestCase): """ def fake_show(*args): - img = copy(self.fake_image) + img = copy.copy(self.fake_image) img['disk_format'] = 'raw' img['min_ram'] = 512 img['min_disk'] = 1 @@ -2205,7 +2280,7 @@ class ComputeAPITestCase(BaseTestCase): """ def fake_show(*args): - img = copy(self.fake_image) + img = copy.copy(self.fake_image) img['disk_format'] = 'raw' img['min_disk'] = 1 return img diff --git a/nova/tests/test_metadata.py b/nova/tests/test_metadata.py index f6816c094..0980bd48f 100644 --- a/nova/tests/test_metadata.py +++ b/nova/tests/test_metadata.py @@ -59,6 +59,7 @@ class MetadataTestCase(test.TestCase): 'vcpus': 1, 'fixed_ips': [], 'root_device_name': '/dev/sda1', + 'info_cache': {'network_info': []}, 'hostname': 'test'}) def fake_get_floating_ips_by_fixed_address(self, context, fixed_ip): |
