Пример #1
0
    def test_blank_attach_fail_volume(self):
        no_blank_volume = self.blank_bdm_dict.copy()
        no_blank_volume['volume_id'] = None
        test_bdm = self.driver_classes['blank'](
                fake_block_device.fake_bdm_object(
                        self.context, no_blank_volume))
        instance = fake_instance.fake_instance_obj(mock.sentinel.ctx,
                                                   **{'uuid': uuids.uuid})
        volume = {'id': 'fake-volume-id-2',
                  'display_name': '%s-blank-vol' % uuids.uuid}

        with test.nested(
            mock.patch.object(self.volume_api, 'create', return_value=volume),
            mock.patch.object(self.volume_api, 'delete'),
        ) as (vol_create, vol_delete):
            wait_func = mock.MagicMock()
            mock_exception = exception.VolumeNotCreated(volume_id=volume['id'],
                                                        seconds=1,
                                                        attempts=1,
                                                        volume_status='error')
            wait_func.side_effect = mock_exception
            self.assertRaises(exception.VolumeNotCreated,
                              test_bdm.attach, context=self.context,
                              instance=instance,
                              volume_api=self.volume_api,
                              virt_driver=self.virt_driver,
                              wait_func=wait_func)

            vol_create.assert_called_once_with(
                self.context, test_bdm.volume_size,
                '%s-blank-vol' % uuids.uuid,
                '', availability_zone=None)
            vol_delete.assert_called_once_with(
                self.context, volume['id'])
Пример #2
0
    def test_blank_attach_volume(self):
        no_blank_volume = self.blank_bdm_dict.copy()
        no_blank_volume['volume_id'] = None
        test_bdm = self.driver_classes['blank'](
                fake_block_device.fake_bdm_object(
                        self.context, no_blank_volume))
        instance = fake_instance.fake_instance_obj(mock.sentinel.ctx,
                                                   **{'uuid': uuids.uuid})
        volume_class = self.driver_classes['volume']
        volume = {'id': 'fake-volume-id-2',
                  'display_name': '%s-blank-vol' % uuids.uuid}

        with test.nested(
            mock.patch.object(self.volume_api, 'create', return_value=volume),
            mock.patch.object(volume_class, 'attach')
        ) as (vol_create, vol_attach):
            test_bdm.attach(self.context, instance, self.volume_api,
                            self.virt_driver)

            vol_create.assert_called_once_with(
                self.context, test_bdm.volume_size,
                '%s-blank-vol' % uuids.uuid,
                '', availability_zone=None)
            vol_attach.assert_called_once_with(self.context, instance,
                                               self.volume_api,
                                               self.virt_driver,
                                               do_check_attach=True)
            self.assertEqual('fake-volume-id-2', test_bdm.volume_id)
Пример #3
0
    def test_image_attach_fail_volume(self):
        fail_volume_image = self.image_bdm_dict.copy()
        fail_volume_image['volume_id'] = None
        test_bdm = self.driver_classes['image'](
                fake_block_device.fake_bdm_object(
                        self.context, fail_volume_image))

        image = {'id': 'fake-image-id-1'}
        volume = {'id': 'fake-volume-id-2',
                  'attach_status': 'detached'}

        instance = fake_instance.fake_instance_obj(mock.sentinel.ctx,
                                                   **{'uuid': 'fake-uuid'})
        with test.nested(
            mock.patch.object(self.volume_api, 'create', return_value=volume),
            mock.patch.object(self.volume_api, 'delete'),
        ) as (vol_create, vol_delete):
            wait_func = mock.MagicMock()
            mock_exception = exception.VolumeNotCreated(volume_id=volume['id'],
                                                        seconds=1,
                                                        attempts=1,
                                                        volume_status='error')
            wait_func.side_effect = mock_exception
            self.assertRaises(exception.VolumeNotCreated,
                              test_bdm.attach, context=self.context,
                              instance=instance,
                              volume_api=self.volume_api,
                              virt_driver=self.virt_driver,
                              wait_func=wait_func)

            vol_create.assert_called_once_with(
                self.context, 1, '', '', image_id=image['id'],
                availability_zone=None)
            vol_delete.assert_called_once_with(self.context, volume['id'])
Пример #4
0
    def test_create_server_with_pci_dev_and_numa(self, img_mock):
        """Verifies that an instance can be booted with cpu pinning and with an
           assigned pci device.
        """

        host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1,
                                             cpu_cores=2, cpu_threads=2,
                                             kB_mem=15740000)
        pci_info = fakelibvirt.HostPciSRIOVDevicesInfo(num_pfs=1, numa_node=1)
        fake_connection = self._get_connection(host_info, pci_info)

        # Create a flavor
        extra_spec = {"pci_passthrough:alias": "%s:1" % self.pfs_alias_name,
                      'hw:numa_nodes': '1',
                      'hw:cpu_policy': 'dedicated',
                      'hw:cpu_thread_policy': 'prefer'}
        flavor_id = self._create_flavor(extra_spec=extra_spec)
        host_pass_mock = self._get_pci_passthrough_filter_spy()
        with test.nested(
            mock.patch('nova.virt.libvirt.host.Host.get_connection',
                       return_value=fake_connection),
            mock.patch('nova.scheduler.filters'
                       '.pci_passthrough_filter.PciPassthroughFilter'
                       '.host_passes',
                       side_effect=host_pass_mock)) as (conn_mock,
                                                       filter_mock):
            pf_server = self._run_build_test(flavor_id, filter_mock)
        self._delete_server(pf_server['id'])
Пример #5
0
 def test_finish_migration(self, mo):
     context = mock.Mock()
     migration = {'source_compute': 'fake-source',
                  'dest_compute': 'fake-dest'}
     instance = stubs._fake_instance()
     bdevice_info = mock.Mock()
     disk_info = mock.Mock()
     network_info = mock.Mock()
     with test.nested(
         mock.patch.object(session.LXDAPISession,
                           'container_defined'),
         mock.patch.object(session.LXDAPISession,
                           'container_stop'),
         mock.patch.object(session.LXDAPISession,
                           'container_init'),
     ) as (
         container_defined,
         container_stop,
         container_init
     ):
         def side_effect(*args, **kwargs):
             # XXX: rockstar (7 Dec 2015) - This mock is a little greedy,
             # and hits too many interfaces. It should become more specific
             # to the single places it needs to fully mocked. Truthiness of
             # the mock changes in py3.
             if args[0] == 'defined':
                 return False
         container_defined.side_effect = side_effect
         self.assertEqual(None,
                          (self.migrate.finish_migration(context,
                                                         migration,
                                                         instance,
                                                         disk_info,
                                                         network_info,
                                                         bdevice_info)))
Пример #6
0
 def test_plug_ivs_hybrid(self):
     calls = {
         "device_exists": [mock.call("qbrvif-xxx-yyy"), mock.call("qvovif-xxx-yyy")],
         "_create_veth_pair": [mock.call("qvbvif-xxx-yyy", "qvovif-xxx-yyy")],
         "execute": [
             mock.call("brctl", "addbr", "qbrvif-xxx-yyy", run_as_root=True),
             mock.call("brctl", "setfd", "qbrvif-xxx-yyy", 0, run_as_root=True),
             mock.call("brctl", "stp", "qbrvif-xxx-yyy", "off", run_as_root=True),
             mock.call(
                 "tee",
                 ("/sys/class/net/qbrvif-xxx-yyy" "/bridge/multicast_snooping"),
                 process_input="0",
                 run_as_root=True,
                 check_exit_code=[0, 1],
             ),
             mock.call("ip", "link", "set", "qbrvif-xxx-yyy", "up", run_as_root=True),
             mock.call("brctl", "addif", "qbrvif-xxx-yyy", "qvbvif-xxx-yyy", run_as_root=True),
         ],
         "create_ivs_vif_port": [
             mock.call("qvovif-xxx-yyy", "aaa-bbb-ccc", "ca:fe:de:ad:be:ef", "f0000000-0000-0000-0000-000000000001")
         ],
     }
     with test.nested(
         mock.patch.object(linux_net, "device_exists", return_value=False),
         mock.patch.object(utils, "execute"),
         mock.patch.object(linux_net, "_create_veth_pair"),
         mock.patch.object(linux_net, "create_ivs_vif_port"),
     ) as (device_exists, execute, _create_veth_pair, create_ivs_vif_port):
         d = vif.LibvirtGenericVIFDriver()
         d.plug_ivs_hybrid(self.instance, self.vif_ivs)
         device_exists.assert_has_calls(calls["device_exists"])
         _create_veth_pair.assert_has_calls(calls["_create_veth_pair"])
         execute.assert_has_calls(calls["execute"])
         create_ivs_vif_port.assert_has_calls(calls["create_ivs_vif_port"])
Пример #7
0
    def _test_attach_volume_iscsi(self, adapter_type=None):
        connection_info = {'driver_volume_type': constants.DISK_FORMAT_ISCSI,
                           'serial': 'volume-fake-id',
                           'data': {'volume': 'vm-10',
                                    'volume_id': 'volume-fake-id'}}
        vm_ref = 'fake-vm-ref'
        default_adapter_type = constants.DEFAULT_ADAPTER_TYPE
        adapter_type = adapter_type or default_adapter_type

        with test.nested(
            mock.patch.object(vm_util, 'get_vm_ref', return_value=vm_ref),
            mock.patch.object(self._volumeops, '_iscsi_discover_target',
                              return_value=(mock.sentinel.device_name,
                                            mock.sentinel.uuid)),
            mock.patch.object(vm_util, 'get_scsi_adapter_type',
                              return_value=adapter_type),
            mock.patch.object(self._volumeops, 'attach_disk_to_vm')
        ) as (get_vm_ref, iscsi_discover_target, get_scsi_adapter_type,
              attach_disk_to_vm):
            self._volumeops.attach_volume(connection_info, self._instance,
                                          adapter_type)

            get_vm_ref.assert_called_once_with(self._volumeops._session,
                                               self._instance)
            iscsi_discover_target.assert_called_once_with(
                connection_info['data'])
            if adapter_type is None:
                self.assertTrue(get_scsi_adapter_type.called)
            attach_disk_to_vm.assert_called_once_with(vm_ref,
                self._instance, adapter_type, 'rdmp',
                device_name=mock.sentinel.device_name)
Пример #8
0
    def test_iscsi_get_host_iqn_instance_not_found(self):
        host_mor = mock.Mock()
        iqn = 'iscsi-name'
        hba = vmwareapi_fake.HostInternetScsiHba(iqn)
        hbas = mock.MagicMock(HostHostBusAdapter=[hba])

        with test.nested(
            mock.patch.object(vm_util, 'get_host_ref_for_vm',
                              side_effect=exception.InstanceNotFound('fake')),
            mock.patch.object(vm_util, 'get_host_ref',
                              return_value=host_mor),
            mock.patch.object(self._volumeops._session, '_call_method',
                              return_value=hbas)
        ) as (fake_get_host_ref_for_vm,
              fake_get_host_ref,
              fake_call_method):
            result = self._volumeops._iscsi_get_host_iqn(self._instance)

            fake_get_host_ref_for_vm.assert_called_once_with(
                        self._volumeops._session, self._instance)
            fake_get_host_ref.assert_called_once_with(
                        self._volumeops._session, self._volumeops._cluster)
            fake_call_method.assert_called_once_with(vutil,
                                    "get_object_property",
                                    host_mor,
                                    "config.storageDevice.hostBusAdapter")

            self.assertEqual(iqn, result)
Пример #9
0
    def test_file_copy(self):
        def fake_call_method(module, method, *args, **kwargs):
            self.assertEqual('CopyDatastoreFile_Task', method)
            src_name = kwargs.get('sourceName')
            self.assertEqual('[ds] fake/path/src_file', src_name)
            src_dc_ref = kwargs.get('sourceDatacenter')
            self.assertEqual('fake-src-dc-ref', src_dc_ref)
            dst_name = kwargs.get('destinationName')
            self.assertEqual('[ds] fake/path/dst_file', dst_name)
            dst_dc_ref = kwargs.get('destinationDatacenter')
            self.assertEqual('fake-dst-dc-ref', dst_dc_ref)
            return 'fake_copy_task'

        with test.nested(
            mock.patch.object(self.session, '_wait_for_task'),
            mock.patch.object(self.session, '_call_method',
                              fake_call_method)
        ) as (_wait_for_task, _call_method):
            src_ds_path = ds_obj.DatastorePath('ds', 'fake/path', 'src_file')
            dst_ds_path = ds_obj.DatastorePath('ds', 'fake/path', 'dst_file')
            ds_util.file_copy(self.session,
                              str(src_ds_path), 'fake-src-dc-ref',
                              str(dst_ds_path), 'fake-dst-dc-ref')
            _wait_for_task.assert_has_calls([
                   mock.call('fake_copy_task')])
Пример #10
0
 def _test_detach_disk_from_vm(self, destroy_disk=False):
     def fake_call_method(module, method, *args, **kwargs):
         vmdk_detach_config_spec = kwargs.get('spec')
         virtual_device_config = vmdk_detach_config_spec.deviceChange[0]
         self.assertEqual('remove', virtual_device_config.operation)
         self.assertEqual('ns0:VirtualDeviceConfigSpec',
                           virtual_device_config.obj_name)
         if destroy_disk:
             self.assertEqual('destroy',
                              virtual_device_config.fileOperation)
         else:
             self.assertFalse(hasattr(virtual_device_config,
                              'fileOperation'))
         return 'fake_configure_task'
     with test.nested(
         mock.patch.object(self._session, '_wait_for_task'),
         mock.patch.object(self._session, '_call_method',
                           fake_call_method)
     ) as (_wait_for_task, _call_method):
         fake_device = vmwareapi_fake.DataObject()
         fake_device.backing = vmwareapi_fake.DataObject()
         fake_device.backing.fileName = 'fake_path'
         fake_device.key = 'fake_key'
         self._volumeops.detach_disk_from_vm('fake_vm_ref', self._instance,
                                             fake_device, destroy_disk)
         _wait_for_task.assert_has_calls([
                mock.call('fake_configure_task')])
Пример #11
0
 def test_authorize_console_encoding(self):
     with test.nested(
             mock.patch.object(self.manager.mc_instance,
                               'set', return_value=None),
             mock.patch.object(self.manager.mc_instance,
                               'get', return_value='["token"]'),
             mock.patch.object(self.manager.mc,
                               'set', return_value=None),
             mock.patch.object(self.manager.mc,
                               'get', return_value=None),
             mock.patch.object(self.manager.mc,
                               'get_multi', return_value=["token1"]),
     ) as (
             mock_instance_set,
             mock_instance_get,
             mock_set,
             mock_get,
             mock_get_multi):
         self.manager.authorize_console(self.context, self.u_token,
                                        'novnc', '127.0.0.1', '8080',
                                        'host', self.u_instance)
         mock_set.assert_has_calls([mock.call(b'token', mock.ANY)])
         mock_instance_get.assert_has_calls([mock.call(b'instance')])
         mock_get_multi.assert_has_calls([mock.call([b'token'])])
         mock_instance_set.assert_has_calls(
                 [mock.call(b'instance', mock.ANY)])
Пример #12
0
    def test_execute_without_destination(self):
        self.destination = None
        self._generate_task()
        self.assertIsNone(self.task.destination)

        with test.nested(
            mock.patch.object(self.task, '_check_host_is_up'),
            mock.patch.object(self.task, '_find_destination'),
            mock.patch.object(self.task.compute_rpcapi, 'live_migration'),
            mock.patch.object(self.migration, 'save')
        ) as (mock_check, mock_find, mock_mig, mock_save):
            mock_find.return_value = "found_host"
            mock_mig.return_value = "bob"

            self.assertEqual("bob", self.task.execute())
            mock_check.assert_called_once_with(self.instance_host)
            mock_find.assert_called_once_with()
            mock_mig.assert_called_once_with(self.context,
                host=self.instance_host,
                instance=self.instance,
                dest="found_host",
                block_migration=self.block_migration,
                migration=self.migration,
                migrate_data=None)
            self.assertTrue(mock_save.called)
            self.assertEqual('found_host', self.migration.dest_compute)
Пример #13
0
    def test_sum_domain_memory_mb_file_backed(self):
        class DiagFakeDomain(object):
            def __init__(self, id, memmb):
                self.id = id
                self.memmb = memmb

            def info(self):
                return [0, 0, self.memmb * 1024]

            def ID(self):
                return self.id

            def name(self):
                return "instance000001"

            def UUIDString(self):
                return uuids.fake

        with test.nested(
                mock.patch.object(host.Host,
                                  "list_guests"),
                mock.patch('sys.platform', 'linux2'),
        ) as (mock_list, mock_platform):
            mock_list.return_value = [
                libvirt_guest.Guest(DiagFakeDomain(0, 4096)),
                libvirt_guest.Guest(DiagFakeDomain(1, 2048)),
                libvirt_guest.Guest(DiagFakeDomain(2, 1024)),
                libvirt_guest.Guest(DiagFakeDomain(3, 1024))]

            self.assertEqual(8192,
                    self.host._sum_domain_memory_mb(include_host=False))
Пример #14
0
    def test_create_server_with_VF_no_PF(self, img_mock):

        host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1,
                                             cpu_cores=2, cpu_threads=2,
                                             kB_mem=15740000)
        pci_info = fakelibvirt.HostPciSRIOVDevicesInfo(num_pfs=1, num_vfs=4)
        fake_connection = self._get_connection(host_info, pci_info)

        # Create a flavor
        extra_spec = {"pci_passthrough:alias": "%s:1" % self.pfs_alias_name}
        extra_spec_vfs = {"pci_passthrough:alias": "%s:1" %
                          self.vfs_alias_name}
        flavor_id = self._create_flavor(extra_spec=extra_spec)
        flavor_id_vfs = self._create_flavor(extra_spec=extra_spec_vfs)
        host_pass_mock = self._get_pci_passthrough_filter_spy()
        with test.nested(
            mock.patch('nova.virt.libvirt.host.Host.get_connection',
                       return_value=fake_connection),
            mock.patch('nova.scheduler.filters'
                       '.pci_passthrough_filter.PciPassthroughFilter'
                       '.host_passes',
                       side_effect=host_pass_mock)) as (conn_mock,
                                                       filter_mock):
            vf_server = self._run_build_test(flavor_id_vfs, filter_mock)
            pf_server = self._run_build_test(flavor_id, filter_mock,
                                             end_status='ERROR')

        self._delete_server(pf_server['id'])
        self._delete_server(vf_server['id'])
Пример #15
0
    def _test_cert_api(self, method, **kwargs):
        ctxt = context.RequestContext('fake_user', 'fake_project')

        rpcapi = cert_rpcapi.CertAPI()
        self.assertIsNotNone(rpcapi.client)
        self.assertEqual(CONF.cert_topic, rpcapi.client.target.topic)

        orig_prepare = rpcapi.client.prepare

        with test.nested(
            mock.patch.object(rpcapi.client, 'call'),
            mock.patch.object(rpcapi.client, 'prepare'),
            mock.patch.object(rpcapi.client, 'can_send_version'),
        ) as (
            rpc_mock, prepare_mock, csv_mock
        ):
            prepare_mock.return_value = rpcapi.client
            rpc_mock.return_value = 'foo'
            csv_mock.side_effect = (
                lambda v: orig_prepare().can_send_version())

            retval = getattr(rpcapi, method)(ctxt, **kwargs)
            self.assertEqual(rpc_mock.return_value, retval)

            prepare_mock.assert_called_once_with()
            rpc_mock.assert_called_once_with(ctxt, method, **kwargs)
Пример #16
0
    def test_create_server_with_pinning(self):

        host_info = NumaHostInfo(cpu_nodes=1, cpu_sockets=1, cpu_cores=5,
                                 cpu_threads=2, kB_mem=15740000)
        fake_connection = self._get_connection(host_info=host_info)

        # Create a flavor
        extra_spec = {
            'hw:cpu_policy': 'dedicated',
            'hw:cpu_thread_policy': 'prefer',
        }

        flavor_id = self._create_flavor(vcpu=5, extra_spec=extra_spec)
        host_pass_mock = self._get_topology_filter_spy()
        with test.nested(
            mock.patch('nova.virt.libvirt.host.Host.get_connection',
                       return_value=fake_connection),
            mock.patch('nova.scheduler.filters'
                       '.numa_topology_filter.NUMATopologyFilter.host_passes',
                       side_effect=host_pass_mock)) as (conn_mock,
                                                       filter_mock):
            server = self._run_build_test(flavor_id, filter_mock)
            ctx = nova_context.get_admin_context()
            inst = objects.Instance.get_by_uuid(ctx, server['id'])
            self.assertEqual(1, len(inst.numa_topology.cells))
            self.assertEqual(5, inst.numa_topology.cells[0].cpu_topology.cores)
Пример #17
0
    def _test_create_mocked(self, update_or_create=False):
        values = {'source_type': 'volume', 'volume_id': 'fake-vol-id',
                  'destination_type': 'volume',
                  'instance_uuid': uuids.instance,
                  'attachment_id': None}
        fake_bdm = fake_block_device.FakeDbBlockDeviceDict(values)

        with test.nested(
            mock.patch.object(
                    db, 'block_device_mapping_create', return_value=fake_bdm),
            mock.patch.object(
                    db, 'block_device_mapping_update_or_create',
                    return_value=fake_bdm),
        ) as (bdm_create_mock, bdm_update_or_create_mock):
            bdm = objects.BlockDeviceMapping(context=self.context, **values)
            if update_or_create:
                method = bdm.update_or_create
            else:
                method = bdm.create

            method()
            if update_or_create:
                bdm_update_or_create_mock.assert_called_once_with(
                        self.context, values, legacy=False)
            else:
                bdm_create_mock.assert_called_once_with(
                        self.context, values, legacy=False)
Пример #18
0
 def test_free_allocated_VF(self):
     self._create_fake_instance()
     with test.nested(
         mock.patch.object(objects.PciDevice, 'get_by_dev_addr',
                            side_effect=self._fake_pci_device_get_by_addr),
         mock.patch.object(objects.PciDeviceList, 'get_by_parent_address',
                            side_effect=self._fake_get_by_parent_address)):
         self._create_pci_devices()
         vf = self.sriov_vf_devices[0]
         dependents = self._fake_get_by_parent_address(None, None,
                                                       vf.parent_addr)
         for devobj in dependents:
             devobj.claim(self.inst)
             devobj.allocate(self.inst)
             self.assertEqual(devobj.status,
                              fields.PciDeviceStatus.ALLOCATED)
         for devobj in dependents[:3]:
             devobj.free(self.inst)
             # check if parent device status is still UNAVAILABLE
             parent = self._fake_pci_device_get_by_addr(None, None,
                                                        devobj.parent_addr)
             self.assertTrue(fields.PciDeviceStatus.UNAVAILABLE,
                             parent.status)
         for devobj in dependents[3:]:
             devobj.free(self.inst)
             # check if parent device status is now AVAILABLE
             parent = self._fake_pci_device_get_by_addr(None, None,
                                                        devobj.parent_addr)
             self.assertTrue(fields.PciDeviceStatus.AVAILABLE,
                             parent.status)
Пример #19
0
    def test_confirm_migration(self):
        migration = mock.Mock()
        instance = stubs._fake_instance()
        network_info = mock.Mock()

        with test.nested(
            mock.patch.object(session.LXDAPISession, 'container_defined'),
            mock.patch.object(session.LXDAPISession, 'profile_delete'),
            mock.patch.object(session.LXDAPISession, 'container_destroy'),
            mock.patch.object(operations.LXDContainerOperations,
                              'unplug_vifs'),
        ) as (
                mock_container_defined,
                mock_profile_delete,
                mock_container_destroy,
                mock_unplug_vifs):
            self.assertEqual(None,
                             self.migrate.confirm_migration(migration,
                                                            instance,
                                                            network_info))
            mock_container_defined.assert_called_once_with(instance.name,
                                                           instance)
            mock_profile_delete.assert_called_once_with(instance)
            mock_unplug_vifs.assert_called_once_with(instance,
                                                     network_info)
Пример #20
0
    def test_extend_qcow_success(self, mock_exec, mock_inst, mock_resize,
                                 mock_extendable, mock_can_resize):
        imgfile = tempfile.NamedTemporaryFile()
        self.addCleanup(imgfile.close)
        imgsize = 10
        device = "/dev/sdh"
        image = imgmodel.LocalFileImage(imgfile, imgmodel.FORMAT_QCOW2)

        self.flags(resize_fs_using_block_device=True)
        mounter = FakeMount.instance_for_format(
            image, None, None)
        mounter.device = device
        mock_inst.return_value = mounter

        with test.nested(
            mock.patch.object(mounter, 'get_dev', autospec=True,
                              return_value=True),
            mock.patch.object(mounter, 'unget_dev', autospec=True),
        ) as (mock_get_dev, mock_unget_dev):

            api.extend(image, imgsize)

            mock_can_resize.assert_called_once_with(imgfile, imgsize)
            mock_exec.assert_called_once_with('qemu-img', 'resize',
                                              imgfile, imgsize)
            mock_extendable.assert_called_once_with(image)
            mock_inst.assert_called_once_with(image, None, None)
            mock_resize.assert_called_once_with(mounter.device,
                                                run_as_root=True,
                                                check_exit_code=[0])

            mock_get_dev.assert_called_once_with()
            mock_unget_dev.assert_called_once_with()
Пример #21
0
    def test_list_base_images(self):
        def fake_get_object_property(vim, mobj, property_name):
            return 'fake-ds-browser'

        def fake_get_sub_folders(session, ds_browser, ds_path):
            files = set()
            files.add('image-ref-uuid')
            return files

        with test.nested(
            mock.patch.object(vutil, 'get_object_property',
                              fake_get_object_property),
            mock.patch.object(ds_util, 'get_sub_folders',
                              fake_get_sub_folders)
        ) as (_get_dynamic, _get_sub_folders):
            fake_ds_ref = fake.ManagedObjectReference('fake-ds-ref')
            datastore = ds_obj.Datastore(name='ds', ref=fake_ds_ref)
            ds_path = datastore.build_path('base_folder')
            images = self._imagecache._list_datastore_images(
                    ds_path, datastore)
            originals = set()
            originals.add('image-ref-uuid')
            self.assertEqual({'originals': originals,
                              'unexplained_images': []},
                             images)
Пример #22
0
    def test_timestamp_cleanup(self):
        def fake_get_timestamp(ds_browser, ds_path):
            self.assertEqual('fake-ds-browser', ds_browser)
            self.assertEqual('[fake-ds] fake-path', str(ds_path))
            if not self.exists:
                return
            ts = '%s%s' % (imagecache.TIMESTAMP_PREFIX,
                           self._time.strftime(imagecache.TIMESTAMP_FORMAT))
            return ts

        with test.nested(
            mock.patch.object(self._imagecache, '_get_timestamp',
                              fake_get_timestamp),
            mock.patch.object(ds_util, 'file_delete')
        ) as (_get_timestamp, _file_delete):
            self.exists = False
            self._imagecache.timestamp_cleanup(
                    'fake-dc-ref', 'fake-ds-browser',
                    ds_obj.DatastorePath('fake-ds', 'fake-path'))
            self.assertEqual(0, _file_delete.call_count)
            self.exists = True
            self._imagecache.timestamp_cleanup(
                    'fake-dc-ref', 'fake-ds-browser',
                    ds_obj.DatastorePath('fake-ds', 'fake-path'))
            expected_ds_path = ds_obj.DatastorePath(
                    'fake-ds', 'fake-path', self._file_name)
            _file_delete.assert_called_once_with(self._session,
                    expected_ds_path, 'fake-dc-ref')
Пример #23
0
    def test_execute_without_destination(self):
        self.destination = None
        self._generate_task()
        self.assertIsNone(self.task.destination)

        with test.nested(
            mock.patch.object(self.task, '_check_host_is_up'),
            mock.patch.object(self.task, '_find_destination'),
            mock.patch.object(self.task.compute_rpcapi, 'live_migration'),
            mock.patch.object(self.migration, 'save'),
            mock.patch('nova.conductor.tasks.migrate.'
                       'replace_allocation_with_migration'),
        ) as (mock_check, mock_find, mock_mig, mock_save, mock_alloc):
            mock_find.return_value = ("found_host", "found_node")
            mock_mig.return_value = "bob"
            mock_alloc.return_value = (mock.MagicMock(), mock.MagicMock())

            self.assertEqual("bob", self.task.execute())
            mock_check.assert_called_once_with(self.instance_host)
            mock_find.assert_called_once_with()
            mock_mig.assert_called_once_with(self.context,
                host=self.instance_host,
                instance=self.instance,
                dest="found_host",
                block_migration=self.block_migration,
                migration=self.migration,
                migrate_data=None)
            self.assertTrue(mock_save.called)
            self.assertEqual('found_host', self.migration.dest_compute)
            self.assertEqual('found_node', self.migration.dest_node)
            self.assertEqual(self.instance.node, self.migration.source_node)
            self.assertTrue(mock_alloc.called)
Пример #24
0
    def test_release_dhcp(self):
        ctxt = context.RequestContext('fake_user', 'fake_project')

        dev = 'eth0'
        address = '192.168.65.158'
        vif_address = '00:0c:29:2c:b2:64'
        host = 'fake-host'

        rpcapi = network_rpcapi.NetworkAPI()
        call_mock = mock.Mock()
        cctxt_mock = mock.Mock(call=call_mock)

        with test.nested(
            mock.patch.object(rpcapi.client, 'can_send_version',
                              return_value=True),
            mock.patch.object(rpcapi.client, 'prepare',
                              return_value=cctxt_mock)
        ) as (
            can_send_mock, prepare_mock
        ):
            rpcapi.release_dhcp(ctxt, host, dev, address, vif_address)

        can_send_mock.assert_called_once_with('1.17')
        prepare_mock.assert_called_once_with(server=host, version='1.17')
        call_mock.assert_called_once_with(ctxt, 'release_dhcp', dev=dev,
                                          address=address,
                                          vif_address=vif_address)
Пример #25
0
    def _test_compute_api(self, method, rpc_method,
                          expected_args=None, **kwargs):
        ctxt = context.RequestContext('fake_user', 'fake_project')

        rpcapi = kwargs.pop('rpcapi_class', compute_rpcapi.ComputeAPI)()
        self.assertIsNotNone(rpcapi.client)
        self.assertEqual(rpcapi.client.target.topic, CONF.compute_topic)

        orig_prepare = rpcapi.client.prepare
        base_version = rpcapi.client.target.version
        expected_version = kwargs.pop('version', base_version)

        expected_kwargs = kwargs.copy()
        if expected_args:
            expected_kwargs.update(expected_args)
        if 'host_param' in expected_kwargs:
            expected_kwargs['host'] = expected_kwargs.pop('host_param')
        else:
            expected_kwargs.pop('host', None)

        cast_and_call = ['confirm_resize', 'stop_instance']
        if rpc_method == 'call' and method in cast_and_call:
            if method == 'confirm_resize':
                kwargs['cast'] = False
            else:
                kwargs['do_cast'] = False
        if 'host' in kwargs:
            host = kwargs['host']
        elif 'instances' in kwargs:
            host = kwargs['instances'][0]['host']
        else:
            host = kwargs['instance']['host']

        if method == 'rebuild_instance' and 'node' in expected_kwargs:
            expected_kwargs['scheduled_node'] = expected_kwargs.pop('node')

        with test.nested(
            mock.patch.object(rpcapi.client, rpc_method),
            mock.patch.object(rpcapi.client, 'prepare'),
            mock.patch.object(rpcapi.client, 'can_send_version'),
        ) as (
            rpc_mock, prepare_mock, csv_mock
        ):
            prepare_mock.return_value = rpcapi.client
            if '_return_value' in kwargs:
                rpc_mock.return_value = kwargs.pop('_return_value')
                del expected_kwargs['_return_value']
            elif rpc_method == 'call':
                rpc_mock.return_value = 'foo'
            else:
                rpc_mock.return_value = None
            csv_mock.side_effect = (
                lambda v: orig_prepare(version=v).can_send_version())

            retval = getattr(rpcapi, method)(ctxt, **kwargs)
            self.assertEqual(retval, rpc_mock.return_value)

            prepare_mock.assert_called_once_with(version=expected_version,
                                                 server=host)
            rpc_mock.assert_called_once_with(ctxt, method, **expected_kwargs)
    def _get_group_details_with_filter_not_configured(self, policy):
        wrong_filter = {
            'affinity': 'ServerGroupAntiAffinityFilter',
            'anti-affinity': 'ServerGroupAffinityFilter',
        }
        self.flags(scheduler_default_filters=[wrong_filter[policy]])

        instance = fake_instance.fake_instance_obj(self.context,
                params={'host': 'hostA'})

        group = objects.InstanceGroup()
        group.uuid = str(uuid.uuid4())
        group.members = [instance.uuid]
        group.policies = [policy]

        with test.nested(
            mock.patch.object(objects.InstanceGroup, 'get_by_instance_uuid',
                              return_value=group),
            mock.patch.object(objects.InstanceGroup, 'get_hosts',
                              return_value=['hostA']),
        ) as (get_group, get_hosts):
            scheduler_utils._SUPPORTS_ANTI_AFFINITY = None
            scheduler_utils._SUPPORTS_AFFINITY = None
            self.assertRaises(exception.UnsupportedPolicyException,
                              scheduler_utils._get_group_details,
                              self.context, 'fake-uuid')
Пример #27
0
    def test_cloudpipe_list(self):

        def network_api_get(context, network_id):
            self.assertEqual(context.project_id, project_id)
            return {'vpn_public_address': '127.0.0.1',
                    'vpn_public_port': 22}

        def fake_get_nw_info_for_instance(instance):
            return fake_network.fake_get_instance_nw_info(self)

        with test.nested(
            mock.patch.object(utils, 'vpn_ping', return_value=True),
            mock.patch.object(compute_utils, 'get_nw_info_for_instance',
                              side_effect=fake_get_nw_info_for_instance),
            mock.patch.object(self.controller.network_api, "get",
                              side_effect=network_api_get),
            mock.patch.object(self.controller.compute_api, "get_all",
                              side_effect=compute_api_get_all)
        ) as (mock_vpn_ping, mock_utils_get, mock_nw_get, mock_cpu_get_all):
            res_dict = self.controller.index(self.req)
            response = {'cloudpipes': [{'project_id': project_id,
                                        'internal_ip': '192.168.1.100',
                                        'public_ip': '127.0.0.1',
                                        'public_port': 22,
                                        'state': 'running',
                                        'instance_id': uuid,
                                        'created_at': '1981-10-20T00:00:00Z'}]}

            self.assertThat(response, matchers.DictMatches(res_dict))
            self.assertTrue(mock_cpu_get_all.called)
            self.assertTrue(mock_nw_get.called)
            self.assertTrue(mock_utils_get.called)
            self.assertTrue(mock_vpn_ping.called)
Пример #28
0
    def test_detach_volume_vmdk_invalid(self):
        connection_info = {'driver_volume_type': 'vmdk',
                           'serial': 'volume-fake-id',
                           'data': {'volume': 'vm-10',
                                    'volume_id': 'volume-fake-id'}}
        instance = mock.MagicMock(name='fake-name', vm_state=vm_states.ACTIVE)
        vmdk_info = vm_util.VmdkInfo('fake-path', constants.ADAPTER_TYPE_IDE,
                                     constants.DISK_TYPE_PREALLOCATED, 1024,
                                     'fake-device')
        with test.nested(
            mock.patch.object(vm_util, 'get_vm_ref',
                              return_value=mock.sentinel.vm_ref),
            mock.patch.object(self._volumeops, '_get_volume_ref'),
            mock.patch.object(self._volumeops,
                              '_get_vmdk_backed_disk_device'),
            mock.patch.object(vm_util, 'get_vmdk_info',
                              return_value=vmdk_info),
            mock.patch.object(vm_util, 'get_vm_state',
                              return_value=power_state.RUNNING)
        ) as (get_vm_ref, get_volume_ref, get_vmdk_backed_disk_device,
              get_vmdk_info, get_vm_state):
            self.assertRaises(exception.Invalid,
                self._volumeops._detach_volume_vmdk, connection_info,
                instance)

            get_vm_ref.assert_called_once_with(self._volumeops._session,
                                               instance)
            get_volume_ref.assert_called_once_with(
                connection_info['data']['volume'])
            get_vmdk_backed_disk_device.assert_called_once_with(
                mock.sentinel.vm_ref, connection_info['data'])
            self.assertTrue(get_vmdk_info.called)
            get_vm_state.assert_called_once_with(self._volumeops._session,
                                                 instance)
Пример #29
0
    def test_create_server_with_pci_dev_and_numa_fails(self, img_mock):
        """This test ensures that it is not possible to allocated CPU and
           memory resources from one NUMA node and a PCI device from another.
        """

        host_info = fakelibvirt.NUMAHostInfo(cpu_nodes=2, cpu_sockets=1,
                                             cpu_cores=2, cpu_threads=2,
                                             kB_mem=15740000)
        pci_info = fakelibvirt.HostPciSRIOVDevicesInfo(num_pfs=1, numa_node=0)
        fake_connection = self._get_connection(host_info, pci_info)

        # Create a flavor
        extra_spec_vm = {'hw:cpu_policy': 'dedicated',
                         'hw:numa_node': '1'}
        extra_spec = {'pci_passthrough:alias': '%s:1' % self.pfs_alias_name,
                      'hw:numa_nodes': '1',
                      'hw:cpu_policy': 'dedicated',
                      'hw:cpu_thread_policy': 'prefer'}
        vm_flavor_id = self._create_flavor(vcpu=4, extra_spec=extra_spec_vm)
        pf_flavor_id = self._create_flavor(extra_spec=extra_spec)
        host_pass_mock = self._get_pci_passthrough_filter_spy()
        with test.nested(
            mock.patch('nova.virt.libvirt.host.Host.get_connection',
                       return_value=fake_connection),
            mock.patch('nova.scheduler.filters'
                       '.pci_passthrough_filter.PciPassthroughFilter'
                       '.host_passes',
                       side_effect=host_pass_mock)) as (conn_mock,
                                                        filter_mock):
            vm_server = self._run_build_test(vm_flavor_id, filter_mock)
            pf_server = self._run_build_test(pf_flavor_id, filter_mock,
                                             end_status='ERROR')
        self._delete_server(vm_server['id'])
        self._delete_server(pf_server['id'])
Пример #30
0
    def test_migrate_disk_power_off_resize(self):
        self.flags(my_ip='fakeip')
        instance = stubs._fake_instance()
        network_info = mock.Mock()
        flavor = mock.Mock()
        context = mock.Mock()
        dest = 'fakeip'

        with test.nested(
            mock.patch.object(session.LXDAPISession, 'container_defined'),
            mock.patch.object(config.LXDContainerConfig, 'create_profile'),
            mock.patch.object(session.LXDAPISession, 'profile_update')
        ) as (
            mock_container_defined,
            mock_create_profile,
            mock_profile_update
        ):
            self.assertEqual('',
                             self.migrate.migrate_disk_and_power_off(
                                 context, instance, dest, flavor,
                                 network_info))
            mock_container_defined.assert_called_once_with(instance.name,
                                                           instance)
            mock_create_profile.assert_called_once_with(instance,
                                                        network_info)
Пример #31
0
    def _test_execute(self,
                      cross_cell_exec_mock,
                      prep_resize_mock,
                      sel_dest_mock,
                      sig_mock,
                      az_mock,
                      gmv_mock,
                      cm_mock,
                      sm_mock,
                      cn_mock,
                      rc_mock,
                      gbf_mock,
                      requested_destination=False,
                      same_cell=True):
        sel_dest_mock.return_value = self.host_lists
        az_mock.return_value = 'myaz'
        gbf_mock.return_value = objects.MigrationList()
        mock_get_resources = \
            self.mock_network_api.get_requested_resource_for_instance
        mock_get_resources.return_value = []

        if requested_destination:
            self.request_spec.requested_destination = objects.Destination(
                host='target_host',
                node=None,
                allow_cross_cell_move=not same_cell)
            self.request_spec.retry = objects.SchedulerRetries.from_dict(
                self.context, self.filter_properties['retry'])
            self.filter_properties.pop('retry')
            self.filter_properties['requested_destination'] = (
                self.request_spec.requested_destination)

        task = self._generate_task()
        gmv_mock.return_value = 23

        # We just need this hook point to set a uuid on the
        # migration before we use it for teardown
        def set_migration_uuid(*a, **k):
            task._migration.uuid = uuids.migration
            return mock.MagicMock()

        # NOTE(danms): It's odd to do this on cn_mock, but it's just because
        # of when we need to have it set in the flow and where we have an easy
        # place to find it via self.migration.
        cn_mock.side_effect = set_migration_uuid

        selection = self.host_lists[0][0]
        with test.nested(
                mock.patch.object(scheduler_utils, 'fill_provider_mapping'),
                mock.patch.object(
                    task,
                    '_is_selected_host_in_source_cell',
                    return_value=same_cell)) as (fill_mock,
                                                 _is_source_cell_mock):
            task.execute()
            fill_mock.assert_called_once_with(task.context, task.reportclient,
                                              task.request_spec, selection)
            _is_source_cell_mock.assert_called_once_with(selection)

        self.ensure_network_metadata_mock.assert_called_once_with(
            self.instance)
        self.heal_reqspec_is_bfv_mock.assert_called_once_with(
            self.context, self.request_spec, self.instance)
        sig_mock.assert_called_once_with(self.context, self.request_spec)
        task.query_client.select_destinations.assert_called_once_with(
            self.context,
            self.request_spec, [self.instance.uuid],
            return_objects=True,
            return_alternates=True)

        if same_cell:
            prep_resize_mock.assert_called_once_with(
                self.context,
                self.instance,
                self.request_spec.image,
                self.flavor,
                selection.service_host,
                task._migration,
                request_spec=self.request_spec,
                filter_properties=self.filter_properties,
                node=selection.nodename,
                clean_shutdown=self.clean_shutdown,
                host_list=[])
            az_mock.assert_called_once_with(self.context, 'host1')
            cross_cell_exec_mock.assert_not_called()
        else:
            cross_cell_exec_mock.assert_called_once_with()
            az_mock.assert_not_called()
            prep_resize_mock.assert_not_called()

        self.assertIsNotNone(task._migration)

        old_flavor = self.instance.flavor
        new_flavor = self.flavor
        self.assertEqual(old_flavor.id, task._migration.old_instance_type_id)
        self.assertEqual(new_flavor.id, task._migration.new_instance_type_id)
        self.assertEqual('pre-migrating', task._migration.status)
        self.assertEqual(self.instance.uuid, task._migration.instance_uuid)
        self.assertEqual(self.instance.host, task._migration.source_compute)
        self.assertEqual(self.instance.node, task._migration.source_node)
        if old_flavor.id != new_flavor.id:
            self.assertEqual('resize', task._migration.migration_type)
        else:
            self.assertEqual('migration', task._migration.migration_type)

        task._migration.create.assert_called_once_with()

        if requested_destination:
            self.assertIsNone(self.request_spec.retry)
            self.assertIn('cell', self.request_spec.requested_destination)
            self.assertIsNotNone(self.request_spec.requested_destination.cell)
            self.assertEqual(
                not same_cell,
                self.request_spec.requested_destination.allow_cross_cell_move)

        mock_get_resources.assert_called_once_with(self.context,
                                                   self.instance.uuid)
        self.assertEqual([], self.request_spec.requested_resources)
Пример #32
0
    def _test_compute_api(self,
                          method,
                          rpc_method,
                          expected_args=None,
                          **kwargs):
        ctxt = context.RequestContext('fake_user', 'fake_project')

        rpcapi = kwargs.pop('rpcapi_class', compute_rpcapi.ComputeAPI)()
        self.assertIsNotNone(rpcapi.client)
        self.assertEqual(rpcapi.client.target.topic, CONF.compute_topic)

        orig_prepare = rpcapi.client.prepare
        base_version = rpcapi.client.target.version
        expected_version = kwargs.pop('version', base_version)

        expected_kwargs = kwargs.copy()
        if expected_args:
            expected_kwargs.update(expected_args)
        if 'host_param' in expected_kwargs:
            expected_kwargs['host'] = expected_kwargs.pop('host_param')
        else:
            expected_kwargs.pop('host', None)

        cast_and_call = ['confirm_resize', 'stop_instance']
        if rpc_method == 'call' and method in cast_and_call:
            if method == 'confirm_resize':
                kwargs['cast'] = False
            else:
                kwargs['do_cast'] = False
        if 'host' in kwargs:
            host = kwargs['host']
        elif 'instances' in kwargs:
            host = kwargs['instances'][0]['host']
        else:
            host = kwargs['instance']['host']

        if method == 'rebuild_instance' and 'node' in expected_kwargs:
            expected_kwargs['scheduled_node'] = expected_kwargs.pop('node')

        with test.nested(
                mock.patch.object(rpcapi.client, rpc_method),
                mock.patch.object(rpcapi.client, 'prepare'),
                mock.patch.object(rpcapi.client, 'can_send_version'),
        ) as (rpc_mock, prepare_mock, csv_mock):
            prepare_mock.return_value = rpcapi.client
            if '_return_value' in kwargs:
                rpc_mock.return_value = kwargs.pop('_return_value')
                del expected_kwargs['_return_value']
            elif rpc_method == 'call':
                rpc_mock.return_value = 'foo'
            else:
                rpc_mock.return_value = None
            csv_mock.side_effect = (
                lambda v: orig_prepare(version=v).can_send_version())

            retval = getattr(rpcapi, method)(ctxt, **kwargs)
            self.assertEqual(retval, rpc_mock.return_value)

            prepare_mock.assert_called_once_with(version=expected_version,
                                                 server=host)
            rpc_mock.assert_called_once_with(ctxt, method, **expected_kwargs)
Пример #33
0
    def test_delete_during_create(self):
        compute = self._start_compute('compute1')

        def delete_race(instance):
            self.api.delete_server(instance.uuid)
            self._wait_for_server_parameter(
                self.api,
                {'id': instance.uuid},
                {'OS-EXT-STS:task_state': task_states.DELETING},
            )

        orig_save = objects.Instance.save

        # an in-memory record of the current instance task state as persisted
        # to the db.
        db_task_states = collections.defaultdict(str)
        active_after_deleting_error = [False]

        # A wrapper round instance.save() which allows us to inject a race
        # under specific conditions before calling the original instance.save()
        def wrap_save(instance, *wrap_args, **wrap_kwargs):
            # We're looking to inject the race before:
            #   instance.save(expected_task_state=task_states.SPAWNING)
            # towards the end of _build_and_run_instance.
            #
            # At this point the driver has finished creating the instance, but
            # we're still on the compute host and still holding the compute
            # host instance lock.
            #
            # This is just a convenient interception point. In order to race
            # the delete could have happened at any point prior to this since
            # the previous instance.save()
            expected_task_state = wrap_kwargs.get('expected_task_state')
            if (instance.vm_state == vm_states.ACTIVE
                    and instance.task_state is None
                    and expected_task_state == task_states.SPAWNING):
                delete_race(instance)

            orig_save(instance, *wrap_args, **wrap_kwargs)

            if (db_task_states[instance.uuid] == task_states.DELETING
                    and instance.vm_state == vm_states.ACTIVE
                    and instance.task_state is None):
                # the instance was in the DELETING task state in the db, and we
                # overwrote that to set it to ACTIVE with no task state.
                # Bug 1848666.
                active_after_deleting_error[0] = True

            db_task_states[instance.uuid] = instance.task_state

        with test.nested(
                mock.patch('nova.objects.Instance.save', wrap_save),
                mock.patch.object(compute.driver, 'spawn'),
                mock.patch.object(compute.driver, 'unplug_vifs'),
        ) as (_, mock_spawn, mock_unplug_vifs):
            # the compute manager doesn't set the ERROR state in cleanup since
            # it might race with delete, therefore we'll be left in BUILDING
            server_req = self._build_server(networks='none')
            created_server = self.api.post_server({'server': server_req})
            self._wait_until_deleted(created_server)

            # assert that we spawned the instance, and unplugged vifs on
            # cleanup
            mock_spawn.assert_called()
            # FIXME(mdbooth): We should have called unplug_vifs in cleanup, but
            # we didn't due to bug 1831771
            mock_unplug_vifs.assert_not_called()
            # FIXME(mdbooth): Bug 1848666
            self.assertTrue(active_after_deleting_error[0])
Пример #34
0
    def test_get_domain_capabilities_non_native_kvm(self):
        # This test assumes that we are on a x86 host and the
        # virt-type is set to kvm. In that case we would expect
        # libvirt to raise an error if you try to get the domain
        # capabilities for non-native archs specifying the kvm virt
        # type.
        archs = {
            'sparc': 'SS-5',
            'mips': 'malta',
            'mipsel': 'malta',
            'ppc': 'g3beige',
            'armv7l': 'virt-2.11',
        }

        # Because we are mocking out the libvirt connection and
        # supplying fake data, no exception will be raised, so we
        # first store a reference to the original
        # _get_domain_capabilities function
        local__get_domain_caps = self.host._get_domain_capabilities

        # We then define our own version that will raise for
        # non-native archs and otherwise delegates to the private
        # function.
        def _get_domain_capabilities(**kwargs):
            arch = kwargs['arch']
            if arch not in archs:
                return local__get_domain_caps(**kwargs)
            else:
                exc = fakelibvirt.make_libvirtError(
                    fakelibvirt.libvirtError,
                    "invalid argument: KVM is not supported by "
                    "'/usr/bin/qemu-system-%s' on this host" % arch,
                    error_code=fakelibvirt.VIR_ERR_INVALID_ARG)
                raise exc

        # Finally we patch to use our own version
        with test.nested(
                mock.patch.object(host.LOG, 'debug'),
                mock.patch.object(self.host, "_get_domain_capabilities"),
        ) as (mock_log, mock_caps):
            mock_caps.side_effect = _get_domain_capabilities
            self.flags(virt_type='kvm', group='libvirt')
            # and call self.host.get_domain_capabilities() directly as
            # the exception should be caught internally
            caps = self.host.get_domain_capabilities()
            # We don't really care what mock_caps is called with,
            # as we assert the behavior we expect below. However we
            # can at least check for the expected debug messages.
            mock_caps.assert_called()
            warnings = []
            for call in mock_log.mock_calls:
                name, args, kwargs = call
                if "Error from libvirt when retrieving domain capabilities" \
                        in args[0]:
                    warnings.append(call)
            self.assertTrue(len(warnings) > 0)

        # The resulting capabilities object should be non-empty
        # as the x86 archs won't raise a libvirtError exception
        self.assertTrue(len(caps) > 0)
        # but all of the archs we mocked out should be skipped and
        # not included in the result set
        for arch in archs:
            self.assertNotIn(arch, caps)
Пример #35
0
    def test_execute_with_destination(self, mock_get_az):
        dest_node = objects.ComputeNode(hypervisor_hostname='dest_node')
        with test.nested(
            mock.patch.object(self.task, '_check_host_is_up'),
            mock.patch.object(self.task, '_check_requested_destination'),
            mock.patch.object(scheduler_utils,
                              'claim_resources_on_destination'),
            mock.patch.object(self.migration, 'save'),
            mock.patch.object(self.task.compute_rpcapi, 'live_migration'),
            mock.patch('nova.conductor.tasks.migrate.'
                       'replace_allocation_with_migration'),
            mock.patch.object(self.task, '_check_destination_is_not_source'),
            mock.patch.object(self.task,
                              '_check_destination_has_enough_memory'),
            mock.patch.object(self.task,
                              '_check_compatible_with_source_hypervisor',
                              return_value=(mock.sentinel.source_node,
                                            dest_node)),
        ) as (mock_check_up, mock_check_dest, mock_claim, mock_save, mock_mig,
              m_alloc, m_check_diff, m_check_enough_mem, m_check_compatible):
            mock_mig.return_value = "bob"
            m_alloc.return_value = (mock.MagicMock(), mock.sentinel.allocs)

            self.assertEqual("bob", self.task.execute())
            mock_check_up.assert_has_calls([
                mock.call(self.instance_host), mock.call(self.destination)])
            mock_check_dest.assert_called_once_with()
            m_check_diff.assert_called_once()
            m_check_enough_mem.assert_called_once()
            m_check_compatible.assert_called_once()
            allocs = mock.sentinel.allocs
            mock_claim.assert_called_once_with(
                self.context, self.task.report_client,
                self.instance, mock.sentinel.source_node, dest_node,
                source_allocations=allocs, consumer_generation=None)
            mock_mig.assert_called_once_with(
                self.context,
                host=self.instance_host,
                instance=self.instance,
                dest=self.destination,
                block_migration=self.block_migration,
                migration=self.migration,
                migrate_data=None)
            self.assertTrue(mock_save.called)
            mock_get_az.assert_called_once_with(self.context, self.destination)
            self.assertEqual('fake-az', self.instance.availability_zone)
            # make sure the source/dest fields were set on the migration object
            self.assertEqual(self.instance.node, self.migration.source_node)
            self.assertEqual(dest_node.hypervisor_hostname,
                             self.migration.dest_node)
            self.assertEqual(self.task.destination,
                             self.migration.dest_compute)
            m_alloc.assert_called_once_with(self.context,
                                            self.instance,
                                            self.migration)
        # When the task is executed with a destination it means the host is
        # being forced and we don't call the scheduler, so we don't need to
        # heal the request spec.
        self.heal_reqspec_is_bfv_mock.assert_not_called()

        # When the task is executed with a destination it means the host is
        # being forced and we don't call the scheduler, so we don't need to
        # modify the request spec
        self.ensure_network_metadata_mock.assert_not_called()
Пример #36
0
    def test_execute_with_destination(self, new_mode=True):
        dest_node = objects.ComputeNode(hypervisor_hostname='dest_node')
        with test.nested(
                mock.patch.object(self.task, '_check_host_is_up'),
                mock.patch.object(self.task,
                                  '_check_requested_destination',
                                  return_value=(mock.sentinel.source_node,
                                                dest_node)),
                mock.patch.object(scheduler_utils,
                                  'claim_resources_on_destination'),
                mock.patch.object(self.migration, 'save'),
                mock.patch.object(self.task.compute_rpcapi, 'live_migration'),
                mock.patch('nova.conductor.tasks.migrate.'
                           'replace_allocation_with_migration'),
                mock.patch(
                    'nova.conductor.tasks.live_migrate.'
                    'should_do_migration_allocation')) as (mock_check_up,
                                                           mock_check_dest,
                                                           mock_claim,
                                                           mock_save, mock_mig,
                                                           m_alloc, mock_sda):
            mock_mig.return_value = "bob"
            m_alloc.return_value = (mock.MagicMock(), mock.sentinel.allocs)
            mock_sda.return_value = new_mode

            self.assertEqual("bob", self.task.execute())
            mock_check_up.assert_called_once_with(self.instance_host)
            mock_check_dest.assert_called_once_with()
            if new_mode:
                allocs = mock.sentinel.allocs
            else:
                allocs = None
            mock_claim.assert_called_once_with(
                self.context,
                self.task.scheduler_client.reportclient,
                self.instance,
                mock.sentinel.source_node,
                dest_node,
                source_node_allocations=allocs)
            mock_mig.assert_called_once_with(
                self.context,
                host=self.instance_host,
                instance=self.instance,
                dest=self.destination,
                block_migration=self.block_migration,
                migration=self.migration,
                migrate_data=None)
            self.assertTrue(mock_save.called)
            # make sure the source/dest fields were set on the migration object
            self.assertEqual(self.instance.node, self.migration.source_node)
            self.assertEqual(dest_node.hypervisor_hostname,
                             self.migration.dest_node)
            self.assertEqual(self.task.destination,
                             self.migration.dest_compute)
            if new_mode:
                m_alloc.assert_called_once_with(self.context, self.instance,
                                                self.migration)
            else:
                m_alloc.assert_not_called()
        # When the task is executed with a destination it means the host is
        # being forced and we don't call the scheduler, so we don't need to
        # heal the request spec.
        self.heal_reqspec_is_bfv_mock.assert_not_called()

        # When the task is executed with a destination it means the host is
        # being forced and we don't call the scheduler, so we don't need to
        # modify the request spec
        self.ensure_network_metadata_mock.assert_not_called()
Пример #37
0
    def test_fetch_image_ova(self, mock_tar_open, mock_write_class,
                             mock_read_class):
        session = mock.MagicMock()
        ovf_descriptor = None
        ovf_path = os.path.join(os.path.dirname(__file__), 'ovf.xml')
        with open(ovf_path) as f:
            ovf_descriptor = f.read()

        with test.nested(
                mock.patch.object(images.IMAGE_API, 'get'),
                mock.patch.object(images.IMAGE_API, 'download'),
                mock.patch.object(images, 'start_transfer'),
                mock.patch.object(images, '_build_shadow_vm_config_spec'),
                mock.patch.object(
                    session,
                    '_call_method')) as (mock_image_api_get,
                                         mock_image_api_download,
                                         mock_start_transfer,
                                         mock_build_shadow_vm_config_spec,
                                         mock_call_method):
            image_data = {'id': 'fake-id', 'disk_format': 'vmdk', 'size': 512}
            instance = mock.MagicMock()
            instance.image_ref = image_data['id']
            mock_image_api_get.return_value = image_data

            vm_folder_ref = mock.MagicMock()
            res_pool_ref = mock.MagicMock()
            context = mock.MagicMock()

            mock_read_handle = mock.MagicMock()
            mock_read_class.return_value = mock_read_handle
            mock_write_handle = mock.MagicMock()
            mock_write_class.return_value = mock_write_handle
            mock_write_handle.get_imported_vm.return_value = \
                mock.sentinel.vm_ref

            mock_ovf = mock.MagicMock()
            mock_ovf.name = 'dsl.ovf'
            mock_vmdk = mock.MagicMock()
            mock_vmdk.name = "Damn_Small_Linux-disk1.vmdk"

            def fake_extract(name):
                if name == mock_ovf:
                    m = mock.MagicMock()
                    m.read.return_value = ovf_descriptor
                    return m
                elif name == mock_vmdk:
                    return mock_read_handle

            mock_tar = mock.MagicMock()
            mock_tar.__iter__ = mock.Mock(
                return_value=iter([mock_ovf, mock_vmdk]))
            mock_tar.extractfile = fake_extract
            mock_tar_open.return_value.__enter__.return_value = mock_tar

            images.fetch_image_ova(context, instance, session, 'fake-vm',
                                   'fake-datastore', vm_folder_ref,
                                   res_pool_ref)

            mock_tar_open.assert_called_once_with(mode='r|',
                                                  fileobj=mock_read_handle)
            mock_start_transfer.assert_called_once_with(
                context,
                mock_read_handle,
                512,
                write_file_handle=mock_write_handle)

            mock_call_method.assert_called_once_with(session.vim,
                                                     "UnregisterVM",
                                                     mock.sentinel.vm_ref)
Пример #38
0
    def test_sev_trait_off_on(self):
        """Test that the compute service reports the SEV trait in the list of
        global traits, but doesn't immediately register it on the
        compute host resource provider in the placement API, due to
        the kvm-amd kernel module's sev parameter file being (mocked
        as) absent.

        Then test that if the SEV capability appears (again via
        mocking), after a restart of the compute service, the trait
        gets registered on the compute host.

        Also test that on both occasions, the inventory of the
        MEM_ENCRYPTION_CONTEXT resource class on the compute host
        corresponds to the absence or presence of the SEV capability.
        """
        self.assertFalse(self.compute.driver._host.supports_amd_sev)

        sev_trait = ost.HW_CPU_X86_AMD_SEV

        global_traits = self._get_all_traits()
        self.assertIn(sev_trait, global_traits)

        traits = self._get_provider_traits(self.host_uuid)
        self.assertNotIn(sev_trait, traits)

        self.assertMemEncryptionSlotsEqual(0)

        # Now simulate the host gaining SEV functionality.  Here we
        # simulate a kernel update or reconfiguration which causes the
        # kvm-amd kernel module's "sev" parameter to become available
        # and set to 1, however it could also happen via a libvirt
        # upgrade, for instance.
        sev_features = \
            fakelibvirt.virConnect._domain_capability_features_with_SEV
        with test.nested(
                self.patch_exists(SEV_KERNEL_PARAM_FILE, True),
                self.patch_open(SEV_KERNEL_PARAM_FILE, "1\n"),
                mock.patch.object(fakelibvirt.virConnect,
                                  '_domain_capability_features',
                                  new=sev_features)) as (mock_exists,
                                                         mock_open,
                                                         mock_features):
            # Retrigger the detection code.  In the real world this
            # would be a restart of the compute service.
            self.compute.driver._host._set_amd_sev_support()
            self.assertTrue(self.compute.driver._host.supports_amd_sev)

            mock_exists.assert_has_calls([mock.call(SEV_KERNEL_PARAM_FILE)])
            mock_open.assert_has_calls([mock.call(SEV_KERNEL_PARAM_FILE)])

            # However it won't disappear in the provider tree and get synced
            # back to placement until we force a reinventory:
            self.compute.manager.reset()
            self._run_periodics()

            traits = self._get_provider_traits(self.host_uuid)
            self.assertIn(sev_trait, traits)

            # Sanity check that we've still got the trait globally.
            self.assertIn(sev_trait, self._get_all_traits())

            self.assertMemEncryptionSlotsEqual(db_const.MAX_INT)
Пример #39
0
    def _test_network_api(self, method, rpc_method, **kwargs):
        ctxt = context.RequestContext('fake_user', 'fake_project')

        rpcapi = network_rpcapi.NetworkAPI()
        self.assertIsNotNone(rpcapi.client)
        self.assertEqual(CONF.network_topic, rpcapi.client.target.topic)

        expected_retval = 'foo' if rpc_method == 'call' else None
        expected_version = kwargs.pop('version', None)
        expected_fanout = kwargs.pop('fanout', None)
        expected_kwargs = kwargs.copy()

        for k, v in expected_kwargs.items():
            if isinstance(v, self.DefaultArg):
                expected_kwargs[k] = v.value
                kwargs.pop(k)

        prepare_kwargs = {}
        if expected_version:
            prepare_kwargs['version'] = expected_version
        if expected_fanout:
            prepare_kwargs['fanout'] = True

        if 'source_compute' in expected_kwargs:
            # Fix up for migrate_instance_* calls.
            expected_kwargs['source'] = expected_kwargs.pop('source_compute')
            expected_kwargs['dest'] = expected_kwargs.pop('dest_compute')

        targeted_methods = [
            'lease_fixed_ip', 'release_fixed_ip', 'rpc_setup_network_on_host',
            '_rpc_allocate_fixed_ip', 'deallocate_fixed_ip', 'update_dns',
            '_associate_floating_ip', '_disassociate_floating_ip',
            'lease_fixed_ip', 'release_fixed_ip', 'migrate_instance_start',
            'migrate_instance_finish',
            'allocate_for_instance', 'deallocate_for_instance',
        ]
        targeted_by_instance = ['deallocate_for_instance']
        if method in targeted_methods and ('host' in expected_kwargs or
                'instance' in expected_kwargs):
            if method in targeted_by_instance:
                host = expected_kwargs['instance']['host']
            else:
                host = expected_kwargs['host']
                if method not in ['allocate_for_instance',
                                  'deallocate_fixed_ip']:
                    expected_kwargs.pop('host')
            if CONF.multi_host:
                prepare_kwargs['server'] = host

        with test.nested(
            mock.patch.object(rpcapi.client, rpc_method),
            mock.patch.object(rpcapi.client, 'prepare'),
            mock.patch.object(rpcapi.client, 'can_send_version'),
        ) as (
            rpc_mock, prepare_mock, csv_mock
        ):

            version_check = [
                'deallocate_for_instance', 'deallocate_fixed_ip',
                'allocate_for_instance', 'release_fixed_ip',
                'set_network_host', 'setup_networks_on_host'
            ]
            if method in version_check:
                csv_mock.return_value = True

            if prepare_kwargs:
                prepare_mock.return_value = rpcapi.client

            if rpc_method == 'call':
                rpc_mock.return_value = 'foo'
            else:
                rpc_mock.return_value = None

            retval = getattr(rpcapi, method)(ctxt, **kwargs)
            self.assertEqual(expected_retval, retval)

            if method in version_check:
                csv_mock.assert_called_once_with(mock.ANY)
            if prepare_kwargs:
                prepare_mock.assert_called_once_with(**prepare_kwargs)
            rpc_mock.assert_called_once_with(ctxt, method, **expected_kwargs)
Пример #40
0
    def test_detach_volume_vmdk(self):
        client_factory = self._volumeops._session.vim.client.factory

        virtual_controller = client_factory.create(
            'ns0:VirtualLsiLogicController')
        virtual_controller.key = 100

        virtual_disk = client_factory.create('ns0:VirtualDisk')
        virtual_disk.controllerKey = virtual_controller.key

        with test.nested(
                mock.patch.object(vm_util,
                                  'get_vm_ref',
                                  return_value=mock.sentinel.vm_ref),
                mock.patch.object(self._volumeops,
                                  '_get_volume_ref',
                                  return_value=mock.sentinel.volume_ref),
                mock.patch.object(self._volumeops,
                                  '_get_vmdk_backed_disk_device',
                                  return_value=virtual_disk),
                mock.patch.object(vm_util,
                                  '_get_device_disk_type',
                                  return_value='fake-disk-type'),
                mock.patch.object(self._volumeops, '_consolidate_vmdk_volume'),
                mock.patch.object(self._volumeops, 'detach_disk_from_vm'),
                mock.patch.object(self._volumeops, '_update_volume_details'),
                mock.patch.object(
                    self._volumeops._session,
                    '_call_method',
                    return_value=[
                        virtual_controller
                    ])) as (get_vm_ref, get_volume_ref,
                            get_vmdk_backed_disk_device, _get_device_disk_type,
                            consolidate_vmdk_volume, detach_disk_from_vm,
                            update_volume_details, session_call_method):

            connection_info = {
                'driver_volume_type': 'vmdk',
                'serial': 'volume-fake-id',
                'data': {
                    'volume': 'vm-10',
                    'volume_id': 'd11a82de-ddaa-448d-b50a-a255a7e61a1e'
                }
            }
            instance = mock.MagicMock(name='fake-name',
                                      vm_state=vm_states.ACTIVE)
            self._volumeops._detach_volume_vmdk(connection_info, instance)

            get_vm_ref.assert_called_once_with(self._volumeops._session,
                                               instance)
            get_volume_ref.assert_called_once_with(
                connection_info['data']['volume'])
            get_vmdk_backed_disk_device.assert_called_once_with(
                mock.sentinel.vm_ref, connection_info['data'])
            adapter_type = vm_util.CONTROLLER_TO_ADAPTER_TYPE.get(
                virtual_controller.__class__.__name__)
            consolidate_vmdk_volume.assert_called_once_with(
                instance,
                mock.sentinel.vm_ref,
                virtual_disk,
                mock.sentinel.volume_ref,
                adapter_type=adapter_type,
                disk_type='fake-disk-type')
            detach_disk_from_vm.assert_called_once_with(
                mock.sentinel.vm_ref, instance, virtual_disk)
            update_volume_details.assert_called_once_with(
                mock.sentinel.vm_ref, connection_info['data']['volume_id'], "")
    def _test_attach_volume_vmdk(self, adapter_type=None):
        connection_info = {
            'driver_volume_type': constants.DISK_FORMAT_VMDK,
            'serial': 'volume-fake-id',
            'data': {
                'volume': 'vm-10',
                'volume_id': 'volume-fake-id'
            }
        }
        vm_ref = 'fake-vm-ref'
        volume_device = mock.MagicMock()
        volume_device.backing.fileName = 'fake-path'
        default_adapter_type = constants.DEFAULT_ADAPTER_TYPE
        disk_type = constants.DEFAULT_DISK_TYPE
        disk_uuid = 'e97f357b-331e-4ad1-b726-89be048fb811'
        backing = mock.Mock(uuid=disk_uuid)
        device = mock.Mock(backing=backing)
        vmdk_info = vm_util.VmdkInfo('fake-path', default_adapter_type,
                                     disk_type, 1024, device)
        adapter_type = adapter_type or default_adapter_type

        if adapter_type == constants.ADAPTER_TYPE_IDE:
            vm_state = 'PoweredOff'
        else:
            vm_state = 'PoweredOn'
        with test.nested(
                mock.patch.object(vm_util, 'get_vm_ref', return_value=vm_ref),
                mock.patch.object(self._volumeops, '_get_volume_ref'),
                mock.patch.object(vm_util,
                                  'get_vmdk_info',
                                  return_value=vmdk_info),
                mock.patch.object(self._volumeops, 'attach_disk_to_vm'),
                mock.patch.object(self._volumeops, '_update_volume_details'),
                mock.patch.object(
                    vm_util, 'get_vm_state',
                    return_value=vm_state)) as (get_vm_ref, get_volume_ref,
                                                get_vmdk_info,
                                                attach_disk_to_vm,
                                                update_volume_details,
                                                get_vm_state):
            self._volumeops.attach_volume(connection_info, self._instance,
                                          adapter_type)

            get_vm_ref.assert_called_once_with(self._volumeops._session,
                                               self._instance)
            get_volume_ref.assert_called_once_with(
                connection_info['data']['volume'])
            self.assertTrue(get_vmdk_info.called)
            attach_disk_to_vm.assert_called_once_with(
                vm_ref,
                self._instance,
                adapter_type,
                constants.DISK_TYPE_PREALLOCATED,
                vmdk_path='fake-path')
            update_volume_details.assert_called_once_with(
                vm_ref, connection_info['data']['volume_id'], disk_uuid)
            if adapter_type == constants.ADAPTER_TYPE_IDE:
                get_vm_state.assert_called_once_with(self._volumeops._session,
                                                     self._instance)
            else:
                self.assertFalse(get_vm_state.called)
Пример #42
0
    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):
        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})
        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:
            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)
Пример #43
0
    def _test_compute_api(self,
                          method,
                          rpc_method,
                          expected_args=None,
                          **kwargs):
        ctxt = context.RequestContext('fake_user', 'fake_project')

        rpcapi = kwargs.pop('rpcapi_class', compute_rpcapi.ComputeAPI)()
        self.assertIsNotNone(rpcapi.router)
        self.assertEqual(rpcapi.router.target.topic, compute_rpcapi.RPC_TOPIC)

        # This test wants to run the real prepare function, so must use
        # a real client object
        default_client = rpcapi.router.default_client

        orig_prepare = default_client.prepare
        base_version = rpcapi.router.target.version
        expected_version = kwargs.pop('version', base_version)

        prepare_extra_kwargs = {}
        cm_timeout = kwargs.pop('call_monitor_timeout', None)
        timeout = kwargs.pop('timeout', None)
        if cm_timeout:
            prepare_extra_kwargs['call_monitor_timeout'] = cm_timeout
        if timeout:
            prepare_extra_kwargs['timeout'] = timeout

        expected_kwargs = kwargs.copy()
        if expected_args:
            expected_kwargs.update(expected_args)
        if 'host_param' in expected_kwargs:
            expected_kwargs['host'] = expected_kwargs.pop('host_param')
        else:
            expected_kwargs.pop('host', None)

        cast_and_call = ['confirm_resize', 'stop_instance']
        if rpc_method == 'call' and method in cast_and_call:
            if method == 'confirm_resize':
                kwargs['cast'] = False
            else:
                kwargs['do_cast'] = False
        if 'host' in kwargs:
            host = kwargs['host']
        elif 'instances' in kwargs:
            host = kwargs['instances'][0]['host']
        elif 'destination' in kwargs:
            host = expected_kwargs.pop('destination')
        else:
            host = kwargs['instance']['host']

        if method == 'rebuild_instance' and 'node' in expected_kwargs:
            expected_kwargs['scheduled_node'] = expected_kwargs.pop('node')

        with test.nested(
                mock.patch.object(default_client, rpc_method),
                mock.patch.object(default_client, 'prepare'),
                mock.patch.object(default_client, 'can_send_version'),
        ) as (rpc_mock, prepare_mock, csv_mock):
            prepare_mock.return_value = default_client
            if '_return_value' in kwargs:
                rpc_mock.return_value = kwargs.pop('_return_value')
                del expected_kwargs['_return_value']
            elif rpc_method == 'call':
                rpc_mock.return_value = 'foo'
            else:
                rpc_mock.return_value = None
            csv_mock.side_effect = (
                lambda v: orig_prepare(version=v).can_send_version())

            retval = getattr(rpcapi, method)(ctxt, **kwargs)
            self.assertEqual(retval, rpc_mock.return_value)

            prepare_mock.assert_called_once_with(version=expected_version,
                                                 server=host,
                                                 **prepare_extra_kwargs)
            rpc_mock.assert_called_once_with(ctxt, method, **expected_kwargs)
Пример #44
0
    def _test_create_volume_backed_image_with_metadata_from_volume(
            self, extra_metadata=None):

        def _fake_id(x):
            return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12)

        body = dict(createImage=dict(name='snapshot_of_volume_backed'))
        if extra_metadata:
            body['createImage']['metadata'] = extra_metadata

        image_service = glance.get_default_image_service()

        def fake_block_device_mapping_get_all_by_instance(context, inst_id,
                                                          use_slave=False):
            return [fake_block_device.FakeDbBlockDeviceDict(
                        {'volume_id': _fake_id('a'),
                         'source_type': 'snapshot',
                         'destination_type': 'volume',
                         'volume_size': 1,
                         'device_name': 'vda',
                         'snapshot_id': 1,
                         'boot_index': 0,
                         'delete_on_termination': False,
                         'no_device': None})]

        self.stub_out('nova.db.block_device_mapping_get_all_by_instance',
                      fake_block_device_mapping_get_all_by_instance)

        instance = fakes.fake_instance_get(
            image_ref='',
            vm_state=vm_states.ACTIVE,
            root_device_name='/dev/vda',
            system_metadata={'image_test_key1': 'test_value1',
                             'image_test_key2': 'test_value2'})
        self.stub_out('nova.db.instance_get_by_uuid', instance)

        volume = dict(id=_fake_id('a'),
                      size=1,
                      host='fake',
                      display_description='fake')

        snapshot = dict(id=_fake_id('d'))

        with test.nested(
            mock.patch.object(
                self.controller.compute_api.volume_api, 'get_absolute_limits',
                return_value={'totalSnapshotsUsed': 0,
                              'maxTotalSnapshots': 10}),
            mock.patch.object(self.controller.compute_api.compute_rpcapi,
                'quiesce_instance',
                side_effect=exception.InstanceQuiesceNotSupported(
                    instance_id='fake', reason='test')),
            mock.patch.object(self.controller.compute_api.volume_api, 'get',
                              return_value=volume),
            mock.patch.object(self.controller.compute_api.volume_api,
                              'create_snapshot_force',
                              return_value=snapshot),
        ) as (mock_get_limits, mock_quiesce, mock_vol_get, mock_vol_create):

            response = self.controller._action_create_image(self.req,
                FAKE_UUID, body=body)
            location = response.headers['Location']
            image_id = location.replace(self.image_base_url, '')
            image = image_service.show(None, image_id)

            properties = image['properties']
            self.assertEqual(properties['test_key1'], 'test_value1')
            self.assertEqual(properties['test_key2'], 'test_value2')
            if extra_metadata:
                for key, val in extra_metadata.items():
                    self.assertEqual(properties[key], val)

            mock_quiesce.assert_called_once_with(mock.ANY, mock.ANY)
            mock_vol_get.assert_called_once_with(mock.ANY, volume['id'])
            mock_vol_create.assert_called_once_with(mock.ANY, volume['id'],
                                                    mock.ANY, mock.ANY)
Пример #45
0
    def test_disconnect_volume_called_during_pre_live_migration_failure(self):
        server = {
            'name':
            'test',
            'imageRef':
            '',
            'flavorRef':
            1,
            'networks':
            'none',
            'host':
            'src',
            'block_device_mapping_v2': [{
                'source_type':
                'volume',
                'destination_type':
                'volume',
                'boot_index':
                0,
                'uuid':
                nova_fixtures.CinderFixture.IMAGE_BACKED_VOL
            }]
        }

        with test.nested(
                mock.patch.object(self.computes['src'].driver,
                                  'get_volume_connector'),
                mock.patch.object(self.computes['src'].driver,
                                  '_connect_volume'),
        ) as (mock_src_connector, mock_src_connect):
            server = self.api.post_server({'server': server})
            self._wait_for_state_change(server, 'ACTIVE')

        # Assert that we called the src connector and connect mocks
        mock_src_connector.assert_called_once()
        mock_src_connect.assert_called_once()

        # Fetch the connection_info from the src
        ctxt = context.get_admin_context()
        bdm = objects.BlockDeviceMapping.get_by_volume_id(
            ctxt,
            nova_fixtures.CinderFixture.IMAGE_BACKED_VOL,
            instance_uuid=server['id'])
        src_connection_info = jsonutils.loads(bdm.connection_info)

        with test.nested(
                mock.patch.object(self.computes['dest'].driver,
                                  'get_volume_connector'),
                mock.patch.object(self.computes['dest'].driver,
                                  '_connect_volume'),
                mock.patch.object(self.computes['dest'].driver,
                                  '_disconnect_volume'),
                mock.patch('nova.volume.cinder.API.attachment_create',
                           side_effect=test.TestingException)) as (
                               mock_dest_connector, mock_dest_connect,
                               mock_dest_disconnect, mock_attachment_create):
            # Attempt to live migrate and ensure it is marked as failed
            self._live_migrate(server, 'failed')

        # Assert that we called the dest connector and attachment_create mocks
        mock_dest_connector.assert_called_once()
        mock_attachment_create.assert_called_once()

        # Assert that connect_volume hasn't been called on the dest
        mock_dest_connect.assert_not_called()

        # FIXME(lyarwood): This is bug #1899835, disconnect_volume shouldn't be
        # called on the destination host without connect_volume first being
        # called and especially using with the connection_info from the source
        mock_dest_disconnect.assert_called_with(mock.ANY,
                                                src_connection_info,
                                                mock.ANY,
                                                encryption=mock.ANY)
Пример #46
0
    def _do_test_create_volume_backed_image(
            self, extra_properties, mock_vol_create_side_effect=None):

        def _fake_id(x):
            return '%s-%s-%s-%s' % (x * 8, x * 4, x * 4, x * 12)

        body = dict(createImage=dict(name='snapshot_of_volume_backed'))

        if extra_properties:
            body['createImage']['metadata'] = extra_properties

        image_service = glance.get_default_image_service()

        bdm = [dict(volume_id=_fake_id('a'),
                    volume_size=1,
                    device_name='vda',
                    delete_on_termination=False)]

        def fake_block_device_mapping_get_all_by_instance(context, inst_id,
                                                          use_slave=False):
            return [fake_block_device.FakeDbBlockDeviceDict(
                        {'volume_id': _fake_id('a'),
                         'source_type': 'snapshot',
                         'destination_type': 'volume',
                         'volume_size': 1,
                         'device_name': 'vda',
                         'snapshot_id': 1,
                         'boot_index': 0,
                         'delete_on_termination': False,
                         'no_device': None})]

        self.stub_out('nova.db.block_device_mapping_get_all_by_instance',
                      fake_block_device_mapping_get_all_by_instance)

        system_metadata = dict(image_kernel_id=_fake_id('b'),
                               image_ramdisk_id=_fake_id('c'),
                               image_root_device_name='/dev/vda',
                               image_block_device_mapping=str(bdm),
                               image_container_format='ami')
        instance = fakes.fake_instance_get(image_ref=uuids.fake,
                                           vm_state=vm_states.ACTIVE,
                                           root_device_name='/dev/vda',
                                           system_metadata=system_metadata)
        self.stub_out('nova.db.instance_get_by_uuid', instance)

        volume = dict(id=_fake_id('a'),
                      size=1,
                      host='fake',
                      display_description='fake')

        snapshot = dict(id=_fake_id('d'))

        with test.nested(
            mock.patch.object(
                self.controller.compute_api.volume_api, 'get_absolute_limits',
                return_value={'totalSnapshotsUsed': 0,
                              'maxTotalSnapshots': 10}),
            mock.patch.object(self.controller.compute_api.compute_rpcapi,
                'quiesce_instance',
                side_effect=exception.InstanceQuiesceNotSupported(
                    instance_id='fake', reason='test')),
            mock.patch.object(self.controller.compute_api.volume_api, 'get',
                              return_value=volume),
            mock.patch.object(self.controller.compute_api.volume_api,
                              'create_snapshot_force',
                              return_value=snapshot),
        ) as (mock_get_limits, mock_quiesce, mock_vol_get, mock_vol_create):

            if mock_vol_create_side_effect:
                mock_vol_create.side_effect = mock_vol_create_side_effect

            response = self.controller._action_create_image(self.req,
                FAKE_UUID, body=body)

            location = response.headers['Location']
            image_id = location.replace(self.image_url or
                 self.image_api.generate_image_url('', self.context),
                                        '')
            image = image_service.show(None, image_id)

            self.assertEqual(image['name'], 'snapshot_of_volume_backed')
            properties = image['properties']
            self.assertEqual(properties['kernel_id'], _fake_id('b'))
            self.assertEqual(properties['ramdisk_id'], _fake_id('c'))
            self.assertEqual(properties['root_device_name'], '/dev/vda')
            self.assertTrue(properties['bdm_v2'])
            bdms = properties['block_device_mapping']
            self.assertEqual(len(bdms), 1)
            self.assertEqual(bdms[0]['boot_index'], 0)
            self.assertEqual(bdms[0]['source_type'], 'snapshot')
            self.assertEqual(bdms[0]['destination_type'], 'volume')
            self.assertEqual(bdms[0]['snapshot_id'], snapshot['id'])
            self.assertEqual('/dev/vda', bdms[0]['device_name'])
            for fld in ('connection_info', 'id', 'instance_uuid'):
                self.assertNotIn(fld, bdms[0])
            for k in extra_properties.keys():
                self.assertEqual(properties[k], extra_properties[k])

            mock_quiesce.assert_called_once_with(mock.ANY, mock.ANY)
            mock_vol_get.assert_called_once_with(mock.ANY, volume['id'])
            mock_vol_create.assert_called_once_with(mock.ANY, volume['id'],
                                                    mock.ANY, mock.ANY)
Пример #47
0
    def _test_spawn(self,
                    mock_copy_virtual_disk,
                    mock_power_on_instance,
                    mock_get_and_set_vnc_config,
                    mock_enlist_image,
                    mock_set_machine_id,
                    mock_mkdir,
                    mock_create_vm,
                    mock_get_create_spec,
                    mock_is_neutron,
                    mock_get_vif_info,
                    mock_get_datacenter_ref_and_name,
                    mock_get_datastore,
                    mock_configure_config_drive,
                    mock_update_vnic_index,
                    mock_create_folders,
                    block_device_info=None,
                    extra_specs=None,
                    config_drive=False):

        if extra_specs is None:
            extra_specs = vm_util.ExtraSpecs()

        image_size = (self._instance.root_gb) * units.Gi / 2
        image = {
            'id': self._image_id,
            'disk_format': 'vmdk',
            'size': image_size,
        }
        image = objects.ImageMeta.from_dict(image)
        image_info = images.VMwareImage(
            image_id=self._image_id,
            file_size=image_size)
        vi = self._vmops._get_vm_config_info(
            self._instance, image_info, extra_specs)

        self._vmops._volumeops = mock.Mock()
        network_info = mock.Mock()
        mock_get_datastore.return_value = self._ds
        mock_get_datacenter_ref_and_name.return_value = self._dc_info
        mock_call_method = mock.Mock(return_value='fake_task')

        if extra_specs is None:
            extra_specs = vm_util.ExtraSpecs()

        with test.nested(
                mock.patch.object(self._session, '_wait_for_task'),
                mock.patch.object(self._session, '_call_method',
                                  mock_call_method),
                mock.patch.object(uuidutils, 'generate_uuid',
                                  return_value='tmp-uuid'),
                mock.patch.object(images, 'fetch_image'),
                mock.patch('nova.image.api.API.get'),
                mock.patch.object(vutil, 'get_inventory_path',
                                  return_value=self._dc_info.name),
                mock.patch.object(self._vmops, '_get_extra_specs',
                                  return_value=extra_specs),
                mock.patch.object(self._vmops, '_get_instance_metadata',
                                  return_value='fake-metadata')
        ) as (_wait_for_task, _call_method, _generate_uuid, _fetch_image,
              _get_img_svc, _get_inventory_path, _get_extra_specs,
              _get_instance_metadata):
            self._vmops.spawn(self._context, self._instance, image,
                              injected_files='fake_files',
                              admin_password='******',
                              network_info=network_info,
                              block_device_info=block_device_info)

            mock_is_neutron.assert_called_once_with()

            self.assertEqual(2, mock_mkdir.call_count)

            mock_get_vif_info.assert_called_once_with(
                self._session, self._cluster.obj, False,
                constants.DEFAULT_VIF_MODEL, network_info)
            mock_get_create_spec.assert_called_once_with(
                self._session.vim.client.factory, self._instance,
                'fake_ds', [], extra_specs, constants.DEFAULT_OS_TYPE,
                profile_spec=None,
                metadata='fake-metadata')
            mock_create_vm.assert_called_once_with(
                self._session, self._instance, 'fake_vm_folder',
                'fake_create_spec', self._cluster.resourcePool)
            mock_get_and_set_vnc_config.assert_called_once_with(
                self._session.vim.client.factory,
                self._instance, 'fake_vm_ref')
            mock_set_machine_id.assert_called_once_with(
                self._session.vim.client.factory,
                self._instance, network_info, vm_ref='fake_vm_ref')
            mock_power_on_instance.assert_called_once_with(
                self._session, self._instance, vm_ref='fake_vm_ref')

            if (block_device_info and
                    'block_device_mapping' in block_device_info):
                bdms = block_device_info['block_device_mapping']
                for bdm in bdms:
                    mock_attach_root = (
                        self._vmops._volumeops.attach_root_volume)
                    mock_attach = self._vmops._volumeops.attach_volume
                    adapter_type = bdm.get('disk_bus') or vi.ii.adapter_type
                    if bdm.get('boot_index') == 0:
                        mock_attach_root.assert_any_call(
                            bdm['connection_info'], self._instance,
                            self._ds.ref, adapter_type)
                    else:
                        mock_attach.assert_any_call(
                            bdm['connection_info'], self._instance,
                            self._ds.ref, adapter_type)

            mock_enlist_image.assert_called_once_with(
                self._image_id, self._ds, self._dc_info.ref)

            upload_file_name = 'vmware_temp/tmp-uuid/%s/%s-flat.vmdk' % (
                self._image_id, self._image_id)
            _fetch_image.assert_called_once_with(
                self._context, self._instance, self._session._host,
                self._session._port, self._dc_info.name, self._ds.name,
                upload_file_name, cookies='Fake-CookieJar')
            self.assertGreater(len(_wait_for_task.mock_calls), 0)
            _get_inventory_path.call_count = 1
            extras = None
            if block_device_info and ('ephemerals' in block_device_info or
                                      'swap' in block_device_info):
                extras = ['CreateVirtualDisk_Task']
            self._verify_spawn_method_calls(_call_method, extras)

            dc_ref = 'fake_dc_ref'
            source_file = six.text_type('[fake_ds] vmware_base/%s/%s.vmdk' %
                                        (self._image_id, self._image_id))
            dest_file = six.text_type('[fake_ds] vmware_base/%s/%s.%d.vmdk' %
                                      (self._image_id, self._image_id,
                                       self._instance['root_gb']))
            # TODO(dims): add more tests for copy_virtual_disk after
            # the disk/image code in spawn gets refactored
            mock_copy_virtual_disk.assert_called_with(self._session,
                                                      dc_ref,
                                                      source_file,
                                                      dest_file)

            if config_drive:
                mock_configure_config_drive.assert_called_once_with(
                    self._instance, 'fake_vm_ref', self._dc_info,
                    self._ds, 'fake_files', 'password', network_info)
            mock_update_vnic_index.assert_called_once_with(
                self._context, self._instance, network_info)