summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChris Behrens <cbehrens@codestud.com>2013-07-01 20:25:51 +0000
committerChris Behrens <cbehrens@codestud.com>2013-07-01 22:50:09 +0000
commit404cd48773f841c9ace2128c25d0f0956392f655 (patch)
tree847d926748008db70367ea1d812a13b2bfdc8e2b
parent43d811bc86b8bf7342ce108e175f3cbd67d14cda (diff)
downloadnova-404cd48773f841c9ace2128c25d0f0956392f655.tar.gz
nova-404cd48773f841c9ace2128c25d0f0956392f655.tar.xz
nova-404cd48773f841c9ace2128c25d0f0956392f655.zip
Break out Compute Manager unit tests
As we convert things to objects, it'll be easier to convert our compute Manager tests to be true unit tests if they are in their own class. There are currently a handful of tests that are true unit tests and require no DB access. These are now moved, subclassing from test.NoDBTestCase. Related to blueprint unified-object-model Change-Id: I5e7ca3a94c32fff268e8b329f165198c873756e1
-rw-r--r--nova/tests/compute/test_compute.py485
-rw-r--r--nova/tests/compute/test_compute_mgr.py524
2 files changed, 524 insertions, 485 deletions
diff --git a/nova/tests/compute/test_compute.py b/nova/tests/compute/test_compute.py
index 73e260990..0e1766077 100644
--- a/nova/tests/compute/test_compute.py
+++ b/nova/tests/compute/test_compute.py
@@ -62,7 +62,6 @@ from nova.openstack.common import uuidutils
from nova import policy
from nova import quota
from nova import test
-from nova.tests.api.openstack import fakes
from nova.tests.compute import fake_resource_tracker
from nova.tests.db import fakes as db_fakes
from nova.tests import fake_instance
@@ -1069,103 +1068,6 @@ class ComputeTestCase(BaseTestCase):
self._assert_state({'vm_state': vm_states.ERROR,
'task_state': None})
- def test_allocate_network_succeeds_after_retries(self):
- # Undo setUp() stubs as this is a true unit test
- self.stubs.UnsetAll()
- self.flags(network_allocate_retries=8)
-
- nwapi = self.compute.network_api
- self.mox.StubOutWithMock(nwapi, 'allocate_for_instance')
- self.mox.StubOutWithMock(time, 'sleep')
-
- instance = {}
- is_vpn = 'fake-is-vpn'
- req_networks = 'fake-req-networks'
- macs = 'fake-macs'
- sec_groups = 'fake-sec-groups'
- final_result = 'meow'
-
- expected_sleep_times = [1, 2, 4, 8, 16, 30, 30, 30]
-
- for sleep_time in expected_sleep_times:
- nwapi.allocate_for_instance(
- self.context, instance, vpn=is_vpn,
- requested_networks=req_networks, macs=macs,
- conductor_api=self.compute.conductor_api,
- security_groups=sec_groups).AndRaise(
- test.TestingException())
- time.sleep(sleep_time)
-
- nwapi.allocate_for_instance(
- self.context, instance, vpn=is_vpn,
- requested_networks=req_networks, macs=macs,
- conductor_api=self.compute.conductor_api,
- security_groups=sec_groups).AndReturn(final_result)
-
- self.mox.ReplayAll()
-
- res = self.compute._allocate_network_async(self.context, instance,
- req_networks,
- macs,
- sec_groups,
- is_vpn)
- self.assertEqual(final_result, res)
-
- def test_allocate_network_fails(self):
- # Undo setUp() stubs as this is a true unit test
- self.stubs.UnsetAll()
- self.flags(network_allocate_retries=0)
-
- nwapi = self.compute.network_api
- self.mox.StubOutWithMock(nwapi, 'allocate_for_instance')
-
- instance = {}
- is_vpn = 'fake-is-vpn'
- req_networks = 'fake-req-networks'
- macs = 'fake-macs'
- sec_groups = 'fake-sec-groups'
-
- nwapi.allocate_for_instance(
- self.context, instance, vpn=is_vpn,
- requested_networks=req_networks, macs=macs,
- conductor_api=self.compute.conductor_api,
- security_groups=sec_groups).AndRaise(test.TestingException())
-
- self.mox.ReplayAll()
-
- self.assertRaises(test.TestingException,
- self.compute._allocate_network_async,
- self.context, instance, req_networks, macs,
- sec_groups, is_vpn)
-
- def test_allocate_network_neg_conf_value_treated_as_zero(self):
- # Undo setUp() stubs as this is a true unit test
- self.stubs.UnsetAll()
- self.flags(network_allocate_retries=-1)
-
- nwapi = self.compute.network_api
- self.mox.StubOutWithMock(nwapi, 'allocate_for_instance')
-
- instance = {}
- is_vpn = 'fake-is-vpn'
- req_networks = 'fake-req-networks'
- macs = 'fake-macs'
- sec_groups = 'fake-sec-groups'
-
- # Only attempted once.
- nwapi.allocate_for_instance(
- self.context, instance, vpn=is_vpn,
- requested_networks=req_networks, macs=macs,
- conductor_api=self.compute.conductor_api,
- security_groups=sec_groups).AndRaise(test.TestingException())
-
- self.mox.ReplayAll()
-
- self.assertRaises(test.TestingException,
- self.compute._allocate_network_async,
- self.context, instance, req_networks, macs,
- sec_groups, is_vpn)
-
def test_run_instance_dealloc_network_instance_not_found(self):
"""spawn network deallocate test.
@@ -4933,334 +4835,6 @@ class ComputeTestCase(BaseTestCase):
self.mox.ReplayAll()
self.compute._destroy_evacuated_instances(fake_context)
- def test_init_host(self):
- our_host = self.compute.host
- fake_context = 'fake-context'
- inst = dict(fakes.stub_instance(1),
- deleted_at=None, created_at=None, updated_at=None,
- deleted=0, info_cache={'instance_uuid': 'fake-uuid',
- 'network_info': None},
- security_groups=None)
- startup_instances = [inst, inst, inst]
-
- def _do_mock_calls(defer_iptables_apply):
- self.compute.driver.init_host(host=our_host)
- context.get_admin_context().AndReturn(fake_context)
- db.instance_get_all_by_host(
- fake_context, our_host, columns_to_join=['info_cache']
- ).AndReturn(startup_instances)
- if defer_iptables_apply:
- self.compute.driver.filter_defer_apply_on()
- self.compute._destroy_evacuated_instances(fake_context)
- self.compute._init_instance(fake_context,
- mox.IsA(instance_obj.Instance))
- self.compute._init_instance(fake_context,
- mox.IsA(instance_obj.Instance))
- self.compute._init_instance(fake_context,
- mox.IsA(instance_obj.Instance))
- if defer_iptables_apply:
- self.compute.driver.filter_defer_apply_off()
- self.compute._report_driver_status(fake_context)
- self.compute.publish_service_capabilities(fake_context)
-
- self.mox.StubOutWithMock(self.compute.driver, 'init_host')
- self.mox.StubOutWithMock(self.compute.driver,
- 'filter_defer_apply_on')
- self.mox.StubOutWithMock(self.compute.driver,
- 'filter_defer_apply_off')
- self.mox.StubOutWithMock(db, 'instance_get_all_by_host')
- self.mox.StubOutWithMock(context, 'get_admin_context')
- self.mox.StubOutWithMock(self.compute,
- '_destroy_evacuated_instances')
- self.mox.StubOutWithMock(self.compute,
- '_init_instance')
- self.mox.StubOutWithMock(self.compute,
- '_report_driver_status')
- self.mox.StubOutWithMock(self.compute,
- 'publish_service_capabilities')
-
- # Test with defer_iptables_apply
- self.flags(defer_iptables_apply=True)
- _do_mock_calls(True)
-
- self.mox.ReplayAll()
- self.compute.init_host()
- self.mox.VerifyAll()
-
- # Test without defer_iptables_apply
- self.mox.ResetAll()
- self.flags(defer_iptables_apply=False)
- _do_mock_calls(False)
-
- self.mox.ReplayAll()
- self.compute.init_host()
- # tearDown() uses context.get_admin_context(), so we have
- # to do the verification here and unstub it.
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
-
- def test_init_host_with_deleted_migration(self):
- our_host = self.compute.host
- not_our_host = 'not-' + our_host
- fake_context = 'fake-context'
-
- deleted_instance = {
- 'name': 'fake-name',
- 'host': not_our_host,
- 'uuid': 'fake-uuid',
- }
-
- self.mox.StubOutWithMock(self.compute.driver, 'init_host')
- self.mox.StubOutWithMock(self.compute.driver, 'destroy')
- self.mox.StubOutWithMock(db, 'instance_get_all_by_host')
- self.mox.StubOutWithMock(context, 'get_admin_context')
- self.mox.StubOutWithMock(self.compute, 'init_virt_events')
- self.mox.StubOutWithMock(self.compute, '_get_instances_on_driver')
- self.mox.StubOutWithMock(self.compute, '_init_instance')
- self.mox.StubOutWithMock(self.compute, '_report_driver_status')
- self.mox.StubOutWithMock(self.compute, 'publish_service_capabilities')
- self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
-
- self.compute.driver.init_host(host=our_host)
- context.get_admin_context().AndReturn(fake_context)
- db.instance_get_all_by_host(fake_context, our_host,
- columns_to_join=['info_cache']
- ).AndReturn([])
- self.compute.init_virt_events()
-
- # simulate failed instance
- self.compute._get_instances_on_driver(
- fake_context, {'deleted': False}).AndReturn([deleted_instance])
- self.compute._get_instance_nw_info(fake_context, deleted_instance
- ).AndRaise(exception.InstanceNotFound(
- instance_id=deleted_instance['uuid']))
- # ensure driver.destroy is called so that driver may
- # clean up any dangling files
- self.compute.driver.destroy(deleted_instance,
- mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
-
- self.compute._report_driver_status(fake_context)
- self.compute.publish_service_capabilities(fake_context)
-
- self.mox.ReplayAll()
- self.compute.init_host()
- # tearDown() uses context.get_admin_context(), so we have
- # to do the verification here and unstub it.
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
-
- def test_init_instance_failed_resume_sets_error(self):
- instance = {
- 'uuid': 'fake-uuid',
- 'info_cache': None,
- 'power_state': power_state.RUNNING,
- 'vm_state': vm_states.ACTIVE,
- 'task_state': None,
- }
- self.flags(resume_guests_state_on_host_boot=True)
- self.mox.StubOutWithMock(self.compute, '_get_power_state')
- self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
- self.mox.StubOutWithMock(self.compute.driver,
- 'resume_state_on_host_boot')
- self.mox.StubOutWithMock(self.compute,
- '_get_instance_volume_block_device_info')
- self.mox.StubOutWithMock(self.compute,
- '_set_instance_error_state')
- self.compute._get_power_state(mox.IgnoreArg(),
- instance).AndReturn(power_state.SHUTDOWN)
- self.compute.driver.plug_vifs(instance, mox.IgnoreArg())
- self.compute._get_instance_volume_block_device_info(mox.IgnoreArg(),
- instance).AndReturn('fake-bdm')
- self.compute.driver.resume_state_on_host_boot(mox.IgnoreArg(),
- instance, mox.IgnoreArg(),
- 'fake-bdm').AndRaise(test.TestingException)
- self.compute._set_instance_error_state(mox.IgnoreArg(),
- instance['uuid'])
- self.mox.ReplayAll()
- self.compute._init_instance('fake-context', instance)
-
- def _test_init_instance_reverts_crashed_migrations(self,
- old_vm_state=None):
- power_on = True if (not old_vm_state or
- old_vm_state == vm_states.ACTIVE) else False
- sys_meta = {
- 'old_vm_state': old_vm_state
- }
- instance = {
- 'uuid': 'foo',
- 'vm_state': vm_states.ERROR,
- 'task_state': task_states.RESIZE_MIGRATING,
- 'power_state': power_state.SHUTDOWN,
- 'system_metadata': sys_meta
- }
- fixed = dict(instance, task_state=None)
- self.mox.StubOutWithMock(compute_utils, 'get_nw_info_for_instance')
- self.mox.StubOutWithMock(utils, 'instance_sys_meta')
- self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
- self.mox.StubOutWithMock(self.compute.driver,
- 'finish_revert_migration')
- self.mox.StubOutWithMock(self.compute,
- '_get_instance_volume_block_device_info')
- self.mox.StubOutWithMock(self.compute.driver, 'get_info')
- self.mox.StubOutWithMock(self.compute, '_instance_update')
-
- compute_utils.get_nw_info_for_instance(instance).AndReturn(
- network_model.NetworkInfo())
- self.compute.driver.plug_vifs(instance, [])
- utils.instance_sys_meta(instance).AndReturn(sys_meta)
- self.compute._get_instance_volume_block_device_info(
- self.context, instance).AndReturn([])
- self.compute.driver.finish_revert_migration(instance, [], [], power_on)
- self.compute._instance_update(self.context, instance['uuid'],
- task_state=None).AndReturn(fixed)
- self.compute.driver.get_info(fixed).AndReturn(
- {'state': power_state.SHUTDOWN})
-
- self.mox.ReplayAll()
-
- self.compute._init_instance(self.context, instance)
-
- def test_init_instance_reverts_crashed_migration_from_active(self):
- self._test_init_instance_reverts_crashed_migrations(
- old_vm_state=vm_states.ACTIVE)
-
- def test_init_instance_reverts_crashed_migration_from_stopped(self):
- self._test_init_instance_reverts_crashed_migrations(
- old_vm_state=vm_states.STOPPED)
-
- def test_init_instance_reverts_crashed_migration_no_old_state(self):
- self._test_init_instance_reverts_crashed_migrations(old_vm_state=None)
-
- def _test_init_instance_update_nw_info_cache_helper(self, legacy_nwinfo):
- self.compute.driver.legacy_nwinfo = lambda *a, **k: legacy_nwinfo
-
- cached_nw_info = fake_network_cache_model.new_vif()
- cached_nw_info = network_model.NetworkInfo([cached_nw_info])
- old_cached_nw_info = copy.deepcopy(cached_nw_info)
-
- # Folsom has no 'type' in network cache info.
- del old_cached_nw_info[0]['type']
- fake_info_cache = {'network_info': old_cached_nw_info.json()}
- instance = {
- 'uuid': 'a-foo-uuid',
- 'vm_state': vm_states.ACTIVE,
- 'task_state': None,
- 'power_state': power_state.RUNNING,
- 'info_cache': fake_info_cache,
- }
-
- self.mox.StubOutWithMock(self.compute, '_get_power_state')
- self.compute._get_power_state(mox.IgnoreArg(),
- instance).AndReturn(power_state.RUNNING)
-
- if legacy_nwinfo:
- self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
- # Call network API to get instance network info, and force
- # an update to instance's info_cache.
- self.compute._get_instance_nw_info(self.context,
- instance).AndReturn(cached_nw_info)
-
- self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
- self.compute.driver.plug_vifs(instance, cached_nw_info.legacy())
- else:
- self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
- self.compute.driver.plug_vifs(instance, cached_nw_info)
-
- self.mox.ReplayAll()
-
- self.compute._init_instance(self.context, instance)
-
- def test_init_instance_update_nw_info_cache_legacy(self):
- """network_info in legacy is form [(network_dict, info_dict)]."""
- self._test_init_instance_update_nw_info_cache_helper(True)
-
- def test_init_instance_update_nw_info_cache(self):
- """network_info is NetworkInfo list-like object."""
- self._test_init_instance_update_nw_info_cache_helper(False)
-
- def test_get_instances_on_driver(self):
- fake_context = context.get_admin_context()
-
- driver_instances = []
- for x in xrange(10):
- instance = dict(uuid=uuidutils.generate_uuid())
- driver_instances.append(instance)
-
- self.mox.StubOutWithMock(self.compute.driver,
- 'list_instance_uuids')
- self.mox.StubOutWithMock(self.compute.conductor_api,
- 'instance_get_all_by_filters')
-
- self.compute.driver.list_instance_uuids().AndReturn(
- [inst['uuid'] for inst in driver_instances])
- self.compute.conductor_api.instance_get_all_by_filters(
- fake_context,
- {'uuid': [inst['uuid'] for
- inst in driver_instances]},
- columns_to_join=[]).AndReturn(
- driver_instances)
-
- self.mox.ReplayAll()
-
- result = self.compute._get_instances_on_driver(fake_context,
- columns_to_join=[])
- self.assertEqual(driver_instances, result)
-
- def test_get_instances_on_driver_fallback(self):
- # Test getting instances when driver doesn't support
- # 'list_instance_uuids'
- self.compute.host = 'host'
- filters = {'host': self.compute.host}
- fake_context = context.get_admin_context()
-
- all_instances = []
- driver_instances = []
- for x in xrange(10):
- instance = dict(name=uuidutils.generate_uuid())
- if x % 2:
- driver_instances.append(instance)
- all_instances.append(instance)
-
- self.mox.StubOutWithMock(self.compute.driver,
- 'list_instance_uuids')
- self.mox.StubOutWithMock(self.compute.driver,
- 'list_instances')
- self.mox.StubOutWithMock(self.compute.conductor_api,
- 'instance_get_all_by_filters')
-
- self.compute.driver.list_instance_uuids().AndRaise(
- NotImplementedError())
- self.compute.driver.list_instances().AndReturn(
- [inst['name'] for inst in driver_instances])
- self.compute.conductor_api.instance_get_all_by_filters(
- fake_context, filters,
- columns_to_join=None).AndReturn(all_instances)
-
- self.mox.ReplayAll()
-
- result = self.compute._get_instances_on_driver(fake_context, filters)
- self.assertEqual(driver_instances, result)
-
- def test_instance_usage_audit(self):
- instances = [{'uuid': 'foo'}]
- self.flags(instance_usage_audit=True)
- self.stubs.Set(compute_utils, 'has_audit_been_run',
- lambda *a, **k: False)
- self.stubs.Set(self.compute.conductor_api,
- 'instance_get_active_by_window_joined',
- lambda *a, **k: instances)
- self.stubs.Set(compute_utils, 'start_instance_usage_audit',
- lambda *a, **k: None)
- self.stubs.Set(compute_utils, 'finish_instance_usage_audit',
- lambda *a, **k: None)
-
- self.mox.StubOutWithMock(self.compute.conductor_api,
- 'notify_usage_exists')
- self.compute.conductor_api.notify_usage_exists(
- self.context, instances[0], ignore_missing_network_data=False)
- self.mox.ReplayAll()
- self.compute._instance_usage_audit(self.context)
-
def test_add_remove_fixed_ip_updates_instance_updated_at(self):
def _noop(*args, **kwargs):
pass
@@ -5340,65 +4914,6 @@ class ComputeTestCase(BaseTestCase):
self.mox.ReplayAll()
self.compute._sync_power_states(ctxt)
- def _get_sync_instance(self, power_state, vm_state, task_state=None):
- instance = instance_obj.Instance()
- instance.uuid = 'fake-uuid'
- instance.power_state = power_state
- instance.vm_state = vm_state
- instance.host = self.compute.host
- instance.task_state = task_state
- self.mox.StubOutWithMock(instance, 'refresh')
- self.mox.StubOutWithMock(instance, 'save')
- return instance
-
- def test_sync_instance_power_state_match(self):
- instance = self._get_sync_instance(power_state.RUNNING,
- vm_states.ACTIVE)
- instance.refresh()
- self.mox.ReplayAll()
- self.compute._sync_instance_power_state(self.context, instance,
- power_state.RUNNING)
-
- def test_sync_instance_power_state_running_stopped(self):
- instance = self._get_sync_instance(power_state.RUNNING,
- vm_states.ACTIVE)
- instance.refresh()
- instance.save()
- self.mox.ReplayAll()
- self.compute._sync_instance_power_state(self.context, instance,
- power_state.SHUTDOWN)
- self.assertEqual(instance.power_state, power_state.SHUTDOWN)
-
- def _test_sync_to_stop(self, power_state, vm_state, driver_power_state,
- stop=True):
- instance = self._get_sync_instance(power_state, vm_state)
- instance.refresh()
- instance.save()
- self.mox.StubOutWithMock(self.compute.conductor_api, 'compute_stop')
- if stop:
- self.compute.conductor_api.compute_stop(self.context, instance)
- self.mox.ReplayAll()
- self.compute._sync_instance_power_state(self.context, instance,
- driver_power_state)
- self.mox.VerifyAll()
- self.mox.UnsetStubs()
-
- def test_sync_instance_power_state_to_stop(self):
- for ps in (power_state.SHUTDOWN, power_state.CRASHED,
- power_state.SUSPENDED):
- self._test_sync_to_stop(power_state.RUNNING, vm_states.ACTIVE, ps)
- self._test_sync_to_stop(power_state.SHUTDOWN, vm_states.STOPPED,
- power_state.RUNNING)
-
- def test_sync_instance_power_state_to_no_stop(self):
- for ps in (power_state.PAUSED, power_state.NOSTATE):
- self._test_sync_to_stop(power_state.RUNNING, vm_states.ACTIVE, ps,
- stop=False)
- for vs in (vm_states.SOFT_DELETED, vm_states.DELETED):
- for ps in (power_state.NOSTATE, power_state.SHUTDOWN):
- self._test_sync_to_stop(power_state.RUNNING, vs, ps,
- stop=False)
-
def _test_lifecycle_event(self, lifecycle_event, power_state):
instance = self._create_fake_instance()
uuid = instance['uuid']
diff --git a/nova/tests/compute/test_compute_mgr.py b/nova/tests/compute/test_compute_mgr.py
new file mode 100644
index 000000000..526fe14d9
--- /dev/null
+++ b/nova/tests/compute/test_compute_mgr.py
@@ -0,0 +1,524 @@
+# 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.
+
+"""Unit tests for ComputeManager()."""
+
+import copy
+import time
+
+import mox
+from oslo.config import cfg
+
+from nova.compute import power_state
+from nova.compute import task_states
+from nova.compute import utils as compute_utils
+from nova.compute import vm_states
+from nova import context
+from nova import db
+from nova import exception
+from nova.network import model as network_model
+from nova.objects import instance as instance_obj
+from nova.openstack.common import importutils
+from nova.openstack.common import uuidutils
+from nova import test
+from nova.tests import fake_instance
+from nova.tests import fake_network_cache_model
+from nova import utils
+
+
+CONF = cfg.CONF
+CONF.import_opt('compute_manager', 'nova.service')
+
+
+class ComputeManagerUnitTestCase(test.NoDBTestCase):
+ def setUp(self):
+ super(ComputeManagerUnitTestCase, self).setUp()
+ self.compute = importutils.import_object(CONF.compute_manager)
+ self.context = context.RequestContext('fake', 'fake')
+
+ def test_allocate_network_succeeds_after_retries(self):
+ self.flags(network_allocate_retries=8)
+
+ nwapi = self.compute.network_api
+ self.mox.StubOutWithMock(nwapi, 'allocate_for_instance')
+ self.mox.StubOutWithMock(time, 'sleep')
+
+ instance = {}
+ is_vpn = 'fake-is-vpn'
+ req_networks = 'fake-req-networks'
+ macs = 'fake-macs'
+ sec_groups = 'fake-sec-groups'
+ final_result = 'meow'
+
+ expected_sleep_times = [1, 2, 4, 8, 16, 30, 30, 30]
+
+ for sleep_time in expected_sleep_times:
+ nwapi.allocate_for_instance(
+ self.context, instance, vpn=is_vpn,
+ requested_networks=req_networks, macs=macs,
+ conductor_api=self.compute.conductor_api,
+ security_groups=sec_groups).AndRaise(
+ test.TestingException())
+ time.sleep(sleep_time)
+
+ nwapi.allocate_for_instance(
+ self.context, instance, vpn=is_vpn,
+ requested_networks=req_networks, macs=macs,
+ conductor_api=self.compute.conductor_api,
+ security_groups=sec_groups).AndReturn(final_result)
+
+ self.mox.ReplayAll()
+
+ res = self.compute._allocate_network_async(self.context, instance,
+ req_networks,
+ macs,
+ sec_groups,
+ is_vpn)
+ self.assertEqual(final_result, res)
+
+ def test_allocate_network_fails(self):
+ self.flags(network_allocate_retries=0)
+
+ nwapi = self.compute.network_api
+ self.mox.StubOutWithMock(nwapi, 'allocate_for_instance')
+
+ instance = {}
+ is_vpn = 'fake-is-vpn'
+ req_networks = 'fake-req-networks'
+ macs = 'fake-macs'
+ sec_groups = 'fake-sec-groups'
+
+ nwapi.allocate_for_instance(
+ self.context, instance, vpn=is_vpn,
+ requested_networks=req_networks, macs=macs,
+ conductor_api=self.compute.conductor_api,
+ security_groups=sec_groups).AndRaise(test.TestingException())
+
+ self.mox.ReplayAll()
+
+ self.assertRaises(test.TestingException,
+ self.compute._allocate_network_async,
+ self.context, instance, req_networks, macs,
+ sec_groups, is_vpn)
+
+ def test_allocate_network_neg_conf_value_treated_as_zero(self):
+ self.flags(network_allocate_retries=-1)
+
+ nwapi = self.compute.network_api
+ self.mox.StubOutWithMock(nwapi, 'allocate_for_instance')
+
+ instance = {}
+ is_vpn = 'fake-is-vpn'
+ req_networks = 'fake-req-networks'
+ macs = 'fake-macs'
+ sec_groups = 'fake-sec-groups'
+
+ # Only attempted once.
+ nwapi.allocate_for_instance(
+ self.context, instance, vpn=is_vpn,
+ requested_networks=req_networks, macs=macs,
+ conductor_api=self.compute.conductor_api,
+ security_groups=sec_groups).AndRaise(test.TestingException())
+
+ self.mox.ReplayAll()
+
+ self.assertRaises(test.TestingException,
+ self.compute._allocate_network_async,
+ self.context, instance, req_networks, macs,
+ sec_groups, is_vpn)
+
+ def test_init_host(self):
+ our_host = self.compute.host
+ fake_context = 'fake-context'
+ inst = fake_instance.fake_db_instance(
+ vm_state=vm_states.ACTIVE,
+ info_cache={'instance_uuid': 'fake-uuid',
+ 'network_info': None},
+ security_groups=None)
+ startup_instances = [inst, inst, inst]
+
+ def _do_mock_calls(defer_iptables_apply):
+ self.compute.driver.init_host(host=our_host)
+ context.get_admin_context().AndReturn(fake_context)
+ db.instance_get_all_by_host(
+ fake_context, our_host, columns_to_join=['info_cache']
+ ).AndReturn(startup_instances)
+ if defer_iptables_apply:
+ self.compute.driver.filter_defer_apply_on()
+ self.compute._destroy_evacuated_instances(fake_context)
+ self.compute._init_instance(fake_context,
+ mox.IsA(instance_obj.Instance))
+ self.compute._init_instance(fake_context,
+ mox.IsA(instance_obj.Instance))
+ self.compute._init_instance(fake_context,
+ mox.IsA(instance_obj.Instance))
+ if defer_iptables_apply:
+ self.compute.driver.filter_defer_apply_off()
+ self.compute._report_driver_status(fake_context)
+ self.compute.publish_service_capabilities(fake_context)
+
+ self.mox.StubOutWithMock(self.compute.driver, 'init_host')
+ self.mox.StubOutWithMock(self.compute.driver,
+ 'filter_defer_apply_on')
+ self.mox.StubOutWithMock(self.compute.driver,
+ 'filter_defer_apply_off')
+ self.mox.StubOutWithMock(db, 'instance_get_all_by_host')
+ self.mox.StubOutWithMock(context, 'get_admin_context')
+ self.mox.StubOutWithMock(self.compute,
+ '_destroy_evacuated_instances')
+ self.mox.StubOutWithMock(self.compute,
+ '_init_instance')
+ self.mox.StubOutWithMock(self.compute,
+ '_report_driver_status')
+ self.mox.StubOutWithMock(self.compute,
+ 'publish_service_capabilities')
+
+ # Test with defer_iptables_apply
+ self.flags(defer_iptables_apply=True)
+ _do_mock_calls(True)
+
+ self.mox.ReplayAll()
+ self.compute.init_host()
+ self.mox.VerifyAll()
+
+ # Test without defer_iptables_apply
+ self.mox.ResetAll()
+ self.flags(defer_iptables_apply=False)
+ _do_mock_calls(False)
+
+ self.mox.ReplayAll()
+ self.compute.init_host()
+ # tearDown() uses context.get_admin_context(), so we have
+ # to do the verification here and unstub it.
+ self.mox.VerifyAll()
+ self.mox.UnsetStubs()
+
+ def test_init_host_with_deleted_migration(self):
+ our_host = self.compute.host
+ not_our_host = 'not-' + our_host
+ fake_context = 'fake-context'
+
+ deleted_instance = {
+ 'name': 'fake-name',
+ 'host': not_our_host,
+ 'uuid': 'fake-uuid',
+ }
+
+ self.mox.StubOutWithMock(self.compute.driver, 'init_host')
+ self.mox.StubOutWithMock(self.compute.driver, 'destroy')
+ self.mox.StubOutWithMock(db, 'instance_get_all_by_host')
+ self.mox.StubOutWithMock(context, 'get_admin_context')
+ self.mox.StubOutWithMock(self.compute, 'init_virt_events')
+ self.mox.StubOutWithMock(self.compute, '_get_instances_on_driver')
+ self.mox.StubOutWithMock(self.compute, '_init_instance')
+ self.mox.StubOutWithMock(self.compute, '_report_driver_status')
+ self.mox.StubOutWithMock(self.compute, 'publish_service_capabilities')
+ self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
+
+ self.compute.driver.init_host(host=our_host)
+ context.get_admin_context().AndReturn(fake_context)
+ db.instance_get_all_by_host(fake_context, our_host,
+ columns_to_join=['info_cache']
+ ).AndReturn([])
+ self.compute.init_virt_events()
+
+ # simulate failed instance
+ self.compute._get_instances_on_driver(
+ fake_context, {'deleted': False}).AndReturn([deleted_instance])
+ self.compute._get_instance_nw_info(fake_context, deleted_instance
+ ).AndRaise(exception.InstanceNotFound(
+ instance_id=deleted_instance['uuid']))
+ # ensure driver.destroy is called so that driver may
+ # clean up any dangling files
+ self.compute.driver.destroy(deleted_instance,
+ mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
+
+ self.compute._report_driver_status(fake_context)
+ self.compute.publish_service_capabilities(fake_context)
+
+ self.mox.ReplayAll()
+ self.compute.init_host()
+ # tearDown() uses context.get_admin_context(), so we have
+ # to do the verification here and unstub it.
+ self.mox.VerifyAll()
+ self.mox.UnsetStubs()
+
+ def test_init_instance_failed_resume_sets_error(self):
+ instance = {
+ 'uuid': 'fake-uuid',
+ 'info_cache': None,
+ 'power_state': power_state.RUNNING,
+ 'vm_state': vm_states.ACTIVE,
+ 'task_state': None,
+ }
+ self.flags(resume_guests_state_on_host_boot=True)
+ self.mox.StubOutWithMock(self.compute, '_get_power_state')
+ self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
+ self.mox.StubOutWithMock(self.compute.driver,
+ 'resume_state_on_host_boot')
+ self.mox.StubOutWithMock(self.compute,
+ '_get_instance_volume_block_device_info')
+ self.mox.StubOutWithMock(self.compute,
+ '_set_instance_error_state')
+ self.compute._get_power_state(mox.IgnoreArg(),
+ instance).AndReturn(power_state.SHUTDOWN)
+ self.compute.driver.plug_vifs(instance, mox.IgnoreArg())
+ self.compute._get_instance_volume_block_device_info(mox.IgnoreArg(),
+ instance).AndReturn('fake-bdm')
+ self.compute.driver.resume_state_on_host_boot(mox.IgnoreArg(),
+ instance, mox.IgnoreArg(),
+ 'fake-bdm').AndRaise(test.TestingException)
+ self.compute._set_instance_error_state(mox.IgnoreArg(),
+ instance['uuid'])
+ self.mox.ReplayAll()
+ self.compute._init_instance('fake-context', instance)
+
+ def _test_init_instance_reverts_crashed_migrations(self,
+ old_vm_state=None):
+ power_on = True if (not old_vm_state or
+ old_vm_state == vm_states.ACTIVE) else False
+ sys_meta = {
+ 'old_vm_state': old_vm_state
+ }
+ instance = {
+ 'uuid': 'foo',
+ 'vm_state': vm_states.ERROR,
+ 'task_state': task_states.RESIZE_MIGRATING,
+ 'power_state': power_state.SHUTDOWN,
+ 'system_metadata': sys_meta
+ }
+ fixed = dict(instance, task_state=None)
+ self.mox.StubOutWithMock(compute_utils, 'get_nw_info_for_instance')
+ self.mox.StubOutWithMock(utils, 'instance_sys_meta')
+ self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
+ self.mox.StubOutWithMock(self.compute.driver,
+ 'finish_revert_migration')
+ self.mox.StubOutWithMock(self.compute,
+ '_get_instance_volume_block_device_info')
+ self.mox.StubOutWithMock(self.compute.driver, 'get_info')
+ self.mox.StubOutWithMock(self.compute, '_instance_update')
+
+ compute_utils.get_nw_info_for_instance(instance).AndReturn(
+ network_model.NetworkInfo())
+ self.compute.driver.plug_vifs(instance, [])
+ utils.instance_sys_meta(instance).AndReturn(sys_meta)
+ self.compute._get_instance_volume_block_device_info(
+ self.context, instance).AndReturn([])
+ self.compute.driver.finish_revert_migration(instance, [], [], power_on)
+ self.compute._instance_update(self.context, instance['uuid'],
+ task_state=None).AndReturn(fixed)
+ self.compute.driver.get_info(fixed).AndReturn(
+ {'state': power_state.SHUTDOWN})
+
+ self.mox.ReplayAll()
+
+ self.compute._init_instance(self.context, instance)
+
+ def test_init_instance_reverts_crashed_migration_from_active(self):
+ self._test_init_instance_reverts_crashed_migrations(
+ old_vm_state=vm_states.ACTIVE)
+
+ def test_init_instance_reverts_crashed_migration_from_stopped(self):
+ self._test_init_instance_reverts_crashed_migrations(
+ old_vm_state=vm_states.STOPPED)
+
+ def test_init_instance_reverts_crashed_migration_no_old_state(self):
+ self._test_init_instance_reverts_crashed_migrations(old_vm_state=None)
+
+ def _test_init_instance_update_nw_info_cache_helper(self, legacy_nwinfo):
+ self.compute.driver.legacy_nwinfo = lambda *a, **k: legacy_nwinfo
+
+ cached_nw_info = fake_network_cache_model.new_vif()
+ cached_nw_info = network_model.NetworkInfo([cached_nw_info])
+ old_cached_nw_info = copy.deepcopy(cached_nw_info)
+
+ # Folsom has no 'type' in network cache info.
+ del old_cached_nw_info[0]['type']
+ fake_info_cache = {'network_info': old_cached_nw_info.json()}
+ instance = {
+ 'uuid': 'a-foo-uuid',
+ 'vm_state': vm_states.ACTIVE,
+ 'task_state': None,
+ 'power_state': power_state.RUNNING,
+ 'info_cache': fake_info_cache,
+ }
+
+ self.mox.StubOutWithMock(self.compute, '_get_power_state')
+ self.compute._get_power_state(mox.IgnoreArg(),
+ instance).AndReturn(power_state.RUNNING)
+
+ if legacy_nwinfo:
+ self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
+ # Call network API to get instance network info, and force
+ # an update to instance's info_cache.
+ self.compute._get_instance_nw_info(self.context,
+ instance).AndReturn(cached_nw_info)
+
+ self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
+ self.compute.driver.plug_vifs(instance, cached_nw_info.legacy())
+ else:
+ self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
+ self.compute.driver.plug_vifs(instance, cached_nw_info)
+
+ self.mox.ReplayAll()
+
+ self.compute._init_instance(self.context, instance)
+
+ def test_init_instance_update_nw_info_cache_legacy(self):
+ """network_info in legacy is form [(network_dict, info_dict)]."""
+ self._test_init_instance_update_nw_info_cache_helper(True)
+
+ def test_init_instance_update_nw_info_cache(self):
+ """network_info is NetworkInfo list-like object."""
+ self._test_init_instance_update_nw_info_cache_helper(False)
+
+ def test_get_instances_on_driver(self):
+ fake_context = context.get_admin_context()
+
+ driver_instances = []
+ for x in xrange(10):
+ instance = dict(uuid=uuidutils.generate_uuid())
+ driver_instances.append(instance)
+
+ self.mox.StubOutWithMock(self.compute.driver,
+ 'list_instance_uuids')
+ self.mox.StubOutWithMock(self.compute.conductor_api,
+ 'instance_get_all_by_filters')
+
+ self.compute.driver.list_instance_uuids().AndReturn(
+ [inst['uuid'] for inst in driver_instances])
+ self.compute.conductor_api.instance_get_all_by_filters(
+ fake_context,
+ {'uuid': [inst['uuid'] for
+ inst in driver_instances]},
+ columns_to_join=[]).AndReturn(
+ driver_instances)
+
+ self.mox.ReplayAll()
+
+ result = self.compute._get_instances_on_driver(fake_context,
+ columns_to_join=[])
+ self.assertEqual(driver_instances, result)
+
+ def test_get_instances_on_driver_fallback(self):
+ # Test getting instances when driver doesn't support
+ # 'list_instance_uuids'
+ self.compute.host = 'host'
+ filters = {'host': self.compute.host}
+ fake_context = context.get_admin_context()
+
+ all_instances = []
+ driver_instances = []
+ for x in xrange(10):
+ instance = dict(name=uuidutils.generate_uuid())
+ if x % 2:
+ driver_instances.append(instance)
+ all_instances.append(instance)
+
+ self.mox.StubOutWithMock(self.compute.driver,
+ 'list_instance_uuids')
+ self.mox.StubOutWithMock(self.compute.driver,
+ 'list_instances')
+ self.mox.StubOutWithMock(self.compute.conductor_api,
+ 'instance_get_all_by_filters')
+
+ self.compute.driver.list_instance_uuids().AndRaise(
+ NotImplementedError())
+ self.compute.driver.list_instances().AndReturn(
+ [inst['name'] for inst in driver_instances])
+ self.compute.conductor_api.instance_get_all_by_filters(
+ fake_context, filters,
+ columns_to_join=None).AndReturn(all_instances)
+
+ self.mox.ReplayAll()
+
+ result = self.compute._get_instances_on_driver(fake_context, filters)
+ self.assertEqual(driver_instances, result)
+
+ def test_instance_usage_audit(self):
+ instances = [{'uuid': 'foo'}]
+ self.flags(instance_usage_audit=True)
+ self.stubs.Set(compute_utils, 'has_audit_been_run',
+ lambda *a, **k: False)
+ self.stubs.Set(self.compute.conductor_api,
+ 'instance_get_active_by_window_joined',
+ lambda *a, **k: instances)
+ self.stubs.Set(compute_utils, 'start_instance_usage_audit',
+ lambda *a, **k: None)
+ self.stubs.Set(compute_utils, 'finish_instance_usage_audit',
+ lambda *a, **k: None)
+
+ self.mox.StubOutWithMock(self.compute.conductor_api,
+ 'notify_usage_exists')
+ self.compute.conductor_api.notify_usage_exists(
+ self.context, instances[0], ignore_missing_network_data=False)
+ self.mox.ReplayAll()
+ self.compute._instance_usage_audit(self.context)
+
+ def _get_sync_instance(self, power_state, vm_state, task_state=None):
+ instance = instance_obj.Instance()
+ instance.uuid = 'fake-uuid'
+ instance.power_state = power_state
+ instance.vm_state = vm_state
+ instance.host = self.compute.host
+ instance.task_state = task_state
+ self.mox.StubOutWithMock(instance, 'refresh')
+ self.mox.StubOutWithMock(instance, 'save')
+ return instance
+
+ def test_sync_instance_power_state_match(self):
+ instance = self._get_sync_instance(power_state.RUNNING,
+ vm_states.ACTIVE)
+ instance.refresh()
+ self.mox.ReplayAll()
+ self.compute._sync_instance_power_state(self.context, instance,
+ power_state.RUNNING)
+
+ def test_sync_instance_power_state_running_stopped(self):
+ instance = self._get_sync_instance(power_state.RUNNING,
+ vm_states.ACTIVE)
+ instance.refresh()
+ instance.save()
+ self.mox.ReplayAll()
+ self.compute._sync_instance_power_state(self.context, instance,
+ power_state.SHUTDOWN)
+ self.assertEqual(instance.power_state, power_state.SHUTDOWN)
+
+ def _test_sync_to_stop(self, power_state, vm_state, driver_power_state,
+ stop=True):
+ instance = self._get_sync_instance(power_state, vm_state)
+ instance.refresh()
+ instance.save()
+ self.mox.StubOutWithMock(self.compute.conductor_api, 'compute_stop')
+ if stop:
+ self.compute.conductor_api.compute_stop(self.context, instance)
+ self.mox.ReplayAll()
+ self.compute._sync_instance_power_state(self.context, instance,
+ driver_power_state)
+ self.mox.VerifyAll()
+ self.mox.UnsetStubs()
+
+ def test_sync_instance_power_state_to_stop(self):
+ for ps in (power_state.SHUTDOWN, power_state.CRASHED,
+ power_state.SUSPENDED):
+ self._test_sync_to_stop(power_state.RUNNING, vm_states.ACTIVE, ps)
+ self._test_sync_to_stop(power_state.SHUTDOWN, vm_states.STOPPED,
+ power_state.RUNNING)
+
+ def test_sync_instance_power_state_to_no_stop(self):
+ for ps in (power_state.PAUSED, power_state.NOSTATE):
+ self._test_sync_to_stop(power_state.RUNNING, vm_states.ACTIVE, ps,
+ stop=False)
+ for vs in (vm_states.SOFT_DELETED, vm_states.DELETED):
+ for ps in (power_state.NOSTATE, power_state.SHUTDOWN):
+ self._test_sync_to_stop(power_state.RUNNING, vs, ps,
+ stop=False)