summaryrefslogtreecommitdiff
path: root/nova/tests/compute/test_compute_mgr.py
diff options
context:
space:
mode:
Diffstat (limited to 'nova/tests/compute/test_compute_mgr.py')
-rw-r--r--nova/tests/compute/test_compute_mgr.py3053
1 files changed, 0 insertions, 3053 deletions
diff --git a/nova/tests/compute/test_compute_mgr.py b/nova/tests/compute/test_compute_mgr.py
deleted file mode 100644
index 0a804ea2a9..0000000000
--- a/nova/tests/compute/test_compute_mgr.py
+++ /dev/null
@@ -1,3053 +0,0 @@
-# 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 contextlib
-import time
-
-from cinderclient import exceptions as cinder_exception
-from eventlet import event as eventlet_event
-import mock
-import mox
-from oslo.config import cfg
-from oslo import messaging
-from oslo.utils import importutils
-
-from nova.compute import manager
-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.conductor import rpcapi as conductor_rpcapi
-from nova import context
-from nova import db
-from nova import exception
-from nova.network import api as network_api
-from nova.network import model as network_model
-from nova import objects
-from nova.objects import block_device as block_device_obj
-from nova.openstack.common import uuidutils
-from nova import test
-from nova.tests.compute import fake_resource_tracker
-from nova.tests import fake_block_device
-from nova.tests import fake_instance
-from nova.tests.objects import test_instance_fault
-from nova.tests.objects import test_instance_info_cache
-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(self.compute, '_instance_update')
- self.mox.StubOutWithMock(time, 'sleep')
-
- instance = fake_instance.fake_instance_obj(
- self.context, expected_attrs=['system_metadata'])
-
- is_vpn = 'fake-is-vpn'
- req_networks = 'fake-req-networks'
- macs = 'fake-macs'
- sec_groups = 'fake-sec-groups'
- final_result = 'meow'
- dhcp_options = None
-
- 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,
- security_groups=sec_groups,
- dhcp_options=dhcp_options).AndRaise(
- test.TestingException())
- time.sleep(sleep_time)
-
- nwapi.allocate_for_instance(
- self.context, instance, vpn=is_vpn,
- requested_networks=req_networks, macs=macs,
- security_groups=sec_groups,
- dhcp_options=dhcp_options).AndReturn(final_result)
- self.compute._instance_update(self.context, instance['uuid'],
- system_metadata={'network_allocated': 'True'})
-
- self.mox.ReplayAll()
-
- res = self.compute._allocate_network_async(self.context, instance,
- req_networks,
- macs,
- sec_groups,
- is_vpn,
- dhcp_options)
- self.assertEqual(final_result, res)
-
- def test_allocate_network_maintains_context(self):
- # override tracker with a version that doesn't need the database:
- class FakeResourceTracker(object):
- def instance_claim(self, context, instance, limits):
- return mox.MockAnything()
-
- self.mox.StubOutWithMock(self.compute, '_get_resource_tracker')
- self.mox.StubOutWithMock(self.compute, '_allocate_network')
- self.mox.StubOutWithMock(objects.BlockDeviceMappingList,
- 'get_by_instance_uuid')
-
- instance = fake_instance.fake_instance_obj(self.context)
-
- objects.BlockDeviceMappingList.get_by_instance_uuid(
- mox.IgnoreArg(), instance.uuid).AndReturn([])
-
- node = 'fake_node'
- self.compute._get_resource_tracker(node).AndReturn(
- FakeResourceTracker())
-
- self.admin_context = False
-
- def fake_allocate(context, *args, **kwargs):
- if context.is_admin:
- self.admin_context = True
-
- # NOTE(vish): The nice mox parameter matchers here don't work well
- # because they raise an exception that gets wrapped by
- # the retry exception handling, so use a side effect
- # to keep track of whether allocate was called with admin
- # context.
- self.compute._allocate_network(mox.IgnoreArg(), instance,
- mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(),
- mox.IgnoreArg()).WithSideEffects(fake_allocate)
-
- self.mox.ReplayAll()
-
- instance, nw_info = self.compute._build_instance(self.context, {}, {},
- None, None, None, True,
- node, instance,
- {}, False)
- self.assertFalse(self.admin_context,
- "_allocate_network called with admin context")
- self.assertEqual(vm_states.BUILDING, instance.vm_state)
- self.assertEqual(task_states.BLOCK_DEVICE_MAPPING, instance.task_state)
-
- def test_reschedule_maintains_context(self):
- # override tracker with a version that causes a reschedule
- class FakeResourceTracker(object):
- def instance_claim(self, context, instance, limits):
- raise test.TestingException()
-
- self.mox.StubOutWithMock(self.compute, '_get_resource_tracker')
- self.mox.StubOutWithMock(self.compute, '_reschedule_or_error')
- self.mox.StubOutWithMock(objects.BlockDeviceMappingList,
- 'get_by_instance_uuid')
- instance = fake_instance.fake_instance_obj(self.context)
-
- objects.BlockDeviceMappingList.get_by_instance_uuid(
- mox.IgnoreArg(), instance.uuid).AndReturn([])
-
- node = 'fake_node'
- self.compute._get_resource_tracker(node).AndReturn(
- FakeResourceTracker())
-
- self.admin_context = False
-
- def fake_retry_or_error(context, *args, **kwargs):
- if context.is_admin:
- self.admin_context = True
-
- # NOTE(vish): we could use a mos parameter matcher here but it leads
- # to a very cryptic error message, so use the same method
- # as the allocate_network_maintains_context test.
- self.compute._reschedule_or_error(mox.IgnoreArg(), instance,
- mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(),
- mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg(),
- mox.IgnoreArg(), mox.IgnoreArg(),
- mox.IgnoreArg()).WithSideEffects(fake_retry_or_error)
-
- self.mox.ReplayAll()
-
- self.assertRaises(test.TestingException,
- self.compute._build_instance, self.context, {}, {},
- None, None, None, True, node, instance, {}, False)
- self.assertFalse(self.admin_context,
- "_reschedule_or_error called with admin context")
-
- 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'
- dhcp_options = None
-
- nwapi.allocate_for_instance(
- self.context, instance, vpn=is_vpn,
- requested_networks=req_networks, macs=macs,
- security_groups=sec_groups,
- dhcp_options=dhcp_options).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, dhcp_options)
-
- 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'
- dhcp_options = None
-
- # Only attempted once.
- nwapi.allocate_for_instance(
- self.context, instance, vpn=is_vpn,
- requested_networks=req_networks, macs=macs,
- security_groups=sec_groups,
- dhcp_options=dhcp_options).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, dhcp_options)
-
- @mock.patch.object(network_api.API, 'allocate_for_instance')
- @mock.patch.object(manager.ComputeManager, '_instance_update')
- @mock.patch.object(time, 'sleep')
- def test_allocate_network_with_conf_value_is_one(
- self, sleep, _instance_update, allocate_for_instance):
- self.flags(network_allocate_retries=1)
-
- instance = fake_instance.fake_instance_obj(
- self.context, expected_attrs=['system_metadata'])
- is_vpn = 'fake-is-vpn'
- req_networks = 'fake-req-networks'
- macs = 'fake-macs'
- sec_groups = 'fake-sec-groups'
- dhcp_options = None
- final_result = 'zhangtralon'
-
- allocate_for_instance.side_effect = [test.TestingException(),
- final_result]
- res = self.compute._allocate_network_async(self.context, instance,
- req_networks,
- macs,
- sec_groups,
- is_vpn,
- dhcp_options)
- self.assertEqual(final_result, res)
- self.assertEqual(1, sleep.call_count)
-
- 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=dict(test_instance_info_cache.fake_info_cache,
- 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'],
- use_slave=False
- ).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(objects.Instance))
- self.compute._init_instance(fake_context,
- mox.IsA(objects.Instance))
- self.compute._init_instance(fake_context,
- mox.IsA(objects.Instance))
- if defer_iptables_apply:
- self.compute.driver.filter_defer_apply_off()
-
- 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')
-
- # 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()
-
- @mock.patch('nova.objects.InstanceList')
- def test_cleanup_host(self, mock_instance_list):
- # just testing whether the cleanup_host method
- # when fired will invoke the underlying driver's
- # equivalent method.
-
- mock_instance_list.get_by_host.return_value = []
-
- with mock.patch.object(self.compute, 'driver') as mock_driver:
- self.compute.init_host()
- mock_driver.init_host.assert_called_once_with(host='fake-mini')
-
- self.compute.cleanup_host()
- mock_driver.cleanup_host.assert_called_once_with(host='fake-mini')
-
- 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 = fake_instance.fake_instance_obj(
- self.context, 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, '_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'],
- use_slave=False
- ).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(fake_context, deleted_instance,
- mox.IgnoreArg(), mox.IgnoreArg(), mox.IgnoreArg())
-
- 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 = fake_instance.fake_instance_obj(
- self.context,
- uuid='fake-uuid',
- info_cache=None,
- power_state=power_state.RUNNING,
- vm_state=vm_states.ACTIVE,
- task_state=None,
- expected_attrs=['info_cache'])
-
- 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_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._get_power_state(mox.IgnoreArg(),
- instance).AndReturn(power_state.SHUTDOWN)
- self.compute._get_power_state(mox.IgnoreArg(),
- instance).AndReturn(power_state.SHUTDOWN)
- self.compute.driver.plug_vifs(instance, mox.IgnoreArg())
- self.compute._get_instance_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)
- self.mox.ReplayAll()
- self.compute._init_instance('fake-context', instance)
-
- def test_init_instance_stuck_in_deleting(self):
- instance = fake_instance.fake_instance_obj(
- self.context,
- uuid='fake-uuid',
- power_state=power_state.RUNNING,
- vm_state=vm_states.ACTIVE,
- task_state=task_states.DELETING)
-
- self.mox.StubOutWithMock(objects.BlockDeviceMappingList,
- 'get_by_instance_uuid')
- self.mox.StubOutWithMock(self.compute, '_delete_instance')
- self.mox.StubOutWithMock(instance, 'obj_load_attr')
-
- bdms = []
- instance.obj_load_attr('metadata')
- instance.obj_load_attr('system_metadata')
- objects.BlockDeviceMappingList.get_by_instance_uuid(
- self.context, instance.uuid).AndReturn(bdms)
- self.compute._delete_instance(self.context, instance, bdms,
- mox.IgnoreArg())
-
- self.mox.ReplayAll()
- self.compute._init_instance(self.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 = fake_instance.fake_instance_obj(
- self.context,
- uuid='foo',
- vm_state=vm_states.ERROR,
- task_state=task_states.RESIZE_MIGRATING,
- power_state=power_state.SHUTDOWN,
- system_metadata=sys_meta,
- expected_attrs=['system_metadata'])
-
- self.mox.StubOutWithMock(compute_utils, 'get_nw_info_for_instance')
- self.mox.StubOutWithMock(self.compute.driver, 'plug_vifs')
- self.mox.StubOutWithMock(self.compute.driver,
- 'finish_revert_migration')
- self.mox.StubOutWithMock(self.compute,
- '_get_instance_block_device_info')
- self.mox.StubOutWithMock(self.compute.driver, 'get_info')
- self.mox.StubOutWithMock(instance, 'save')
- self.mox.StubOutWithMock(self.compute, '_retry_reboot')
-
- self.compute._retry_reboot(self.context, instance).AndReturn(
- (False, None))
- compute_utils.get_nw_info_for_instance(instance).AndReturn(
- network_model.NetworkInfo())
- self.compute.driver.plug_vifs(instance, [])
- self.compute._get_instance_block_device_info(
- self.context, instance).AndReturn([])
- self.compute.driver.finish_revert_migration(self.context, instance,
- [], [], power_on)
- instance.save()
- self.compute.driver.get_info(instance).AndReturn(
- {'state': power_state.SHUTDOWN})
- self.compute.driver.get_info(instance).AndReturn(
- {'state': power_state.SHUTDOWN})
-
- self.mox.ReplayAll()
-
- self.compute._init_instance(self.context, instance)
- self.assertIsNone(instance.task_state)
-
- 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_resets_crashed_live_migration(self):
- instance = fake_instance.fake_instance_obj(
- self.context,
- uuid='foo',
- vm_state=vm_states.ACTIVE,
- task_state=task_states.MIGRATING)
- with contextlib.nested(
- mock.patch.object(instance, 'save'),
- mock.patch('nova.compute.utils.get_nw_info_for_instance',
- return_value=network_model.NetworkInfo())
- ) as (save, get_nw_info):
- self.compute._init_instance(self.context, instance)
- save.assert_called_once_with(expected_task_state=['migrating'])
- get_nw_info.assert_called_once_with(instance)
- self.assertIsNone(instance.task_state)
- self.assertEqual(vm_states.ACTIVE, instance.vm_state)
-
- def _test_init_instance_sets_building_error(self, vm_state,
- task_state=None):
- instance = fake_instance.fake_instance_obj(
- self.context,
- uuid='foo',
- vm_state=vm_state,
- task_state=task_state)
- with mock.patch.object(instance, 'save') as save:
- self.compute._init_instance(self.context, instance)
- save.assert_called_once_with()
- self.assertIsNone(instance.task_state)
- self.assertEqual(vm_states.ERROR, instance.vm_state)
-
- def test_init_instance_sets_building_error(self):
- self._test_init_instance_sets_building_error(vm_states.BUILDING)
-
- def test_init_instance_sets_rebuilding_errors(self):
- tasks = [task_states.REBUILDING,
- task_states.REBUILD_BLOCK_DEVICE_MAPPING,
- task_states.REBUILD_SPAWNING]
- vms = [vm_states.ACTIVE, vm_states.STOPPED]
-
- for vm_state in vms:
- for task_state in tasks:
- self._test_init_instance_sets_building_error(
- vm_state, task_state)
-
- def _test_init_instance_sets_building_tasks_error(self, instance):
- with mock.patch.object(instance, 'save') as save:
- self.compute._init_instance(self.context, instance)
- save.assert_called_once_with()
- self.assertIsNone(instance.task_state)
- self.assertEqual(vm_states.ERROR, instance.vm_state)
-
- def test_init_instance_sets_building_tasks_error_scheduling(self):
- instance = fake_instance.fake_instance_obj(
- self.context,
- uuid='foo',
- vm_state=None,
- task_state=task_states.SCHEDULING)
- self._test_init_instance_sets_building_tasks_error(instance)
-
- def test_init_instance_sets_building_tasks_error_block_device(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = None
- instance.task_state = task_states.BLOCK_DEVICE_MAPPING
- self._test_init_instance_sets_building_tasks_error(instance)
-
- def test_init_instance_sets_building_tasks_error_networking(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = None
- instance.task_state = task_states.NETWORKING
- self._test_init_instance_sets_building_tasks_error(instance)
-
- def test_init_instance_sets_building_tasks_error_spawning(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = None
- instance.task_state = task_states.SPAWNING
- self._test_init_instance_sets_building_tasks_error(instance)
-
- def _test_init_instance_cleans_image_states(self, instance):
- with mock.patch.object(instance, 'save') as save:
- self.compute._get_power_state = mock.Mock()
- self.compute.driver.post_interrupted_snapshot_cleanup = mock.Mock()
- instance.info_cache = None
- instance.power_state = power_state.RUNNING
- self.compute._init_instance(self.context, instance)
- save.assert_called_once_with()
- self.compute.driver.post_interrupted_snapshot_cleanup.\
- assert_called_once_with(self.context, instance)
- self.assertIsNone(instance.task_state)
-
- def test_init_instance_cleans_image_state_pending_upload(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.IMAGE_PENDING_UPLOAD
- self._test_init_instance_cleans_image_states(instance)
-
- def test_init_instance_cleans_image_state_uploading(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.IMAGE_UPLOADING
- self._test_init_instance_cleans_image_states(instance)
-
- def test_init_instance_cleans_image_state_snapshot(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.IMAGE_SNAPSHOT
- self._test_init_instance_cleans_image_states(instance)
-
- def test_init_instance_cleans_image_state_snapshot_pending(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.IMAGE_SNAPSHOT_PENDING
- self._test_init_instance_cleans_image_states(instance)
-
- def test_init_instance_errors_when_not_migrating(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ERROR
- instance.task_state = task_states.IMAGE_UPLOADING
- self.mox.StubOutWithMock(compute_utils, 'get_nw_info_for_instance')
- self.mox.ReplayAll()
- self.compute._init_instance(self.context, instance)
- self.mox.VerifyAll()
-
- def test_init_instance_deletes_error_deleting_instance(self):
- instance = fake_instance.fake_instance_obj(
- self.context,
- uuid='fake',
- vm_state=vm_states.ERROR,
- task_state=task_states.DELETING)
- self.mox.StubOutWithMock(objects.BlockDeviceMappingList,
- 'get_by_instance_uuid')
- self.mox.StubOutWithMock(self.compute, '_delete_instance')
- self.mox.StubOutWithMock(instance, 'obj_load_attr')
-
- bdms = []
- instance.obj_load_attr('metadata')
- instance.obj_load_attr('system_metadata')
- objects.BlockDeviceMappingList.get_by_instance_uuid(
- self.context, instance.uuid).AndReturn(bdms)
- self.compute._delete_instance(self.context, instance, bdms,
- mox.IgnoreArg())
- self.mox.ReplayAll()
-
- self.compute._init_instance(self.context, instance)
- self.mox.VerifyAll()
-
- @mock.patch('nova.context.RequestContext.elevated')
- @mock.patch('nova.compute.utils.get_nw_info_for_instance')
- @mock.patch(
- 'nova.compute.manager.ComputeManager._get_instance_block_device_info')
- @mock.patch('nova.virt.driver.ComputeDriver.destroy')
- @mock.patch('nova.virt.driver.ComputeDriver.get_volume_connector')
- def test_shutdown_instance_endpoint_not_found(self, mock_connector,
- mock_destroy, mock_blk_device_info, mock_nw_info, mock_elevated):
- mock_connector.side_effect = cinder_exception.EndpointNotFound
- mock_elevated.return_value = self.context
- instance = fake_instance.fake_instance_obj(
- self.context,
- uuid='fake',
- vm_state=vm_states.ERROR,
- task_state=task_states.DELETING)
- bdms = [mock.Mock(id=1, is_volume=True)]
-
- self.compute._shutdown_instance(self.context, instance, bdms,
- notify=False, try_deallocate_networks=False)
-
- def _test_init_instance_retries_reboot(self, instance, reboot_type,
- return_power_state):
- with contextlib.nested(
- mock.patch.object(self.compute, '_get_power_state',
- return_value=return_power_state),
- mock.patch.object(self.compute.compute_rpcapi, 'reboot_instance'),
- mock.patch.object(compute_utils, 'get_nw_info_for_instance')
- ) as (
- _get_power_state,
- reboot_instance,
- get_nw_info_for_instance
- ):
- self.compute._init_instance(self.context, instance)
- call = mock.call(self.context, instance, block_device_info=None,
- reboot_type=reboot_type)
- reboot_instance.assert_has_calls([call])
-
- def test_init_instance_retries_reboot_pending(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.task_state = task_states.REBOOT_PENDING
- for state in vm_states.ALLOW_SOFT_REBOOT:
- instance.vm_state = state
- self._test_init_instance_retries_reboot(instance, 'SOFT',
- power_state.RUNNING)
-
- def test_init_instance_retries_reboot_pending_hard(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.task_state = task_states.REBOOT_PENDING_HARD
- for state in vm_states.ALLOW_HARD_REBOOT:
- # NOTE(dave-mcnally) while a reboot of a vm in error state is
- # possible we don't attempt to recover an error during init
- if state == vm_states.ERROR:
- continue
- instance.vm_state = state
- self._test_init_instance_retries_reboot(instance, 'HARD',
- power_state.RUNNING)
-
- def test_init_instance_retries_reboot_started(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.REBOOT_STARTED
- self._test_init_instance_retries_reboot(instance, 'HARD',
- power_state.NOSTATE)
-
- def test_init_instance_retries_reboot_started_hard(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.REBOOT_STARTED_HARD
- self._test_init_instance_retries_reboot(instance, 'HARD',
- power_state.NOSTATE)
-
- def _test_init_instance_cleans_reboot_state(self, instance):
- with contextlib.nested(
- mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.RUNNING),
- mock.patch.object(instance, 'save', autospec=True),
- mock.patch.object(compute_utils, 'get_nw_info_for_instance')
- ) as (
- _get_power_state,
- instance_save,
- get_nw_info_for_instance
- ):
- self.compute._init_instance(self.context, instance)
- instance_save.assert_called_once_with()
- self.assertIsNone(instance.task_state)
- self.assertEqual(vm_states.ACTIVE, instance.vm_state)
-
- def test_init_instance_cleans_image_state_reboot_started(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.REBOOT_STARTED
- instance.power_state = power_state.RUNNING
- self._test_init_instance_cleans_reboot_state(instance)
-
- def test_init_instance_cleans_image_state_reboot_started_hard(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.REBOOT_STARTED_HARD
- instance.power_state = power_state.RUNNING
- self._test_init_instance_cleans_reboot_state(instance)
-
- def test_init_instance_retries_power_off(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.id = 1
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.POWERING_OFF
- with mock.patch.object(self.compute, 'stop_instance'):
- self.compute._init_instance(self.context, instance)
- call = mock.call(self.context, instance)
- self.compute.stop_instance.assert_has_calls([call])
-
- def test_init_instance_retries_power_on(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.id = 1
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.POWERING_ON
- with mock.patch.object(self.compute, 'start_instance'):
- self.compute._init_instance(self.context, instance)
- call = mock.call(self.context, instance)
- self.compute.start_instance.assert_has_calls([call])
-
- def test_init_instance_retries_power_on_silent_exception(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.id = 1
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.POWERING_ON
- with mock.patch.object(self.compute, 'start_instance',
- return_value=Exception):
- init_return = self.compute._init_instance(self.context, instance)
- call = mock.call(self.context, instance)
- self.compute.start_instance.assert_has_calls([call])
- self.assertIsNone(init_return)
-
- def test_init_instance_retries_power_off_silent_exception(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.id = 1
- instance.vm_state = vm_states.ACTIVE
- instance.task_state = task_states.POWERING_OFF
- with mock.patch.object(self.compute, 'stop_instance',
- return_value=Exception):
- init_return = self.compute._init_instance(self.context, instance)
- call = mock.call(self.context, instance)
- self.compute.stop_instance.assert_has_calls([call])
- self.assertIsNone(init_return)
-
- def test_get_instances_on_driver(self):
- fake_context = context.get_admin_context()
-
- driver_instances = []
- for x in xrange(10):
- driver_instances.append(fake_instance.fake_db_instance())
-
- self.mox.StubOutWithMock(self.compute.driver,
- 'list_instance_uuids')
- self.mox.StubOutWithMock(db, 'instance_get_all_by_filters')
-
- self.compute.driver.list_instance_uuids().AndReturn(
- [inst['uuid'] for inst in driver_instances])
- db.instance_get_all_by_filters(
- fake_context,
- {'uuid': [inst['uuid'] for
- inst in driver_instances]},
- 'created_at', 'desc', columns_to_join=None,
- limit=None, marker=None,
- use_slave=True).AndReturn(
- driver_instances)
-
- self.mox.ReplayAll()
-
- result = self.compute._get_instances_on_driver(fake_context)
- self.assertEqual([x['uuid'] for x in driver_instances],
- [x['uuid'] for x in 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()
-
- self.flags(instance_name_template='inst-%i')
-
- all_instances = []
- driver_instances = []
- for x in xrange(10):
- instance = fake_instance.fake_db_instance(name='inst-%i' % x,
- id=x)
- 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(db, '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])
- db.instance_get_all_by_filters(
- fake_context, filters,
- 'created_at', 'desc', columns_to_join=None,
- limit=None, marker=None,
- use_slave=True).AndReturn(all_instances)
-
- self.mox.ReplayAll()
-
- result = self.compute._get_instances_on_driver(fake_context, filters)
- self.assertEqual([x['uuid'] for x in driver_instances],
- [x['uuid'] for x in result])
-
- def test_instance_usage_audit(self):
- instances = [objects.Instance(uuid='foo')]
-
- @classmethod
- def fake_get(*a, **k):
- return instances
-
- self.flags(instance_usage_audit=True)
- self.stubs.Set(compute_utils, 'has_audit_been_run',
- lambda *a, **k: False)
- self.stubs.Set(objects.InstanceList,
- 'get_active_by_window_joined', fake_get)
- 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,
- shutdown_terminate=False):
- instance = objects.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
- instance.shutdown_terminate = shutdown_terminate
- 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(use_slave=False)
- 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(use_slave=False)
- 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, force=False, shutdown_terminate=False):
- instance = self._get_sync_instance(
- power_state, vm_state, shutdown_terminate=shutdown_terminate)
- instance.refresh(use_slave=False)
- instance.save()
- self.mox.StubOutWithMock(self.compute.compute_api, 'stop')
- self.mox.StubOutWithMock(self.compute.compute_api, 'delete')
- self.mox.StubOutWithMock(self.compute.compute_api, 'force_stop')
- if shutdown_terminate:
- self.compute.compute_api.delete(self.context, instance)
- elif stop:
- if force:
- self.compute.compute_api.force_stop(self.context, instance)
- else:
- self.compute.compute_api.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)
-
- for ps in (power_state.SHUTDOWN, power_state.CRASHED):
- self._test_sync_to_stop(power_state.PAUSED, vm_states.PAUSED, ps,
- force=True)
-
- self._test_sync_to_stop(power_state.SHUTDOWN, vm_states.STOPPED,
- power_state.RUNNING, force=True)
-
- def test_sync_instance_power_state_to_terminate(self):
- self._test_sync_to_stop(power_state.RUNNING, vm_states.ACTIVE,
- power_state.SHUTDOWN,
- force=False, shutdown_terminate=True)
-
- 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)
-
- @mock.patch('nova.compute.manager.ComputeManager.'
- '_sync_instance_power_state')
- def test_query_driver_power_state_and_sync_pending_task(
- self, mock_sync_power_state):
- with mock.patch.object(self.compute.driver,
- 'get_info') as mock_get_info:
- db_instance = objects.Instance(uuid='fake-uuid',
- task_state=task_states.POWERING_OFF)
- self.compute._query_driver_power_state_and_sync(self.context,
- db_instance)
- self.assertFalse(mock_get_info.called)
- self.assertFalse(mock_sync_power_state.called)
-
- @mock.patch('nova.compute.manager.ComputeManager.'
- '_sync_instance_power_state')
- def test_query_driver_power_state_and_sync_not_found_driver(
- self, mock_sync_power_state):
- error = exception.InstanceNotFound(instance_id=1)
- with mock.patch.object(self.compute.driver,
- 'get_info', side_effect=error) as mock_get_info:
- db_instance = objects.Instance(uuid='fake-uuid', task_state=None)
- self.compute._query_driver_power_state_and_sync(self.context,
- db_instance)
- mock_get_info.assert_called_once_with(db_instance)
- mock_sync_power_state.assert_called_once_with(self.context,
- db_instance,
- power_state.NOSTATE,
- use_slave=True)
-
- def test_run_pending_deletes(self):
- self.flags(instance_delete_interval=10)
-
- class FakeInstance(object):
- def __init__(self, uuid, name, smd):
- self.uuid = uuid
- self.name = name
- self.system_metadata = smd
- self.cleaned = False
-
- def __getitem__(self, name):
- return getattr(self, name)
-
- def save(self, context):
- pass
-
- class FakeInstanceList(object):
- def get_by_filters(self, *args, **kwargs):
- return []
-
- a = FakeInstance('123', 'apple', {'clean_attempts': '100'})
- b = FakeInstance('456', 'orange', {'clean_attempts': '3'})
- c = FakeInstance('789', 'banana', {})
-
- self.mox.StubOutWithMock(objects.InstanceList,
- 'get_by_filters')
- objects.InstanceList.get_by_filters(
- {'read_deleted': 'yes'},
- {'deleted': True, 'soft_deleted': False, 'host': 'fake-mini',
- 'cleaned': False},
- expected_attrs=['info_cache', 'security_groups',
- 'system_metadata'],
- use_slave=True).AndReturn([a, b, c])
-
- self.mox.StubOutWithMock(self.compute.driver, 'delete_instance_files')
- self.compute.driver.delete_instance_files(
- mox.IgnoreArg()).AndReturn(True)
- self.compute.driver.delete_instance_files(
- mox.IgnoreArg()).AndReturn(False)
-
- self.mox.ReplayAll()
-
- self.compute._run_pending_deletes({})
- self.assertFalse(a.cleaned)
- self.assertEqual('100', a.system_metadata['clean_attempts'])
- self.assertTrue(b.cleaned)
- self.assertEqual('4', b.system_metadata['clean_attempts'])
- self.assertFalse(c.cleaned)
- self.assertEqual('1', c.system_metadata['clean_attempts'])
-
- def test_attach_interface_failure(self):
- # Test that the fault methods are invoked when an attach fails
- db_instance = fake_instance.fake_db_instance()
- f_instance = objects.Instance._from_db_object(self.context,
- objects.Instance(),
- db_instance)
- e = exception.InterfaceAttachFailed(instance_uuid=f_instance.uuid)
-
- @mock.patch.object(compute_utils, 'add_instance_fault_from_exc')
- @mock.patch.object(self.compute.network_api,
- 'allocate_port_for_instance',
- side_effect=e)
- def do_test(meth, add_fault):
- self.assertRaises(exception.InterfaceAttachFailed,
- self.compute.attach_interface,
- self.context, f_instance, 'net_id', 'port_id',
- None)
- add_fault.assert_has_calls(
- mock.call(self.context, f_instance, e,
- mock.ANY))
-
- do_test()
-
- def test_detach_interface_failure(self):
- # Test that the fault methods are invoked when a detach fails
-
- # Build test data that will cause a PortNotFound exception
- f_instance = mock.MagicMock()
- f_instance.info_cache = mock.MagicMock()
- f_instance.info_cache.network_info = []
-
- @mock.patch.object(compute_utils, 'add_instance_fault_from_exc')
- @mock.patch.object(self.compute, '_set_instance_error_state')
- def do_test(meth, add_fault):
- self.assertRaises(exception.PortNotFound,
- self.compute.detach_interface,
- self.context, f_instance, 'port_id')
- add_fault.assert_has_calls(
- mock.call(self.context, f_instance, mock.ANY, mock.ANY))
-
- do_test()
-
- def test_swap_volume_volume_api_usage(self):
- # This test ensures that volume_id arguments are passed to volume_api
- # and that volume states are OK
- volumes = {}
- old_volume_id = uuidutils.generate_uuid()
- volumes[old_volume_id] = {'id': old_volume_id,
- 'display_name': 'old_volume',
- 'status': 'detaching',
- 'size': 1}
- new_volume_id = uuidutils.generate_uuid()
- volumes[new_volume_id] = {'id': new_volume_id,
- 'display_name': 'new_volume',
- 'status': 'available',
- 'size': 2}
-
- def fake_vol_api_roll_detaching(context, volume_id):
- self.assertTrue(uuidutils.is_uuid_like(volume_id))
- if volumes[volume_id]['status'] == 'detaching':
- volumes[volume_id]['status'] = 'in-use'
-
- fake_bdm = fake_block_device.FakeDbBlockDeviceDict(
- {'device_name': '/dev/vdb', 'source_type': 'volume',
- 'destination_type': 'volume', 'instance_uuid': 'fake',
- 'connection_info': '{"foo": "bar"}'})
-
- def fake_vol_api_func(context, volume, *args):
- self.assertTrue(uuidutils.is_uuid_like(volume))
- return {}
-
- def fake_vol_get(context, volume_id):
- self.assertTrue(uuidutils.is_uuid_like(volume_id))
- return volumes[volume_id]
-
- def fake_vol_unreserve(context, volume_id):
- self.assertTrue(uuidutils.is_uuid_like(volume_id))
- if volumes[volume_id]['status'] == 'attaching':
- volumes[volume_id]['status'] = 'available'
-
- def fake_vol_migrate_volume_completion(context, old_volume_id,
- new_volume_id, error=False):
- self.assertTrue(uuidutils.is_uuid_like(old_volume_id))
- self.assertTrue(uuidutils.is_uuid_like(new_volume_id))
- volumes[old_volume_id]['status'] = 'in-use'
- return {'save_volume_id': new_volume_id}
-
- def fake_func_exc(*args, **kwargs):
- raise AttributeError # Random exception
-
- def fake_swap_volume(old_connection_info, new_connection_info,
- instance, mountpoint, resize_to):
- self.assertEqual(resize_to, 2)
-
- self.stubs.Set(self.compute.volume_api, 'roll_detaching',
- fake_vol_api_roll_detaching)
- self.stubs.Set(self.compute.volume_api, 'get', fake_vol_get)
- self.stubs.Set(self.compute.volume_api, 'initialize_connection',
- fake_vol_api_func)
- self.stubs.Set(self.compute.volume_api, 'unreserve_volume',
- fake_vol_unreserve)
- self.stubs.Set(self.compute.volume_api, 'terminate_connection',
- fake_vol_api_func)
- self.stubs.Set(db, 'block_device_mapping_get_by_volume_id',
- lambda x, y, z: fake_bdm)
- self.stubs.Set(self.compute.driver, 'get_volume_connector',
- lambda x: {})
- self.stubs.Set(self.compute.driver, 'swap_volume',
- fake_swap_volume)
- self.stubs.Set(self.compute.volume_api, 'migrate_volume_completion',
- fake_vol_migrate_volume_completion)
- self.stubs.Set(db, 'block_device_mapping_update',
- lambda *a, **k: fake_bdm)
- self.stubs.Set(db,
- 'instance_fault_create',
- lambda x, y:
- test_instance_fault.fake_faults['fake-uuid'][0])
-
- # Good path
- self.compute.swap_volume(self.context, old_volume_id, new_volume_id,
- fake_instance.fake_instance_obj(
- self.context, **{'uuid': 'fake'}))
- self.assertEqual(volumes[old_volume_id]['status'], 'in-use')
-
- # Error paths
- volumes[old_volume_id]['status'] = 'detaching'
- volumes[new_volume_id]['status'] = 'attaching'
- self.stubs.Set(self.compute.driver, 'swap_volume', fake_func_exc)
- self.assertRaises(AttributeError, self.compute.swap_volume,
- self.context, old_volume_id, new_volume_id,
- fake_instance.fake_instance_obj(
- self.context, **{'uuid': 'fake'}))
- self.assertEqual(volumes[old_volume_id]['status'], 'in-use')
- self.assertEqual(volumes[new_volume_id]['status'], 'available')
-
- volumes[old_volume_id]['status'] = 'detaching'
- volumes[new_volume_id]['status'] = 'attaching'
- self.stubs.Set(self.compute.volume_api, 'initialize_connection',
- fake_func_exc)
- self.assertRaises(AttributeError, self.compute.swap_volume,
- self.context, old_volume_id, new_volume_id,
- fake_instance.fake_instance_obj(
- self.context, **{'uuid': 'fake'}))
- self.assertEqual(volumes[old_volume_id]['status'], 'in-use')
- self.assertEqual(volumes[new_volume_id]['status'], 'available')
-
- def test_check_can_live_migrate_source(self):
- is_volume_backed = 'volume_backed'
- dest_check_data = dict(foo='bar')
- db_instance = fake_instance.fake_db_instance()
- instance = objects.Instance._from_db_object(
- self.context, objects.Instance(), db_instance)
- expected_dest_check_data = dict(dest_check_data,
- is_volume_backed=is_volume_backed)
-
- self.mox.StubOutWithMock(self.compute.compute_api,
- 'is_volume_backed_instance')
- self.mox.StubOutWithMock(self.compute,
- '_get_instance_block_device_info')
- self.mox.StubOutWithMock(self.compute.driver,
- 'check_can_live_migrate_source')
-
- self.compute.compute_api.is_volume_backed_instance(
- self.context, instance).AndReturn(is_volume_backed)
- self.compute._get_instance_block_device_info(
- self.context, instance, refresh_conn_info=True
- ).AndReturn({'block_device_mapping': 'fake'})
- self.compute.driver.check_can_live_migrate_source(
- self.context, instance, expected_dest_check_data,
- {'block_device_mapping': 'fake'})
-
- self.mox.ReplayAll()
-
- self.compute.check_can_live_migrate_source(
- self.context, instance=instance,
- dest_check_data=dest_check_data)
-
- def _test_check_can_live_migrate_destination(self, do_raise=False,
- has_mig_data=False):
- db_instance = fake_instance.fake_db_instance(host='fake-host')
- instance = objects.Instance._from_db_object(
- self.context, objects.Instance(), db_instance)
- instance.host = 'fake-host'
- block_migration = 'block_migration'
- disk_over_commit = 'disk_over_commit'
- src_info = 'src_info'
- dest_info = 'dest_info'
- dest_check_data = dict(foo='bar')
- mig_data = dict(cow='moo')
- expected_result = dict(mig_data)
- if has_mig_data:
- dest_check_data['migrate_data'] = dict(cat='meow')
- expected_result.update(cat='meow')
-
- self.mox.StubOutWithMock(self.compute, '_get_compute_info')
- self.mox.StubOutWithMock(self.compute.driver,
- 'check_can_live_migrate_destination')
- self.mox.StubOutWithMock(self.compute.compute_rpcapi,
- 'check_can_live_migrate_source')
- self.mox.StubOutWithMock(self.compute.driver,
- 'check_can_live_migrate_destination_cleanup')
-
- self.compute._get_compute_info(self.context,
- 'fake-host').AndReturn(src_info)
- self.compute._get_compute_info(self.context,
- CONF.host).AndReturn(dest_info)
- self.compute.driver.check_can_live_migrate_destination(
- self.context, instance, src_info, dest_info,
- block_migration, disk_over_commit).AndReturn(dest_check_data)
-
- mock_meth = self.compute.compute_rpcapi.check_can_live_migrate_source(
- self.context, instance, dest_check_data)
- if do_raise:
- mock_meth.AndRaise(test.TestingException())
- self.mox.StubOutWithMock(db, 'instance_fault_create')
- db.instance_fault_create(
- self.context, mox.IgnoreArg()).AndReturn(
- test_instance_fault.fake_faults['fake-uuid'][0])
- else:
- mock_meth.AndReturn(mig_data)
- self.compute.driver.check_can_live_migrate_destination_cleanup(
- self.context, dest_check_data)
-
- self.mox.ReplayAll()
-
- result = self.compute.check_can_live_migrate_destination(
- self.context, instance=instance,
- block_migration=block_migration,
- disk_over_commit=disk_over_commit)
- self.assertEqual(expected_result, result)
-
- def test_check_can_live_migrate_destination_success(self):
- self._test_check_can_live_migrate_destination()
-
- def test_check_can_live_migrate_destination_success_w_mig_data(self):
- self._test_check_can_live_migrate_destination(has_mig_data=True)
-
- def test_check_can_live_migrate_destination_fail(self):
- self.assertRaises(
- test.TestingException,
- self._test_check_can_live_migrate_destination,
- do_raise=True)
-
- @mock.patch('nova.compute.manager.InstanceEvents._lock_name')
- def test_prepare_for_instance_event(self, lock_name_mock):
- inst_obj = objects.Instance(uuid='foo')
- result = self.compute.instance_events.prepare_for_instance_event(
- inst_obj, 'test-event')
- self.assertIn('foo', self.compute.instance_events._events)
- self.assertIn('test-event',
- self.compute.instance_events._events['foo'])
- self.assertEqual(
- result,
- self.compute.instance_events._events['foo']['test-event'])
- self.assertTrue(hasattr(result, 'send'))
- lock_name_mock.assert_called_once_with(inst_obj)
-
- @mock.patch('nova.compute.manager.InstanceEvents._lock_name')
- def test_pop_instance_event(self, lock_name_mock):
- event = eventlet_event.Event()
- self.compute.instance_events._events = {
- 'foo': {
- 'test-event': event,
- }
- }
- inst_obj = objects.Instance(uuid='foo')
- event_obj = objects.InstanceExternalEvent(name='test-event',
- tag=None)
- result = self.compute.instance_events.pop_instance_event(inst_obj,
- event_obj)
- self.assertEqual(result, event)
- lock_name_mock.assert_called_once_with(inst_obj)
-
- @mock.patch('nova.compute.manager.InstanceEvents._lock_name')
- def test_clear_events_for_instance(self, lock_name_mock):
- event = eventlet_event.Event()
- self.compute.instance_events._events = {
- 'foo': {
- 'test-event': event,
- }
- }
- inst_obj = objects.Instance(uuid='foo')
- result = self.compute.instance_events.clear_events_for_instance(
- inst_obj)
- self.assertEqual(result, {'test-event': event})
- lock_name_mock.assert_called_once_with(inst_obj)
-
- def test_instance_events_lock_name(self):
- inst_obj = objects.Instance(uuid='foo')
- result = self.compute.instance_events._lock_name(inst_obj)
- self.assertEqual(result, 'foo-events')
-
- def test_prepare_for_instance_event_again(self):
- inst_obj = objects.Instance(uuid='foo')
- self.compute.instance_events.prepare_for_instance_event(
- inst_obj, 'test-event')
- # A second attempt will avoid creating a new list; make sure we
- # get the current list
- result = self.compute.instance_events.prepare_for_instance_event(
- inst_obj, 'test-event')
- self.assertIn('foo', self.compute.instance_events._events)
- self.assertIn('test-event',
- self.compute.instance_events._events['foo'])
- self.assertEqual(
- result,
- self.compute.instance_events._events['foo']['test-event'])
- self.assertTrue(hasattr(result, 'send'))
-
- def test_process_instance_event(self):
- event = eventlet_event.Event()
- self.compute.instance_events._events = {
- 'foo': {
- 'test-event': event,
- }
- }
- inst_obj = objects.Instance(uuid='foo')
- event_obj = objects.InstanceExternalEvent(name='test-event', tag=None)
- self.compute._process_instance_event(inst_obj, event_obj)
- self.assertTrue(event.ready())
- self.assertEqual(event_obj, event.wait())
- self.assertEqual({}, self.compute.instance_events._events)
-
- def test_external_instance_event(self):
- instances = [
- objects.Instance(id=1, uuid='uuid1'),
- objects.Instance(id=2, uuid='uuid2')]
- events = [
- objects.InstanceExternalEvent(name='network-changed',
- tag='tag1',
- instance_uuid='uuid1'),
- objects.InstanceExternalEvent(name='foo', instance_uuid='uuid2',
- tag='tag2')]
-
- @mock.patch.object(self.compute.network_api, 'get_instance_nw_info')
- @mock.patch.object(self.compute, '_process_instance_event')
- def do_test(_process_instance_event, get_instance_nw_info):
- self.compute.external_instance_event(self.context,
- instances, events)
- get_instance_nw_info.assert_called_once_with(self.context,
- instances[0])
- _process_instance_event.assert_called_once_with(instances[1],
- events[1])
- do_test()
-
- def test_retry_reboot_pending_soft(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.task_state = task_states.REBOOT_PENDING
- instance.vm_state = vm_states.ACTIVE
- with mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.RUNNING):
- allow_reboot, reboot_type = self.compute._retry_reboot(
- context, instance)
- self.assertTrue(allow_reboot)
- self.assertEqual(reboot_type, 'SOFT')
-
- def test_retry_reboot_pending_hard(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.task_state = task_states.REBOOT_PENDING_HARD
- instance.vm_state = vm_states.ACTIVE
- with mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.RUNNING):
- allow_reboot, reboot_type = self.compute._retry_reboot(
- context, instance)
- self.assertTrue(allow_reboot)
- self.assertEqual(reboot_type, 'HARD')
-
- def test_retry_reboot_starting_soft_off(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.task_state = task_states.REBOOT_STARTED
- with mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.NOSTATE):
- allow_reboot, reboot_type = self.compute._retry_reboot(
- context, instance)
- self.assertTrue(allow_reboot)
- self.assertEqual(reboot_type, 'HARD')
-
- def test_retry_reboot_starting_hard_off(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.task_state = task_states.REBOOT_STARTED_HARD
- with mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.NOSTATE):
- allow_reboot, reboot_type = self.compute._retry_reboot(
- context, instance)
- self.assertTrue(allow_reboot)
- self.assertEqual(reboot_type, 'HARD')
-
- def test_retry_reboot_starting_hard_on(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.task_state = task_states.REBOOT_STARTED_HARD
- with mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.RUNNING):
- allow_reboot, reboot_type = self.compute._retry_reboot(
- context, instance)
- self.assertFalse(allow_reboot)
- self.assertEqual(reboot_type, 'HARD')
-
- def test_retry_reboot_no_reboot(self):
- instance = objects.Instance(self.context)
- instance.uuid = 'foo'
- instance.task_state = 'bar'
- with mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.RUNNING):
- allow_reboot, reboot_type = self.compute._retry_reboot(
- context, instance)
- self.assertFalse(allow_reboot)
- self.assertEqual(reboot_type, 'HARD')
-
- @mock.patch('nova.objects.BlockDeviceMapping.get_by_volume_id')
- @mock.patch('nova.compute.manager.ComputeManager._detach_volume')
- @mock.patch('nova.objects.Instance._from_db_object')
- def test_remove_volume_connection(self, inst_from_db, detach, bdm_get):
- bdm = mock.sentinel.bdm
- inst_obj = mock.sentinel.inst_obj
- bdm_get.return_value = bdm
- inst_from_db.return_value = inst_obj
- with mock.patch.object(self.compute, 'volume_api'):
- self.compute.remove_volume_connection(self.context, 'vol',
- inst_obj)
- detach.assert_called_once_with(self.context, inst_obj, bdm)
-
- def _test_rescue(self, clean_shutdown=True):
- instance = fake_instance.fake_instance_obj(
- self.context, vm_state=vm_states.ACTIVE)
- fake_nw_info = network_model.NetworkInfo()
- rescue_image_meta = {'id': 'fake', 'name': 'fake'}
- with contextlib.nested(
- mock.patch.object(objects.InstanceActionEvent, 'event_start'),
- mock.patch.object(objects.InstanceActionEvent,
- 'event_finish_with_failure'),
- mock.patch.object(self.context, 'elevated',
- return_value=self.context),
- mock.patch.object(self.compute, '_get_instance_nw_info',
- return_value=fake_nw_info),
- mock.patch.object(self.compute, '_get_rescue_image',
- return_value=rescue_image_meta),
- mock.patch.object(self.compute, '_notify_about_instance_usage'),
- mock.patch.object(self.compute, '_power_off_instance'),
- mock.patch.object(self.compute.driver, 'rescue'),
- mock.patch.object(self.compute.conductor_api,
- 'notify_usage_exists'),
- mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.RUNNING),
- mock.patch.object(instance, 'save')
- ) as (
- event_start, event_finish, elevated_context, get_nw_info,
- get_rescue_image, notify_instance_usage, power_off_instance,
- driver_rescue, notify_usage_exists, get_power_state, instance_save
- ):
- self.compute.rescue_instance(
- self.context, instance, rescue_password='verybadpass',
- rescue_image_ref=None, clean_shutdown=clean_shutdown)
-
- # assert the field values on the instance object
- self.assertEqual(vm_states.RESCUED, instance.vm_state)
- self.assertIsNone(instance.task_state)
- self.assertEqual(power_state.RUNNING, instance.power_state)
- self.assertIsNotNone(instance.launched_at)
-
- # assert our mock calls
- get_nw_info.assert_called_once_with(self.context, instance)
- get_rescue_image.assert_called_once_with(
- self.context, instance, None)
-
- extra_usage_info = {'rescue_image_name': 'fake'}
- notify_calls = [
- mock.call(self.context, instance, "rescue.start",
- extra_usage_info=extra_usage_info,
- network_info=fake_nw_info),
- mock.call(self.context, instance, "rescue.end",
- extra_usage_info=extra_usage_info,
- network_info=fake_nw_info)
- ]
- notify_instance_usage.assert_has_calls(notify_calls)
-
- power_off_instance.assert_called_once_with(self.context, instance,
- clean_shutdown)
-
- driver_rescue.assert_called_once_with(
- self.context, instance, fake_nw_info, rescue_image_meta,
- 'verybadpass')
-
- notify_usage_exists.assert_called_once_with(
- self.context, instance, current_period=True)
-
- instance_save.assert_called_once_with(
- expected_task_state=task_states.RESCUING)
-
- def test_rescue(self):
- self._test_rescue()
-
- def test_rescue_forced_shutdown(self):
- self._test_rescue(clean_shutdown=False)
-
- def test_unrescue(self):
- instance = fake_instance.fake_instance_obj(
- self.context, vm_state=vm_states.RESCUED)
- fake_nw_info = network_model.NetworkInfo()
- with contextlib.nested(
- mock.patch.object(objects.InstanceActionEvent, 'event_start'),
- mock.patch.object(objects.InstanceActionEvent,
- 'event_finish_with_failure'),
- mock.patch.object(self.context, 'elevated',
- return_value=self.context),
- mock.patch.object(self.compute, '_get_instance_nw_info',
- return_value=fake_nw_info),
- mock.patch.object(self.compute, '_notify_about_instance_usage'),
- mock.patch.object(self.compute.driver, 'unrescue'),
- mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.RUNNING),
- mock.patch.object(instance, 'save')
- ) as (
- event_start, event_finish, elevated_context, get_nw_info,
- notify_instance_usage, driver_unrescue, get_power_state,
- instance_save
- ):
- self.compute.unrescue_instance(self.context, instance)
-
- # assert the field values on the instance object
- self.assertEqual(vm_states.ACTIVE, instance.vm_state)
- self.assertIsNone(instance.task_state)
- self.assertEqual(power_state.RUNNING, instance.power_state)
-
- # assert our mock calls
- get_nw_info.assert_called_once_with(self.context, instance)
-
- notify_calls = [
- mock.call(self.context, instance, "unrescue.start",
- network_info=fake_nw_info),
- mock.call(self.context, instance, "unrescue.end",
- network_info=fake_nw_info)
- ]
- notify_instance_usage.assert_has_calls(notify_calls)
-
- driver_unrescue.assert_called_once_with(instance, fake_nw_info)
-
- instance_save.assert_called_once_with(
- expected_task_state=task_states.UNRESCUING)
-
- @mock.patch.object(objects.InstanceActionEvent, 'event_start')
- @mock.patch.object(objects.InstanceActionEvent,
- 'event_finish_with_failure')
- @mock.patch('nova.compute.manager.ComputeManager._get_power_state',
- return_value=power_state.RUNNING)
- @mock.patch.object(objects.Instance, 'save')
- @mock.patch('nova.utils.generate_password', return_value='fake-pass')
- def test_set_admin_password(self, gen_password_mock,
- instance_save_mock, power_state_mock,
- event_finish_mock, event_start_mock):
- # Ensure instance can have its admin password set.
- instance = fake_instance.fake_instance_obj(
- self.context,
- vm_state=vm_states.ACTIVE,
- task_state=task_states.UPDATING_PASSWORD)
-
- @mock.patch.object(self.context, 'elevated', return_value=self.context)
- @mock.patch.object(self.compute.driver, 'set_admin_password')
- def do_test(driver_mock, elevated_mock):
- # call the manager method
- self.compute.set_admin_password(self.context, instance, None)
- # make our assertions
- self.assertEqual(vm_states.ACTIVE, instance.vm_state)
- self.assertIsNone(instance.task_state)
-
- power_state_mock.assert_called_once_with(self.context, instance)
- driver_mock.assert_called_once_with(instance, 'fake-pass')
- instance_save_mock.assert_called_once_with(
- expected_task_state=task_states.UPDATING_PASSWORD)
-
- do_test()
-
- @mock.patch.object(objects.InstanceActionEvent, 'event_start')
- @mock.patch.object(objects.InstanceActionEvent,
- 'event_finish_with_failure')
- @mock.patch('nova.compute.manager.ComputeManager._get_power_state',
- return_value=power_state.NOSTATE)
- @mock.patch.object(objects.Instance, 'save')
- @mock.patch.object(compute_utils, 'add_instance_fault_from_exc')
- def test_set_admin_password_bad_state(self, add_fault_mock,
- instance_save_mock, power_state_mock,
- event_finish_mock, event_start_mock):
- # Test setting password while instance is rebuilding.
- instance = fake_instance.fake_instance_obj(self.context)
- with mock.patch.object(self.context, 'elevated',
- return_value=self.context):
- # call the manager method
- self.assertRaises(exception.InstancePasswordSetFailed,
- self.compute.set_admin_password,
- self.context, instance, None)
-
- # make our assertions
- power_state_mock.assert_called_once_with(self.context, instance)
- instance_save_mock.assert_called_once_with(
- expected_task_state=task_states.UPDATING_PASSWORD)
- add_fault_mock.assert_called_once_with(
- self.context, instance, mock.ANY, mock.ANY)
-
- @mock.patch.object(objects.InstanceActionEvent, 'event_start')
- @mock.patch.object(objects.InstanceActionEvent,
- 'event_finish_with_failure')
- @mock.patch('nova.utils.generate_password', return_value='fake-pass')
- @mock.patch('nova.compute.manager.ComputeManager._get_power_state',
- return_value=power_state.RUNNING)
- @mock.patch('nova.compute.manager.ComputeManager._instance_update')
- @mock.patch.object(objects.Instance, 'save')
- @mock.patch.object(compute_utils, 'add_instance_fault_from_exc')
- def _do_test_set_admin_password_driver_error(self, exc,
- expected_vm_state,
- expected_task_state,
- expected_exception,
- add_fault_mock,
- instance_save_mock,
- update_mock,
- power_state_mock,
- gen_password_mock,
- event_finish_mock,
- event_start_mock):
- # Ensure expected exception is raised if set_admin_password fails.
- instance = fake_instance.fake_instance_obj(
- self.context,
- vm_state=vm_states.ACTIVE,
- task_state=task_states.UPDATING_PASSWORD)
-
- @mock.patch.object(self.context, 'elevated', return_value=self.context)
- @mock.patch.object(self.compute.driver, 'set_admin_password',
- side_effect=exc)
- def do_test(driver_mock, elevated_mock):
- # error raised from the driver should not reveal internal
- # information so a new error is raised
- self.assertRaises(expected_exception,
- self.compute.set_admin_password,
- self.context,
- instance=instance,
- new_pass=None)
-
- if expected_exception == NotImplementedError:
- instance_save_mock.assert_called_once_with(
- expected_task_state=task_states.UPDATING_PASSWORD)
- else:
- # setting the instance to error state
- instance_save_mock.assert_called_once_with()
-
- self.assertEqual(expected_vm_state, instance.vm_state)
- # check revert_task_state decorator
- update_mock.assert_called_once_with(
- self.context, instance.uuid,
- task_state=expected_task_state)
- # check wrap_instance_fault decorator
- add_fault_mock.assert_called_once_with(
- self.context, instance, mock.ANY, mock.ANY)
-
- do_test()
-
- def test_set_admin_password_driver_not_authorized(self):
- # Ensure expected exception is raised if set_admin_password not
- # authorized.
- exc = exception.Forbidden('Internal error')
- expected_exception = exception.InstancePasswordSetFailed
- self._do_test_set_admin_password_driver_error(
- exc, vm_states.ERROR, None, expected_exception)
-
- def test_set_admin_password_driver_not_implemented(self):
- # Ensure expected exception is raised if set_admin_password not
- # implemented by driver.
- exc = NotImplementedError()
- expected_exception = NotImplementedError
- self._do_test_set_admin_password_driver_error(
- exc, vm_states.ACTIVE, None, expected_exception)
-
- def _test_init_host_with_partial_migration(self, task_state=None,
- vm_state=vm_states.ACTIVE):
- our_host = self.compute.host
- instance_1 = objects.Instance(self.context)
- instance_1.uuid = 'foo'
- instance_1.task_state = task_state
- instance_1.vm_state = vm_state
- instance_1.host = 'not-' + our_host
- instance_2 = objects.Instance(self.context)
- instance_2.uuid = 'bar'
- instance_2.task_state = None
- instance_2.vm_state = vm_states.ACTIVE
- instance_2.host = 'not-' + our_host
-
- with contextlib.nested(
- mock.patch.object(self.compute, '_get_instances_on_driver',
- return_value=[instance_1,
- instance_2]),
- mock.patch.object(self.compute, '_get_instance_nw_info',
- return_value=None),
- mock.patch.object(self.compute, '_get_instance_block_device_info',
- return_value={}),
- mock.patch.object(self.compute, '_is_instance_storage_shared',
- return_value=False),
- mock.patch.object(self.compute.driver, 'destroy')
- ) as (_get_instances_on_driver, _get_instance_nw_info,
- _get_instance_block_device_info, _is_instance_storage_shared,
- destroy):
- self.compute._destroy_evacuated_instances(self.context)
- destroy.assert_called_once_with(self.context, instance_2, None,
- {}, True)
-
- def test_init_host_with_partial_migration_migrating(self):
- self._test_init_host_with_partial_migration(
- task_state=task_states.MIGRATING)
-
- def test_init_host_with_partial_migration_resize_migrating(self):
- self._test_init_host_with_partial_migration(
- task_state=task_states.RESIZE_MIGRATING)
-
- def test_init_host_with_partial_migration_resize_migrated(self):
- self._test_init_host_with_partial_migration(
- task_state=task_states.RESIZE_MIGRATED)
-
- def test_init_host_with_partial_migration_finish_resize(self):
- self._test_init_host_with_partial_migration(
- task_state=task_states.RESIZE_FINISH)
-
- def test_init_host_with_partial_migration_resized(self):
- self._test_init_host_with_partial_migration(
- vm_state=vm_states.RESIZED)
-
- @mock.patch('nova.compute.manager.ComputeManager._instance_update')
- def test_error_out_instance_on_exception_not_implemented_err(self,
- inst_update_mock):
- instance = fake_instance.fake_instance_obj(self.context)
-
- def do_test():
- with self.compute._error_out_instance_on_exception(
- self.context, instance, instance_state=vm_states.STOPPED):
- raise NotImplementedError('test')
-
- self.assertRaises(NotImplementedError, do_test)
- inst_update_mock.assert_called_once_with(
- self.context, instance.uuid,
- vm_state=vm_states.STOPPED, task_state=None)
-
- @mock.patch('nova.compute.manager.ComputeManager._instance_update')
- def test_error_out_instance_on_exception_inst_fault_rollback(self,
- inst_update_mock):
- instance = fake_instance.fake_instance_obj(self.context)
-
- def do_test():
- with self.compute._error_out_instance_on_exception(self.context,
- instance):
- raise exception.InstanceFaultRollback(
- inner_exception=test.TestingException('test'))
-
- self.assertRaises(test.TestingException, do_test)
- inst_update_mock.assert_called_once_with(
- self.context, instance.uuid,
- vm_state=vm_states.ACTIVE, task_state=None)
-
- @mock.patch('nova.compute.manager.ComputeManager.'
- '_set_instance_error_state')
- def test_error_out_instance_on_exception_unknown_with_quotas(self,
- set_error):
- instance = fake_instance.fake_instance_obj(self.context)
- quotas = mock.create_autospec(objects.Quotas, spec_set=True)
-
- def do_test():
- with self.compute._error_out_instance_on_exception(
- self.context, instance, quotas):
- raise test.TestingException('test')
-
- self.assertRaises(test.TestingException, do_test)
- self.assertEqual(1, len(quotas.method_calls))
- self.assertEqual(mock.call.rollback(), quotas.method_calls[0])
- set_error.assert_called_once_with(self.context, instance)
-
- def test_cleanup_volumes(self):
- instance = fake_instance.fake_instance_obj(self.context)
- bdm_do_not_delete_dict = fake_block_device.FakeDbBlockDeviceDict(
- {'volume_id': 'fake-id1', 'source_type': 'image',
- 'delete_on_termination': False})
- bdm_delete_dict = fake_block_device.FakeDbBlockDeviceDict(
- {'volume_id': 'fake-id2', 'source_type': 'image',
- 'delete_on_termination': True})
- bdms = block_device_obj.block_device_make_list(self.context,
- [bdm_do_not_delete_dict, bdm_delete_dict])
-
- with mock.patch.object(self.compute.volume_api,
- 'delete') as volume_delete:
- self.compute._cleanup_volumes(self.context, instance.uuid, bdms)
- volume_delete.assert_called_once_with(self.context,
- bdms[1].volume_id)
-
- def test_cleanup_volumes_exception_do_not_raise(self):
- instance = fake_instance.fake_instance_obj(self.context)
- bdm_dict1 = fake_block_device.FakeDbBlockDeviceDict(
- {'volume_id': 'fake-id1', 'source_type': 'image',
- 'delete_on_termination': True})
- bdm_dict2 = fake_block_device.FakeDbBlockDeviceDict(
- {'volume_id': 'fake-id2', 'source_type': 'image',
- 'delete_on_termination': True})
- bdms = block_device_obj.block_device_make_list(self.context,
- [bdm_dict1, bdm_dict2])
-
- with mock.patch.object(self.compute.volume_api,
- 'delete',
- side_effect=[test.TestingException(), None]) as volume_delete:
- self.compute._cleanup_volumes(self.context, instance.uuid, bdms,
- raise_exc=False)
- calls = [mock.call(self.context, bdm.volume_id) for bdm in bdms]
- self.assertEqual(calls, volume_delete.call_args_list)
-
- def test_cleanup_volumes_exception_raise(self):
- instance = fake_instance.fake_instance_obj(self.context)
- bdm_dict1 = fake_block_device.FakeDbBlockDeviceDict(
- {'volume_id': 'fake-id1', 'source_type': 'image',
- 'delete_on_termination': True})
- bdm_dict2 = fake_block_device.FakeDbBlockDeviceDict(
- {'volume_id': 'fake-id2', 'source_type': 'image',
- 'delete_on_termination': True})
- bdms = block_device_obj.block_device_make_list(self.context,
- [bdm_dict1, bdm_dict2])
-
- with mock.patch.object(self.compute.volume_api,
- 'delete',
- side_effect=[test.TestingException(), None]) as volume_delete:
- self.assertRaises(test.TestingException,
- self.compute._cleanup_volumes, self.context, instance.uuid,
- bdms)
- calls = [mock.call(self.context, bdm.volume_id) for bdm in bdms]
- self.assertEqual(calls, volume_delete.call_args_list)
-
- def test_start_building(self):
- instance = fake_instance.fake_instance_obj(self.context)
- with mock.patch.object(self.compute, '_instance_update') as update:
- self.compute._start_building(self.context, instance)
- update.assert_called_once_with(
- self.context, instance.uuid, vm_state=vm_states.BUILDING,
- task_state=None, expected_task_state=(task_states.SCHEDULING,
- None))
-
- def _test_prebuild_instance_build_abort_exception(self, exc):
- instance = fake_instance.fake_instance_obj(self.context)
- with contextlib.nested(
- mock.patch.object(self.compute, '_check_instance_exists'),
- mock.patch.object(self.compute, '_start_building',
- side_effect=exc)
- ) as (
- check, start
- ):
- # run the code
- self.assertRaises(exception.BuildAbortException,
- self.compute._prebuild_instance,
- self.context, instance)
- # assert the calls
- check.assert_called_once_with(self.context, instance)
- start.assert_called_once_with(self.context, instance)
-
- def test_prebuild_instance_instance_not_found(self):
- self._test_prebuild_instance_build_abort_exception(
- exception.InstanceNotFound(instance_id='fake'))
-
- def test_prebuild_instance_unexpected_deleting_task_state_err(self):
- self._test_prebuild_instance_build_abort_exception(
- exception.UnexpectedDeletingTaskStateError(expected='foo',
- actual='bar'))
-
- def test_stop_instance_task_state_none_power_state_shutdown(self):
- # Tests that stop_instance doesn't puke when the instance power_state
- # is shutdown and the task_state is None.
- instance = fake_instance.fake_instance_obj(
- self.context, vm_state=vm_states.ACTIVE,
- task_state=None, power_state=power_state.SHUTDOWN)
-
- @mock.patch.object(objects.InstanceActionEvent, 'event_start')
- @mock.patch.object(objects.InstanceActionEvent,
- 'event_finish_with_failure')
- @mock.patch.object(self.compute, '_get_power_state',
- return_value=power_state.SHUTDOWN)
- @mock.patch.object(self.compute, '_notify_about_instance_usage')
- @mock.patch.object(self.compute, '_power_off_instance')
- @mock.patch.object(instance, 'save')
- def do_test(save_mock, power_off_mock, notify_mock, get_state_mock,
- event_finish_mock, event_start_mock):
- # run the code
- self.compute.stop_instance(self.context, instance)
- # assert the calls
- self.assertEqual(2, get_state_mock.call_count)
- notify_mock.assert_has_calls([
- mock.call(self.context, instance, 'power_off.start'),
- mock.call(self.context, instance, 'power_off.end')
- ])
- power_off_mock.assert_called_once_with(
- self.context, instance, True)
- save_mock.assert_called_once_with(
- expected_task_state=[task_states.POWERING_OFF, None])
- self.assertEqual(power_state.SHUTDOWN, instance.power_state)
- self.assertIsNone(instance.task_state)
- self.assertEqual(vm_states.STOPPED, instance.vm_state)
-
- do_test()
-
- def test_reset_network_driver_not_implemented(self):
- instance = fake_instance.fake_instance_obj(self.context)
-
- @mock.patch.object(self.compute.driver, 'reset_network',
- side_effect=NotImplementedError())
- @mock.patch.object(compute_utils, 'add_instance_fault_from_exc')
- def do_test(mock_add_fault, mock_reset):
- self.assertRaises(messaging.ExpectedException,
- self.compute.reset_network,
- self.context,
- instance)
-
- self.compute = utils.ExceptionHelper(self.compute)
-
- self.assertRaises(NotImplementedError,
- self.compute.reset_network,
- self.context,
- instance)
-
- do_test()
-
- def test_rebuild_default_impl(self):
- def _detach(context, bdms):
- pass
-
- def _attach(context, instance, bdms, do_check_attach=True):
- return {'block_device_mapping': 'shared_block_storage'}
-
- def _spawn(context, instance, image_meta, injected_files,
- admin_password, network_info=None, block_device_info=None):
- self.assertEqual(block_device_info['block_device_mapping'],
- 'shared_block_storage')
-
- with contextlib.nested(
- mock.patch.object(self.compute.driver, 'destroy',
- return_value=None),
- mock.patch.object(self.compute.driver, 'spawn',
- side_effect=_spawn),
- mock.patch.object(objects.Instance, 'save',
- return_value=None)
- ) as(
- mock_destroy,
- mock_spawn,
- mock_save
- ):
- instance = fake_instance.fake_instance_obj(self.context)
- instance.task_state = task_states.REBUILDING
- instance.save(expected_task_state=[task_states.REBUILDING])
- self.compute._rebuild_default_impl(self.context,
- instance,
- None,
- [],
- admin_password='new_pass',
- bdms=[],
- detach_block_devices=_detach,
- attach_block_devices=_attach,
- network_info=None,
- recreate=True,
- block_device_info=None,
- preserve_ephemeral=False)
-
- self.assertFalse(mock_destroy.called)
- self.assertTrue(mock_save.called)
- self.assertTrue(mock_spawn.called)
-
-
-class ComputeManagerBuildInstanceTestCase(test.NoDBTestCase):
- def setUp(self):
- super(ComputeManagerBuildInstanceTestCase, self).setUp()
- self.compute = importutils.import_object(CONF.compute_manager)
- self.context = context.RequestContext('fake', 'fake')
- self.instance = fake_instance.fake_instance_obj(self.context,
- vm_state=vm_states.ACTIVE,
- expected_attrs=['metadata', 'system_metadata', 'info_cache'])
- self.admin_pass = 'pass'
- self.injected_files = []
- self.image = {}
- self.node = 'fake-node'
- self.limits = {}
- self.requested_networks = []
- self.security_groups = []
- self.block_device_mapping = []
- self.filter_properties = {'retry': {'num_attempts': 1,
- 'hosts': [[self.compute.host,
- 'fake-node']]}}
-
- def fake_network_info():
- return network_model.NetworkInfo()
-
- self.network_info = network_model.NetworkInfoAsyncWrapper(
- fake_network_info)
- self.block_device_info = self.compute._prep_block_device(context,
- self.instance, self.block_device_mapping)
-
- # override tracker with a version that doesn't need the database:
- fake_rt = fake_resource_tracker.FakeResourceTracker(self.compute.host,
- self.compute.driver, self.node)
- self.compute._resource_tracker_dict[self.node] = fake_rt
-
- def _do_build_instance_update(self, reschedule_update=False):
- self.mox.StubOutWithMock(self.instance, 'save')
- self.instance.save(
- expected_task_state=(task_states.SCHEDULING, None)).AndReturn(
- self.instance)
- if reschedule_update:
- self.instance.save().AndReturn(self.instance)
-
- def _build_and_run_instance_update(self):
- self.mox.StubOutWithMock(self.instance, 'save')
- self._build_resources_instance_update(stub=False)
- self.instance.save(expected_task_state=
- task_states.BLOCK_DEVICE_MAPPING).AndReturn(self.instance)
-
- def _build_resources_instance_update(self, stub=True):
- if stub:
- self.mox.StubOutWithMock(self.instance, 'save')
- self.instance.save().AndReturn(self.instance)
-
- def _notify_about_instance_usage(self, event, stub=True, **kwargs):
- if stub:
- self.mox.StubOutWithMock(self.compute,
- '_notify_about_instance_usage')
- self.compute._notify_about_instance_usage(self.context, self.instance,
- event, **kwargs)
-
- def _instance_action_events(self):
- self.mox.StubOutWithMock(objects.InstanceActionEvent, 'event_start')
- self.mox.StubOutWithMock(objects.InstanceActionEvent,
- 'event_finish_with_failure')
- objects.InstanceActionEvent.event_start(
- self.context, self.instance.uuid, mox.IgnoreArg(),
- want_result=False)
- objects.InstanceActionEvent.event_finish_with_failure(
- self.context, self.instance.uuid, mox.IgnoreArg(),
- exc_val=mox.IgnoreArg(), exc_tb=mox.IgnoreArg(),
- want_result=False)
-
- @mock.patch('nova.utils.spawn_n')
- def test_build_and_run_instance_called_with_proper_args(self, mock_spawn):
- mock_spawn.side_effect = lambda f, *a, **k: f(*a, **k)
- self.mox.StubOutWithMock(self.compute, '_build_and_run_instance')
- self._do_build_instance_update()
- self.compute._build_and_run_instance(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node, self.limits,
- self.filter_properties)
- self._instance_action_events()
- self.mox.ReplayAll()
-
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties=self.filter_properties,
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=self.requested_networks,
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
-
- # This test when sending an icehouse compatible rpc call to juno compute
- # node, NetworkRequest object can load from three items tuple.
- @mock.patch('nova.objects.InstanceActionEvent.event_finish_with_failure')
- @mock.patch('nova.objects.InstanceActionEvent.event_start')
- @mock.patch('nova.objects.Instance.save')
- @mock.patch('nova.compute.manager.ComputeManager._build_and_run_instance')
- @mock.patch('nova.utils.spawn_n')
- def test_build_and_run_instance_with_icehouse_requested_network(
- self, mock_spawn, mock_build_and_run, mock_save, mock_event_start,
- mock_event_finish):
- mock_spawn.side_effect = lambda f, *a, **k: f(*a, **k)
- mock_save.return_value = self.instance
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties=self.filter_properties,
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=[('fake_network_id', '10.0.0.1',
- 'fake_port_id')],
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
- requested_network = mock_build_and_run.call_args[0][5][0]
- self.assertEqual('fake_network_id', requested_network.network_id)
- self.assertEqual('10.0.0.1', str(requested_network.address))
- self.assertEqual('fake_port_id', requested_network.port_id)
-
- @mock.patch('nova.utils.spawn_n')
- def test_build_abort_exception(self, mock_spawn):
- def fake_spawn(f, *args, **kwargs):
- # NOTE(danms): Simulate the detached nature of spawn so that
- # we confirm that the inner task has the fault logic
- try:
- return f(*args, **kwargs)
- except Exception:
- pass
-
- mock_spawn.side_effect = fake_spawn
-
- self.mox.StubOutWithMock(self.compute, '_build_and_run_instance')
- self.mox.StubOutWithMock(self.compute, '_cleanup_allocated_networks')
- self.mox.StubOutWithMock(self.compute, '_cleanup_volumes')
- self.mox.StubOutWithMock(compute_utils, 'add_instance_fault_from_exc')
- self.mox.StubOutWithMock(self.compute, '_set_instance_error_state')
- self.mox.StubOutWithMock(self.compute.compute_task_api,
- 'build_instances')
- self._do_build_instance_update()
- self.compute._build_and_run_instance(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node, self.limits,
- self.filter_properties).AndRaise(
- exception.BuildAbortException(reason='',
- instance_uuid=self.instance.uuid))
- self.compute._cleanup_allocated_networks(self.context, self.instance,
- self.requested_networks)
- self.compute._cleanup_volumes(self.context, self.instance.uuid,
- self.block_device_mapping, raise_exc=False)
- compute_utils.add_instance_fault_from_exc(self.context,
- self.instance, mox.IgnoreArg(), mox.IgnoreArg())
- self.compute._set_instance_error_state(self.context, self.instance)
- self._instance_action_events()
- self.mox.ReplayAll()
-
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties=self.filter_properties,
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=self.requested_networks,
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
-
- @mock.patch('nova.utils.spawn_n')
- def test_rescheduled_exception(self, mock_spawn):
- mock_spawn.side_effect = lambda f, *a, **k: f(*a, **k)
- self.mox.StubOutWithMock(self.compute, '_build_and_run_instance')
- self.mox.StubOutWithMock(self.compute, '_set_instance_error_state')
- self.mox.StubOutWithMock(self.compute.compute_task_api,
- 'build_instances')
- self._do_build_instance_update(reschedule_update=True)
- self.compute._build_and_run_instance(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node, self.limits,
- self.filter_properties).AndRaise(
- exception.RescheduledException(reason='',
- instance_uuid=self.instance.uuid))
- self.compute.compute_task_api.build_instances(self.context,
- [self.instance], self.image, self.filter_properties,
- self.admin_pass, self.injected_files, self.requested_networks,
- self.security_groups, self.block_device_mapping)
- self._instance_action_events()
- self.mox.ReplayAll()
-
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties=self.filter_properties,
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=self.requested_networks,
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
-
- def test_rescheduled_exception_with_non_ascii_exception(self):
- exc = exception.NovaException(u's\xe9quence')
- self.mox.StubOutWithMock(self.compute.driver, 'spawn')
- self.mox.StubOutWithMock(conductor_rpcapi.ConductorAPI,
- 'instance_update')
- self.mox.StubOutWithMock(self.compute, '_build_networks_for_instance')
- self.mox.StubOutWithMock(self.compute, '_shutdown_instance')
- self.compute._build_networks_for_instance(self.context, self.instance,
- self.requested_networks, self.security_groups).AndReturn(
- self.network_info)
- self.compute._shutdown_instance(self.context, self.instance,
- self.block_device_mapping, self.requested_networks,
- try_deallocate_networks=False)
- self._notify_about_instance_usage('create.start',
- extra_usage_info={'image_name': self.image.get('name')})
- self._build_and_run_instance_update()
- self.compute.driver.spawn(self.context, self.instance, self.image,
- self.injected_files, self.admin_pass,
- network_info=self.network_info,
- block_device_info=self.block_device_info).AndRaise(exc)
- self._notify_about_instance_usage('create.error',
- fault=exc, stub=False)
- conductor_rpcapi.ConductorAPI.instance_update(
- self.context, self.instance['uuid'], mox.IgnoreArg(), 'conductor')
- self.mox.ReplayAll()
-
- self.assertRaises(exception.RescheduledException,
- self.compute._build_and_run_instance, self.context,
- self.instance, self.image, self.injected_files,
- self.admin_pass, self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node,
- self.limits, self.filter_properties)
-
- @mock.patch('nova.utils.spawn_n')
- def test_rescheduled_exception_without_retry(self, mock_spawn):
- mock_spawn.side_effect = lambda f, *a, **k: f(*a, **k)
- self.mox.StubOutWithMock(self.compute, '_build_and_run_instance')
- self.mox.StubOutWithMock(compute_utils, 'add_instance_fault_from_exc')
- self.mox.StubOutWithMock(self.compute, '_set_instance_error_state')
- self.mox.StubOutWithMock(self.compute, '_cleanup_allocated_networks')
- self.mox.StubOutWithMock(self.compute, '_cleanup_volumes')
- self._do_build_instance_update()
- self.compute._build_and_run_instance(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node, self.limits,
- {}).AndRaise(
- exception.RescheduledException(reason='',
- instance_uuid=self.instance.uuid))
- self.compute._cleanup_allocated_networks(self.context, self.instance,
- self.requested_networks)
- compute_utils.add_instance_fault_from_exc(self.context, self.instance,
- mox.IgnoreArg(), mox.IgnoreArg())
- self.compute._set_instance_error_state(self.context,
- self.instance)
- self._instance_action_events()
- self.mox.ReplayAll()
-
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties={},
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=self.requested_networks,
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
-
- @mock.patch('nova.utils.spawn_n')
- def test_rescheduled_exception_do_not_deallocate_network(self, mock_spawn):
- mock_spawn.side_effect = lambda f, *a, **k: f(*a, **k)
- self.mox.StubOutWithMock(self.compute, '_build_and_run_instance')
- self.mox.StubOutWithMock(self.compute.driver,
- 'deallocate_networks_on_reschedule')
- self.mox.StubOutWithMock(self.compute, '_cleanup_allocated_networks')
- self.mox.StubOutWithMock(self.compute.compute_task_api,
- 'build_instances')
- self._do_build_instance_update(reschedule_update=True)
- self.compute._build_and_run_instance(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node, self.limits,
- self.filter_properties).AndRaise(
- exception.RescheduledException(reason='',
- instance_uuid=self.instance.uuid))
- self.compute.driver.deallocate_networks_on_reschedule(
- self.instance).AndReturn(False)
- self.compute.compute_task_api.build_instances(self.context,
- [self.instance], self.image, self.filter_properties,
- self.admin_pass, self.injected_files, self.requested_networks,
- self.security_groups, self.block_device_mapping)
- self._instance_action_events()
- self.mox.ReplayAll()
-
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties=self.filter_properties,
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=self.requested_networks,
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
-
- @mock.patch('nova.utils.spawn_n')
- def test_rescheduled_exception_deallocate_network(self, mock_spawn):
- mock_spawn.side_effect = lambda f, *a, **k: f(*a, **k)
- self.mox.StubOutWithMock(self.compute, '_build_and_run_instance')
- self.mox.StubOutWithMock(self.compute.driver,
- 'deallocate_networks_on_reschedule')
- self.mox.StubOutWithMock(self.compute, '_cleanup_allocated_networks')
- self.mox.StubOutWithMock(self.compute.compute_task_api,
- 'build_instances')
- self._do_build_instance_update(reschedule_update=True)
- self.compute._build_and_run_instance(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node, self.limits,
- self.filter_properties).AndRaise(
- exception.RescheduledException(reason='',
- instance_uuid=self.instance.uuid))
- self.compute.driver.deallocate_networks_on_reschedule(
- self.instance).AndReturn(True)
- self.compute._cleanup_allocated_networks(self.context, self.instance,
- self.requested_networks)
- self.compute.compute_task_api.build_instances(self.context,
- [self.instance], self.image, self.filter_properties,
- self.admin_pass, self.injected_files, self.requested_networks,
- self.security_groups, self.block_device_mapping)
- self._instance_action_events()
- self.mox.ReplayAll()
-
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties=self.filter_properties,
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=self.requested_networks,
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
-
- def _test_build_and_run_exceptions(self, exc, set_error=False,
- cleanup_volumes=False):
- self.mox.StubOutWithMock(self.compute, '_build_and_run_instance')
- self.mox.StubOutWithMock(self.compute, '_cleanup_allocated_networks')
- self.mox.StubOutWithMock(self.compute, '_cleanup_volumes')
- self.mox.StubOutWithMock(self.compute.compute_task_api,
- 'build_instances')
- self._do_build_instance_update()
- self.compute._build_and_run_instance(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node, self.limits,
- self.filter_properties).AndRaise(exc)
- self.compute._cleanup_allocated_networks(self.context, self.instance,
- self.requested_networks)
- if cleanup_volumes:
- self.compute._cleanup_volumes(self.context, self.instance.uuid,
- self.block_device_mapping, raise_exc=False)
- if set_error:
- self.mox.StubOutWithMock(self.compute, '_set_instance_error_state')
- self.mox.StubOutWithMock(compute_utils,
- 'add_instance_fault_from_exc')
- compute_utils.add_instance_fault_from_exc(self.context,
- self.instance, mox.IgnoreArg(), mox.IgnoreArg())
- self.compute._set_instance_error_state(self.context, self.instance)
- self._instance_action_events()
- self.mox.ReplayAll()
-
- with mock.patch('nova.utils.spawn_n') as mock_spawn:
- mock_spawn.side_effect = lambda f, *a, **k: f(*a, **k)
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties=self.filter_properties,
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=self.requested_networks,
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
-
- def test_build_and_run_notfound_exception(self):
- self._test_build_and_run_exceptions(exception.InstanceNotFound(
- instance_id=''))
-
- def test_build_and_run_unexpecteddeleting_exception(self):
- self._test_build_and_run_exceptions(
- exception.UnexpectedDeletingTaskStateError(expected='',
- actual=''))
-
- def test_build_and_run_buildabort_exception(self):
- self._test_build_and_run_exceptions(exception.BuildAbortException(
- instance_uuid='', reason=''), set_error=True, cleanup_volumes=True)
-
- def test_build_and_run_unhandled_exception(self):
- self._test_build_and_run_exceptions(test.TestingException(),
- set_error=True, cleanup_volumes=True)
-
- def test_instance_not_found(self):
- exc = exception.InstanceNotFound(instance_id=1)
- self.mox.StubOutWithMock(self.compute.driver, 'spawn')
- self.mox.StubOutWithMock(conductor_rpcapi.ConductorAPI,
- 'instance_update')
- self.mox.StubOutWithMock(self.compute, '_build_networks_for_instance')
- self.mox.StubOutWithMock(self.compute, '_shutdown_instance')
- self.compute._build_networks_for_instance(self.context, self.instance,
- self.requested_networks, self.security_groups).AndReturn(
- self.network_info)
- self.compute._shutdown_instance(self.context, self.instance,
- self.block_device_mapping, self.requested_networks,
- try_deallocate_networks=False)
- self._notify_about_instance_usage('create.start',
- extra_usage_info={'image_name': self.image.get('name')})
- self._build_and_run_instance_update()
- self.compute.driver.spawn(self.context, self.instance, self.image,
- self.injected_files, self.admin_pass,
- network_info=self.network_info,
- block_device_info=self.block_device_info).AndRaise(exc)
- self._notify_about_instance_usage('create.end',
- fault=exc, stub=False)
- conductor_rpcapi.ConductorAPI.instance_update(
- self.context, self.instance.uuid, mox.IgnoreArg(), 'conductor')
- self.mox.ReplayAll()
-
- self.assertRaises(exception.InstanceNotFound,
- self.compute._build_and_run_instance, self.context,
- self.instance, self.image, self.injected_files,
- self.admin_pass, self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node,
- self.limits, self.filter_properties)
-
- def test_reschedule_on_exception(self):
- self.mox.StubOutWithMock(self.compute.driver, 'spawn')
- self.mox.StubOutWithMock(conductor_rpcapi.ConductorAPI,
- 'instance_update')
- self.mox.StubOutWithMock(self.compute, '_build_networks_for_instance')
- self.mox.StubOutWithMock(self.compute, '_shutdown_instance')
- self.compute._build_networks_for_instance(self.context, self.instance,
- self.requested_networks, self.security_groups).AndReturn(
- self.network_info)
- self.compute._shutdown_instance(self.context, self.instance,
- self.block_device_mapping, self.requested_networks,
- try_deallocate_networks=False)
- self._notify_about_instance_usage('create.start',
- extra_usage_info={'image_name': self.image.get('name')})
- self._build_and_run_instance_update()
- exc = test.TestingException()
- self.compute.driver.spawn(self.context, self.instance, self.image,
- self.injected_files, self.admin_pass,
- network_info=self.network_info,
- block_device_info=self.block_device_info).AndRaise(exc)
- conductor_rpcapi.ConductorAPI.instance_update(
- self.context, self.instance.uuid, mox.IgnoreArg(), 'conductor')
- self._notify_about_instance_usage('create.error',
- fault=exc, stub=False)
- self.mox.ReplayAll()
-
- self.assertRaises(exception.RescheduledException,
- self.compute._build_and_run_instance, self.context,
- self.instance, self.image, self.injected_files,
- self.admin_pass, self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node,
- self.limits, self.filter_properties)
-
- def test_spawn_network_alloc_failure(self):
- # Because network allocation is asynchronous, failures may not present
- # themselves until the virt spawn method is called.
- self._test_build_and_run_spawn_exceptions(exception.NoMoreNetworks())
-
- def test_build_and_run_flavor_disk_too_small_exception(self):
- self._test_build_and_run_spawn_exceptions(
- exception.FlavorDiskTooSmall())
-
- def test_build_and_run_flavor_memory_too_small_exception(self):
- self._test_build_and_run_spawn_exceptions(
- exception.FlavorMemoryTooSmall())
-
- def test_build_and_run_image_not_active_exception(self):
- self._test_build_and_run_spawn_exceptions(
- exception.ImageNotActive(image_id=self.image.get('id')))
-
- def test_build_and_run_image_unacceptable_exception(self):
- self._test_build_and_run_spawn_exceptions(
- exception.ImageUnacceptable(image_id=self.image.get('id'),
- reason=""))
-
- def _test_build_and_run_spawn_exceptions(self, exc):
- with contextlib.nested(
- mock.patch.object(self.compute.driver, 'spawn',
- side_effect=exc),
- mock.patch.object(conductor_rpcapi.ConductorAPI,
- 'instance_update'),
- mock.patch.object(self.instance, 'save',
- side_effect=[self.instance, self.instance]),
- mock.patch.object(self.compute,
- '_build_networks_for_instance',
- return_value=self.network_info),
- mock.patch.object(self.compute,
- '_notify_about_instance_usage'),
- mock.patch.object(self.compute,
- '_shutdown_instance'),
- mock.patch.object(self.compute,
- '_validate_instance_group_policy')
- ) as (spawn, instance_update, save,
- _build_networks_for_instance, _notify_about_instance_usage,
- _shutdown_instance, _validate_instance_group_policy):
-
- self.assertRaises(exception.BuildAbortException,
- self.compute._build_and_run_instance, self.context,
- self.instance, self.image, self.injected_files,
- self.admin_pass, self.requested_networks,
- self.security_groups, self.block_device_mapping, self.node,
- self.limits, self.filter_properties)
-
- _validate_instance_group_policy.assert_called_once_with(
- self.context, self.instance, self.filter_properties)
- _build_networks_for_instance.assert_has_calls(
- mock.call(self.context, self.instance,
- self.requested_networks, self.security_groups))
-
- _notify_about_instance_usage.assert_has_calls([
- mock.call(self.context, self.instance, 'create.start',
- extra_usage_info={'image_name': self.image.get('name')}),
- mock.call(self.context, self.instance, 'create.error',
- fault=exc)])
-
- save.assert_has_calls([
- mock.call(),
- mock.call(
- expected_task_state=task_states.BLOCK_DEVICE_MAPPING)])
-
- spawn.assert_has_calls(mock.call(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- network_info=self.network_info,
- block_device_info=self.block_device_info))
-
- instance_update.assert_has_calls(mock.call(self.context,
- self.instance.uuid, mock.ANY, 'conductor'))
-
- _shutdown_instance.assert_called_once_with(self.context,
- self.instance, self.block_device_mapping,
- self.requested_networks, try_deallocate_networks=False)
-
- @mock.patch('nova.compute.manager.ComputeManager._get_power_state')
- def test_spawn_waits_for_network_and_saves_info_cache(self, gps):
- inst = mock.MagicMock()
- network_info = mock.MagicMock()
- with mock.patch.object(self.compute, 'driver'):
- self.compute._spawn(self.context, inst, {}, network_info, None,
- None, None)
- network_info.wait.assert_called_once_with(do_raise=True)
- self.assertEqual(network_info, inst.info_cache.network_info)
- inst.save.assert_called_with(expected_task_state=task_states.SPAWNING)
-
- @mock.patch('nova.utils.spawn_n')
- def test_reschedule_on_resources_unavailable(self, mock_spawn):
- mock_spawn.side_effect = lambda f, *a, **k: f(*a, **k)
- reason = 'resource unavailable'
- exc = exception.ComputeResourcesUnavailable(reason=reason)
-
- class FakeResourceTracker(object):
- def instance_claim(self, context, instance, limits):
- raise exc
-
- self.mox.StubOutWithMock(self.compute, '_get_resource_tracker')
- self.mox.StubOutWithMock(self.compute.compute_task_api,
- 'build_instances')
- self.compute._get_resource_tracker(self.node).AndReturn(
- FakeResourceTracker())
- self._do_build_instance_update(reschedule_update=True)
- self._notify_about_instance_usage('create.start',
- extra_usage_info={'image_name': self.image.get('name')})
- self._notify_about_instance_usage('create.error',
- fault=exc, stub=False)
- self.compute.compute_task_api.build_instances(self.context,
- [self.instance], self.image, self.filter_properties,
- self.admin_pass, self.injected_files, self.requested_networks,
- self.security_groups, self.block_device_mapping)
- self._instance_action_events()
- self.mox.ReplayAll()
-
- self.compute.build_and_run_instance(self.context, self.instance,
- self.image, request_spec={},
- filter_properties=self.filter_properties,
- injected_files=self.injected_files,
- admin_password=self.admin_pass,
- requested_networks=self.requested_networks,
- security_groups=self.security_groups,
- block_device_mapping=self.block_device_mapping, node=self.node,
- limits=self.limits)
-
- def test_build_resources_buildabort_reraise(self):
- exc = exception.BuildAbortException(
- instance_uuid=self.instance.uuid, reason='')
- self.mox.StubOutWithMock(self.compute, '_build_resources')
- self.mox.StubOutWithMock(conductor_rpcapi.ConductorAPI,
- 'instance_update')
- conductor_rpcapi.ConductorAPI.instance_update(
- self.context, self.instance.uuid, mox.IgnoreArg(), 'conductor')
- self._notify_about_instance_usage('create.start',
- extra_usage_info={'image_name': self.image.get('name')})
- self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups, self.image,
- self.block_device_mapping).AndRaise(exc)
- self._notify_about_instance_usage('create.error',
- fault=exc, stub=False)
- self.mox.ReplayAll()
- self.assertRaises(exception.BuildAbortException,
- self.compute._build_and_run_instance, self.context,
- self.instance, self.image, self.injected_files,
- self.admin_pass, self.requested_networks,
- self.security_groups, self.block_device_mapping, self.node,
- self.limits, self.filter_properties)
-
- def test_build_resources_reraises_on_failed_bdm_prep(self):
- self.mox.StubOutWithMock(self.compute, '_prep_block_device')
- self.mox.StubOutWithMock(self.compute, '_build_networks_for_instance')
- self.compute._build_networks_for_instance(self.context, self.instance,
- self.requested_networks, self.security_groups).AndReturn(
- self.network_info)
- self._build_resources_instance_update()
- self.compute._prep_block_device(self.context, self.instance,
- self.block_device_mapping).AndRaise(test.TestingException())
- self.mox.ReplayAll()
-
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- pass
- except Exception as e:
- self.assertIsInstance(e, exception.BuildAbortException)
-
- def test_failed_bdm_prep_from_delete_raises_unexpected(self):
- with contextlib.nested(
- mock.patch.object(self.compute,
- '_build_networks_for_instance',
- return_value=self.network_info),
- mock.patch.object(self.instance, 'save',
- side_effect=exception.UnexpectedDeletingTaskStateError(
- actual=task_states.DELETING, expected='None')),
- ) as (_build_networks_for_instance, save):
-
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- pass
- except Exception as e:
- self.assertIsInstance(e,
- exception.UnexpectedDeletingTaskStateError)
-
- _build_networks_for_instance.assert_has_calls(
- mock.call(self.context, self.instance,
- self.requested_networks, self.security_groups))
-
- save.assert_has_calls(mock.call())
-
- def test_build_resources_aborts_on_failed_network_alloc(self):
- self.mox.StubOutWithMock(self.compute, '_build_networks_for_instance')
- self.compute._build_networks_for_instance(self.context, self.instance,
- self.requested_networks, self.security_groups).AndRaise(
- test.TestingException())
- self.mox.ReplayAll()
-
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups, self.image,
- self.block_device_mapping):
- pass
- except Exception as e:
- self.assertIsInstance(e, exception.BuildAbortException)
-
- def test_failed_network_alloc_from_delete_raises_unexpected(self):
- with mock.patch.object(self.compute,
- '_build_networks_for_instance') as _build_networks:
-
- exc = exception.UnexpectedDeletingTaskStateError
- _build_networks.side_effect = exc(actual=task_states.DELETING,
- expected='None')
-
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- pass
- except Exception as e:
- self.assertIsInstance(e, exc)
-
- _build_networks.assert_has_calls(
- mock.call(self.context, self.instance,
- self.requested_networks, self.security_groups))
-
- def test_build_resources_with_network_info_obj_on_spawn_failure(self):
- self.mox.StubOutWithMock(self.compute, '_build_networks_for_instance')
- self.mox.StubOutWithMock(self.compute, '_shutdown_instance')
- self.compute._build_networks_for_instance(self.context, self.instance,
- self.requested_networks, self.security_groups).AndReturn(
- network_model.NetworkInfo())
- self.compute._shutdown_instance(self.context, self.instance,
- self.block_device_mapping, self.requested_networks,
- try_deallocate_networks=False)
- self._build_resources_instance_update()
- self.mox.ReplayAll()
-
- test_exception = test.TestingException()
-
- def fake_spawn():
- raise test_exception
-
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- fake_spawn()
- except Exception as e:
- self.assertEqual(test_exception, e)
-
- def test_build_resources_cleans_up_and_reraises_on_spawn_failure(self):
- self.mox.StubOutWithMock(self.compute, '_build_networks_for_instance')
- self.mox.StubOutWithMock(self.compute, '_shutdown_instance')
- self.compute._build_networks_for_instance(self.context, self.instance,
- self.requested_networks, self.security_groups).AndReturn(
- self.network_info)
- self.compute._shutdown_instance(self.context, self.instance,
- self.block_device_mapping, self.requested_networks,
- try_deallocate_networks=False)
- self._build_resources_instance_update()
- self.mox.ReplayAll()
-
- test_exception = test.TestingException()
-
- def fake_spawn():
- raise test_exception
-
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- fake_spawn()
- except Exception as e:
- self.assertEqual(test_exception, e)
-
- @mock.patch('nova.network.model.NetworkInfoAsyncWrapper.wait')
- @mock.patch(
- 'nova.compute.manager.ComputeManager._build_networks_for_instance')
- @mock.patch('nova.objects.Instance.save')
- def test_build_resources_instance_not_found_before_yield(
- self, mock_save, mock_build_network, mock_info_wait):
- mock_build_network.return_value = self.network_info
- expected_exc = exception.InstanceNotFound(
- instance_id=self.instance.uuid)
- mock_save.side_effect = expected_exc
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- raise
- except Exception as e:
- self.assertEqual(expected_exc, e)
- mock_build_network.assert_called_once_with(self.context, self.instance,
- self.requested_networks, self.security_groups)
- mock_info_wait.assert_called_once_with(do_raise=False)
-
- @mock.patch('nova.network.model.NetworkInfoAsyncWrapper.wait')
- @mock.patch(
- 'nova.compute.manager.ComputeManager._build_networks_for_instance')
- @mock.patch('nova.objects.Instance.save')
- def test_build_resources_unexpected_task_error_before_yield(
- self, mock_save, mock_build_network, mock_info_wait):
- mock_build_network.return_value = self.network_info
- mock_save.side_effect = exception.UnexpectedTaskStateError(
- expected='', actual='')
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- raise
- except exception.BuildAbortException:
- pass
- mock_build_network.assert_called_once_with(self.context, self.instance,
- self.requested_networks, self.security_groups)
- mock_info_wait.assert_called_once_with(do_raise=False)
-
- @mock.patch('nova.network.model.NetworkInfoAsyncWrapper.wait')
- @mock.patch(
- 'nova.compute.manager.ComputeManager._build_networks_for_instance')
- @mock.patch('nova.objects.Instance.save')
- def test_build_resources_exception_before_yield(
- self, mock_save, mock_build_network, mock_info_wait):
- mock_build_network.return_value = self.network_info
- mock_save.side_effect = Exception()
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- raise
- except exception.BuildAbortException:
- pass
- mock_build_network.assert_called_once_with(self.context, self.instance,
- self.requested_networks, self.security_groups)
- mock_info_wait.assert_called_once_with(do_raise=False)
-
- def test_build_resources_aborts_on_cleanup_failure(self):
- self.mox.StubOutWithMock(self.compute, '_build_networks_for_instance')
- self.mox.StubOutWithMock(self.compute, '_shutdown_instance')
- self.compute._build_networks_for_instance(self.context, self.instance,
- self.requested_networks, self.security_groups).AndReturn(
- self.network_info)
- self.compute._shutdown_instance(self.context, self.instance,
- self.block_device_mapping, self.requested_networks,
- try_deallocate_networks=False).AndRaise(
- test.TestingException())
- self._build_resources_instance_update()
- self.mox.ReplayAll()
-
- def fake_spawn():
- raise test.TestingException()
-
- try:
- with self.compute._build_resources(self.context, self.instance,
- self.requested_networks, self.security_groups,
- self.image, self.block_device_mapping):
- fake_spawn()
- except Exception as e:
- self.assertIsInstance(e, exception.BuildAbortException)
-
- def test_build_networks_if_not_allocated(self):
- instance = fake_instance.fake_instance_obj(self.context,
- system_metadata={},
- expected_attrs=['system_metadata'])
-
- self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
- self.mox.StubOutWithMock(self.compute, '_allocate_network')
- self.compute._allocate_network(self.context, instance,
- self.requested_networks, None, self.security_groups, None)
- self.mox.ReplayAll()
-
- self.compute._build_networks_for_instance(self.context, instance,
- self.requested_networks, self.security_groups)
-
- def test_build_networks_if_allocated_false(self):
- instance = fake_instance.fake_instance_obj(self.context,
- system_metadata=dict(network_allocated='False'),
- expected_attrs=['system_metadata'])
-
- self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
- self.mox.StubOutWithMock(self.compute, '_allocate_network')
- self.compute._allocate_network(self.context, instance,
- self.requested_networks, None, self.security_groups, None)
- self.mox.ReplayAll()
-
- self.compute._build_networks_for_instance(self.context, instance,
- self.requested_networks, self.security_groups)
-
- def test_return_networks_if_found(self):
- instance = fake_instance.fake_instance_obj(self.context,
- system_metadata=dict(network_allocated='True'),
- expected_attrs=['system_metadata'])
-
- def fake_network_info():
- return network_model.NetworkInfo([{'address': '123.123.123.123'}])
-
- self.mox.StubOutWithMock(self.compute, '_get_instance_nw_info')
- self.mox.StubOutWithMock(self.compute, '_allocate_network')
- self.compute._get_instance_nw_info(self.context, instance).AndReturn(
- network_model.NetworkInfoAsyncWrapper(fake_network_info))
- self.mox.ReplayAll()
-
- self.compute._build_networks_for_instance(self.context, instance,
- self.requested_networks, self.security_groups)
-
- def test_cleanup_allocated_networks_instance_not_found(self):
- with contextlib.nested(
- mock.patch.object(self.compute, '_deallocate_network'),
- mock.patch.object(self.instance, 'save',
- side_effect=exception.InstanceNotFound(instance_id=''))
- ) as (_deallocate_network, save):
- # Testing that this doesn't raise an exeption
- self.compute._cleanup_allocated_networks(self.context,
- self.instance, self.requested_networks)
- save.assert_called_once_with()
- self.assertEqual('False',
- self.instance.system_metadata['network_allocated'])
-
- @mock.patch.object(conductor_rpcapi.ConductorAPI, 'instance_update')
- def test_launched_at_in_create_end_notification(self,
- mock_instance_update):
-
- def fake_notify(*args, **kwargs):
- if args[2] == 'create.end':
- # Check that launched_at is set on the instance
- self.assertIsNotNone(args[1].launched_at)
-
- with contextlib.nested(
- mock.patch.object(self.compute.driver, 'spawn'),
- mock.patch.object(self.compute,
- '_build_networks_for_instance', return_value=[]),
- mock.patch.object(self.instance, 'save'),
- mock.patch.object(self.compute, '_notify_about_instance_usage',
- side_effect=fake_notify)
- ) as (mock_spawn, mock_networks, mock_save, mock_notify):
- self.compute._build_and_run_instance(self.context, self.instance,
- self.image, self.injected_files, self.admin_pass,
- self.requested_networks, self.security_groups,
- self.block_device_mapping, self.node, self.limits,
- self.filter_properties)
- expected_call = mock.call(self.context, self.instance,
- 'create.end', extra_usage_info={'message': u'Success'},
- network_info=[])
- create_end_call = mock_notify.call_args_list[
- mock_notify.call_count - 1]
- self.assertEqual(expected_call, create_end_call)
-
- @mock.patch.object(conductor_rpcapi.ConductorAPI, 'instance_update')
- def test_create_end_on_instance_delete(self, mock_instance_update):
-
- def fake_notify(*args, **kwargs):
- if args[2] == 'create.end':
- # Check that launched_at is set on the instance
- self.assertIsNotNone(args[1].launched_at)
-
- exc = exception.InstanceNotFound(instance_id='')
-
- with contextlib.nested(
- mock.patch.object(self.compute.driver, 'spawn'),
- mock.patch.object(self.compute,
- '_build_networks_for_instance', return_value=[]),
- mock.patch.object(self.instance, 'save',
- side_effect=[None, None, exc]),
- mock.patch.object(self.compute, '_notify_about_instance_usage',
- side_effect=fake_notify)
- ) as (mock_spawn, mock_networks, mock_save, mock_notify):
- self.assertRaises(exception.InstanceNotFound,
- self.compute._build_and_run_instance, self.context,
- self.instance, self.image, self.injected_files,
- self.admin_pass, self.requested_networks,
- self.security_groups, self.block_device_mapping, self.node,
- self.limits, self.filter_properties)
- expected_call = mock.call(self.context, self.instance,
- 'create.end', fault=exc)
- create_end_call = mock_notify.call_args_list[
- mock_notify.call_count - 1]
- self.assertEqual(expected_call, create_end_call)
-
-
-class ComputeManagerMigrationTestCase(test.NoDBTestCase):
- def setUp(self):
- super(ComputeManagerMigrationTestCase, self).setUp()
- self.compute = importutils.import_object(CONF.compute_manager)
- self.context = context.RequestContext('fake', 'fake')
- self.image = {}
- self.instance = fake_instance.fake_instance_obj(self.context,
- vm_state=vm_states.ACTIVE,
- expected_attrs=['metadata', 'system_metadata', 'info_cache'])
- self.migration = objects.Migration()
- self.migration.status = 'migrating'
-
- def test_finish_resize_failure(self):
- elevated_context = self.context.elevated()
- with contextlib.nested(
- mock.patch.object(self.compute, '_finish_resize',
- side_effect=exception.ResizeError(reason='')),
- mock.patch.object(objects.InstanceActionEvent, 'event_start'),
- mock.patch.object(objects.InstanceActionEvent,
- 'event_finish_with_failure'),
- mock.patch.object(db, 'instance_fault_create'),
- mock.patch.object(self.compute, '_instance_update'),
- mock.patch.object(self.migration, 'save'),
- mock.patch.object(self.context, 'elevated',
- return_value=elevated_context)
- ) as (meth, event_start, event_finish, fault_create, instance_update,
- migration_save, context_elevated):
- fault_create.return_value = (
- test_instance_fault.fake_faults['fake-uuid'][0])
- self.assertRaises(
- exception.ResizeError, self.compute.finish_resize,
- context=self.context, disk_info=[], image=self.image,
- instance=self.instance, reservations=[],
- migration=self.migration
- )
- self.assertEqual("error", self.migration.status)
- migration_save.assert_has_calls([mock.call(elevated_context)])
-
- def test_resize_instance_failure(self):
- elevated_context = self.context.elevated()
- self.migration.dest_host = None
- with contextlib.nested(
- mock.patch.object(self.compute.driver,
- 'migrate_disk_and_power_off',
- side_effect=exception.ResizeError(reason='')),
- mock.patch.object(objects.InstanceActionEvent, 'event_start'),
- mock.patch.object(objects.InstanceActionEvent,
- 'event_finish_with_failure'),
- mock.patch.object(db, 'instance_fault_create'),
- mock.patch.object(self.compute, '_instance_update'),
- mock.patch.object(self.migration, 'save'),
- mock.patch.object(self.context, 'elevated',
- return_value=elevated_context),
- mock.patch.object(self.compute, '_get_instance_nw_info',
- return_value=None),
- mock.patch.object(self.instance, 'save'),
- mock.patch.object(self.compute, '_notify_about_instance_usage'),
- mock.patch.object(self.compute,
- '_get_instance_block_device_info',
- return_value=None),
- mock.patch.object(objects.BlockDeviceMappingList,
- 'get_by_instance_uuid',
- return_value=None)
- ) as (meth, event_start, event_finish, fault_create, instance_update,
- migration_save, context_elevated, nw_info, save_inst, notify,
- vol_block_info, bdm):
- fault_create.return_value = (
- test_instance_fault.fake_faults['fake-uuid'][0])
- self.assertRaises(
- exception.ResizeError, self.compute.resize_instance,
- context=self.context, instance=self.instance, image=self.image,
- reservations=[], migration=self.migration, instance_type='type'
- )
- self.assertEqual("error", self.migration.status)
- migration_save.assert_has_calls([mock.call(elevated_context)])