|
12 | 12 | import time |
13 | 13 | import warnings |
14 | 14 |
|
15 | | -try: |
16 | | - from urllib.parse import urlencode |
17 | | - from urllib.request import Request, urlopen, urlretrieve |
18 | | -except ImportError: |
19 | | - from urllib import urlencode, urlretrieve |
20 | | - from urllib2 import Request, urlopen |
| 15 | +import requests |
21 | 16 |
|
| 17 | +from firefox_code_coverage import taskcluster |
22 | 18 |
|
23 | 19 | FINISHED_STATUSES = ["completed", "failed", "exception"] |
24 | 20 | ALL_STATUSES = FINISHED_STATUSES + ["unscheduled", "pending", "running"] |
|
28 | 24 | GRCOV_ARTIFACT = "public/build/grcov.tar.xz" |
29 | 25 |
|
30 | 26 |
|
31 | | -def get_json(url, params=None, headers={}): |
32 | | - if params is not None: |
33 | | - url += "?" + urlencode(params) |
34 | | - |
35 | | - request = Request(url, headers=headers) |
36 | | - r = urlopen(request).read().decode("utf-8") |
37 | | - |
38 | | - return json.loads(r) |
39 | | - |
40 | | - |
41 | 27 | def is_taskcluster_loaner(): |
42 | 28 | return "TASKCLUSTER_INTERACTIVE" in os.environ |
43 | 29 |
|
44 | 30 |
|
45 | 31 | def get_task(branch, revision): |
46 | | - task = get_json( |
47 | | - f"https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/gecko.v2.{branch}.revision.{revision}.firefox.decision" |
48 | | - ) |
| 32 | + index = taskcluster.get_service("index") |
| 33 | + task = index.findTask(f"gecko.v2.{branch}.revision.{revision}.firefox.decision") |
49 | 34 | return task["taskId"] |
50 | 35 |
|
51 | 36 |
|
52 | 37 | def get_last_task(): |
53 | | - revision = get_json( |
| 38 | + resp = requests.get( |
54 | 39 | "https://api.coverage.moz.tools/v2/latest?repository=mozilla-central" |
55 | | - )[0]["revision"] |
| 40 | + ) |
| 41 | + resp.raise_for_status() |
| 42 | + data = resp.json() |
| 43 | + revision = data[0]["revision"] |
56 | 44 | return get_task("mozilla-central", revision) |
57 | 45 |
|
58 | 46 |
|
59 | 47 | def get_task_details(task_id): |
60 | | - task_details = get_json( |
61 | | - "https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/" + task_id |
62 | | - ) |
63 | | - return task_details |
| 48 | + queue = taskcluster.get_service("queue") |
| 49 | + return queue.task(task_id) |
64 | 50 |
|
65 | 51 |
|
66 | 52 | def get_task_artifacts(task_id): |
67 | | - artifacts = get_json( |
68 | | - "https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/" |
69 | | - + task_id |
70 | | - + "/artifacts" |
71 | | - ) |
72 | | - return artifacts["artifacts"] |
| 53 | + queue = taskcluster.get_service("queue") |
| 54 | + response = queue.listLatestArtifacts(task_id) |
| 55 | + return response["artifacts"] |
73 | 56 |
|
74 | 57 |
|
75 | 58 | def get_tasks_in_group(group_id): |
76 | | - reply = get_json( |
77 | | - "https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task-group/" |
78 | | - + group_id |
79 | | - + "/list", |
80 | | - {"limit": "200"}, |
81 | | - ) |
82 | | - tasks = reply["tasks"] |
83 | | - while "continuationToken" in reply: |
84 | | - reply = get_json( |
85 | | - "https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task-group/" |
86 | | - + group_id |
87 | | - + "/list", |
88 | | - {"limit": "200", "continuationToken": reply["continuationToken"]}, |
89 | | - ) |
90 | | - tasks += reply["tasks"] |
| 59 | + tasks = [] |
| 60 | + |
| 61 | + def _save_tasks(response): |
| 62 | + tasks.extend(response["tasks"]) |
| 63 | + |
| 64 | + queue = taskcluster.get_service("queue") |
| 65 | + queue.listTaskGroup(group_id, paginationHandler=_save_tasks) |
| 66 | + |
91 | 67 | return tasks |
92 | 68 |
|
93 | 69 |
|
| 70 | +def download_binary(url, path, retries=5): |
| 71 | + """Download a binary file from an url""" |
| 72 | + for i in range(1, retries + 1): |
| 73 | + try: |
| 74 | + artifact = requests.get(url, stream=True) |
| 75 | + artifact.raise_for_status() |
| 76 | + |
| 77 | + with open(path, "wb") as f: |
| 78 | + for chunk in artifact.iter_content(chunk_size=8192): |
| 79 | + f.write(chunk) |
| 80 | + break |
| 81 | + except: # noqa: E722 |
| 82 | + try: |
| 83 | + os.remove(path) |
| 84 | + except OSError: |
| 85 | + pass |
| 86 | + |
| 87 | + if i == retries: |
| 88 | + raise Exception( |
| 89 | + "Download failed after {} retries - {}".format(retries, url) |
| 90 | + ) |
| 91 | + |
| 92 | + time.sleep(7 * i) |
| 93 | + |
| 94 | + |
94 | 95 | def download_artifact(task_id, artifact, artifacts_path): |
95 | 96 | fname = os.path.join( |
96 | 97 | artifacts_path, task_id + "_" + os.path.basename(artifact["name"]) |
97 | 98 | ) |
| 99 | + |
| 100 | + # As recommended by Taskcluster doc, use requests to download |
| 101 | + # from the artifact public url instead of relying on the client method |
| 102 | + queue = taskcluster.get_service("queue") |
| 103 | + url = queue.buildUrl("getLatestArtifact", task_id, artifact["name"]) |
| 104 | + |
98 | 105 | if not os.path.exists(fname): |
99 | | - while True: |
100 | | - try: |
101 | | - urlretrieve( |
102 | | - "https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/" |
103 | | - + task_id |
104 | | - + "/artifacts/" |
105 | | - + artifact["name"], |
106 | | - fname, |
107 | | - ) |
108 | | - break |
109 | | - except: # noqa: E722 |
110 | | - try: |
111 | | - os.remove(fname) |
112 | | - except OSError: |
113 | | - pass |
114 | | - |
115 | | - time.sleep(7) |
| 106 | + download_binary(url, fname) |
| 107 | + |
116 | 108 | return fname |
117 | 109 |
|
118 | 110 |
|
@@ -145,11 +137,8 @@ def get_platform(task_name): |
145 | 137 |
|
146 | 138 |
|
147 | 139 | def get_task_status(task_id): |
148 | | - status = get_json( |
149 | | - "https://firefox-ci-tc.services.mozilla.com/api/queue/v1/task/{}/status".format( |
150 | | - task_id |
151 | | - ) |
152 | | - ) |
| 140 | + queue = taskcluster.get_service("queue") |
| 141 | + status = queue.status(task_id) |
153 | 142 | return status["status"]["state"] |
154 | 143 |
|
155 | 144 |
|
@@ -316,10 +305,9 @@ def download_grcov(): |
316 | 305 |
|
317 | 306 | dest = tempfile.mkdtemp(suffix="grcov") |
318 | 307 | archive = os.path.join(dest, "grcov.tar.xz") |
319 | | - url = "https://firefox-ci-tc.services.mozilla.com/api/index/v1/task/{index}/artifacts/{artifact}".format( |
320 | | - index=GRCOV_INDEX, artifact=GRCOV_ARTIFACT |
321 | | - ) |
322 | | - urlretrieve(url, archive) |
| 308 | + index = taskcluster.get_service("index") |
| 309 | + url = index.buildUrl("findArtifactFromTask", GRCOV_INDEX, GRCOV_ARTIFACT) |
| 310 | + download_binary(url, archive) |
323 | 311 |
|
324 | 312 | # Extract archive in temp |
325 | 313 | tar = tarfile.open(archive, "r:xz") |
|
0 commit comments