Skip to content

Commit 9988654

Browse files
GitHKAndrei Neagu
andauthored
🐛 fixing flaky test test_checked_once_task_is_auto_removed (#4527)
Co-authored-by: Andrei Neagu <[email protected]>
1 parent d361314 commit 9988654

File tree

2 files changed

+44
-43
lines changed

2 files changed

+44
-43
lines changed

packages/service-library/src/servicelib/long_running_tasks/_task.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -206,11 +206,11 @@ def get_task_status(
206206
done = task.done()
207207

208208
return TaskStatus.parse_obj(
209-
dict(
210-
task_progress=tracked_task.task_progress,
211-
done=done,
212-
started=tracked_task.started,
213-
)
209+
{
210+
"task_progress": tracked_task.task_progress,
211+
"done": done,
212+
"started": tracked_task.started,
213+
}
214214
)
215215

216216
def get_task_result(

packages/service-library/tests/long_running_tasks/test_long_running_tasks_task.py

Lines changed: 39 additions & 38 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,9 @@
66

77
import asyncio
88
import urllib.parse
9+
from collections.abc import AsyncIterator
910
from datetime import datetime
10-
from typing import AsyncIterator, Final
11+
from typing import Any, Final
1112

1213
import pytest
1314
from faker import Faker
@@ -24,17 +25,18 @@
2425
TaskStatus,
2526
)
2627
from servicelib.long_running_tasks._task import TasksManager, start_task
28+
from tenacity import TryAgain
2729
from tenacity._asyncio import AsyncRetrying
2830
from tenacity.retry import retry_if_exception_type
2931
from tenacity.stop import stop_after_delay
3032
from tenacity.wait import wait_fixed
3133

32-
_RETRY_PARAMS = dict(
33-
reraise=True,
34-
wait=wait_fixed(0.1),
35-
stop=stop_after_delay(60),
36-
retry=retry_if_exception_type(AssertionError),
37-
)
34+
_RETRY_PARAMS: dict[str, Any] = {
35+
"reraise": True,
36+
"wait": wait_fixed(0.1),
37+
"stop": stop_after_delay(60),
38+
"retry": retry_if_exception_type((AssertionError, TryAgain)),
39+
}
3840

3941

4042
async def a_background_task(
@@ -47,7 +49,8 @@ async def a_background_task(
4749
await asyncio.sleep(1)
4850
task_progress.update(percent=ProgressPercent((i + 1) / total_sleep))
4951
if raise_when_finished:
50-
raise RuntimeError("raised this error as instructed")
52+
msg = "raised this error as instructed"
53+
raise RuntimeError(msg)
5154

5255
return 42
5356

@@ -59,7 +62,8 @@ async def fast_background_task(task_progress: TaskProgress) -> int:
5962

6063
async def failing_background_task(task_progress: TaskProgress):
6164
"""this task does nothing and returns a constant"""
62-
raise RuntimeError("failing asap")
65+
msg = "failing asap"
66+
raise RuntimeError(msg)
6367

6468

6569
TEST_CHECK_STALE_INTERVAL_S: Final[float] = 1
@@ -75,42 +79,37 @@ async def tasks_manager() -> AsyncIterator[TasksManager]:
7579
await tasks_manager.close()
7680

7781

78-
async def test_unchecked_task_is_auto_removed(tasks_manager: TasksManager):
82+
@pytest.mark.parametrize("check_task_presence_before", [True, False])
83+
async def test_task_is_auto_removed(
84+
tasks_manager: TasksManager, check_task_presence_before: bool
85+
):
7986
task_id = start_task(
8087
tasks_manager,
8188
a_background_task,
8289
raise_when_finished=False,
8390
total_sleep=10 * TEST_CHECK_STALE_INTERVAL_S,
8491
)
85-
await asyncio.sleep(2 * TEST_CHECK_STALE_INTERVAL_S + 1)
86-
async for attempt in AsyncRetrying(**_RETRY_PARAMS):
87-
with attempt:
88-
with pytest.raises(TaskNotFoundError):
89-
tasks_manager.get_task_status(task_id, with_task_context=None)
90-
with pytest.raises(TaskNotFoundError):
91-
tasks_manager.get_task_result(task_id, with_task_context=None)
92-
with pytest.raises(TaskNotFoundError):
93-
tasks_manager.get_task_result_old(task_id)
9492

93+
if check_task_presence_before:
94+
# immediately after starting the task is still there
95+
task_status = tasks_manager.get_task_status(task_id, with_task_context=None)
96+
assert task_status
9597

96-
async def test_checked_once_task_is_auto_removed(tasks_manager: TasksManager):
97-
task_id = start_task(
98-
tasks_manager,
99-
a_background_task,
100-
raise_when_finished=False,
101-
total_sleep=10 * TEST_CHECK_STALE_INTERVAL_S,
102-
)
103-
# check once (different branch in code)
104-
tasks_manager.get_task_status(task_id, with_task_context=None)
105-
await asyncio.sleep(2 * TEST_CHECK_STALE_INTERVAL_S + 1)
98+
# wait for task to be automatically removed
99+
# meaning no calls via the manager methods are received
106100
async for attempt in AsyncRetrying(**_RETRY_PARAMS):
107101
with attempt:
108-
with pytest.raises(TaskNotFoundError):
109-
tasks_manager.get_task_status(task_id, with_task_context=None)
110-
with pytest.raises(TaskNotFoundError):
111-
tasks_manager.get_task_result(task_id, with_task_context=None)
112-
with pytest.raises(TaskNotFoundError):
113-
tasks_manager.get_task_result_old(task_id)
102+
for tasks in tasks_manager._tasks_groups.values(): # noqa: SLF001
103+
if task_id in tasks:
104+
msg = "wait till no element is found any longer"
105+
raise TryAgain(msg)
106+
107+
with pytest.raises(TaskNotFoundError):
108+
tasks_manager.get_task_status(task_id, with_task_context=None)
109+
with pytest.raises(TaskNotFoundError):
110+
tasks_manager.get_task_result(task_id, with_task_context=None)
111+
with pytest.raises(TaskNotFoundError):
112+
tasks_manager.get_task_result_old(task_id)
114113

115114

116115
async def test_checked_task_is_not_auto_removed(tasks_manager: TasksManager):
@@ -182,7 +181,9 @@ async def not_unique_task(task_progress: TaskProgress):
182181

183182

184183
def test_get_task_id():
185-
assert TasksManager._create_task_id("") != TasksManager._create_task_id("")
184+
obj1 = TasksManager._create_task_id("") # noqa: SLF001
185+
obj2 = TasksManager._create_task_id("") # noqa: SLF001
186+
assert obj1 != obj2
186187

187188

188189
async def test_get_status(tasks_manager: TasksManager):
@@ -248,7 +249,7 @@ async def test_get_result_old_finished_with_error(tasks_manager: TasksManager):
248249
assert task_result.result is None
249250
assert task_result.error is not None
250251
assert task_result.error.startswith(f"Task {task_id} finished with exception:")
251-
assert 'raise RuntimeError("failing asap")' in task_result.error
252+
assert "failing asap" in task_result.error
252253

253254

254255
async def test_get_result_task_was_cancelled_multiple_times(
@@ -364,7 +365,7 @@ async def test_list_tasks(tasks_manager: TasksManager):
364365
NUM_TASKS = 10
365366
task_ids = []
366367
for _ in range(NUM_TASKS):
367-
task_ids.append(
368+
task_ids.append( # noqa: PERF401
368369
start_task(
369370
tasks_manager=tasks_manager,
370371
task=a_background_task,

0 commit comments

Comments
 (0)