Skip to content

Commit 1db4153

Browse files
committed
more cleanups
1 parent 7173187 commit 1db4153

File tree

1 file changed

+83
-120
lines changed

1 file changed

+83
-120
lines changed

packages/service-library/tests/redis/test_decorators.py

Lines changed: 83 additions & 120 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,6 @@
77
import asyncio
88
import datetime
99
from collections.abc import Awaitable, Callable
10-
from contextlib import AbstractAsyncContextManager
1110
from datetime import timedelta
1211
from itertools import chain
1312
from unittest.mock import Mock
@@ -24,7 +23,6 @@
2423
)
2524
from servicelib.redis._errors import LockLostError
2625
from servicelib.utils import logged_gather
27-
from settings_library.redis import RedisDatabase
2826
from tenacity.asyncio import AsyncRetrying
2927
from tenacity.retry import retry_if_exception_type
3028
from tenacity.stop import stop_after_delay
@@ -43,11 +41,6 @@ async def _is_locked(redis_client_sdk: RedisClientSDK, lock_name: str) -> bool:
4341
return await lock.locked()
4442

4543

46-
@pytest.fixture
47-
def lock_name(faker: Faker) -> str:
48-
return faker.pystr()
49-
50-
5144
def _exclusive_sleeping_task(
5245
redis_client_sdk: RedisClientSDK | Callable[..., RedisClientSDK],
5346
lock_name: str | Callable[..., str],
@@ -69,39 +62,33 @@ async def _() -> float:
6962

7063
@pytest.fixture
7164
def sleep_duration(faker: Faker) -> float:
72-
return faker.pyfloat(positive=True, min_value=0.2, max_value=0.8)
65+
return faker.pyfloat(min_value=0.2, max_value=0.8)
7366

7467

7568
async def test_exclusive_with_empty_lock_key_raises(redis_client_sdk: RedisClientSDK):
76-
@exclusive(redis_client_sdk, lock_key="")
77-
async def _():
78-
pass
79-
8069
with pytest.raises(ValueError, match="lock_key cannot be empty"):
81-
await _()
70+
71+
@exclusive(redis_client_sdk, lock_key="")
72+
async def _():
73+
pass
8274

8375

8476
async def test_exclusive_decorator(
85-
get_redis_client_sdk: Callable[
86-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
87-
],
77+
redis_client_sdk: RedisClientSDK,
8878
lock_name: str,
8979
sleep_duration: float,
9080
):
91-
async with get_redis_client_sdk(RedisDatabase.RESOURCES) as redis_client:
92-
for _ in range(3):
93-
assert (
94-
await _exclusive_sleeping_task(
95-
redis_client, lock_name, sleep_duration
96-
)()
97-
== sleep_duration
98-
)
81+
for _ in range(3):
82+
assert (
83+
await _exclusive_sleeping_task(
84+
redis_client_sdk, lock_name, sleep_duration
85+
)()
86+
== sleep_duration
87+
)
9988

10089

10190
async def test_exclusive_decorator_with_key_builder(
102-
get_redis_client_sdk: Callable[
103-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
104-
],
91+
redis_client_sdk: RedisClientSDK,
10592
lock_name: str,
10693
sleep_duration: float,
10794
):
@@ -110,72 +97,62 @@ def _get_lock_name(*args, **kwargs) -> str:
11097
assert kwargs is not None
11198
return lock_name
11299

113-
async with get_redis_client_sdk(RedisDatabase.RESOURCES) as redis_client:
114-
for _ in range(3):
115-
assert (
116-
await _exclusive_sleeping_task(
117-
redis_client, _get_lock_name, sleep_duration
118-
)()
119-
== sleep_duration
120-
)
100+
for _ in range(3):
101+
assert (
102+
await _exclusive_sleeping_task(
103+
redis_client_sdk, _get_lock_name, sleep_duration
104+
)()
105+
== sleep_duration
106+
)
121107

122108

123109
async def test_exclusive_decorator_with_client_builder(
124-
get_redis_client_sdk: Callable[
125-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
126-
],
110+
redis_client_sdk: RedisClientSDK,
127111
lock_name: str,
128112
sleep_duration: float,
129113
):
130-
async with get_redis_client_sdk(RedisDatabase.RESOURCES) as redis_client:
131-
132-
def _get_redis_client_builder(*args, **kwargs) -> RedisClientSDK:
133-
assert args is not None
134-
assert kwargs is not None
135-
return redis_client
136-
137-
for _ in range(3):
138-
assert (
139-
await _exclusive_sleeping_task(
140-
_get_redis_client_builder, lock_name, sleep_duration
141-
)()
142-
== sleep_duration
143-
)
114+
def _get_redis_client_builder(*args, **kwargs) -> RedisClientSDK:
115+
assert args is not None
116+
assert kwargs is not None
117+
return redis_client_sdk
118+
119+
for _ in range(3):
120+
assert (
121+
await _exclusive_sleeping_task(
122+
_get_redis_client_builder, lock_name, sleep_duration
123+
)()
124+
== sleep_duration
125+
)
144126

145127

146128
async def _acquire_lock_and_exclusively_sleep(
147-
get_redis_client_sdk: Callable[
148-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
149-
],
129+
redis_client_sdk: RedisClientSDK,
150130
lock_name: str | Callable[..., str],
151131
sleep_duration: float,
152132
) -> None:
153-
async with get_redis_client_sdk(RedisDatabase.RESOURCES) as redis_client_sdk:
154-
redis_lock_name = lock_name() if callable(lock_name) else lock_name
133+
redis_lock_name = lock_name() if callable(lock_name) else lock_name
155134

156-
@exclusive(redis_client_sdk, lock_key=lock_name)
157-
async def _() -> float:
158-
assert await _is_locked(redis_client_sdk, redis_lock_name)
159-
await asyncio.sleep(sleep_duration)
160-
assert await _is_locked(redis_client_sdk, redis_lock_name)
161-
return sleep_duration
135+
@exclusive(redis_client_sdk, lock_key=lock_name)
136+
async def _() -> float:
137+
assert await _is_locked(redis_client_sdk, redis_lock_name)
138+
await asyncio.sleep(sleep_duration)
139+
assert await _is_locked(redis_client_sdk, redis_lock_name)
140+
return sleep_duration
162141

163-
assert await _() == sleep_duration
142+
assert await _() == sleep_duration
164143

165-
assert not await _is_locked(redis_client_sdk, redis_lock_name)
144+
assert not await _is_locked(redis_client_sdk, redis_lock_name)
166145

167146

168147
async def test_exclusive_parallel_lock_is_released_and_reacquired(
169-
get_redis_client_sdk: Callable[
170-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
171-
],
148+
redis_client_sdk: RedisClientSDK,
172149
lock_name: str,
173150
):
174151
parallel_tasks = 10
175152
results = await logged_gather(
176153
*[
177154
_acquire_lock_and_exclusively_sleep(
178-
get_redis_client_sdk, lock_name, sleep_duration=1
155+
redis_client_sdk, lock_name, sleep_duration=1
179156
)
180157
for _ in range(parallel_tasks)
181158
],
@@ -187,8 +164,7 @@ async def test_exclusive_parallel_lock_is_released_and_reacquired(
187164
) == parallel_tasks - 1
188165

189166
# check lock is released
190-
async with get_redis_client_sdk(RedisDatabase.RESOURCES) as redis_client_sdk:
191-
assert not await _is_locked(redis_client_sdk, lock_name)
167+
assert not await _is_locked(redis_client_sdk, lock_name)
192168

193169

194170
async def _sleep_task(sleep_interval: float, on_sleep_events: Mock) -> None:
@@ -211,39 +187,34 @@ async def _assert_on_sleep_done(on_sleep_events: Mock, *, stop_after: float):
211187

212188

213189
async def _assert_task_completes_once(
214-
get_redis_client_sdk: Callable[
215-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
216-
],
190+
redis_client_sdk: RedisClientSDK,
217191
stop_after: float,
218192
) -> tuple[float, ...]:
219-
async with get_redis_client_sdk(RedisDatabase.RESOURCES) as redis_client_sdk:
220-
sleep_events = Mock()
221-
222-
started_task = start_exclusive_periodic_task(
223-
redis_client_sdk,
224-
_sleep_task,
225-
task_period=timedelta(seconds=1),
226-
task_name="pytest_sleep_task",
227-
sleep_interval=1,
228-
on_sleep_events=sleep_events,
229-
)
193+
sleep_events = Mock()
194+
195+
started_task = start_exclusive_periodic_task(
196+
redis_client_sdk,
197+
_sleep_task,
198+
task_period=timedelta(seconds=1),
199+
task_name="pytest_sleep_task",
200+
sleep_interval=1,
201+
on_sleep_events=sleep_events,
202+
)
230203

231-
await _assert_on_sleep_done(sleep_events, stop_after=stop_after)
204+
await _assert_on_sleep_done(sleep_events, stop_after=stop_after)
232205

233-
await cancel_wait_task(started_task, max_delay=5)
206+
await cancel_wait_task(started_task, max_delay=5)
234207

235-
events_timestamps: tuple[float, ...] = tuple(
236-
x.args[0].timestamp() for x in sleep_events.call_args_list
237-
)
238-
return events_timestamps
208+
events_timestamps: tuple[float, ...] = tuple(
209+
x.args[0].timestamp() for x in sleep_events.call_args_list
210+
)
211+
return events_timestamps
239212

240213

241214
async def test_start_exclusive_periodic_task_single(
242-
get_redis_client_sdk: Callable[
243-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
244-
],
215+
redis_client_sdk: RedisClientSDK,
245216
):
246-
await _assert_task_completes_once(get_redis_client_sdk, stop_after=2)
217+
await _assert_task_completes_once(redis_client_sdk, stop_after=2)
247218

248219

249220
def _check_elements_lower(lst: list) -> bool:
@@ -260,14 +231,12 @@ def test__check_elements_lower():
260231

261232

262233
async def test_start_exclusive_periodic_task_parallel_all_finish(
263-
get_redis_client_sdk: Callable[
264-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
265-
],
234+
redis_client_sdk: RedisClientSDK,
266235
):
267236
parallel_tasks = 10
268237
results: list[tuple[float, float]] = await logged_gather(
269238
*[
270-
_assert_task_completes_once(get_redis_client_sdk, stop_after=60)
239+
_assert_task_completes_once(redis_client_sdk, stop_after=60)
271240
for _ in range(parallel_tasks)
272241
],
273242
reraise=False,
@@ -289,27 +258,21 @@ async def test_start_exclusive_periodic_task_parallel_all_finish(
289258

290259

291260
async def test_exclusive_raises_if_lock_is_lost(
292-
get_redis_client_sdk: Callable[
293-
[RedisDatabase], AbstractAsyncContextManager[RedisClientSDK]
294-
],
295-
faker: Faker,
261+
redis_client_sdk: RedisClientSDK,
262+
lock_name: str,
296263
):
297-
lock_name = faker.pystr()
298-
299264
started_event = asyncio.Event()
300265

301-
async with get_redis_client_sdk(RedisDatabase.RESOURCES) as redis_client_sdk:
302-
303-
@exclusive(redis_client_sdk, lock_key=lock_name)
304-
async def _(time_to_sleep: datetime.timedelta) -> datetime.timedelta:
305-
started_event.set()
306-
await asyncio.sleep(time_to_sleep.total_seconds())
307-
return time_to_sleep
308-
309-
exclusive_task = asyncio.create_task(_(datetime.timedelta(seconds=10)))
310-
await asyncio.wait_for(started_event.wait(), timeout=2)
311-
# let's simlulate lost lock by forcefully deleting it
312-
await redis_client_sdk._client.delete(lock_name) # noqa: SLF001
313-
314-
with pytest.raises(LockLostError):
315-
await exclusive_task
266+
@exclusive(redis_client_sdk, lock_key=lock_name)
267+
async def _(time_to_sleep: datetime.timedelta) -> datetime.timedelta:
268+
started_event.set()
269+
await asyncio.sleep(time_to_sleep.total_seconds())
270+
return time_to_sleep
271+
272+
exclusive_task = asyncio.create_task(_(datetime.timedelta(seconds=10)))
273+
await asyncio.wait_for(started_event.wait(), timeout=2)
274+
# let's simlulate lost lock by forcefully deleting it
275+
await redis_client_sdk.redis.delete(lock_name)
276+
277+
with pytest.raises(LockLostError):
278+
await exclusive_task

0 commit comments

Comments
 (0)