def test_baseline_cpu_not_supported(self): # Handle just the NO_SUPPORT error not_supported_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, 'this function is not supported by the connection driver:' ' virConnectBaselineCPU', error_code=fakelibvirt.VIR_ERR_NO_SUPPORT) with mock.patch.object(fakelibvirt.virConnect, 'baselineCPU', side_effect=not_supported_exc): caps = self.host.get_capabilities() self.assertEqual(vconfig.LibvirtConfigCaps, type(caps)) self.assertNotIn('aes', [x.name for x in caps.host.cpu.features]) # Clear cached result so we can test again... self.host._caps = None # Other errors should not be caught other_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, 'other exc', error_code=fakelibvirt.VIR_ERR_NO_DOMAIN) with mock.patch.object(fakelibvirt.virConnect, 'baselineCPU', side_effect=other_exc): self.assertRaises(fakelibvirt.libvirtError, self.host.get_capabilities)
def test_baseline_cpu_not_supported(self): # `mock` has trouble stubbing attributes that don't exist yet, so # fallback to plain-Python attribute setting/deleting cap_str = 'VIR_CONNECT_BASELINE_CPU_EXPAND_FEATURES' if not hasattr(host.libvirt, cap_str): setattr(host.libvirt, cap_str, True) self.addCleanup(delattr, host.libvirt, cap_str) # Handle just the NO_SUPPORT error not_supported_exc = fakelibvirt.make_libvirtError( libvirt.libvirtError, 'this function is not supported by the connection driver:' ' virConnectBaselineCPU', error_code=libvirt.VIR_ERR_NO_SUPPORT) with mock.patch.object(fakelibvirt.virConnect, 'baselineCPU', side_effect=not_supported_exc): caps = self.host.get_capabilities() self.assertEqual(vconfig.LibvirtConfigCaps, type(caps)) self.assertNotIn('aes', [x.name for x in caps.host.cpu.features]) # Clear cached result so we can test again... self.host._caps = None # Other errors should not be caught other_exc = fakelibvirt.make_libvirtError( libvirt.libvirtError, 'other exc', error_code=libvirt.VIR_ERR_NO_DOMAIN) with mock.patch.object(fakelibvirt.virConnect, 'baselineCPU', side_effect=other_exc): self.assertRaises(libvirt.libvirtError, self.host.get_capabilities)
def test_job_info_no_support(self, mock_stats, mock_info): mock_stats.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "virDomainGetJobStats not implemented", fakelibvirt.VIR_ERR_NO_SUPPORT) mock_info.return_value = [ fakelibvirt.VIR_DOMAIN_JOB_UNBOUNDED, 100, 99, 10, 11, 12, 75, 50, 33, 1, 2, 3] info = self.guest.get_job_info() self.assertIsInstance(info, libvirt_guest.JobInfo) self.assertEqual(fakelibvirt.VIR_DOMAIN_JOB_UNBOUNDED, info.type) self.assertEqual(100, info.time_elapsed) self.assertEqual(99, info.time_remaining) self.assertEqual(10, info.data_total) self.assertEqual(11, info.data_processed) self.assertEqual(12, info.data_remaining) self.assertEqual(75, info.memory_total) self.assertEqual(50, info.memory_processed) self.assertEqual(33, info.memory_remaining) self.assertEqual(1, info.disk_total) self.assertEqual(2, info.disk_processed) self.assertEqual(3, info.disk_remaining) mock_stats.assert_called_once_with() mock_info.assert_called_once_with()
def test_detach_device_with_retry_invalid_argument(self): # This simulates a persistent domain detach failing because # the device is not found conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "</xml>" self.domain.isPersistent.return_value = True get_config = mock.Mock() # Simulate the persistent domain attach attempt followed by the live # domain attach attempt and success get_config.side_effect = [conf, conf, conf, None, None] fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "", error_message="invalid argument: no target device vdb", error_code=fakelibvirt.VIR_ERR_INVALID_ARG, error_domain=fakelibvirt.VIR_FROM_DOMAIN) # Detach from persistent raises not found, detach from live succeeds self.domain.detachDeviceFlags.side_effect = [fake_exc, None] retry_detach = self.guest.detach_device_with_retry(get_config, fake_device, live=True, inc_sleep_time=.01, max_retry_count=3) # We should have tried to detach from the persistent domain self.domain.detachDeviceFlags.assert_called_once_with( "</xml>", flags=(fakelibvirt.VIR_DOMAIN_AFFECT_CONFIG | fakelibvirt.VIR_DOMAIN_AFFECT_LIVE)) # During the retry detach, should detach from the live domain self.domain.detachDeviceFlags.reset_mock() retry_detach() # We should have tried to detach from the live domain self.domain.detachDeviceFlags.assert_called_once_with( "</xml>", flags=fakelibvirt.VIR_DOMAIN_AFFECT_LIVE)
def test_list_devices_unsupported(self, mock_listDevices): not_supported_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, 'this function is not supported by the connection driver:' ' listDevices', error_code=fakelibvirt.VIR_ERR_NO_SUPPORT) mock_listDevices.side_effect = not_supported_exc self.assertEqual([], self.host._list_devices('mdev', 8))
def test_live_migration_find_type_no_domain(self, mock_active): mock_active.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "No domain with ID", error_code=fakelibvirt.VIR_ERR_NO_DOMAIN) self.assertEqual(migration.find_job_type(self.guest, self.instance), fakelibvirt.VIR_DOMAIN_JOB_COMPLETED)
def test_live_migration_find_type_bad_err(self, mock_active): mock_active.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "Something weird happened", error_code=fakelibvirt.VIR_ERR_INTERNAL_ERROR) self.assertEqual(migration.find_job_type(self.guest, self.instance), fakelibvirt.VIR_DOMAIN_JOB_FAILED)
def test_job_info_no_domain(self, mock_stats, mock_info): mock_stats.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "virDomainGetJobStats not implemented", fakelibvirt.VIR_ERR_NO_SUPPORT) mock_info.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "No such domain with UUID blah", fakelibvirt.VIR_ERR_NO_DOMAIN) info = self.guest.get_job_info() self.assertIsInstance(info, libvirt_guest.JobInfo) self.assertEqual(fakelibvirt.VIR_DOMAIN_JOB_COMPLETED, info.type) self.assertEqual(0, info.time_elapsed) self.assertEqual(0, info.time_remaining) self.assertEqual(0, info.memory_total) self.assertEqual(0, info.memory_processed) self.assertEqual(0, info.memory_remaining) mock_stats.assert_called_once_with() mock_info.assert_called_once_with()
def test_job_info_operation_invalid(self, mock_stats, mock_info): mock_stats.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "virDomainGetJobStats not implemented", fakelibvirt.VIR_ERR_NO_SUPPORT) mock_info.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "Domain is not running", fakelibvirt.VIR_ERR_OPERATION_INVALID) info = self.guest.get_job_info() self.assertIsInstance(info, libvirt_guest.JobInfo) self.assertEqual(fakelibvirt.VIR_DOMAIN_JOB_COMPLETED, info.type) self.assertEqual(0, info.time_elapsed) self.assertEqual(0, info.time_remaining) self.assertEqual(0, info.memory_total) self.assertEqual(0, info.memory_processed) self.assertEqual(0, info.memory_remaining) mock_stats.assert_called_once_with() mock_info.assert_called_once_with()
def _test_detach_device_with_retry_first_detach_failure( self, error_code=None, error_message=None, supports_device_missing=False): # This simulates a persistent or live domain detach failing because the # device is not found during the first attempt to detach the device. # We should still attempt to detach the device from the live config if # the detach from persistent failed OR we should retry the detach from # the live config if the first detach from live config failed. # Note that the side effects in this test case [fake_exc, None] could # not happen in real life if the first detach failed because the detach # from live raised not found. In real life, the second attempt to # detach from live would raise not found again because the device is # not present. The purpose of this test is to verify that we try to # detach a second time if the first detach fails, so we are OK with the # unrealistic side effects for detach from live failing the first time. conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "</xml>" self.domain.isPersistent.return_value = True get_config = mock.Mock() # Simulate an inactive or live detach attempt which fails (not found) # followed by a live config detach attempt that is successful get_config.side_effect = [conf, conf, conf, None, None] fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "", error_message=error_message, error_code=error_code, error_domain=fakelibvirt.VIR_FROM_DOMAIN) # Detach from persistent or live raises not found, detach from live # succeeds afterward self.domain.detachDeviceFlags.side_effect = [fake_exc, None] retry_detach = self.guest.detach_device_with_retry( get_config, fake_device, live=True, inc_sleep_time=.01, max_retry_count=3, supports_device_missing_error_code=supports_device_missing) # We should have tried to detach from the persistent domain self.domain.detachDeviceFlags.assert_called_once_with( "</xml>", flags=(fakelibvirt.VIR_DOMAIN_AFFECT_CONFIG | fakelibvirt.VIR_DOMAIN_AFFECT_LIVE)) # During the retry detach, should detach from the live domain self.domain.detachDeviceFlags.reset_mock() retry_detach() # We should have tried to detach from the live domain self.domain.detachDeviceFlags.assert_called_once_with( "</xml>", flags=fakelibvirt.VIR_DOMAIN_AFFECT_LIVE)
def test_get_domain_by_name_raises(self, fake_lookup): fake_lookup.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, 'Domain not found: no domain with matching name', error_code=fakelibvirt.VIR_ERR_NO_DOMAIN, error_domain=fakelibvirt.VIR_FROM_QEMU) self.assertRaises(exception.InstanceNotFound, self.host._get_domain_by_name, "wibble") fake_lookup.assert_called_once_with("wibble")
def test_get_domain_by_name_raises(self, fake_lookup): fake_lookup.side_effect = fakelibvirt.make_libvirtError( libvirt.libvirtError, 'Domain not found: no domain with matching name', error_code=libvirt.VIR_ERR_NO_DOMAIN, error_domain=libvirt.VIR_FROM_QEMU) self.assertRaises(exception.InstanceNotFound, self.host._get_domain_by_name, "wibble") fake_lookup.assert_called_once_with("wibble")
def test_get_domain_raises(self, fake_lookup): instance = objects.Instance(uuid=uuids.instance, vm_state=vm_states.ACTIVE) fake_lookup.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, 'Domain not found: no domain with matching name', error_code=fakelibvirt.VIR_ERR_NO_DOMAIN, error_domain=fakelibvirt.VIR_FROM_QEMU) with testtools.ExpectedException(exception.InstanceNotFound): self.host._get_domain(instance) fake_lookup.assert_called_once_with(uuids.instance)
def test_broken_connection(self, mock_ver): for (error, domain) in ( (libvirt.VIR_ERR_SYSTEM_ERROR, libvirt.VIR_FROM_REMOTE), (libvirt.VIR_ERR_SYSTEM_ERROR, libvirt.VIR_FROM_RPC), (libvirt.VIR_ERR_INTERNAL_ERROR, libvirt.VIR_FROM_RPC)): conn = self.host._connect("qemu:///system", False) mock_ver.side_effect = fakelibvirt.make_libvirtError( libvirt.libvirtError, "Connection broken", error_code=error, error_domain=domain) self.assertFalse(self.host._test_connection(conn))
def test_live_migration_update_downtime_err(self, mock_dt): steps = [ (9000, 50), (18000, 200), ] mock_dt.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "Failed to set downtime", error_code=fakelibvirt.VIR_ERR_INTERNAL_ERROR) newdt = migration.update_downtime(self.guest, self.instance, 50, steps, 22000) self.assertEqual(newdt, 200) mock_dt.assert_called_once_with(200)
def test_detach_device_with_retry_invalid_argument(self, mock_detach): # This simulates a persistent domain detach failing because # the device is not found conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "</xml>" get_config = mock.Mock(return_value=conf) fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "", error_message="invalid argument: no target device vdb", error_code=fakelibvirt.VIR_ERR_INVALID_ARG, error_domain=fakelibvirt.VIR_FROM_DOMAIN) mock_detach.side_effect = fake_exc self.assertRaises(exception.DeviceNotFound, self.guest.detach_device_with_retry, get_config, fake_device, persistent=True, live=True, inc_sleep_time=.01, max_retry_count=3)
def test_job_stats_no_domain(self, mock_stats, mock_info): mock_stats.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "No such domain with UUID blah", fakelibvirt.VIR_ERR_NO_DOMAIN) info = host.DomainJobInfo.for_domain(self.dom) self.assertIsInstance(info, host.DomainJobInfo) self.assertEqual(fakelibvirt.VIR_DOMAIN_JOB_COMPLETED, info.type) self.assertEqual(0, info.time_elapsed) self.assertEqual(0, info.time_remaining) self.assertEqual(0, info.memory_total) self.assertEqual(0, info.memory_processed) self.assertEqual(0, info.memory_remaining) mock_stats.assert_called_once_with() self.assertFalse(mock_info.called)
def test_job_stats_operation_invalid(self, mock_stats, mock_info): mock_stats.side_effect = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "Domain is not running", fakelibvirt.VIR_ERR_OPERATION_INVALID) info = host.DomainJobInfo.for_domain(self.dom) self.assertIsInstance(info, host.DomainJobInfo) self.assertEqual(fakelibvirt.VIR_DOMAIN_JOB_COMPLETED, info.type) self.assertEqual(0, info.time_elapsed) self.assertEqual(0, info.time_remaining) self.assertEqual(0, info.memory_total) self.assertEqual(0, info.memory_processed) self.assertEqual(0, info.memory_remaining) mock_stats.assert_called_once_with() self.assertFalse(mock_info.called)
def test_detach_device_with_retry_operation_failed(self, mock_detach): conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "</xml>" get_config = mock.Mock(return_value=conf) fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, msg="invalid argument: no target device vdb", error_code=fakelibvirt.VIR_ERR_OPERATION_FAILED, error_message="disk vdb not found", error_domain=fakelibvirt.VIR_FROM_DOMAIN) mock_detach.side_effect = [None, fake_exc] retry_detach = self.guest.detach_device_with_retry( get_config, fake_device, persistent=True, live=True, inc_sleep_time=.01, max_retry_count=3) # Some time later, we can do the wait/retry to ensure detach self.domain.detachDeviceFlags.reset_mock() self.assertRaises(exception.DeviceNotFound, retry_detach)
def test_detach_device_with_retry_operation_failed(self, mock_detach): # This simulates a retry of the transient/live domain detach # failing because the device is not found conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "</xml>" get_config = mock.Mock(return_value=conf) fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "", error_message="operation failed: disk vdb not found", error_code=fakelibvirt.VIR_ERR_OPERATION_FAILED, error_domain=fakelibvirt.VIR_FROM_DOMAIN) mock_detach.side_effect = [None, fake_exc] retry_detach = self.guest.detach_device_with_retry( get_config, fake_device, persistent=True, live=True, inc_sleep_time=.01, max_retry_count=3) # Some time later, we can do the wait/retry to ensure detach self.assertRaises(exception.DeviceNotFound, retry_detach)
def test_broken_connection(self): for (error, domain) in ( (libvirt.VIR_ERR_SYSTEM_ERROR, libvirt.VIR_FROM_REMOTE), (libvirt.VIR_ERR_SYSTEM_ERROR, libvirt.VIR_FROM_RPC), (libvirt.VIR_ERR_INTERNAL_ERROR, libvirt.VIR_FROM_RPC)): conn = fakelibvirt.Connection("qemu:///system") hostimpl = host.Host("qemu:///system") with contextlib.nested( mock.patch.object( hostimpl, "_connect", return_value=conn), mock.patch.object( conn, "getLibVersion", side_effect=fakelibvirt.make_libvirtError( libvirt.libvirtError, "Connection broken", error_code=error, error_domain=domain))): self.assertFalse(hostimpl._test_connection(conn))
def test_detach_device_with_retry_operation_failed(self, mock_detach): # This simulates a retry of the transient/live domain detach # failing because the device is not found conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "</xml>" self.domain.isPersistent.return_value = True get_config = mock.Mock(return_value=conf) fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "", error_message="operation failed: disk vdb not found", error_code=fakelibvirt.VIR_ERR_OPERATION_FAILED, error_domain=fakelibvirt.VIR_FROM_DOMAIN) mock_detach.side_effect = [None, fake_exc] retry_detach = self.guest.detach_device_with_retry( get_config, fake_device, live=True, inc_sleep_time=.01, max_retry_count=3) # Some time later, we can do the wait/retry to ensure detach self.assertRaises(exception.DeviceNotFound, retry_detach)
def test_get_domain_info(self, mock_has_min_version): test_host = host.Host("qemu:///system") domain = mock.MagicMock() expected = [power_state.RUNNING, 512, 512, None, None] race = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, 'ERR', error_code=fakelibvirt.VIR_ERR_OPERATION_FAILED, error_message='cannot read cputime for domain') mock_has_min_version.return_value = True domain.info.return_value = expected actual = compat.get_domain_info(fakelibvirt, test_host, domain) self.assertEqual(actual, expected) self.assertEqual(domain.info.call_count, 1) domain.info.reset_mock() domain.info.side_effect = race self.assertRaises(fakelibvirt.libvirtError, compat.get_domain_info, fakelibvirt, test_host, domain) self.assertEqual(domain.info.call_count, 1) domain.info.reset_mock() mock_has_min_version.return_value = False domain.info.side_effect = [race, expected] actual = compat.get_domain_info(fakelibvirt, test_host, domain) self.assertEqual(actual, expected) self.assertEqual(domain.info.call_count, 2) domain.info.reset_mock() domain.info.side_effect = race self.assertRaises(fakelibvirt.libvirtError, compat.get_domain_info, fakelibvirt, test_host, domain) self.assertEqual(domain.info.call_count, 2)
def test_detach_device_with_retry_invalid_argument(self): # This simulates a persistent domain detach failing because # the device is not found conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "</xml>" self.domain.isPersistent.return_value = True self.domain.info.return_value = (1, 2, 3, 4, 5) get_config = mock.Mock() # Simulate the persistent domain attach attempt followed by the live # domain attach attempt and success get_config.side_effect = [conf, conf, None] fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "", error_message="invalid argument: no target device vdb", error_code=fakelibvirt.VIR_ERR_INVALID_ARG, error_domain=fakelibvirt.VIR_FROM_DOMAIN) # Detach from persistent raises not found, detach from live succeeds self.domain.detachDeviceFlags.side_effect = [fake_exc, None] retry_detach = self.guest.detach_device_with_retry(get_config, fake_device, self.host, inc_sleep_time=.01, max_retry_count=3) # We should have tried to detach from the persistent domain self.domain.detachDeviceFlags.assert_called_once_with( "</xml>", flags=(fakelibvirt.VIR_DOMAIN_AFFECT_CONFIG | fakelibvirt.VIR_DOMAIN_AFFECT_LIVE)) # During the retry detach, should detach from the live domain self.domain.detachDeviceFlags.reset_mock() retry_detach() # We should have tried to detach from the live domain self.domain.detachDeviceFlags.assert_called_once_with( "</xml>", flags=fakelibvirt.VIR_DOMAIN_AFFECT_LIVE)
def test_detach_device_with_retry_invalid_argument_no_live(self): # This simulates a persistent domain detach failing because # the device is not found conf = mock.Mock(spec=vconfig.LibvirtConfigGuestDevice) conf.to_xml.return_value = "</xml>" self.domain.isPersistent.return_value = True get_config = mock.Mock() # Simulate the persistent domain attach attempt get_config.return_value = conf fake_device = "vdb" fake_exc = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "", error_message="invalid argument: no target device vdb", error_code=fakelibvirt.VIR_ERR_INVALID_ARG, error_domain=fakelibvirt.VIR_FROM_DOMAIN) # Detach from persistent raises not found self.domain.detachDeviceFlags.side_effect = fake_exc self.assertRaises(exception.DeviceNotFound, self.guest.detach_device_with_retry, get_config, fake_device, live=False, inc_sleep_time=.01, max_retry_count=3) # We should have tried to detach from the persistent domain self.domain.detachDeviceFlags.assert_called_once_with( "</xml>", flags=fakelibvirt.VIR_DOMAIN_AFFECT_CONFIG)
def fake_list_all(flags): ex = fakelibvirt.make_libvirtError( libvirt.libvirtError, "API is not supported", error_code=libvirt.VIR_ERR_NO_SUPPORT) raise ex
def fake_list_all(flags): ex = fakelibvirt.make_libvirtError( fakelibvirt.libvirtError, "API is not supported", error_code=fakelibvirt.VIR_ERR_NO_SUPPORT) raise ex