@@ -377,6 +377,48 @@ def test_detach_device_with_retry_first_detach_device_missing(self):
377
377
error_message = "device not found: disk vdb not found" ,
378
378
supports_device_missing = True )
379
379
380
+ def test_detach_device_with_already_in_process_of_unplug_error (self ):
381
+ # Assert that DeviceNotFound is raised when encountering
382
+ # https://bugzilla.redhat.com/show_bug.cgi?id=1878659
383
+ # This is raised as QEMU returns a VIR_ERR_INTERNAL_ERROR when
384
+ # a request to device_del is made while another is about to complete.
385
+
386
+ self .domain .isPersistent .return_value = True
387
+ conf = mock .Mock (spec = vconfig .LibvirtConfigGuestDevice )
388
+ conf .to_xml .return_value = "</xml>"
389
+
390
+ existing_unplug_exc = fakelibvirt .make_libvirtError (
391
+ fakelibvirt .libvirtError , "" ,
392
+ error_message = 'device vdb is already in the process of unplug' ,
393
+ error_code = fakelibvirt .VIR_ERR_INTERNAL_ERROR ,
394
+ error_domain = fakelibvirt .VIR_FROM_DOMAIN
395
+ )
396
+ device_missing_exc = fakelibvirt .make_libvirtError (
397
+ fakelibvirt .libvirtError , "" ,
398
+ error_message = 'device not found: disk vdb not found' ,
399
+ error_code = fakelibvirt .VIR_ERR_DEVICE_MISSING ,
400
+ error_domain = fakelibvirt .VIR_FROM_DOMAIN
401
+ )
402
+
403
+ # Raise VIR_ERR_INTERNAL_ERROR on the second call before raising
404
+ # VIR_ERR_DEVICE_MISSING to mock the first call successfully detaching
405
+ # the device asynchronously.
406
+ self .domain .detachDeviceFlags .side_effect = [
407
+ None ,
408
+ existing_unplug_exc ,
409
+ device_missing_exc
410
+ ]
411
+
412
+ retry_detach = self .guest .detach_device_with_retry (
413
+ mock .Mock (return_value = conf ),
414
+ 'vdb' ,
415
+ live = True ,
416
+ inc_sleep_time = .01
417
+ )
418
+
419
+ # Assert that we raise exception.DeviceNotFound
420
+ self .assertRaises (exception .DeviceNotFound , retry_detach )
421
+
380
422
def test_get_xml_desc (self ):
381
423
self .guest .get_xml_desc ()
382
424
self .domain .XMLDesc .assert_called_once_with (flags = 0 )
0 commit comments