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

Side by Side Diff: tools/auto_bisect/request_build.py

Issue 806943007: Use builder_type when requesting/fetching builds, and add support for full linux builds. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Fixes in response to code review Created 5 years, 11 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 | « tools/auto_bisect/fetch_build.py ('k') | tools/run-bisect-perf-regression.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 # Copyright 2014 The Chromium Authors. All rights reserved. 1 # Copyright 2014 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 """This module contains functionality for starting build try jobs via HTTP. 5 """This module contains functionality for starting build try jobs via HTTP.
6 6
7 This includes both sending a request to start a job, and also related code 7 This includes both sending a request to start a job, and also related code
8 for querying the status of the job. 8 for querying the status of the job.
9 9
10 This module can be either run as a stand-alone script to send a request to a 10 This module can be either run as a stand-alone script to send a request to a
11 builder, or imported and used by calling the public functions below. 11 builder, or imported and used by calling the public functions below.
12 """ 12 """
13 13
14 import getpass 14 import getpass
15 import json 15 import json
16 import optparse 16 import optparse
17 import os 17 import os
18 import sys 18 import sys
19 import urllib 19 import urllib
20 import urllib2 20 import urllib2
21 21
22 import fetch_build 22 import fetch_build
23 23
24 # URL template for fetching JSON data about builds. 24 # URL template for fetching JSON data about builds.
25 BUILDER_JSON_URL = ('%(server_url)s/json/builders/%(bot_name)s/builds/' 25 BUILDER_JSON_URL = ('%(server_url)s/json/builders/%(bot_name)s/builds/'
26 '%(build_num)s?as_text=1&filter=0') 26 '%(build_num)s?as_text=1&filter=0')
27 27
28 # URL template for displaying build steps. 28 # URL template for displaying build steps.
29 BUILDER_HTML_URL = ('%(server_url)s/builders/%(bot_name)s/builds/%(build_num)s') 29 BUILDER_HTML_URL = '%(server_url)s/builders/%(bot_name)s/builds/%(build_num)s'
30 30
31 # Try server status page for the perf try server. 31 # Try server status page URLs, used to get build status.
32 PERF_TRY_SERVER_URL = 'http://build.chromium.org/p/tryserver.chromium.perf' 32 PERF_TRY_SERVER_URL = 'http://build.chromium.org/p/tryserver.chromium.perf'
33 LINUX_TRY_SERVER_URL = 'http://build.chromium.org/p/tryserver.chromium.linux'
33 34
34 # Hostname of the tryserver where perf bisect builders are hosted. 35 # Status codes that can be returned by the GetBuildStatus method
35 # This is used for posting build requests to the tryserver.
36 PERF_BISECT_BUILDER_HOST = 'master4.golo.chromium.org'
37
38 # The default 'try_job_port' on tryserver to post build request.
39 PERF_BISECT_BUILDER_PORT = 8341
40
41 # Status codes that can be returned by the GetBuildStatus method.
42 # From buildbot.status.builder. 36 # From buildbot.status.builder.
43 # See: http://docs.buildbot.net/current/developer/results.html 37 # See: http://docs.buildbot.net/current/developer/results.html
44 SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY, TRYPENDING = range(7) 38 SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY, TRYPENDING = range(7)
45
46 OK = (SUCCESS, WARNINGS) # These indicate build is complete. 39 OK = (SUCCESS, WARNINGS) # These indicate build is complete.
47 FAILED = (FAILURE, EXCEPTION, SKIPPED) # These indicate build failure. 40 FAILED = (FAILURE, EXCEPTION, SKIPPED) # These indicate build failure.
48 PENDING = (RETRY, TRYPENDING) # These indicate in progress or in pending queue. 41 PENDING = (RETRY, TRYPENDING) # These indicate in progress or in pending queue.
49 42
50 43
51 class ServerAccessError(Exception): 44 class ServerAccessError(Exception):
52 45
53 def __str__(self): 46 def __str__(self):
54 return '%s\nSorry, cannot connect to server.' % self.args[0] 47 return '%s\nSorry, cannot connect to server.' % self.args[0]
55 48
56 49
57 def PostTryJob(host, port, params):
58 """Sends a build request to the server using the HTTP protocol.
59
60 The required parameters are:
61 'revision': "src@rev", where rev is a git hash or SVN revision.
62 'bot': Name of builder bot to use, e.g. "win_perf_bisect_builder".
63
64 Args:
65 host: Hostname of the try server.
66 port: Port of the try server.
67 params: A dictionary of parameters to be sent in the POST request.
68
69 Returns:
70 True if the request is posted successfully.
71
72 Raises:
73 ServerAccessError: Failed to make a request to the try server.
74 ValueError: Not all of the expected inputs were given.
75 """
76 if not params.get('revision'):
77 raise ValueError('Missing revision number.')
78 if not params.get('bot'):
79 raise ValueError('Missing bot name.')
80
81 base_url = 'http://%s:%s/send_try_patch' % (host, port)
82 print 'Posting build request by HTTP.'
83 print 'URL: %s, params: %s' % (base_url, params)
84
85 connection = None
86 try:
87 print 'Opening connection...'
88 connection = urllib2.urlopen(base_url, urllib.urlencode(params))
89 print 'Done, request sent to server to produce build.'
90 except IOError as e:
91 raise ServerAccessError('%s is unaccessible. Reason: %s' % (base_url, e))
92 if not connection:
93 raise ServerAccessError('%s is unaccessible.' % base_url)
94
95 response = connection.read()
96 print 'Received response from server: %s' % response
97 if response != 'OK':
98 raise ServerAccessError('Response was not "OK".')
99 return True
100
101
102 def _IsBuildRunning(build_data): 50 def _IsBuildRunning(build_data):
103 """Checks whether the build is in progress on buildbot. 51 """Checks whether the build is in progress on buildbot.
104 52
105 Presence of currentStep element in build JSON indicates build is in progress. 53 Presence of currentStep element in build JSON indicates build is in progress.
106 54
107 Args: 55 Args:
108 build_data: A dictionary with build data, loaded from buildbot JSON API. 56 build_data: A dictionary with build data, loaded from buildbot JSON API.
109 57
110 Returns: 58 Returns:
111 True if build is in progress, otherwise False. 59 True if build is in progress, otherwise False.
(...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after
211 tryserver URL for the perf tryserver. 159 tryserver URL for the perf tryserver.
212 160
213 Args: 161 Args:
214 builder_type: Determines what type of builder is used, e.g. "perf". 162 builder_type: Determines what type of builder is used, e.g. "perf".
215 163
216 Returns: 164 Returns:
217 URL of the buildbot as a string. 165 URL of the buildbot as a string.
218 """ 166 """
219 if builder_type == fetch_build.PERF_BUILDER: 167 if builder_type == fetch_build.PERF_BUILDER:
220 return PERF_TRY_SERVER_URL 168 return PERF_TRY_SERVER_URL
221 else: 169 if builder_type == fetch_build.FULL_BUILDER:
222 raise NotImplementedError('Cannot yet get non-perf builds.') 170 return LINUX_TRY_SERVER_URL
171 raise NotImplementedError('Unsupported builder type "%s".' % builder_type)
223 172
224 173
225 def GetBuildStatus(build_num, bot_name, builder_type): 174 def GetBuildStatus(build_num, bot_name, builder_type):
226 """Gets build status from the buildbot status page for a given build number. 175 """Gets build status from the buildbot status page for a given build number.
227 176
228 Args: 177 Args:
229 build_num: A build number on tryserver to determine its status. 178 build_num: A build number on tryserver to determine its status.
230 bot_name: Name of the bot where the build information is scanned. 179 bot_name: Name of the bot where the build information is scanned.
231 builder_type: Type of builder, e.g. "perf". 180 builder_type: Type of builder, e.g. "perf".
232 181
233 Returns: 182 Returns:
234 A pair which consists of build status (SUCCESS, FAILED or PENDING) and a 183 A pair which consists of build status (SUCCESS, FAILED or PENDING) and a
235 link to build status page on the waterfall. 184 link to build status page on the waterfall.
236 """ 185 """
186 # TODO(prasadv, qyearsley): Make this a method of BuildArchive
187 # (which may be renamed to BuilderTryBot or Builder).
237 results_url = None 188 results_url = None
238 if build_num: 189 if build_num:
239 # Get the URL for requesting JSON data with status information. 190 # Get the URL for requesting JSON data with status information.
240 server_url = _GetBuildBotUrl(builder_type) 191 server_url = _GetBuildBotUrl(builder_type)
241 buildbot_url = BUILDER_JSON_URL % { 192 buildbot_url = BUILDER_JSON_URL % {
242 'server_url': server_url, 193 'server_url': server_url,
243 'bot_name': bot_name, 194 'bot_name': bot_name,
244 'build_num': build_num, 195 'build_num': build_num,
245 } 196 }
246 build_data = _GetBuildData(buildbot_url) 197 build_data = _GetBuildData(buildbot_url)
(...skipping 23 matching lines...) Expand all
270 to identify the build on status page. 221 to identify the build on status page.
271 222
272 Args: 223 Args:
273 build_reason: A unique build name set to build on tryserver. 224 build_reason: A unique build name set to build on tryserver.
274 bot_name: Name of the bot where the build information is scanned. 225 bot_name: Name of the bot where the build information is scanned.
275 builder_type: Type of builder, e.g. "perf". 226 builder_type: Type of builder, e.g. "perf".
276 227
277 Returns: 228 Returns:
278 A build number as a string if found, otherwise None. 229 A build number as a string if found, otherwise None.
279 """ 230 """
231 # TODO(prasadv, qyearsley): Make this a method of BuildArchive
232 # (which may be renamed to BuilderTryBot or Builder).
280 # Gets the buildbot url for the given host and port. 233 # Gets the buildbot url for the given host and port.
281 server_url = _GetBuildBotUrl(builder_type) 234 server_url = _GetBuildBotUrl(builder_type)
282 buildbot_url = BUILDER_JSON_URL % { 235 buildbot_url = BUILDER_JSON_URL % {
283 'server_url': server_url, 236 'server_url': server_url,
284 'bot_name': bot_name, 237 'bot_name': bot_name,
285 'build_num': '_all', 238 'build_num': '_all',
286 } 239 }
287 builds_json = _FetchBuilderData(buildbot_url) 240 builds_json = _FetchBuilderData(buildbot_url)
288 if builds_json: 241 if builds_json:
289 builds_data = json.loads(builds_json) 242 builds_data = json.loads(builds_json)
290 for current_build in builds_data: 243 for current_build in builds_data:
291 if builds_data[current_build].get('reason') == build_reason: 244 if builds_data[current_build].get('reason') == build_reason:
292 return builds_data[current_build].get('number') 245 return builds_data[current_build].get('number')
293 return None 246 return None
294
295
296 def _GetRequestParams(options):
297 """Extracts request parameters which will be passed to PostTryJob.
298
299 Args:
300 options: The options object parsed from the command line.
301
302 Returns:
303 A dictionary with parameters to pass to PostTryJob.
304 """
305 params = {
306 'user': options.user,
307 'name': options.name,
308 }
309 # Add other parameters if they're available in the options object.
310 for key in ['email', 'revision', 'root', 'bot', 'patch']:
311 option = getattr(options, key)
312 if option:
313 params[key] = option
314 return params
315
316
317 def _GenParser():
318 """Returns a parser for getting command line arguments."""
319 usage = ('%prog [options]\n'
320 'Post a build request to the try server for the given revision.')
321 parser = optparse.OptionParser(usage=usage)
322 parser.add_option('-H', '--host',
323 help='Host address of the try server (required).')
324 parser.add_option('-P', '--port', type='int',
325 help='HTTP port of the try server (required).')
326 parser.add_option('-u', '--user', default=getpass.getuser(),
327 dest='user',
328 help='Owner user name [default: %default]')
329 parser.add_option('-e', '--email',
330 default=os.environ.get('TRYBOT_RESULTS_EMAIL_ADDRESS',
331 os.environ.get('EMAIL_ADDRESS')),
332 help=('Email address where to send the results. Use either '
333 'the TRYBOT_RESULTS_EMAIL_ADDRESS environment '
334 'variable or EMAIL_ADDRESS to set the email address '
335 'the try bots report results to [default: %default]'))
336 parser.add_option('-n', '--name',
337 default='try_job_http',
338 help='Descriptive name of the try job')
339 parser.add_option('-b', '--bot',
340 help=('Only one builder per run may be specified; to post '
341 'jobs on on multiple builders, run script for each '
342 'builder separately.'))
343 parser.add_option('-r', '--revision',
344 help=('Revision to use for the try job. The revision may '
345 'be determined by the try server; see its waterfall '
346 'for more info.'))
347 parser.add_option('--root',
348 help=('Root to use for the patch; base subdirectory for '
349 'patch created in a subdirectory.'))
350 parser.add_option('--patch',
351 help='Patch information.')
352 return parser
353
354
355 def Main(_):
356 """Posts a try job based on command line parameters."""
357 parser = _GenParser()
358 options, _ = parser.parse_args()
359 if not options.host or not options.port:
360 parser.print_help()
361 return 1
362 params = _GetRequestParams(options)
363 PostTryJob(options.host, options.port, params)
364
365
366 if __name__ == '__main__':
367 sys.exit(Main(sys.argv))
OLDNEW
« no previous file with comments | « tools/auto_bisect/fetch_build.py ('k') | tools/run-bisect-perf-regression.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698