def _save_device_metadata(self, context, instance, block_device_info): """Builds a metadata object for instance devices, that maps the user provided tag to the hypervisor assigned device address. """ metadata = [] metadata.extend(self._get_vif_metadata(context, instance.uuid)) if block_device_info: metadata.extend(self._block_dev_man.get_bdm_metadata( context, instance, block_device_info)) if metadata: instance.device_metadata = objects.InstanceDeviceMetadata( devices=metadata)
class _VirtDriverTestCase(_FakeDriverBackendTestCase): def setUp(self): super(_VirtDriverTestCase, self).setUp() self.flags(instances_path=self.useFixture(fixtures.TempDir()).path) self.connection = importutils.import_object(self.driver_module, fake.FakeVirtAPI()) self.ctxt = test_utils.get_test_admin_context() self.image_service = fake_image.FakeImageService() # NOTE(dripton): resolve_driver_format does some file reading and # writing and chowning that complicate testing too much by requiring # using real directories with proper permissions. Just stub it out # here; we test it in test_imagebackend.py self.stub_out( 'nova.virt.libvirt.imagebackend.Image.' 'resolve_driver_format', imagebackend.Image._get_driver_format) os_vif.initialize() def _get_running_instance(self, obj=True): instance_ref = test_utils.get_test_instance(obj=obj) network_info = test_utils.get_test_network_info() network_info[0]['network']['subnets'][0]['meta']['dhcp_server'] = \ '1.1.1.1' image_meta = test_utils.get_test_image_object(None, instance_ref) self.connection.spawn(self.ctxt, instance_ref, image_meta, [], 'herp', {}, network_info=network_info) return instance_ref, network_info @catch_notimplementederror def test_init_host(self): self.connection.init_host('myhostname') @catch_notimplementederror def test_list_instances(self): self.connection.list_instances() @catch_notimplementederror def test_list_instance_uuids(self): self.connection.list_instance_uuids() @catch_notimplementederror def test_spawn(self): instance_ref, network_info = self._get_running_instance() domains = self.connection.list_instances() self.assertIn(instance_ref['name'], domains) num_instances = self.connection.get_num_instances() self.assertEqual(1, num_instances) @catch_notimplementederror def test_snapshot_not_running(self): instance_ref = test_utils.get_test_instance() img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'}) self.assertRaises(exception.InstanceNotRunning, self.connection.snapshot, self.ctxt, instance_ref, img_ref['id'], lambda *args, **kwargs: None) @catch_notimplementederror def test_snapshot_running(self): img_ref = self.image_service.create(self.ctxt, {'name': 'snap-1'}) instance_ref, network_info = self._get_running_instance() self.connection.snapshot(self.ctxt, instance_ref, img_ref['id'], lambda *args, **kwargs: None) @catch_notimplementederror def test_post_interrupted_snapshot_cleanup(self): instance_ref, network_info = self._get_running_instance() self.connection.post_interrupted_snapshot_cleanup( self.ctxt, instance_ref) @catch_notimplementederror def test_reboot(self): reboot_type = "SOFT" instance_ref, network_info = self._get_running_instance() self.connection.reboot(self.ctxt, instance_ref, network_info, reboot_type) @catch_notimplementederror def test_get_host_ip_addr(self): host_ip = self.connection.get_host_ip_addr() # Will raise an exception if it's not a valid IP at all ip = netaddr.IPAddress(host_ip) # For now, assume IPv4. self.assertEqual(ip.version, 4) @catch_notimplementederror def test_set_admin_password(self): instance, network_info = self._get_running_instance(obj=True) self.connection.set_admin_password(instance, 'p4ssw0rd') @catch_notimplementederror def test_inject_file(self): instance_ref, network_info = self._get_running_instance() self.connection.inject_file(instance_ref, base64.b64encode(b'/testfile'), base64.b64encode(b'testcontents')) @catch_notimplementederror def test_resume_state_on_host_boot(self): instance_ref, network_info = self._get_running_instance() self.connection.resume_state_on_host_boot(self.ctxt, instance_ref, network_info) @catch_notimplementederror def test_rescue(self): image_meta = objects.ImageMeta.from_dict({}) instance_ref, network_info = self._get_running_instance() self.connection.rescue(self.ctxt, instance_ref, network_info, image_meta, '') @catch_notimplementederror @mock.patch('os.unlink') @mock.patch('nova.virt.libvirt.utils.load_file', return_value='') def test_unrescue_unrescued_instance(self, mock_load_file, mock_unlink): instance_ref, network_info = self._get_running_instance() self.connection.unrescue(instance_ref, network_info) @catch_notimplementederror @mock.patch('os.unlink') def test_unrescue_rescued_instance(self, mock_unlink): image_meta = objects.ImageMeta.from_dict({}) instance_ref, network_info = self._get_running_instance() self.connection.rescue(self.ctxt, instance_ref, network_info, image_meta, '') self.connection.unrescue(instance_ref, network_info) @catch_notimplementederror def test_poll_rebooting_instances(self): instances = [self._get_running_instance()] self.connection.poll_rebooting_instances(10, instances) @catch_notimplementederror def test_migrate_disk_and_power_off(self): instance_ref, network_info = self._get_running_instance() flavor_ref = test_utils.get_test_flavor() self.connection.migrate_disk_and_power_off(self.ctxt, instance_ref, 'dest_host', flavor_ref, network_info) @catch_notimplementederror def test_power_off(self): instance_ref, network_info = self._get_running_instance() self.connection.power_off(instance_ref) @catch_notimplementederror def test_power_on_running(self): instance_ref, network_info = self._get_running_instance() self.connection.power_on(self.ctxt, instance_ref, network_info, None) @catch_notimplementederror def test_power_on_powered_off(self): instance_ref, network_info = self._get_running_instance() self.connection.power_off(instance_ref) self.connection.power_on(self.ctxt, instance_ref, network_info, None) @catch_notimplementederror def test_trigger_crash_dump(self): instance_ref, network_info = self._get_running_instance() self.connection.trigger_crash_dump(instance_ref) @catch_notimplementederror def test_soft_delete(self): instance_ref, network_info = self._get_running_instance(obj=True) self.connection.soft_delete(instance_ref) @catch_notimplementederror def test_restore_running(self): instance_ref, network_info = self._get_running_instance() self.connection.restore(instance_ref) @catch_notimplementederror def test_restore_soft_deleted(self): instance_ref, network_info = self._get_running_instance() self.connection.soft_delete(instance_ref) self.connection.restore(instance_ref) @catch_notimplementederror def test_pause(self): instance_ref, network_info = self._get_running_instance() self.connection.pause(instance_ref) @catch_notimplementederror def test_unpause_unpaused_instance(self): instance_ref, network_info = self._get_running_instance() self.connection.unpause(instance_ref) @catch_notimplementederror def test_unpause_paused_instance(self): instance_ref, network_info = self._get_running_instance() self.connection.pause(instance_ref) self.connection.unpause(instance_ref) @catch_notimplementederror def test_suspend(self): instance_ref, network_info = self._get_running_instance() self.connection.suspend(self.ctxt, instance_ref) @catch_notimplementederror def test_resume_unsuspended_instance(self): instance_ref, network_info = self._get_running_instance() self.connection.resume(self.ctxt, instance_ref, network_info) @catch_notimplementederror def test_resume_suspended_instance(self): instance_ref, network_info = self._get_running_instance() self.connection.suspend(self.ctxt, instance_ref) self.connection.resume(self.ctxt, instance_ref, network_info) @catch_notimplementederror def test_destroy_instance_nonexistent(self): fake_instance = test_utils.get_test_instance(obj=True) network_info = test_utils.get_test_network_info() self.connection.destroy(self.ctxt, fake_instance, network_info) @catch_notimplementederror def test_destroy_instance(self): instance_ref, network_info = self._get_running_instance() self.assertIn(instance_ref['name'], self.connection.list_instances()) self.connection.destroy(self.ctxt, instance_ref, network_info) self.assertNotIn(instance_ref['name'], self.connection.list_instances()) @catch_notimplementederror def test_get_volume_connector(self): result = self.connection.get_volume_connector({'id': 'fake'}) self.assertIn('ip', result) self.assertIn('initiator', result) self.assertIn('host', result) return result @catch_notimplementederror def test_get_volume_connector_storage_ip(self): ip = 'my_ip' storage_ip = 'storage_ip' self.flags(my_block_storage_ip=storage_ip, my_ip=ip) result = self.connection.get_volume_connector({'id': 'fake'}) self.assertIn('ip', result) self.assertIn('initiator', result) self.assertIn('host', result) self.assertEqual(storage_ip, result['ip']) @catch_notimplementederror @mock.patch.object(libvirt.driver.LibvirtDriver, '_build_device_metadata', return_value=objects.InstanceDeviceMetadata()) def test_attach_detach_volume(self, _): instance_ref, network_info = self._get_running_instance() connection_info = { "driver_volume_type": "fake", "serial": "fake_serial", "data": {} } self.assertIsNone( self.connection.attach_volume(None, connection_info, instance_ref, '/dev/sda')) self.assertIsNone( self.connection.detach_volume(mock.sentinel.context, connection_info, instance_ref, '/dev/sda')) @catch_notimplementederror @mock.patch.object(libvirt.driver.LibvirtDriver, '_build_device_metadata', return_value=objects.InstanceDeviceMetadata()) def test_swap_volume(self, _): instance_ref, network_info = self._get_running_instance() self.assertIsNone( self.connection.attach_volume(None, { 'driver_volume_type': 'fake', 'data': {} }, instance_ref, '/dev/sda')) self.assertIsNone( self.connection.swap_volume(None, { 'driver_volume_type': 'fake', 'data': {} }, { 'driver_volume_type': 'fake', 'data': {} }, instance_ref, '/dev/sda', 2)) @catch_notimplementederror @mock.patch.object(libvirt.driver.LibvirtDriver, '_build_device_metadata', return_value=objects.InstanceDeviceMetadata()) def test_attach_detach_different_power_states(self, _): instance_ref, network_info = self._get_running_instance() connection_info = { "driver_volume_type": "fake", "serial": "fake_serial", "data": {} } self.connection.power_off(instance_ref) self.connection.attach_volume(None, connection_info, instance_ref, '/dev/sda') bdm = { 'root_device_name': None, 'swap': None, 'ephemerals': [], 'block_device_mapping': driver_block_device.convert_volumes([ objects.BlockDeviceMapping( self.ctxt, **fake_block_device.FakeDbBlockDeviceDict({ 'id': 1, 'instance_uuid': instance_ref['uuid'], 'device_name': '/dev/sda', 'source_type': 'volume', 'destination_type': 'volume', 'delete_on_termination': False, 'snapshot_id': None, 'volume_id': 'abcdedf', 'volume_size': None, 'no_device': None })), ]) } bdm['block_device_mapping'][0]['connection_info'] = ({ 'driver_volume_type': 'fake', 'data': {} }) with mock.patch.object(driver_block_device.DriverVolumeBlockDevice, 'save'): self.connection.power_on(self.ctxt, instance_ref, network_info, bdm) self.connection.detach_volume(mock.sentinel.context, connection_info, instance_ref, '/dev/sda') @catch_notimplementederror def test_get_info(self): instance_ref, network_info = self._get_running_instance() info = self.connection.get_info(instance_ref) self.assertIsInstance(info, hardware.InstanceInfo) @catch_notimplementederror def test_get_info_for_unknown_instance(self): fake_instance = test_utils.get_test_instance(obj=True) self.assertRaises(exception.NotFound, self.connection.get_info, fake_instance) @catch_notimplementederror def test_get_diagnostics(self): instance_ref, network_info = self._get_running_instance(obj=True) self.connection.get_diagnostics(instance_ref) @catch_notimplementederror def test_get_instance_diagnostics(self): instance_ref, network_info = self._get_running_instance(obj=True) instance_ref['launched_at'] = timeutils.utcnow() self.connection.get_instance_diagnostics(instance_ref) @catch_notimplementederror def test_block_stats(self): instance_ref, network_info = self._get_running_instance() stats = self.connection.block_stats(instance_ref, 'someid') self.assertEqual(len(stats), 5) @catch_notimplementederror def test_get_console_output(self): instance_ref, network_info = self._get_running_instance() console_output = self.connection.get_console_output( self.ctxt, instance_ref) self.assertIsInstance(console_output, six.string_types) @catch_notimplementederror def test_get_vnc_console(self): instance, network_info = self._get_running_instance(obj=True) vnc_console = self.connection.get_vnc_console(self.ctxt, instance) self.assertIsInstance(vnc_console, ctype.ConsoleVNC) @catch_notimplementederror def test_get_spice_console(self): instance_ref, network_info = self._get_running_instance() spice_console = self.connection.get_spice_console( self.ctxt, instance_ref) self.assertIsInstance(spice_console, ctype.ConsoleSpice) @catch_notimplementederror def test_get_rdp_console(self): instance_ref, network_info = self._get_running_instance() rdp_console = self.connection.get_rdp_console(self.ctxt, instance_ref) self.assertIsInstance(rdp_console, ctype.ConsoleRDP) @catch_notimplementederror def test_get_serial_console(self): instance_ref, network_info = self._get_running_instance() serial_console = self.connection.get_serial_console( self.ctxt, instance_ref) self.assertIsInstance(serial_console, ctype.ConsoleSerial) @catch_notimplementederror def test_get_mks_console(self): instance_ref, network_info = self._get_running_instance() mks_console = self.connection.get_mks_console(self.ctxt, instance_ref) self.assertIsInstance(mks_console, ctype.ConsoleMKS) @catch_notimplementederror def test_get_console_pool_info(self): instance_ref, network_info = self._get_running_instance() console_pool = self.connection.get_console_pool_info(instance_ref) self.assertIn('address', console_pool) self.assertIn('username', console_pool) self.assertIn('password', console_pool) @catch_notimplementederror def test_refresh_security_group_rules(self): # FIXME: Create security group and add the instance to it instance_ref, network_info = self._get_running_instance() self.connection.refresh_security_group_rules(1) @catch_notimplementederror def test_refresh_instance_security_rules(self): # FIXME: Create security group and add the instance to it instance_ref, network_info = self._get_running_instance() self.connection.refresh_instance_security_rules(instance_ref) @catch_notimplementederror def test_ensure_filtering_for_instance(self): instance = test_utils.get_test_instance(obj=True) network_info = test_utils.get_test_network_info() self.connection.ensure_filtering_rules_for_instance( instance, network_info) @catch_notimplementederror def test_unfilter_instance(self): instance_ref = test_utils.get_test_instance() network_info = test_utils.get_test_network_info() self.connection.unfilter_instance(instance_ref, network_info) def test_live_migration(self): instance_ref, network_info = self._get_running_instance() fake_context = context.RequestContext('fake', 'fake') migration = objects.Migration(context=fake_context, id=1) migrate_data = objects.LibvirtLiveMigrateData( migration=migration, bdms=[], block_migration=False, serial_listen_addr='127.0.0.1') self.connection.live_migration(self.ctxt, instance_ref, 'otherhost', lambda *a, **b: None, lambda *a, **b: None, migrate_data=migrate_data) @catch_notimplementederror def test_live_migration_force_complete(self): instance_ref, network_info = self._get_running_instance() self.connection.active_migrations[instance_ref.uuid] = deque() self.connection.live_migration_force_complete(instance_ref) @catch_notimplementederror def test_live_migration_abort(self): instance_ref, network_info = self._get_running_instance() self.connection.live_migration_abort(instance_ref) @catch_notimplementederror def _check_available_resource_fields(self, host_status): keys = [ 'vcpus', 'memory_mb', 'local_gb', 'vcpus_used', 'memory_mb_used', 'hypervisor_type', 'hypervisor_version', 'hypervisor_hostname', 'cpu_info', 'disk_available_least', 'supported_instances' ] for key in keys: self.assertIn(key, host_status) self.assertIsInstance(host_status['hypervisor_version'], int) @catch_notimplementederror def test_get_available_resource(self): available_resource = self.connection.get_available_resource( 'myhostname') self._check_available_resource_fields(available_resource) @catch_notimplementederror def test_get_available_nodes(self): self.connection.get_available_nodes(False) @catch_notimplementederror def _check_host_cpu_status_fields(self, host_cpu_status): self.assertIn('kernel', host_cpu_status) self.assertIn('idle', host_cpu_status) self.assertIn('user', host_cpu_status) self.assertIn('iowait', host_cpu_status) self.assertIn('frequency', host_cpu_status) @catch_notimplementederror def test_get_host_cpu_stats(self): host_cpu_status = self.connection.get_host_cpu_stats() self._check_host_cpu_status_fields(host_cpu_status) @catch_notimplementederror def test_set_host_enabled(self): self.connection.set_host_enabled(True) @catch_notimplementederror def test_get_host_uptime(self): self.connection.get_host_uptime() @catch_notimplementederror def test_host_power_action_reboot(self): self.connection.host_power_action('reboot') @catch_notimplementederror def test_host_power_action_shutdown(self): self.connection.host_power_action('shutdown') @catch_notimplementederror def test_host_power_action_startup(self): self.connection.host_power_action('startup') @catch_notimplementederror def test_add_to_aggregate(self): self.connection.add_to_aggregate(self.ctxt, 'aggregate', 'host') @catch_notimplementederror def test_remove_from_aggregate(self): self.connection.remove_from_aggregate(self.ctxt, 'aggregate', 'host') def test_events(self): got_events = [] def handler(event): got_events.append(event) self.connection.register_event_listener(handler) event1 = virtevent.LifecycleEvent( "cef19ce0-0ca2-11df-855d-b19fbce37686", virtevent.EVENT_LIFECYCLE_STARTED) event2 = virtevent.LifecycleEvent( "cef19ce0-0ca2-11df-855d-b19fbce37686", virtevent.EVENT_LIFECYCLE_PAUSED) self.connection.emit_event(event1) self.connection.emit_event(event2) want_events = [event1, event2] self.assertEqual(want_events, got_events) event3 = virtevent.LifecycleEvent( "cef19ce0-0ca2-11df-855d-b19fbce37686", virtevent.EVENT_LIFECYCLE_RESUMED) event4 = virtevent.LifecycleEvent( "cef19ce0-0ca2-11df-855d-b19fbce37686", virtevent.EVENT_LIFECYCLE_STOPPED) self.connection.emit_event(event3) self.connection.emit_event(event4) want_events = [event1, event2, event3, event4] self.assertEqual(want_events, got_events) def test_event_bad_object(self): # Passing in something which does not inherit # from virtevent.Event def handler(event): pass self.connection.register_event_listener(handler) badevent = {"foo": "bar"} self.assertRaises(ValueError, self.connection.emit_event, badevent) def test_event_bad_callback(self): # Check that if a callback raises an exception, # it does not propagate back out of the # 'emit_event' call def handler(event): raise Exception("Hit Me!") self.connection.register_event_listener(handler) event1 = virtevent.LifecycleEvent( "cef19ce0-0ca2-11df-855d-b19fbce37686", virtevent.EVENT_LIFECYCLE_STARTED) self.connection.emit_event(event1) def test_emit_unicode_event(self): """Tests that we do not fail on translated unicode events.""" started_event = virtevent.LifecycleEvent( "cef19ce0-0ca2-11df-855d-b19fbce37686", virtevent.EVENT_LIFECYCLE_STARTED) callback = mock.Mock() self.connection.register_event_listener(callback) with mock.patch.object(started_event, 'get_name', return_value=u'\xF0\x9F\x92\xA9'): self.connection.emit_event(started_event) callback.assert_called_once_with(started_event) def test_set_bootable(self): self.assertRaises(NotImplementedError, self.connection.set_bootable, 'instance', True) @catch_notimplementederror def test_get_instance_disk_info(self): # This should be implemented by any driver that supports live migrate. instance_ref, network_info = self._get_running_instance() self.connection.get_instance_disk_info(instance_ref, block_device_info={}) @catch_notimplementederror def test_get_device_name_for_instance(self): instance, _ = self._get_running_instance() self.connection.get_device_name_for_instance( instance, [], mock.Mock(spec=objects.BlockDeviceMapping)) def test_network_binding_host_id(self): # NOTE(jroll) self._get_running_instance calls spawn(), so we can't # use it to test this method. Make a simple object instead; we just # need instance.host. instance = objects.Instance(self.ctxt, host='somehost') self.assertEqual( instance.host, self.connection.network_binding_host_id(self.ctxt, instance)) def test_get_allocation_ratio(self): inv = {} self.flags(cpu_allocation_ratio=16.1) self.flags(ram_allocation_ratio=1.6) self.flags(disk_allocation_ratio=1.1) expeced_ratios = { orc.VCPU: CONF.cpu_allocation_ratio, orc.MEMORY_MB: CONF.ram_allocation_ratio, orc.DISK_GB: CONF.disk_allocation_ratio } # If conf is set, return conf self.assertEqual(expeced_ratios, self.connection._get_allocation_ratios(inv)) self.flags(cpu_allocation_ratio=None) self.flags(ram_allocation_ratio=None) self.flags(disk_allocation_ratio=None) self.flags(initial_cpu_allocation_ratio=15.9) self.flags(initial_ram_allocation_ratio=1.4) self.flags(initial_disk_allocation_ratio=0.9) expeced_ratios = { orc.VCPU: CONF.initial_cpu_allocation_ratio, orc.MEMORY_MB: CONF.initial_ram_allocation_ratio, orc.DISK_GB: CONF.initial_disk_allocation_ratio } # if conf is unset and inv doesn't exists, return init conf self.assertEqual(expeced_ratios, self.connection._get_allocation_ratios(inv)) inv = { orc.VCPU: { 'allocation_ratio': 3.0 }, orc.MEMORY_MB: { 'allocation_ratio': 3.1 }, orc.DISK_GB: { 'allocation_ratio': 3.2 } } expeced_ratios = { orc.VCPU: inv[orc.VCPU]['allocation_ratio'], orc.MEMORY_MB: inv[orc.MEMORY_MB]['allocation_ratio'], orc.DISK_GB: inv[orc.DISK_GB]['allocation_ratio'] } # if conf is unset and inv exists, return inv self.assertEqual(expeced_ratios, self.connection._get_allocation_ratios(inv))
# under the License. import mock from oslo_serialization import jsonutils from nova import objects from nova.tests.unit.objects import test_objects fake_net_interface_meta = objects.NetworkInterfaceMetadata( mac='52:54:00:f6:35:8f', tags=['mytag1'], bus=objects.PCIDeviceBus(address='0000:00:03.0'), vlan=1000) fake_pci_disk_meta = objects.DiskMetadata( bus=objects.PCIDeviceBus(address='0000:00:09.0'), tags=['nfvfunc3']) fake_obj_devices_metadata = objects.InstanceDeviceMetadata( devices=[fake_net_interface_meta, fake_pci_disk_meta]) fake_devices_metadata = fake_obj_devices_metadata._to_json() fake_db_metadata = { 'created_at': None, 'updated_at': None, 'deleted_at': None, 'deleted': 0, 'id': 1, 'device_metadata': fake_obj_devices_metadata._to_json() } fake_old_db_metadata = dict(fake_db_metadata) # copy fake_old_db_metadata['device_metadata'] = jsonutils.dumps( fake_devices_metadata)