Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(30)

Side by Side Diff: ct/py/trigger_wait_ct_task.py

Issue 1370523002: Add script that triggers a task on CTFE and then waits for its completion or times out (Closed) Base URL: https://skia.googlesource.com/buildbot@master
Patch Set: Add patchset option Created 5 years, 2 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
1 #!/usr/bin/env python
2 # Copyright (c) 2015 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file.
5
6 """Python utility that triggers and waits for tasks to complete on CTFE."""
7
8 import base64
9 import hashlib
10 import json
11 import optparse
12 import requests
13 import sys
14 import time
15
16
17 CTFE_HOST = "http://ct.skia.org"
18 CTFE_QUEUE = CTFE_HOST + '/queue/'
19 CHROMIUM_PERF_TASK_POST_URI = CTFE_HOST + "/_/webhook_add_chromium_perf_task"
20 GET_CHROMIUM_PERF_RUN_STATUS_URI = CTFE_HOST + "/get_chromium_perf_run_status"
21 CHROMIUM_PERF_RUNS_HISTORY = CTFE_HOST + "/chromium_perf_runs/"
22 GCE_WEBHOOK_SALT_METADATA_URI = (
23 "http://metadata/computeMetadata/v1/project/attributes/"
24 "webhook_request_salt")
25
26
27 POLLING_FREQUENCY_SECS = 60 # 1 minute.
28 TRYBOT_DEADLINE_SECS = 24 * 60 * 60 # 24 hours.
29
30
31 class CtTrybotException(Exception):
32 pass
33
34
35 def _CreateTaskJSON(options):
36 """Creates a JSON representation of the requested task."""
37 task_params = {}
38 task_params["username"] = options.requester
39 task_params["benchmark"] = options.benchmark
40 task_params["platform"] = "Linux"
41 task_params["page_sets"] = "10k"
42 task_params["repeat_runs"] = "3"
43 task_params["benchmark_args"] = "--output-format=csv-pivot-table"
44 task_params["browser_args_nopatch"] = (
45 "--disable-setuid-sandbox --enable-threaded-compositing "
46 "--enable-impl-side-painting")
47 task_params["browser_args_withpatch"] = (
48 "--disable-setuid-sandbox --enable-threaded-compositing "
49 "--enable-impl-side-painting")
50
51 trybot_params = {}
52 trybot_params["issue"] = options.issue
53 trybot_params["patchset"] = options.patchset
54 trybot_params["task"] = task_params
55 return json.dumps(trybot_params)
56
57
58 def _GetWebhookSaltFromMetadata():
59 """Gets webhook_request_salt from GCE's metadata server."""
60 headers = {"Metadata-Flavor": "Google"}
61 resp = requests.get(GCE_WEBHOOK_SALT_METADATA_URI, headers=headers)
62 if resp.status_code != 200:
63 raise CtTrybotException(
64 'Return code from %s was %s' % (GCE_WEBHOOK_SALT_METADATA_URI,
65 resp.status_code))
66 return resp.text
67
68
69 def _TriggerTask(options):
70 """Triggers the requested task on CTFE and returns the new task's ID."""
71 task = _CreateTaskJSON(options)
72 m = hashlib.sha512()
73 m.update(task)
74 m.update('notverysecret' if options.local else _GetWebhookSaltFromMetadata())
75 encoded = base64.standard_b64encode(m.digest())
76
77 headers = {
78 "Content-type": "application/x-www-form-urlencoded",
79 "Accept": "application/json",
80 "X-Webhook-Auth-Hash": encoded}
81 resp = requests.post(CHROMIUM_PERF_TASK_POST_URI, task, headers=headers)
82
83 if resp.status_code != 200:
84 raise CtTrybotException(
85 'Return code from %s was %s' % (CHROMIUM_PERF_TASK_POST_URI,
86 resp.status_code))
87 try:
88 ret = json.loads(resp.text)
89 except ValueError, e:
90 raise CtTrybotException(
91 'Did not get a JSON response from %s: %s' % (
92 CHROMIUM_PERF_TASK_POST_URI, e))
93 return ret["taskID"]
94
95
96 def TriggerAndWait(options):
97 task_id = _TriggerTask(options)
98
99 print
100 print 'Task %s has been successfull scheduled on CTFE (%s).' % (
101 task_id, CHROMIUM_PERF_RUNS_HISTORY)
102 print 'You will get an email once the task has been picked up by the server.'
103 print
104 print
105
106 # Now poll CTFE till the task completes or till deadline is hit.
107 time_started_polling = time.time()
108 while True:
109 if (time.time() - time_started_polling) > TRYBOT_DEADLINE_SECS:
110 raise CtTrybotException(
111 'Task did not complete in the deadline of %s seconds.' % (
112 TRYBOT_DEADLINE_SECS))
113
114 # Get the status of the task the trybot added.
115 get_url = '%s?task_id=%s' % (GET_CHROMIUM_PERF_RUN_STATUS_URI, task_id)
116 resp = requests.get(get_url)
117 if resp.status_code != 200:
118 raise CtTrybotException(
119 'Return code from %s was %s' % (GET_CHROMIUM_PERF_RUN_STATUS_URI,
120 resp.status_code))
121 try:
122 ret = json.loads(resp.text)
123 except ValueError, e:
124 raise CtTrybotException(
125 'Did not get a JSON response from %s: %s' % (get_url, e))
126 # Assert that the status is for the task we asked for.
127 assert int(ret["taskID"]) == int(task_id)
128
129 status = ret["status"]
130 if status == "Completed":
131 print
132 print ('Your run was successfully completed. Please check your email for '
133 'results of the run.')
134 print
135 return 0
136 elif status == "Completed with failures":
137 print
138 raise CtTrybotException(
139 'Your run was completed with failures. Please check your email for '
140 'links to logs of the run.')
141
142 print ('The current status of the task %s is "%s". You can view the size '
143 'of the queue here: %s' % (task_id, status, CTFE_QUEUE))
144 print 'Checking again after %s seconds' % POLLING_FREQUENCY_SECS
145 print
146 time.sleep(POLLING_FREQUENCY_SECS)
147
148
149 if '__main__' == __name__:
150 option_parser = optparse.OptionParser()
151 option_parser.add_option(
152 '', '--issue',
153 help='The Rietveld CL number to get the patch from.')
154 option_parser.add_option(
155 '', '--patchset',
156 help='The Rietveld CL patchset to use.')
157 option_parser.add_option(
158 '', '--requester',
159 help='Email address of the user who requested this run.')
160 option_parser.add_option(
161 '', '--benchmark',
162 help='The CT benchmark to run on the patch.')
163 option_parser.add_option(
164 '', '--local', default=False, action='store_true',
165 help='Uses a dummy metadata salt if this flag is true else it tries to '
166 'get the salt from GCE metadata.')
167 options, unused_args = option_parser.parse_args()
168 if (not options.issue or not options.patchset or not options.requester
169 or not options.benchmark):
170 option_parser.error('Must specify issue, patchset, requester and benchmark')
171
172 sys.exit(TriggerAndWait(options))
173
OLDNEW
« no previous file with comments | « no previous file | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698