Skip to content

Commit 2f45d5b

Browse files
committed
Add a intergration tests for renewal thread use on gevent/eventlet. Ref #91.
1 parent 5a5d040 commit 2f45d5b

File tree

3 files changed

+60
-7
lines changed

3 files changed

+60
-7
lines changed

tests/helper.py

Lines changed: 17 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
import logging
55
import os
66
import sys
7+
import threading
78
import time
89

910
from redis import StrictRedis
@@ -20,11 +21,26 @@
2021
datefmt="%x~%X"
2122
)
2223
test_name = sys.argv[1]
23-
24+
if ':' in test_name:
25+
test_name, effect = test_name.split(':')
26+
logging.info('Applying effect %r.', effect)
27+
if effect == 'gevent':
28+
from gevent import monkey
29+
monkey.patch_all()
30+
elif effect == 'eventlet':
31+
import eventlet
32+
eventlet.monkey_patch()
33+
else:
34+
raise RuntimeError('Invalid effect spec %r.' % effect)
35+
logging.info('threading.get_ident.__module__=%s', threading.get_ident.__module__)
2436
if test_name == 'test_simple':
2537
conn = StrictRedis(unix_socket_path=UDS_PATH)
2638
with Lock(conn, "foobar"):
2739
time.sleep(0.1)
40+
elif test_name == 'test_simple_auto_renewal':
41+
conn = StrictRedis(unix_socket_path=UDS_PATH)
42+
with Lock(conn, "foobar", expire=1, auto_renewal=True) as lock:
43+
time.sleep(2)
2844
elif test_name == 'test_no_block':
2945
conn = StrictRedis(unix_socket_path=UDS_PATH)
3046
lock = Lock(conn, "foobar")

tests/test_redis_lock.py

Lines changed: 41 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@
44
import gc
55
import logging
66
import multiprocessing
7-
import os
87
import platform
98
import sys
109
import threading
@@ -30,6 +29,7 @@
3029
from redis_lock import TimeoutTooLarge
3130
from redis_lock import reset_all
3231

32+
pytest_plugins = 'pytester',
3333

3434
def maybe_decode(data):
3535
if isinstance(data, bytes):
@@ -56,6 +56,22 @@ def conn(request, make_conn):
5656
return make_conn()
5757

5858

59+
@pytest.fixture(params=['normal', 'gevent', 'eventlet'])
60+
def effect(request):
61+
def wrap_name_with_effect(name):
62+
if request.param == 'normal':
63+
return name
64+
else:
65+
return '{}:{}'.format(name, request.param)
66+
67+
wrap_name_with_effect.expected_impl = {
68+
'normal': '_thread',
69+
'gevent': 'gevent.thread',
70+
'eventlet': 'eventlet.green.thread',
71+
}[request.param]
72+
return wrap_name_with_effect
73+
74+
5975
@pytest.fixture
6076
def make_process(request):
6177
"""Process factory, that makes processes, that terminate themselves
@@ -78,19 +94,38 @@ def test_upgrade(request, conn):
7894
assert not lock.acquire(blocking=False)
7995

8096

81-
def test_simple(redis_server):
82-
with TestProcess(sys.executable, HELPER, 'test_simple') as proc:
97+
def test_simple(redis_server, effect):
98+
with TestProcess(sys.executable, HELPER, effect('test_simple')) as proc:
8399
with dump_on_error(proc.read):
84100
name = 'lock:foobar'
85101
wait_for_strings(
86102
proc.read, TIMEOUT,
87-
'Getting %r ...' % name,
88-
'Got lock for %r.' % name,
89-
'Releasing %r.' % name,
103+
'Acquiring Lock(%r) ...' % name,
104+
'Acquired Lock(%r).' % name,
105+
'Releasing Lock(%r).' % name,
90106
'DIED.',
91107
)
92108

93109

110+
def test_simple_auto_renewal(redis_server, effect, LineMatcher):
111+
with TestProcess(sys.executable, HELPER, effect('test_simple_auto_renewal')) as proc:
112+
with dump_on_error(proc.read):
113+
name = 'lock:foobar'
114+
wait_for_strings(proc.read, TIMEOUT, 'DIED.', )
115+
LineMatcher(proc.read().splitlines()).fnmatch_lines([
116+
'* threading.get_ident.__module__=%s' % effect.expected_impl,
117+
'* Acquiring Lock(%r) ...' % name,
118+
'* Acquired Lock(%r).' % name,
119+
'* Starting renewal thread for Lock(%r). Refresh interval: 0.6666666666666666 seconds.' % name,
120+
'* Refreshing Lock(%r).' % name,
121+
'* Refreshing Lock(%r).' % name,
122+
'* Signaling renewal thread for Lock(%r) to exit.' % name,
123+
'* Exiting renewal thread for Lock(%r).' % name,
124+
'* Renewal thread for Lock(%r) exited.' % name,
125+
'* Releasing Lock(%r).' % name,
126+
])
127+
128+
94129
def test_no_block(conn):
95130
with Lock(conn, "foobar"):
96131
with TestProcess(sys.executable, HELPER, 'test_no_block') as proc:

tox.ini

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,8 @@ deps =
4545
django-redis==5.2.0
4646
process-tests
4747
redis==4.2.0
48+
gevent==21.12.0
49+
eventlet==0.33.0
4850
commands =
4951
nocov: {posargs:pytest -vv --ignore=src}
5052
cover: {posargs:pytest --cov --cov-report=term-missing -vv}

0 commit comments

Comments
 (0)