Skip to content

Commit 4e7a566

Browse files
authored
test: Deflake test_schedule_list and test_task_list by polling eventually consistent listings (#951)
`test_schedule_list` and `test_task_list` failed in CI ([schedule run](https://github.com/apify/apify-client-python/actions/runs/29497290807/job/87617167353), [task run](https://github.com/apify/apify-client-python/actions/runs/29498108478/job/87619855853)) because they assert read-your-write on listing endpoints: they list resources immediately after creating them, and under load the listing can serve a view that hasn't yet caught up with the creates, so the fresh IDs are sometimes missing. The creates themselves succeeded in both cases, so these are eventual-consistency flakes, not client bugs. The fix wraps each list read in the existing `poll_until_condition` helper (30 s ceiling), waiting until the created IDs appear in the listing. The original assertions still run on the final page, so a real regression still fails. Follows the same deflaking pattern as #824, #831, #844, and #868.
1 parent 5ad7c91 commit 4e7a566

2 files changed

Lines changed: 22 additions & 10 deletions

File tree

tests/integration/test_schedule.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
from typing import TYPE_CHECKING
66

7-
from .._utils import collect_iterate_until_present, get_random_resource_name, maybe_await
7+
from .._utils import collect_iterate_until_present, get_random_resource_name, maybe_await, poll_until_condition
88
from apify_client._models import Actor, ListOfSchedules, Schedule, ScheduleActionRunActor, ScheduleShort
99

1010
if TYPE_CHECKING:
@@ -110,10 +110,16 @@ async def test_schedule_list(client: ApifyClient | ApifyClientAsync) -> None:
110110
assert isinstance(created_2, Schedule)
111111

112112
try:
113-
# List schedules
114-
schedules_page = await maybe_await(client.schedules().list(limit=100))
115-
assert isinstance(schedules_page, ListOfSchedules)
116-
assert schedules_page.items is not None
113+
# Poll until both fresh schedules appear in the listing (eventual consistency)
114+
async def list_schedules() -> ListOfSchedules:
115+
page = await maybe_await(client.schedules().list(limit=100))
116+
assert isinstance(page, ListOfSchedules)
117+
return page
118+
119+
schedules_page = await poll_until_condition(
120+
list_schedules,
121+
lambda page: {created_1.id, created_2.id} <= {s.id for s in page.items},
122+
)
117123

118124
# Verify our schedules are in the list
119125
schedule_ids = [s.id for s in schedules_page.items]

tests/integration/test_task.py

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
from datetime import timedelta
77
from typing import TYPE_CHECKING
88

9-
from .._utils import collect_iterate_until_present, get_random_resource_name, maybe_await
9+
from .._utils import collect_iterate_until_present, get_random_resource_name, maybe_await, poll_until_condition
1010
from apify_client._models import Actor, ListOfRuns, ListOfTasks, ListOfWebhooks, Run, RunShort, Task, TaskShort
1111

1212
if TYPE_CHECKING:
@@ -106,10 +106,16 @@ async def test_task_list(client: ApifyClient | ApifyClientAsync) -> None:
106106
assert isinstance(created_task, Task)
107107

108108
try:
109-
# List tasks
110-
tasks_page = await maybe_await(client.tasks().list(limit=100))
111-
assert isinstance(tasks_page, ListOfTasks)
112-
assert tasks_page.items is not None
109+
# Poll until the fresh task appears in the listing (eventual consistency)
110+
async def list_tasks() -> ListOfTasks:
111+
page = await maybe_await(client.tasks().list(limit=100))
112+
assert isinstance(page, ListOfTasks)
113+
return page
114+
115+
tasks_page = await poll_until_condition(
116+
list_tasks,
117+
lambda page: created_task.id in {t.id for t in page.items},
118+
)
113119

114120
# Verify our task is in the list
115121
task_ids = [t.id for t in tasks_page.items]

0 commit comments

Comments
 (0)