示例#1
0
 def our_fake_method(message, **kwargs):
     raise test.TestingException('this should be returned')
示例#2
0
 def our_fake_method(message, **kwargs):
     raise test.TestingException('should not be reached')
示例#3
0
 def test_spawn_performs_rollback_and_throws_exception(self):
     self.assertRaises(test.TestingException,
                       self._test_spawn,
                       throw_exception=test.TestingException())
示例#4
0
    def _create_instance_data(self):
        """Creates an instance record and associated data like BDMs, VIFs,
        migrations, etc in the source cell and returns the Instance object.

        The idea is to create as many things from the
        Instance.INSTANCE_OPTIONAL_ATTRS list as possible.

        :returns: The created Instance and Migration objects
        """
        # Create the nova-compute services record first.
        fake_service = test_service._fake_service()
        fake_service.pop('version', None)  # version field is immutable
        fake_service.pop('id', None)  # cannot create with an id set
        service = objects.Service(self.source_context, **fake_service)
        service.create()
        # Create the compute node using the service.
        fake_compute_node = copy.copy(test_compute_node.fake_compute_node)
        fake_compute_node['host'] = service.host
        fake_compute_node['hypervisor_hostname'] = service.host
        fake_compute_node['stats'] = {}  # the object requires a dict
        fake_compute_node['service_id'] = service.id
        fake_compute_node.pop('id', None)  # cannot create with an id set
        compute_node = objects.ComputeNode(self.source_context,
                                           **fake_compute_node)
        compute_node.create()

        # Build an Instance object with basic fields set.
        updates = {
            'metadata': {
                'foo': 'bar'
            },
            'system_metadata': {
                'roles': ['member']
            },
            'host': compute_node.host,
            'node': compute_node.hypervisor_hostname
        }
        inst = fake_instance.fake_instance_obj(self.source_context, **updates)
        delattr(inst, 'id')  # cannot create an instance with an id set
        # Now we have to dirty all of the fields because fake_instance_obj
        # uses Instance._from_db_object to create the Instance object we have
        # but _from_db_object calls obj_reset_changes() which resets all of
        # the fields that were on the object, including the basic stuff like
        # the 'host' field, which means those fields don't get set in the DB.
        # TODO(mriedem): This should live in fake_instance_obj with a
        # make_creatable kwarg.
        for field in inst.obj_fields:
            if field in inst:
                setattr(inst, field, getattr(inst, field))
        # Make sure at least one expected basic field is dirty on the Instance.
        self.assertIn('host', inst.obj_what_changed())
        # Set the optional fields on the instance before creating it.
        inst.pci_requests = objects.InstancePCIRequests(requests=[
            objects.InstancePCIRequest(
                **test_instance_pci_requests.fake_pci_requests[0])
        ])
        inst.numa_topology = objects.InstanceNUMATopology(
            cells=test_instance_numa.fake_obj_numa_topology.cells)
        inst.trusted_certs = objects.TrustedCerts(ids=[uuids.cert])
        inst.vcpu_model = test_vcpu_model.fake_vcpumodel
        inst.keypairs = objects.KeyPairList(
            objects=[objects.KeyPair(**test_keypair.fake_keypair)])
        inst.device_metadata = (
            test_instance_device_metadata.get_fake_obj_device_metadata(
                self.source_context))
        # FIXME(mriedem): db.instance_create does not handle tags
        inst.obj_reset_changes(['tags'])
        inst.create()

        bdm = {
            'instance_uuid': inst.uuid,
            'source_type': 'volume',
            'destination_type': 'volume',
            'volume_id': uuids.volume_id,
            'volume_size': 1,
            'device_name': '/dev/vda',
        }
        bdm = objects.BlockDeviceMapping(
            self.source_context,
            **fake_block_device.FakeDbBlockDeviceDict(bdm_dict=bdm))
        delattr(bdm, 'id')  # cannot create a bdm with an id set
        bdm.obj_reset_changes(['id'])
        bdm.create()

        vif = objects.VirtualInterface(self.source_context,
                                       address='de:ad:be:ef:ca:fe',
                                       uuid=uuids.port,
                                       instance_uuid=inst.uuid)
        vif.create()

        info_cache = objects.InstanceInfoCache().new(self.source_context,
                                                     inst.uuid)
        info_cache.network_info = network_model.NetworkInfo(
            [network_model.VIF(id=vif.uuid, address=vif.address)])
        info_cache.save(update_cells=False)

        objects.TagList.create(self.source_context, inst.uuid, ['test'])

        try:
            raise test.TestingException('test-fault')
        except test.TestingException as fault:
            compute_utils.add_instance_fault_from_exc(self.source_context,
                                                      inst, fault)

        objects.InstanceAction().action_start(self.source_context,
                                              inst.uuid,
                                              'resize',
                                              want_result=False)
        objects.InstanceActionEvent().event_start(self.source_context,
                                                  inst.uuid,
                                                  'migrate_server',
                                                  want_result=False)

        # Create a fake migration for the cross-cell resize operation.
        migration = objects.Migration(
            self.source_context,
            **test_migration.fake_db_migration(instance_uuid=inst.uuid,
                                               cross_cell_move=True,
                                               migration_type='resize'))
        delattr(migration, 'id')  # cannot create a migration with an id set
        migration.obj_reset_changes(['id'])
        migration.create()

        # Create an old non-resize migration to make sure it is copied to the
        # target cell database properly.
        old_migration = objects.Migration(
            self.source_context,
            **test_migration.fake_db_migration(instance_uuid=inst.uuid,
                                               migration_type='live-migration',
                                               status='completed',
                                               uuid=uuids.old_migration))
        delattr(old_migration, 'id')  # cannot create a migration with an id
        old_migration.obj_reset_changes(['id'])
        old_migration.create()

        fake_pci_device = copy.copy(test_pci_device.fake_db_dev)
        fake_pci_device['extra_info'] = {}  # the object requires a dict
        fake_pci_device['compute_node_id'] = compute_node.id
        pci_device = objects.PciDevice.create(self.source_context,
                                              fake_pci_device)
        pci_device.allocate(inst)  # sets the status and instance_uuid fields
        pci_device.save()

        # Return a fresh copy of the instance from the DB with as many joined
        # fields loaded as possible.
        expected_attrs = copy.copy(instance_obj.INSTANCE_OPTIONAL_ATTRS)
        # Cannot load fault from get_by_uuid.
        expected_attrs.remove('fault')
        inst = objects.Instance.get_by_uuid(self.source_context,
                                            inst.uuid,
                                            expected_attrs=expected_attrs)
        return inst, migration
示例#5
0
 def fake_run_instance(message, host_sched_kwargs):
     call_info['num_tries'] += 1
     raise test.TestingException()
示例#6
0
 def _fake_exit(error):
     raise test.TestingException()
示例#7
0
 def error_apply():
     raise test.TestingException()
示例#8
0
 def get_metric_names(self):
     raise test.TestingException()
示例#9
0
 def _migrate_stub(self, domain, destination, params, flags):
     raise test.TestingException('_migrate_stub() must be implemented in '
                                 ' tests that expect the live migration '
                                 ' to start.')
示例#10
0
def bad_fetcher(image_id):
    raise test.TestingException("just plain bad.")
示例#11
0
 def async_wrapper():
     raise test.TestingException()
示例#12
0
 def _get_fake_response(self, raw_response=None, exc=False):
     if exc:
         return messaging.Response('fake', test.TestingException(), True)
     if raw_response is None:
         raw_response = 'fake-response'
     return messaging.Response('fake', raw_response, False)
示例#13
0
def bad_function_exception():
    raise test.TestingException()
示例#14
0
 def our_fake_method_failing(message, **kwargs):
     raise test.TestingException('fake failure')
示例#15
0
 def test_get_image_meta_unexpected_exception(self):
     error = test.TestingException()
     with testtools.ExpectedException(test.TestingException):
         self._test_get_image_meta_exception(error)
示例#16
0
 def get_metrics(self, **kwargs):
     raise test.TestingException()
示例#17
0
 def fake_grab_target_cells(filter_properties):
     call_info['num_tries'] += 1
     raise test.TestingException()
示例#18
0
def bad_function_exception(blah="a", boo="b", context=None):
    raise test.TestingException()
示例#19
0
 def _test(self, *args):
     raise test.TestingException("shouldn't be called")
示例#20
0
class ShelveComputeManagerTestCase(test_compute.BaseTestCase):
    @mock.patch.object(objects.BlockDeviceMappingList, 'get_by_instance_uuid')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_terminate_volume_connections')
    @mock.patch.object(nova.virt.fake.SmallFakeDriver, 'power_off')
    @mock.patch.object(nova.virt.fake.SmallFakeDriver, 'snapshot')
    @mock.patch.object(nova.compute.manager.ComputeManager, '_get_power_state')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_notify_about_instance_usage')
    @mock.patch('nova.compute.utils.notify_about_instance_action')
    def _shelve_instance(self,
                         shelved_offload_time,
                         mock_notify,
                         mock_notify_instance_usage,
                         mock_get_power_state,
                         mock_snapshot,
                         mock_power_off,
                         mock_terminate,
                         mock_get_bdms,
                         clean_shutdown=True,
                         guest_power_state=power_state.RUNNING):
        mock_get_power_state.return_value = 123

        CONF.set_override('shelved_offload_time', shelved_offload_time)
        host = 'fake-mini'
        instance = self._create_fake_instance_obj(
            params={
                'host': host,
                'power_state': guest_power_state
            })
        image_id = 'fake_image_id'
        host = 'fake-mini'
        self.useFixture(utils_fixture.TimeFixture())
        instance.task_state = task_states.SHELVING
        instance.save()

        fake_bdms = None
        if shelved_offload_time == 0:
            fake_bdms = objects.BlockDeviceMappingList()
            mock_get_bdms.return_value = fake_bdms

        tracking = {'last_state': instance.vm_state}

        def check_save(expected_task_state=None):
            self.assertEqual(123, instance.power_state)
            if tracking['last_state'] == vm_states.ACTIVE:
                if CONF.shelved_offload_time == 0:
                    self.assertEqual(task_states.SHELVING_OFFLOADING,
                                     instance.task_state)
                else:
                    self.assertIsNone(instance.task_state)
                self.assertEqual(vm_states.SHELVED, instance.vm_state)
                self.assertEqual([
                    task_states.SHELVING, task_states.SHELVING_IMAGE_UPLOADING
                ], expected_task_state)
                self.assertIn('shelved_at', instance.system_metadata)
                self.assertEqual(image_id,
                                 instance.system_metadata['shelved_image_id'])
                self.assertEqual(host,
                                 instance.system_metadata['shelved_host'])
                tracking['last_state'] = instance.vm_state
            elif (tracking['last_state'] == vm_states.SHELVED
                  and CONF.shelved_offload_time == 0):
                self.assertIsNone(instance.task_state)
                self.assertEqual(vm_states.SHELVED_OFFLOADED,
                                 instance.vm_state)
                self.assertEqual(
                    [task_states.SHELVING, task_states.SHELVING_OFFLOADING],
                    expected_task_state)
                tracking['last_state'] = instance.vm_state
            elif (tracking['last_state'] == vm_states.SHELVED_OFFLOADED
                  and CONF.shelved_offload_time == 0):
                self.assertIsNone(instance.host)
                self.assertIsNone(instance.node)
                self.assertIsNone(expected_task_state)
            else:
                self.fail('Unexpected save!')

        with test.nested(
                mock.patch.object(instance, 'save'),
                mock.patch.object(
                    self.compute.network_api,
                    'cleanup_instance_network_on_host')) as (mock_save,
                                                             mock_cleanup):
            mock_save.side_effect = check_save
            self.compute.shelve_instance(self.context,
                                         instance,
                                         image_id=image_id,
                                         clean_shutdown=clean_shutdown)
            mock_notify.assert_has_calls([
                mock.call(self.context,
                          instance,
                          'fake-mini',
                          action='shelve',
                          phase='start',
                          bdms=fake_bdms),
                mock.call(self.context,
                          instance,
                          'fake-mini',
                          action='shelve',
                          phase='end',
                          bdms=fake_bdms)
            ])

        # prepare expect call lists
        mock_notify_instance_usage_call_list = [
            mock.call(self.context, instance, 'shelve.start'),
            mock.call(self.context, instance, 'shelve.end')
        ]
        mock_power_off_call_list = []
        mock_get_power_state_call_list = [mock.call(self.context, instance)]
        mock_cleanup_call_list = []

        if clean_shutdown:
            if guest_power_state == power_state.PAUSED:
                mock_power_off_call_list.append(mock.call(instance, 0, 0))
            else:
                mock_power_off_call_list.append(
                    mock.call(instance, CONF.shutdown_timeout,
                              CONF.compute.shutdown_retry_interval))
        else:
            mock_power_off_call_list.append(mock.call(instance, 0, 0))

        if CONF.shelved_offload_time == 0:
            mock_notify_instance_usage_call_list.extend([
                mock.call(self.context, instance, 'shelve_offload.start'),
                mock.call(self.context, instance, 'shelve_offload.end')
            ])
            mock_power_off_call_list.append(mock.call(instance, 0, 0))
            mock_get_power_state_call_list.append(
                mock.call(self.context, instance))
            # instance.host is replaced with host because
            # original instance.host is clear after
            # ComputeManager.shelve_instance execute with
            # shelved_offload_time == 0
            mock_cleanup_call_list.append(
                mock.call(self.context, instance, host))

        mock_notify_instance_usage.assert_has_calls(
            mock_notify_instance_usage_call_list)
        mock_power_off.assert_has_calls(mock_power_off_call_list)
        mock_cleanup.assert_has_calls(mock_cleanup_call_list)
        mock_snapshot.assert_called_once_with(self.context, instance,
                                              'fake_image_id', mock.ANY)
        mock_get_power_state.assert_has_calls(mock_get_power_state_call_list)

        if CONF.shelved_offload_time == 0:
            self.assertTrue(mock_terminate.called)

    def test_shelve(self):
        self._shelve_instance(-1)

    def test_shelve_forced_shutdown(self):
        self._shelve_instance(-1, clean_shutdown=False)

    def test_shelve_and_offload(self):
        self._shelve_instance(0)

    def test_shelve_paused_instance(self):
        self._shelve_instance(-1, guest_power_state=power_state.PAUSED)

    @mock.patch.object(nova.virt.fake.SmallFakeDriver, 'power_off')
    def test_shelve_offload(self, mock_power_off):
        instance = self._shelve_offload()
        mock_power_off.assert_called_once_with(
            instance, CONF.shutdown_timeout,
            CONF.compute.shutdown_retry_interval)

    @mock.patch.object(nova.virt.fake.SmallFakeDriver, 'power_off')
    def test_shelve_offload_forced_shutdown(self, mock_power_off):
        instance = self._shelve_offload(clean_shutdown=False)
        mock_power_off.assert_called_once_with(instance, 0, 0)

    @mock.patch.object(compute_utils, 'EventReporter')
    @mock.patch.object(objects.BlockDeviceMappingList, 'get_by_instance_uuid')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_terminate_volume_connections')
    @mock.patch('nova.compute.resource_tracker.ResourceTracker.'
                'delete_allocation_for_shelve_offloaded_instance')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_update_resource_tracker')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_get_power_state',
                       return_value=123)
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_notify_about_instance_usage')
    @mock.patch('nova.compute.utils.notify_about_instance_action')
    def _shelve_offload(self,
                        mock_notify,
                        mock_notify_instance_usage,
                        mock_get_power_state,
                        mock_update_resource_tracker,
                        mock_delete_alloc,
                        mock_terminate,
                        mock_get_bdms,
                        mock_event,
                        clean_shutdown=True):
        host = 'fake-mini'
        instance = self._create_fake_instance_obj(params={'host': host})
        instance.task_state = task_states.SHELVING
        instance.save()
        self.useFixture(utils_fixture.TimeFixture())
        fake_bdms = objects.BlockDeviceMappingList()
        mock_get_bdms.return_value = fake_bdms

        with mock.patch.object(instance, 'save'):
            self.compute.shelve_offload_instance(self.context,
                                                 instance,
                                                 clean_shutdown=clean_shutdown)
            mock_notify.assert_has_calls([
                mock.call(self.context,
                          instance,
                          'fake-mini',
                          action='shelve_offload',
                          phase='start',
                          bdms=fake_bdms),
                mock.call(self.context,
                          instance,
                          'fake-mini',
                          action='shelve_offload',
                          phase='end',
                          bdms=fake_bdms)
            ])

        self.assertEqual(vm_states.SHELVED_OFFLOADED, instance.vm_state)
        self.assertIsNone(instance.task_state)
        self.assertTrue(mock_terminate.called)

        # prepare expect call lists
        mock_notify_instance_usage_call_list = [
            mock.call(self.context, instance, 'shelve_offload.start'),
            mock.call(self.context, instance, 'shelve_offload.end')
        ]

        mock_notify_instance_usage.assert_has_calls(
            mock_notify_instance_usage_call_list)
        # instance.host is replaced with host because
        # original instance.host is clear after
        # ComputeManager.shelve_offload_instance execute
        mock_get_power_state.assert_called_once_with(self.context, instance)
        mock_update_resource_tracker.assert_called_once_with(
            self.context, instance)
        mock_delete_alloc.assert_called_once_with(self.context, instance)
        mock_event.assert_called_once_with(self.context,
                                           'compute_shelve_offload_instance',
                                           CONF.host, instance.uuid)

        return instance

    @mock.patch('nova.objects.BlockDeviceMappingList.get_by_instance_uuid')
    @mock.patch('nova.compute.utils.notify_about_instance_action')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_notify_about_instance_usage')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_prep_block_device',
                       return_value='fake_bdm')
    @mock.patch.object(nova.virt.fake.SmallFakeDriver, 'spawn')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_get_power_state',
                       return_value=123)
    @mock.patch.object(neutron_api.API, 'setup_instance_network_on_host')
    def test_unshelve(self, mock_setup_network, mock_get_power_state,
                      mock_spawn, mock_prep_block_device,
                      mock_notify_instance_usage, mock_notify_instance_action,
                      mock_get_bdms):
        mock_bdms = mock.Mock()
        mock_get_bdms.return_value = mock_bdms
        instance = self._create_fake_instance_obj()
        instance.task_state = task_states.UNSHELVING
        instance.save()
        image = {'id': uuids.image_id}
        node = test_compute.NODENAME
        limits = {}
        filter_properties = {'limits': limits}
        host = 'fake-mini'
        cur_time = timeutils.utcnow()
        # Adding shelved_* keys in system metadata to verify
        # whether those are deleted after unshelve call.
        sys_meta = dict(instance.system_metadata)
        sys_meta['shelved_at'] = cur_time.isoformat()
        sys_meta['shelved_image_id'] = image['id']
        sys_meta['shelved_host'] = host
        instance.system_metadata = sys_meta

        self.deleted_image_id = None

        def fake_delete(self2, ctxt, image_id):
            self.deleted_image_id = image_id

        def fake_claim(context, instance, node, limits):
            instance.host = self.compute.host
            requests = objects.InstancePCIRequests(requests=[])
            return claims.Claim(context, instance, test_compute.NODENAME,
                                self.rt, _fake_resources(), requests)

        tracking = {
            'last_state': instance.task_state,
            'spawned': False,
        }

        def check_save(expected_task_state=None):
            if tracking['last_state'] == task_states.UNSHELVING:
                if tracking['spawned']:
                    self.assertIsNone(instance.task_state)
                else:
                    self.assertEqual(task_states.SPAWNING, instance.task_state)
                    tracking['spawned'] = True
                tracking['last_state'] == instance.task_state
            elif tracking['last_state'] == task_states.SPAWNING:
                self.assertEqual(vm_states.ACTIVE, instance.vm_state)
                tracking['last_state'] == instance.task_state
            else:
                self.fail('Unexpected save!')

        fake_image.stub_out_image_service(self)
        self.stub_out('nova.tests.unit.image.fake._FakeImageService.delete',
                      fake_delete)

        with mock.patch.object(self.rt, 'instance_claim',
                               side_effect=fake_claim), \
                 mock.patch.object(instance, 'save') as mock_save:
            mock_save.side_effect = check_save
            self.compute.unshelve_instance(self.context,
                                           instance,
                                           image=image,
                                           filter_properties=filter_properties,
                                           node=node)

        mock_notify_instance_action.assert_has_calls([
            mock.call(self.context,
                      instance,
                      'fake-mini',
                      action='unshelve',
                      phase='start',
                      bdms=mock_bdms),
            mock.call(self.context,
                      instance,
                      'fake-mini',
                      action='unshelve',
                      phase='end',
                      bdms=mock_bdms)
        ])

        # prepare expect call lists
        mock_notify_instance_usage_call_list = [
            mock.call(self.context, instance, 'unshelve.start'),
            mock.call(self.context, instance, 'unshelve.end')
        ]

        mock_notify_instance_usage.assert_has_calls(
            mock_notify_instance_usage_call_list)
        mock_prep_block_device.assert_called_once_with(self.context, instance,
                                                       mock.ANY)
        mock_setup_network.assert_called_once_with(self.context, instance,
                                                   self.compute.host)
        mock_spawn.assert_called_once_with(self.context,
                                           instance,
                                           test.MatchType(objects.ImageMeta),
                                           injected_files=[],
                                           admin_password=None,
                                           allocations={},
                                           network_info=[],
                                           block_device_info='fake_bdm')
        self.mock_get_allocs.assert_called_once_with(self.context,
                                                     instance.uuid)
        mock_get_power_state.assert_called_once_with(self.context, instance)

        self.assertNotIn('shelved_at', instance.system_metadata)
        self.assertNotIn('shelved_image_id', instance.system_metadata)
        self.assertNotIn('shelved_host', instance.system_metadata)
        self.assertEqual(image['id'], self.deleted_image_id)
        self.assertEqual(instance.host, self.compute.host)

        self.assertEqual(123, instance.power_state)
        self.assertEqual(vm_states.ACTIVE, instance.vm_state)
        self.assertIsNone(instance.task_state)
        self.assertIsNone(instance.key_data)
        self.assertEqual(self.compute.host, instance.host)
        self.assertFalse(instance.auto_disk_config)

    @mock.patch('nova.objects.BlockDeviceMappingList.get_by_instance_uuid')
    @mock.patch('nova.compute.utils.notify_about_instance_action')
    @mock.patch.object(nova.compute.resource_tracker.ResourceTracker,
                       'instance_claim')
    @mock.patch.object(neutron_api.API, 'setup_instance_network_on_host')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_get_power_state',
                       return_value=123)
    @mock.patch.object(nova.virt.fake.SmallFakeDriver, 'spawn')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_prep_block_device',
                       return_value='fake_bdm')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_notify_about_instance_usage')
    @mock.patch('nova.utils.get_image_from_system_metadata')
    def test_unshelve_volume_backed(
            self, mock_image_meta, mock_notify_instance_usage,
            mock_prep_block_device, mock_spawn, mock_get_power_state,
            mock_setup_network, mock_instance_claim,
            mock_notify_instance_action, mock_get_bdms):
        mock_bdms = mock.Mock()
        mock_get_bdms.return_value = mock_bdms
        instance = self._create_fake_instance_obj()
        node = test_compute.NODENAME
        limits = {}
        filter_properties = {'limits': limits}
        instance.task_state = task_states.UNSHELVING
        instance.save()
        image_meta = {'properties': {'base_image_ref': uuids.image_id}}
        mock_image_meta.return_value = image_meta

        tracking = {'last_state': instance.task_state}

        def fake_claim(context, instance, node, limits):
            instance.host = self.compute.host
            requests = objects.InstancePCIRequests(requests=[])
            return claims.Claim(context, instance, test_compute.NODENAME,
                                self.rt, _fake_resources(), requests)

        mock_instance_claim.side_effect = fake_claim

        def check_save(expected_task_state=None):
            if tracking['last_state'] == task_states.UNSHELVING:
                self.assertEqual(task_states.SPAWNING, instance.task_state)
                tracking['last_state'] = instance.task_state
            elif tracking['last_state'] == task_states.SPAWNING:
                self.assertEqual(123, instance.power_state)
                self.assertEqual(vm_states.ACTIVE, instance.vm_state)
                self.assertIsNone(instance.task_state)
                self.assertIsNone(instance.key_data)
                self.assertFalse(instance.auto_disk_config)
                self.assertIsNone(instance.task_state)
                tracking['last_state'] = instance.task_state
            else:
                self.fail('Unexpected save!')

        with mock.patch.object(instance, 'save') as mock_save:
            mock_save.side_effect = check_save
            self.compute.unshelve_instance(self.context,
                                           instance,
                                           image=None,
                                           filter_properties=filter_properties,
                                           node=node)

        mock_notify_instance_action.assert_has_calls([
            mock.call(self.context,
                      instance,
                      'fake-mini',
                      action='unshelve',
                      phase='start',
                      bdms=mock_bdms),
            mock.call(self.context,
                      instance,
                      'fake-mini',
                      action='unshelve',
                      phase='end',
                      bdms=mock_bdms)
        ])

        # prepare expect call lists
        mock_notify_instance_usage_call_list = [
            mock.call(self.context, instance, 'unshelve.start'),
            mock.call(self.context, instance, 'unshelve.end')
        ]

        mock_notify_instance_usage.assert_has_calls(
            mock_notify_instance_usage_call_list)
        mock_prep_block_device.assert_called_once_with(self.context, instance,
                                                       mock.ANY)
        mock_setup_network.assert_called_once_with(self.context, instance,
                                                   self.compute.host)
        mock_instance_claim.assert_called_once_with(self.context, instance,
                                                    test_compute.NODENAME,
                                                    limits)
        mock_spawn.assert_called_once_with(self.context,
                                           instance,
                                           test.MatchType(objects.ImageMeta),
                                           injected_files=[],
                                           admin_password=None,
                                           allocations={},
                                           network_info=[],
                                           block_device_info='fake_bdm')
        self.mock_get_allocs.assert_called_once_with(self.context,
                                                     instance.uuid)
        mock_get_power_state.assert_called_once_with(self.context, instance)

    @mock.patch('nova.objects.BlockDeviceMappingList.get_by_instance_uuid')
    @mock.patch('nova.compute.utils.notify_about_instance_action')
    @mock.patch.object(nova.compute.resource_tracker.ResourceTracker,
                       'instance_claim')
    @mock.patch.object(neutron_api.API, 'setup_instance_network_on_host')
    @mock.patch.object(nova.virt.fake.SmallFakeDriver,
                       'spawn',
                       side_effect=test.TestingException('oops!'))
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_prep_block_device',
                       return_value='fake_bdm')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_notify_about_instance_usage')
    @mock.patch('nova.utils.get_image_from_system_metadata')
    @mock.patch.object(nova.compute.manager.ComputeManager,
                       '_terminate_volume_connections')
    def test_unshelve_spawn_fails_cleanup_volume_connections(
            self, mock_terminate_volume_connections, mock_image_meta,
            mock_notify_instance_usage, mock_prep_block_device, mock_spawn,
            mock_setup_network, mock_instance_claim,
            mock_notify_instance_action, mock_get_bdms):
        """Tests error handling when a instance fails to unshelve and makes
        sure that volume connections are cleaned up from the host
        and that the host/node values are unset on the instance.
        """
        mock_bdms = mock.Mock()
        mock_get_bdms.return_value = mock_bdms
        instance = self._create_fake_instance_obj()
        node = test_compute.NODENAME
        limits = {}
        filter_properties = {'limits': limits}
        instance.task_state = task_states.UNSHELVING
        instance.save()
        image_meta = {'properties': {'base_image_ref': uuids.image_id}}
        mock_image_meta.return_value = image_meta

        tracking = {'last_state': instance.task_state}

        def fake_claim(context, instance, node, limits):
            instance.host = self.compute.host
            instance.node = node
            requests = objects.InstancePCIRequests(requests=[])
            return claims.Claim(context,
                                instance,
                                node,
                                self.rt,
                                _fake_resources(),
                                requests,
                                limits=limits)

        mock_instance_claim.side_effect = fake_claim

        def check_save(expected_task_state=None):
            if tracking['last_state'] == task_states.UNSHELVING:
                # This is before we've failed.
                self.assertEqual(task_states.SPAWNING, instance.task_state)
                tracking['last_state'] = instance.task_state
            elif tracking['last_state'] == task_states.SPAWNING:
                # This is after we've failed.
                self.assertIsNone(instance.host)
                self.assertIsNone(instance.node)
                self.assertIsNone(instance.task_state)
                tracking['last_state'] = instance.task_state
            else:
                self.fail('Unexpected save!')

        with mock.patch.object(instance, 'save') as mock_save:
            mock_save.side_effect = check_save
            self.assertRaises(test.TestingException,
                              self.compute.unshelve_instance,
                              self.context,
                              instance,
                              image=None,
                              filter_properties=filter_properties,
                              node=node)

        mock_notify_instance_action.assert_called_once_with(self.context,
                                                            instance,
                                                            'fake-mini',
                                                            action='unshelve',
                                                            phase='start',
                                                            bdms=mock_bdms)
        mock_notify_instance_usage.assert_called_once_with(
            self.context, instance, 'unshelve.start')
        mock_prep_block_device.assert_called_once_with(self.context, instance,
                                                       mock_bdms)
        mock_setup_network.assert_called_once_with(self.context, instance,
                                                   self.compute.host)
        mock_instance_claim.assert_called_once_with(self.context, instance,
                                                    test_compute.NODENAME,
                                                    limits)
        mock_spawn.assert_called_once_with(self.context,
                                           instance,
                                           test.MatchType(objects.ImageMeta),
                                           injected_files=[],
                                           admin_password=None,
                                           allocations={},
                                           network_info=[],
                                           block_device_info='fake_bdm')
        mock_terminate_volume_connections.assert_called_once_with(
            self.context, instance, mock_bdms)

    @mock.patch.object(objects.InstanceList, 'get_by_filters')
    def test_shelved_poll_none_offloaded(self, mock_get_by_filters):
        # Test instances are not offloaded when shelved_offload_time is -1
        self.flags(shelved_offload_time=-1)
        self.compute._poll_shelved_instances(self.context)
        self.assertEqual(0, mock_get_by_filters.call_count)

    @mock.patch('oslo_utils.timeutils.is_older_than')
    def test_shelved_poll_none_exist(self, mock_older):
        self.flags(shelved_offload_time=1)
        mock_older.return_value = False

        with mock.patch.object(self.compute, 'shelve_offload_instance') as soi:
            self.compute._poll_shelved_instances(self.context)
            self.assertFalse(soi.called)

    @mock.patch('oslo_utils.timeutils.is_older_than')
    def test_shelved_poll_not_timedout(self, mock_older):
        mock_older.return_value = False
        self.flags(shelved_offload_time=1)
        shelved_time = timeutils.utcnow()
        time_fixture = self.useFixture(utils_fixture.TimeFixture(shelved_time))
        time_fixture.advance_time_seconds(CONF.shelved_offload_time - 1)
        instance = self._create_fake_instance_obj()
        instance.vm_state = vm_states.SHELVED
        instance.task_state = None
        instance.host = self.compute.host
        sys_meta = instance.system_metadata
        sys_meta['shelved_at'] = shelved_time.isoformat()
        instance.save()

        with mock.patch.object(self.compute, 'shelve_offload_instance') as soi:
            self.compute._poll_shelved_instances(self.context)
            self.assertFalse(soi.called)
            self.assertTrue(mock_older.called)

    def test_shelved_poll_timedout(self):
        self.flags(shelved_offload_time=1)
        shelved_time = timeutils.utcnow()
        time_fixture = self.useFixture(utils_fixture.TimeFixture(shelved_time))
        time_fixture.advance_time_seconds(CONF.shelved_offload_time + 1)
        instance = self._create_fake_instance_obj()
        instance.vm_state = vm_states.SHELVED
        instance.task_state = None
        instance.host = self.compute.host
        sys_meta = instance.system_metadata
        sys_meta['shelved_at'] = shelved_time.isoformat()
        instance.save()

        data = []

        def fake_soi(context, instance, **kwargs):
            data.append(instance.uuid)

        with mock.patch.object(self.compute, 'shelve_offload_instance') as soi:
            soi.side_effect = fake_soi
            self.compute._poll_shelved_instances(self.context)
            self.assertTrue(soi.called)
            self.assertEqual(instance.uuid, data[0])

    @mock.patch('oslo_utils.timeutils.is_older_than')
    @mock.patch('oslo_utils.timeutils.parse_strtime')
    def test_shelved_poll_filters_task_state(self, mock_parse, mock_older):
        self.flags(shelved_offload_time=1)
        mock_older.return_value = True
        instance1 = self._create_fake_instance_obj()
        instance1.task_state = task_states.SPAWNING
        instance1.vm_state = vm_states.SHELVED
        instance1.host = self.compute.host
        instance1.system_metadata = {'shelved_at': ''}
        instance1.save()
        instance2 = self._create_fake_instance_obj()
        instance2.task_state = None
        instance2.vm_state = vm_states.SHELVED
        instance2.host = self.compute.host
        instance2.system_metadata = {'shelved_at': ''}
        instance2.save()

        data = []

        def fake_soi(context, instance, **kwargs):
            data.append(instance.uuid)

        with mock.patch.object(self.compute, 'shelve_offload_instance') as soi:
            soi.side_effect = fake_soi
            self.compute._poll_shelved_instances(self.context)
            self.assertTrue(soi.called)
            self.assertEqual([instance2.uuid], data)

    @mock.patch('oslo_utils.timeutils.is_older_than')
    @mock.patch('oslo_utils.timeutils.parse_strtime')
    def test_shelved_poll_checks_task_state_on_save(self, mock_parse,
                                                    mock_older):
        self.flags(shelved_offload_time=1)
        mock_older.return_value = True
        instance = self._create_fake_instance_obj()
        instance.task_state = None
        instance.vm_state = vm_states.SHELVED
        instance.host = self.compute.host
        instance.system_metadata = {'shelved_at': ''}
        instance.save()

        def fake_parse_hook(timestring):
            instance.task_state = task_states.SPAWNING
            instance.save()

        mock_parse.side_effect = fake_parse_hook

        with mock.patch.object(self.compute, 'shelve_offload_instance') as soi:
            self.compute._poll_shelved_instances(self.context)
            self.assertFalse(soi.called)
示例#21
0
 def connect(self, *args, **kwargs):
     raise test.TestingException()
示例#22
0
def bad_function_exception(self, context, extra, blah="a", boo="b", zoo=None):
    raise test.TestingException('bad things happened')
示例#23
0
 def fake_unpack_context(*args, **kwargs):
     info['unpacked'] = True
     raise test.TestingException('moo')
示例#24
0
 def test_finish_migrate_performs_rollback_on_error(self):
     self.assertRaises(test.TestingException,
                       self._test_finish_migration,
                       power_on=False,
                       resize_instance=False,
                       throw_exception=test.TestingException())
示例#25
0
 def no_mtu(*args, **kwargs):
     if 'mtu' in kwargs:
         raise test.TestingException("mtu should not pass through")
     return [{}]