Allow to start unit test without eventlet
The end goals is to be able to run at least some of the unit tests without eventlet. But there are things preventing that for now. We need to make sure that the oslo.sevice backed is not initialized to eventlet by any early import code before our monkey_patch module can do the selective backed selection based on the env variable. The nova.tests.unit module had some import time code execution that is forcing imports that initialize the oslo.service backend too early, way before nova would do it in normal execution. We could remove objects.register_all() from nova/tests/unit/__init__.py as it seems tests are passing without it. Still that would not be enough so I eventually decide to keep it. The other issue is that the unit test discovery imports all modules under nova.tests.unit and that eventually imports oslo.messaging and that also forces oslo.service backend selection. So we injected an early call to our smart monkey_patch module to preempt that. This does not change the imported modules as monkey_patch module imported anyhow via nova.test module. Just changed the order to allow oslo.service backend selection explicitly. After this patch the unit test can be run via OS_NOVA_DISABLE_EVENTLET_PATCHING=true tox -e py312 Most of the test will pass but there are a bunch of test timing out or hanging. Change-Id: I210cb6a30deaee779d55f88f0f57584c65b0dc05 Signed-off-by: Balazs Gibizer <gibi@redhat.com>
This commit is contained in:
@@ -94,17 +94,7 @@ def patch():
|
||||
|
||||
# NOTE(gibi): We were asked not to monkey patch. Let's enforce it by
|
||||
# removing the possibility to monkey_patch accidentally
|
||||
def poison(*args, **kwargs):
|
||||
raise RuntimeError(
|
||||
"The service is started with native threading via "
|
||||
"OS_NOVA_DISABLE_EVENTLET_PATCHING set to '%s', but then the "
|
||||
"service tried to call eventlet.monkey_patch(). This is a "
|
||||
"bug."
|
||||
% os.environ.get('OS_NOVA_DISABLE_EVENTLET_PATCHING', ''))
|
||||
|
||||
import eventlet
|
||||
eventlet.monkey_patch = poison
|
||||
eventlet.patcher.monkey_patch = poison
|
||||
poison_eventlet()
|
||||
|
||||
from oslo_log import log as logging
|
||||
LOG = logging.getLogger(__name__)
|
||||
@@ -112,3 +102,30 @@ def patch():
|
||||
"Service is starting with native threading. This is currently "
|
||||
"experimental. Do not use it in production without first "
|
||||
"testing it in pre-production.")
|
||||
|
||||
|
||||
def _poison(*args, **kwargs):
|
||||
raise RuntimeError(
|
||||
"The service is started with native threading via "
|
||||
"OS_NOVA_DISABLE_EVENTLET_PATCHING set to '%s', but then the "
|
||||
"service tried to call eventlet.monkey_patch(). This is a bug."
|
||||
% os.environ.get('OS_NOVA_DISABLE_EVENTLET_PATCHING', ''))
|
||||
|
||||
|
||||
def poison_eventlet():
|
||||
import eventlet
|
||||
eventlet.monkey_patch = _poison
|
||||
eventlet.patcher.monkey_patch = _poison
|
||||
|
||||
# We want to have this but cannot have this yet as we still have common
|
||||
# code that imports eventlet like nova.utils.tpool
|
||||
#
|
||||
# class PoisonEventletImport:
|
||||
# def find_spec(self, fullname, path, target=None):
|
||||
# if fullname.startswith('eventlet'):
|
||||
# raise ImportError(
|
||||
# "The service started in threading mode so it should "
|
||||
# "not import eventlet")
|
||||
|
||||
# import sys
|
||||
# sys.meta_path.insert(0, PoisonEventletImport())
|
||||
|
@@ -22,6 +22,21 @@
|
||||
:platform: Unix
|
||||
"""
|
||||
|
||||
# The import order in the test environment is different from the import
|
||||
# order in a real env. During unit testing nova.test.unit is imported first
|
||||
# to discover the unit tests, then the modules under it are imported. This
|
||||
# test discovery import forces the import of oslo.messaging eventually that
|
||||
# import time run code that uses the oslo.service backend which forces the
|
||||
# initialization of the backed to the default eventlet. This prevents
|
||||
# our tests to run with the threading backend. To avoid this we force the
|
||||
# backend registration early here by using our common monkey_patch mode
|
||||
# that already does smart backend selection based on env variables.
|
||||
# The monkey_patching would be used anyhow when nova.test is imported so
|
||||
# this does not change the end result just the order of imports
|
||||
# autopep8: off
|
||||
from nova import monkey_patch ; monkey_patch.patch() # noqa
|
||||
# autopep8: on
|
||||
|
||||
from nova import objects
|
||||
|
||||
# NOTE(comstud): Make sure we have all of the objects loaded. We do this
|
||||
|
3
tox.ini
3
tox.ini
@@ -48,6 +48,9 @@ passenv =
|
||||
PYTHONOPTIMIZE
|
||||
# there is also secret magic in subunit-trace which lets you run in a fail only
|
||||
# mode. To do this define the TRACE_FAILONLY environmental variable.
|
||||
|
||||
# allow running without eventlet
|
||||
OS_NOVA_DISABLE_EVENTLET_PATCHING
|
||||
commands =
|
||||
stestr run {posargs}
|
||||
env TEST_OSPROFILER=1 stestr run --combine --no-discover 'nova.tests.unit.test_profiler'
|
||||
|
Reference in New Issue
Block a user