diff --git a/nova/tests/unit/virt/libvirt/test_driver.py b/nova/tests/unit/virt/libvirt/test_driver.py index debd2c4b24..72ad73193b 100644 --- a/nova/tests/unit/virt/libvirt/test_driver.py +++ b/nova/tests/unit/virt/libvirt/test_driver.py @@ -29998,6 +29998,16 @@ class LibvirtNonblockingTestCase(test.NoDBTestCase): group='libvirt') def test_connection_to_primitive(self): + if utils.concurrency_mode_threading(): + self.skipTest( + "In threading mode nova does not use eventlet.tpool to " + "wrap the libvirt calls. This test case asserts that the " + "libvirt connection having eventlet.tpool.Proxy objects " + "are serializable. See " + "https://bugs.launchpad.net/nova/+bug/962840. " + "As Proxy object is not present in threading mode this test " + "is not valid. ") + # Test bug 962840. import nova.virt.libvirt.driver as libvirt_driver drvr = libvirt_driver.LibvirtDriver('') @@ -30007,6 +30017,13 @@ class LibvirtNonblockingTestCase(test.NoDBTestCase): @mock.patch.object(eventlet.tpool, 'execute') @mock.patch.object(objects.Service, 'get_by_compute_host') def test_tpool_execute_calls_libvirt(self, mock_svc, mock_execute): + if utils.concurrency_mode_threading(): + self.skipTest( + "In threading mode nova does not use eventlet.tpool to " + "wrap the libvirt calls. This test case asserts that libvirt " + "connect goes through the tpool, so in threading mode this " + "test case is invalid.") + conn = fakelibvirt.virConnect() conn.is_expected = True diff --git a/nova/tests/unit/virt/libvirt/test_host.py b/nova/tests/unit/virt/libvirt/test_host.py index ec80178454..417b250509 100644 --- a/nova/tests/unit/virt/libvirt/test_host.py +++ b/nova/tests/unit/virt/libvirt/test_host.py @@ -2298,6 +2298,13 @@ class TestLibvirtSEVESSupported(TestLibvirtSEV): class LibvirtTpoolProxyTestCase(test.NoDBTestCase): def setUp(self): + if utils.concurrency_mode_threading(): + self.skipTest( + "In threading mode nova does not use eventlet.tpool.Proxy to " + "wrap the libvirt calls. This test asserts that such calls " + "are returning Proxy objects. So these test cases are not " + "valid.") + super(LibvirtTpoolProxyTestCase, self).setUp() self.useFixture(nova_fixtures.LibvirtFixture()) diff --git a/nova/utils.py b/nova/utils.py index 792095dd10..41ad9388e0 100644 --- a/nova/utils.py +++ b/nova/utils.py @@ -1290,11 +1290,11 @@ def _log_executor_stats(executor): executor._delayed_work.unfinished_tasks, stats) -def tpool_wrap(target): +def tpool_wrap(target, autowrap=()): """Wrap the target into an eventlet Tpool Proxy object if running in eventlet mode. In threading mode no wrapping is applied. """ if concurrency_mode_threading(): return target else: - return tpool.Proxy(target) + return tpool.Proxy(target, autowrap=autowrap) diff --git a/nova/virt/libvirt/driver.py b/nova/virt/libvirt/driver.py index 4f51be8c1b..e28de694a5 100644 --- a/nova/virt/libvirt/driver.py +++ b/nova/virt/libvirt/driver.py @@ -48,7 +48,6 @@ import uuid from castellan import key_manager from copy import deepcopy -from eventlet import tpool from lxml import etree from os_brick import encryptors from os_brick.encryptors import luks as luks_encryptor @@ -193,24 +192,6 @@ VOLUME_DRIVERS = { } -def patch_tpool_proxy(): - """eventlet.tpool.Proxy doesn't work with old-style class in __str__() - or __repr__() calls. See bug #962840 for details. - We perform a monkey patch to replace those two instance methods. - """ - - def str_method(self): - return str(self._obj) - - def repr_method(self): - return repr(self._obj) - - tpool.Proxy.__str__ = str_method - tpool.Proxy.__repr__ = repr_method - - -patch_tpool_proxy() - # For information about when MIN_{LIBVIRT,QEMU}_VERSION and # NEXT_MIN_{LIBVIRT,QEMU}_VERSION can be changed, consult the following: # diff --git a/nova/virt/libvirt/host.py b/nova/virt/libvirt/host.py index dd366f226c..c29f883fce 100644 --- a/nova/virt/libvirt/host.py +++ b/nova/virt/libvirt/host.py @@ -41,7 +41,6 @@ import typing as ty from eventlet import greenio from eventlet import greenthread from eventlet import patcher -from eventlet import tpool from oslo_log import log as logging from oslo_serialization import jsonutils from oslo_utils import excutils @@ -195,7 +194,7 @@ class Host(object): # eventlet's event loop, starving all other greenthreads until # completion. eventlet's tpool.Proxy handles this situation for us by # executing proxied calls in a native thread. - return tpool.Proxy(obj, autowrap=self._libvirt_proxy_classes) + return utils.tpool_wrap(obj, autowrap=self._libvirt_proxy_classes) def _native_thread(self): """Receives async events coming in from libvirtd. diff --git a/threading_unit_test_excludes.txt b/threading_unit_test_excludes.txt index 4d88fcfab8..9a6f4406a9 100644 --- a/threading_unit_test_excludes.txt +++ b/threading_unit_test_excludes.txt @@ -2,9 +2,11 @@ nova.tests.unit.console.rfb.test_authvencrypt.RFBAuthSchemeVeNCryptTestCase.test nova.tests.unit.console.rfb.test_authvencrypt.RFBAuthSchemeVeNCryptTestCase.test_security_handshake_without_x509 nova.tests.unit.console.rfb.test_authvencrypt.RFBAuthSchemeVeNCryptTestCase.test_security_handshake_with_x509 nova.tests.unit.test_context.ContextTestCase.test_scatter_gather_cells_queued_task_cancelled + +# Wait until eventlet.Event is removed by https://review.opendev.org/c/openstack/nova/+/949754 nova.tests.unit.virt.libvirt.test_driver.CacheConcurrencyTestCase.test_different_fname_concurrency nova.tests.unit.virt.libvirt.test_driver.CacheConcurrencyTestCase.test_same_fname_concurrency -nova.tests.unit.virt.libvirt.test_driver.LibvirtDriverTestCase.test_rescue + nova.tests.unit.virt.libvirt.test_driver.TestUpdateProviderTree.test_image_cache_disk_reservation nova.tests.unit.virt.libvirt.test_driver.TestUpdateProviderTree.test_update_provider_tree nova.tests.unit.virt.libvirt.test_driver.TestUpdateProviderTree.test_update_provider_tree_for_pcpu_reshape @@ -18,47 +20,6 @@ nova.tests.unit.virt.libvirt.test_driver.TestUpdateProviderTree.test_update_prov nova.tests.unit.virt.libvirt.volume.test_mount.HostMountStateTestCase.test_mount_concurrent nova.tests.unit.virt.libvirt.volume.test_mount.HostMountStateTestCase.test_mount_concurrent_no_interfere nova.tests.unit.virt.libvirt.volume.test_mount.MountManagerTestCase.test_host_up_waits_for_completion -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_attach_detach_different_power_states -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_attach_detach_volume -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_block_stats -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_destroy_instance -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_force_hard_reboot -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_console_output -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_diagnostics -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_info -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_instance_diagnostics -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_instance_disk_info -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_mks_console -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_serial_console -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_spice_console -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_get_vnc_console -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_live_migration -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_live_migration_force_complete -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_pause -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_poll_rebooting_instances -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_power_off -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_power_on_powered_off -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_power_on_running -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_reboot -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_rescue -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_restore_running -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_restore_soft_deleted -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_resume_state_on_host_boot -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_resume_suspended_instance -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_resume_unsuspended_instance -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_set_admin_password -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_snapshot_running -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_soft_delete -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_spawn -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_suspend -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_swap_volume -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_trigger_crash_dump -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unpause_paused_instance -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unpause_unpaused_instance -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unplug_vifs_with_destroy_vifs_false -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unplug_vifs_with_destroy_vifs_true -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unrescue_rescued_instance -nova.tests.unit.virt.test_virt_drivers.LibvirtConnTestCase.test_unrescue_unrescued_instance nova.tests.unit.virt.vmwareapi.test_vm_util.VMwareVMUtilTestCase.test_create_vm_invalid_guestid # Independent failure ~10% with multiple possible error: # - sqlalchemy.exc.OperationalError: (sqlite3.OperationalError) not an error