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

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: 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"
borenet 2015/09/24 18:42:46 Can we plumb the platform and page_sets parameters
rmistry 2015/09/24 18:51:18 Yes we could plumb different combinations of the p
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["task"] = task_params
54 return json.dumps(trybot_params)
55
56
57 def _GetWebhookSaltFromMetadata():
58 """Gets webhook_request_salt from GCE's metadata server."""
59 headers = {"Metadata-Flavor": "Google"}
60 resp = requests.get(GCE_WEBHOOK_SALT_METADATA_URI, headers=headers)
61 if resp.status_code != 200:
62 raise CtTrybotException(
63 'Return code from %s was %s' % (GCE_WEBHOOK_SALT_METADATA_URI,
64 resp.status_code))
65 return resp.text
66
67
68 def _TriggerTask(options):
69 """Triggers the requested task on CTFE and returns the new task's ID."""
70 task = _CreateTaskJSON(options)
71 m = hashlib.sha512()
72 m.update(task)
73 m.update('notverysecret' if options.local else _GetWebhookSaltFromMetadata())
74 encoded = base64.standard_b64encode(m.digest())
75
76 headers = {
77 "Content-type": "application/x-www-form-urlencoded",
78 "Accept": "application/json",
79 "X-Webhook-Auth-Hash": encoded}
80 resp = requests.post(CHROMIUM_PERF_TASK_POST_URI, task, headers=headers)
81
82 if resp.status_code != 200:
83 raise CtTrybotException(
84 'Return code from %s was %s' % (CHROMIUM_PERF_TASK_POST_URI,
85 resp.status_code))
86 try:
87 ret = json.loads(resp.text)
88 except ValueError, e:
89 raise CtTrybotException(
90 'Did not get a JSON response from %s: %s' % (
91 CHROMIUM_PERF_TASK_POST_URI, e))
92 return ret["taskID"]
93
94
95 def TriggerAndWait(options):
96 task_id = _TriggerTask(options)
97
98 print
99 print 'Task %s has been successfull scheduled on CTFE (%s).' % (
100 task_id, CHROMIUM_PERF_RUNS_HISTORY)
101 print 'You will get an email once the task has been picked up by the server.'
102 print
103 print
104
105 # Now poll CTFE till the task completes or till deadline is hit.
106 time_started_polling = time.time()
107 while True:
108 if (time.time() - time_started_polling) > TRYBOT_DEADLINE_SECS:
109 raise CtTrybotException(
110 'Task did not complete in the deadline of %s seconds.' % (
111 TRYBOT_DEADLINE_SECS))
112
113 # Get the status of the task the trybot added.
114 get_url = '%s?task_id=%s' % (GET_CHROMIUM_PERF_RUN_STATUS_URI, task_id)
115 resp = requests.get(get_url)
116 if resp.status_code != 200:
117 raise CtTrybotException(
118 'Return code from %s was %s' % (GET_CHROMIUM_PERF_RUN_STATUS_URI,
119 resp.status_code))
120 try:
121 ret = json.loads(resp.text)
122 except ValueError, e:
123 raise CtTrybotException(
124 'Did not get a JSON response from %s: %s' % (get_url, e))
125 # Assert that the status is for the task we asked for.
126 assert int(ret["taskID"]) == int(task_id)
127
128 status = ret["status"]
129 if status == "Completed":
130 print
131 print ('Your run was successfully completed. Please check your email for '
132 'results of the run.')
133 print
134 return 0
135 elif status == "Completed with failures":
136 print
137 raise CtTrybotException(
138 'Your run was completed with failures. Please check your email for '
139 'links to logs of the run.')
140
141 print ('The current status of the task %s is "%s". You can view the size '
142 'of the queue here: %s' % (task_id, status, CTFE_QUEUE))
143 print 'Checking again after %s seconds' % POLLING_FREQUENCY_SECS
144 print
145 time.sleep(POLLING_FREQUENCY_SECS)
146
147
148 if '__main__' == __name__:
149 option_parser = optparse.OptionParser()
150 option_parser.add_option(
151 '', '--issue',
152 help='The Rietveld CL number to get the patch from.')
borenet 2015/09/24 18:42:46 Looks like we're missing the patchset option?
rmistry 2015/09/24 18:51:18 I initially thought it would always use only the l
153 option_parser.add_option(
154 '', '--requester',
155 help='Email address of the user who requested this run.')
156 option_parser.add_option(
157 '', '--benchmark',
158 help='The CT benchmark to run on the patch.')
159 option_parser.add_option(
160 '', '--local', default=False, action='store_true',
161 help='Uses a dummy metadata salt if this flag is true else it tries to '
162 'get the salt from GCE metadata.')
163 options, unused_args = option_parser.parse_args()
164 if not options.issue or not options.requester or not options.benchmark:
165 option_parser.error('Must specify issue, requester and benchmark')
166
167 sys.exit(TriggerAndWait(options))
168
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