Skip to content

Commit a341851

Browse files
author
Balazs Gibizer
committed
Move ReaderWriterLock to the test tree
The commit I168fffac8002f274a905cfd53ac4f6c9abe18803 added a wrapper around fasteners.ReaderWriterLock to fix up an issue with eventlet. But the wrapper was added to nova.utils module that is use not only by the nova tests but also the nova production code. This made the fixture library a dependency of the nova production code. While the current ReaderWriterLock usage only limited to the nova test sub tree. The I712f88fc1b6053fe6d1f13e708f3bd8874452a8f commit fix the issue of not having fixtures in the nova requirements.txt. However I think a better fix is to move the wrapper to the test subtree instead. This patch does that and restores the state of the requirements.txt Change-Id: I6903ce53b9b91325f7268cf2ebd02e4488579560 Related-Bug: #1958075
1 parent 1ddb8f8 commit a341851

File tree

4 files changed

+38
-37
lines changed

4 files changed

+38
-37
lines changed

nova/tests/fixtures/nova.py

Lines changed: 37 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
"""Fixtures for Nova tests."""
1818

1919
import collections
20+
import contextlib
2021
from contextlib import contextmanager
2122
import functools
2223
import logging as std_logging
@@ -28,6 +29,7 @@
2829
import futurist
2930
import mock
3031
from openstack import service_description
32+
from oslo_concurrency import lockutils
3133
from oslo_config import cfg
3234
from oslo_db import exception as db_exc
3335
from oslo_db.sqlalchemy import enginefacade
@@ -405,7 +407,7 @@ def __init__(self):
405407
# to point to a cell, we need to take an exclusive lock to
406408
# prevent any other calls to get_context_manager() until we
407409
# reset to the default.
408-
self._cell_lock = utils.ReaderWriterLock()
410+
self._cell_lock = ReaderWriterLock()
409411

410412
def _cache_schema(self, connection_str):
411413
# NOTE(melwitt): See the regular Database fixture for why
@@ -1721,3 +1723,37 @@ def test_case_id_wrapper(*args, **kwargs):
17211723
# our initialization to the child eventlet
17221724
self.useFixture(
17231725
fixtures.MonkeyPatch('nova.utils.spawn_n', wrapped_spawn_n))
1726+
1727+
1728+
class ReaderWriterLock(lockutils.ReaderWriterLock):
1729+
"""Wrap oslo.concurrency lockutils.ReaderWriterLock to support eventlet.
1730+
1731+
As of fasteners >= 0.15, the workaround code to use eventlet.getcurrent()
1732+
if eventlet patching is detected has been removed and
1733+
threading.current_thread is being used instead. Although we are running in
1734+
a greenlet in our test environment, we are not running in a greenlet of
1735+
type GreenThread. A GreenThread is created by calling eventlet.spawn() and
1736+
spawn() is not used to run our tests. At the time of this writing, the
1737+
eventlet patched threading.current_thread() method falls back to the
1738+
original unpatched current_thread() method if it is not called from a
1739+
GreenThead [1] and that breaks our tests involving this fixture.
1740+
1741+
We can work around this by patching threading.current_thread() with
1742+
eventlet.getcurrent() during creation of the lock object, if we detect we
1743+
are eventlet patched. If we are not eventlet patched, we use a no-op
1744+
context manager.
1745+
1746+
Note: this wrapper should be used for any ReaderWriterLock because any lock
1747+
may possibly be running inside a plain greenlet created by spawn_n().
1748+
1749+
See https://github.com/eventlet/eventlet/issues/731 for details.
1750+
1751+
[1] https://github.com/eventlet/eventlet/blob/v0.32.0/eventlet/green/threading.py#L128 # noqa
1752+
"""
1753+
1754+
def __init__(self, *a, **kw):
1755+
eventlet_patched = eventlet.patcher.is_monkey_patched('thread')
1756+
mpatch = fixtures.MonkeyPatch(
1757+
'threading.current_thread', eventlet.getcurrent)
1758+
with mpatch if eventlet_patched else contextlib.ExitStack():
1759+
super().__init__(*a, **kw)

nova/utils.py

Lines changed: 0 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,6 @@
2929
import tempfile
3030

3131
import eventlet
32-
import fixtures
3332
from keystoneauth1 import loading as ks_loading
3433
import netaddr
3534
from openstack import connection
@@ -1144,37 +1143,3 @@ def reset(wrapper, *args, **kwargs):
11441143
wrapper.reset = functools.partial(reset, wrapper)
11451144
return wrapper
11461145
return outer_wrapper
1147-
1148-
1149-
class ReaderWriterLock(lockutils.ReaderWriterLock):
1150-
"""Wrap oslo.concurrency lockutils.ReaderWriterLock to support eventlet.
1151-
1152-
As of fasteners >= 0.15, the workaround code to use eventlet.getcurrent()
1153-
if eventlet patching is detected has been removed and
1154-
threading.current_thread is being used instead. Although we are running in
1155-
a greenlet in our test environment, we are not running in a greenlet of
1156-
type GreenThread. A GreenThread is created by calling eventlet.spawn() and
1157-
spawn() is not used to run our tests. At the time of this writing, the
1158-
eventlet patched threading.current_thread() method falls back to the
1159-
original unpatched current_thread() method if it is not called from a
1160-
GreenThead [1] and that breaks our tests involving this fixture.
1161-
1162-
We can work around this by patching threading.current_thread() with
1163-
eventlet.getcurrent() during creation of the lock object, if we detect we
1164-
are eventlet patched. If we are not eventlet patched, we use a no-op
1165-
context manager.
1166-
1167-
Note: this wrapper should be used for any ReaderWriterLock because any lock
1168-
may possibly be running inside a plain greenlet created by spawn_n().
1169-
1170-
See https://github.com/eventlet/eventlet/issues/731 for details.
1171-
1172-
[1] https://github.com/eventlet/eventlet/blob/v0.32.0/eventlet/green/threading.py#L128 # noqa
1173-
"""
1174-
1175-
def __init__(self, *a, **kw):
1176-
eventlet_patched = eventlet.patcher.is_monkey_patched('thread')
1177-
mpatch = fixtures.MonkeyPatch(
1178-
'threading.current_thread', eventlet.getcurrent)
1179-
with mpatch if eventlet_patched else contextlib.ExitStack():
1180-
return super().__init__(*a, **kw)

requirements.txt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -68,4 +68,3 @@ futurist>=1.8.0 # Apache-2.0
6868
openstacksdk>=0.35.0 # Apache-2.0
6969
dataclasses>=0.7;python_version=='3.6' # Apache 2.0 License
7070
PyYAML>=5.1 # MIT
71-
fixtures>=3.0.0 # Apache-2.0/BSD

test-requirements.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ mypy>=0.761 # MIT
77
types-paramiko>=0.1.3 # Apache-2.0
88
coverage!=4.4,>=4.0 # Apache-2.0
99
ddt>=1.2.1 # MIT
10+
fixtures>=3.0.0 # Apache-2.0/BSD
1011
mock>=3.0.0 # BSD
1112
psycopg2-binary>=2.8 # LGPL/ZPL
1213
PyMySQL>=0.8.0 # MIT License

0 commit comments

Comments
 (0)