From 6db87086c76bdf9f43bdf933dd2853665c3d7cc0 Mon Sep 17 00:00:00 2001 From: Julien Cristau Date: Thu, 2 Oct 2025 11:52:02 +0200 Subject: [PATCH] fix: call listTasks properly 1) listTasks takes a single parameter, so `index.listTasks(index_path, {})` would fail with `Incorrect number of positional arguments` 2) with that fixed, pagination handling was missing, so we'd only ever get up to 1000 entries back 3) tests missed it because they were mocking out the API call --- src/taskgraph/util/taskcluster.py | 10 +++---- test/test_util_taskcluster.py | 50 ++++++++++++++++++++----------- 2 files changed, 37 insertions(+), 23 deletions(-) diff --git a/src/taskgraph/util/taskcluster.py b/src/taskgraph/util/taskcluster.py index 479547649..c0a20d833 100644 --- a/src/taskgraph/util/taskcluster.py +++ b/src/taskgraph/util/taskcluster.py @@ -216,12 +216,12 @@ def list_tasks(index_path): in the index. Results are sorted by expiration date from oldest to newest. """ index = get_taskcluster_client("index") - response = index.listTasks(index_path, {}) + tasks = [] - if not response or "tasks" not in response: - return [] + def pagination_handler(response): + tasks.extend(response["tasks"]) - tasks = response.get("tasks", []) + index.listTasks(index_path, paginationHandler=pagination_handler) # We can sort on expires because in the general case # all of these tasks should be created with the same expires time so they end up in @@ -229,7 +229,7 @@ def list_tasks(index_path): # fetching each task and sorting on the created date. tasks.sort(key=lambda t: parse_time(t["expires"])) - task_ids = [t["taskId"] for t in tasks if "taskId" in t] + task_ids = [t["taskId"] for t in tasks] return task_ids diff --git a/test/test_util_taskcluster.py b/test/test_util_taskcluster.py index 0a8b2482b..c15a92b34 100644 --- a/test/test_util_taskcluster.py +++ b/test/test_util_taskcluster.py @@ -233,28 +233,42 @@ def mock_client(service): mock_index.findArtifactFromTask.assert_called_with(index, path) -def test_list_tasks(monkeypatch): +def test_list_tasks(monkeypatch, responses, root_url): index = "foo" - mock_index = mock.MagicMock() - - def mock_client(service): - if service == "index": - return mock_index - return mock.MagicMock() - - monkeypatch.setattr(tc, "get_taskcluster_client", mock_client) - - mock_index.listTasks.return_value = { - "tasks": [ - {"taskId": "123", "expires": "2023-02-10T19:07:33.700Z"}, - {"taskId": "abc", "expires": "2023-02-09T19:07:33.700Z"}, - ] - } + monkeypatch.setattr(os, "environ", {"TASKCLUSTER_ROOT_URL": root_url}) + responses.get( + f"{root_url}/api/index/v1/tasks/{index}", + json={ + "tasks": [ + { + "namespace": "foo.A08Cbf8KSFqMsa3J0m-yTg", + "taskId": "A08Cbf8KSFqMsa3J0m-yTg", + "rank": 0, + "data": {}, + "expires": "2025-10-29T11:58:45.474Z", + } + ], + "continuationToken": "qzxkXG8ZWa", + }, + ) + responses.get( + f"{root_url}/api/index/v1/tasks/{index}", + json={ + "tasks": [ + { + "namespace": "foo.a0ha8axBTVCCgq1zm6uUhQ", + "taskId": "a0ha8axBTVCCgq1zm6uUhQ", + "rank": 0, + "data": {}, + "expires": "2025-10-29T11:57:33.217Z", + } + ], + }, + ) result = tc.list_tasks(index) - assert result == ["abc", "123"] - mock_index.listTasks.assert_called_with(index, {}) + assert result == ["a0ha8axBTVCCgq1zm6uUhQ", "A08Cbf8KSFqMsa3J0m-yTg"] def test_parse_time():