OLD | NEW |
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 |
| 23 |
22 # URL template for fetching JSON data about builds. | 24 # URL template for fetching JSON data about builds. |
23 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/' |
24 '%(build_num)s?as_text=1&filter=0') | 26 '%(build_num)s?as_text=1&filter=0') |
25 | 27 |
26 # URL template for displaying build steps. | 28 # URL template for displaying build steps. |
27 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') |
28 | 30 |
29 # Try server status page for the perf try server. | 31 # Try server status page for the perf try server. |
30 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' |
31 | 33 |
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
194 | 196 |
195 Returns: | 197 Returns: |
196 A dictionary with build information if build exists, otherwise None. | 198 A dictionary with build information if build exists, otherwise None. |
197 """ | 199 """ |
198 builds_json = _FetchBuilderData(buildbot_url) | 200 builds_json = _FetchBuilderData(buildbot_url) |
199 if builds_json: | 201 if builds_json: |
200 return json.loads(builds_json) | 202 return json.loads(builds_json) |
201 return None | 203 return None |
202 | 204 |
203 | 205 |
204 def _GetBuildBotUrl(builder_host, builder_port): | 206 def _GetBuildBotUrl(builder_type): |
205 """Gets build bot URL for fetching build info. | 207 """Gets build bot URL for fetching build info. |
206 | 208 |
207 Bisect builder bots are hosted on tryserver.chromium.perf, though we cannot | 209 Bisect builder bots are hosted on tryserver.chromium.perf, though we cannot |
208 access this tryserver using host and port number directly, so we use another | 210 access this tryserver using host and port number directly, so we use another |
209 tryserver URL for the perf tryserver. | 211 tryserver URL for the perf tryserver. |
210 | 212 |
211 Args: | 213 Args: |
212 builder_host: Hostname of the server where the builder is hosted. | 214 builder_type: Determines what type of builder is used, e.g. "perf". |
213 builder_port: Port number of ther server where the builder is hosted. | |
214 | 215 |
215 Returns: | 216 Returns: |
216 URL of the buildbot as a string. | 217 URL of the buildbot as a string. |
217 """ | 218 """ |
218 if (builder_host == PERF_BISECT_BUILDER_HOST and | 219 if builder_type == fetch_build.PERF_BUILDER: |
219 builder_port == PERF_BISECT_BUILDER_PORT): | |
220 return PERF_TRY_SERVER_URL | 220 return PERF_TRY_SERVER_URL |
221 else: | 221 else: |
222 return 'http://%s:%s' % (builder_host, builder_port) | 222 raise NotImplementedError('Cannot yet get non-perf builds.') |
223 | 223 |
224 | 224 |
225 def GetBuildStatus(build_num, bot_name, builder_host, builder_port): | 225 def GetBuildStatus(build_num, bot_name, builder_type): |
226 """Gets build status from the buildbot status page for a given build number. | 226 """Gets build status from the buildbot status page for a given build number. |
227 | 227 |
228 Args: | 228 Args: |
229 build_num: A build number on tryserver to determine its status. | 229 build_num: A build number on tryserver to determine its status. |
230 bot_name: Name of the bot where the build information is scanned. | 230 bot_name: Name of the bot where the build information is scanned. |
231 builder_host: Hostname of the server where the builder is hosted. | 231 builder_type: Type of builder, e.g. "perf". |
232 builder_port: Port number of the server where the builder is hosted. | |
233 | 232 |
234 Returns: | 233 Returns: |
235 A pair which consists of build status (SUCCESS, FAILED or PENDING) and a | 234 A pair which consists of build status (SUCCESS, FAILED or PENDING) and a |
236 link to build status page on the waterfall. | 235 link to build status page on the waterfall. |
237 """ | 236 """ |
238 results_url = None | 237 results_url = None |
239 if build_num: | 238 if build_num: |
240 # Get the URL for requesting JSON data with status information. | 239 # Get the URL for requesting JSON data with status information. |
241 server_url = _GetBuildBotUrl(builder_host, builder_port) | 240 server_url = _GetBuildBotUrl(builder_type) |
242 buildbot_url = BUILDER_JSON_URL % { | 241 buildbot_url = BUILDER_JSON_URL % { |
243 'server_url': server_url, | 242 'server_url': server_url, |
244 'bot_name': bot_name, | 243 'bot_name': bot_name, |
245 'build_num': build_num, | 244 'build_num': build_num, |
246 } | 245 } |
247 build_data = _GetBuildData(buildbot_url) | 246 build_data = _GetBuildData(buildbot_url) |
248 if build_data: | 247 if build_data: |
249 # Link to build on the buildbot showing status of build steps. | 248 # Link to build on the buildbot showing status of build steps. |
250 results_url = BUILDER_HTML_URL % { | 249 results_url = BUILDER_HTML_URL % { |
251 'server_url': server_url, | 250 'server_url': server_url, |
252 'bot_name': bot_name, | 251 'bot_name': bot_name, |
253 'build_num': build_num, | 252 'build_num': build_num, |
254 } | 253 } |
255 if _IsBuildFailed(build_data): | 254 if _IsBuildFailed(build_data): |
256 return (FAILED, results_url) | 255 return (FAILED, results_url) |
257 | 256 |
258 elif _IsBuildSuccessful(build_data): | 257 elif _IsBuildSuccessful(build_data): |
259 return (OK, results_url) | 258 return (OK, results_url) |
260 return (PENDING, results_url) | 259 return (PENDING, results_url) |
261 | 260 |
262 | 261 |
263 def GetBuildNumFromBuilder(build_reason, bot_name, builder_host, builder_port): | 262 def GetBuildNumFromBuilder(build_reason, bot_name, builder_type): |
264 """Gets build number on build status page for a given 'build reason'. | 263 """Gets build number on build status page for a given 'build reason'. |
265 | 264 |
266 This function parses the JSON data from buildbot page and collects basic | 265 This function parses the JSON data from buildbot page and collects basic |
267 information about the all the builds, and then uniquely identifies the build | 266 information about the all the builds, and then uniquely identifies the build |
268 based on the 'reason' attribute in builds's JSON data. | 267 based on the 'reason' attribute in builds's JSON data. |
269 | 268 |
270 The 'reason' attribute set is when a build request is posted, and it is used | 269 The 'reason' attribute set is when a build request is posted, and it is used |
271 to identify the build on status page. | 270 to identify the build on status page. |
272 | 271 |
273 Args: | 272 Args: |
274 build_reason: A unique build name set to build on tryserver. | 273 build_reason: A unique build name set to build on tryserver. |
275 bot_name: Name of the bot where the build information is scanned. | 274 bot_name: Name of the bot where the build information is scanned. |
276 builder_host: Hostname of the server where the builder is hosted. | 275 builder_type: Type of builder, e.g. "perf". |
277 builder_port: Port number of ther server where the builder is hosted. | |
278 | 276 |
279 Returns: | 277 Returns: |
280 A build number as a string if found, otherwise None. | 278 A build number as a string if found, otherwise None. |
281 """ | 279 """ |
282 # Gets the buildbot url for the given host and port. | 280 # Gets the buildbot url for the given host and port. |
283 server_url = _GetBuildBotUrl(builder_host, builder_port) | 281 server_url = _GetBuildBotUrl(builder_type) |
284 buildbot_url = BUILDER_JSON_URL % { | 282 buildbot_url = BUILDER_JSON_URL % { |
285 'server_url': server_url, | 283 'server_url': server_url, |
286 'bot_name': bot_name, | 284 'bot_name': bot_name, |
287 'build_num': '_all', | 285 'build_num': '_all', |
288 } | 286 } |
289 builds_json = _FetchBuilderData(buildbot_url) | 287 builds_json = _FetchBuilderData(buildbot_url) |
290 if builds_json: | 288 if builds_json: |
291 builds_data = json.loads(builds_json) | 289 builds_data = json.loads(builds_json) |
292 for current_build in builds_data: | 290 for current_build in builds_data: |
293 if builds_data[current_build].get('reason') == build_reason: | 291 if builds_data[current_build].get('reason') == build_reason: |
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
360 options, _ = parser.parse_args() | 358 options, _ = parser.parse_args() |
361 if not options.host or not options.port: | 359 if not options.host or not options.port: |
362 parser.print_help() | 360 parser.print_help() |
363 return 1 | 361 return 1 |
364 params = _GetRequestParams(options) | 362 params = _GetRequestParams(options) |
365 PostTryJob(options.host, options.port, params) | 363 PostTryJob(options.host, options.port, params) |
366 | 364 |
367 | 365 |
368 if __name__ == '__main__': | 366 if __name__ == '__main__': |
369 sys.exit(Main(sys.argv)) | 367 sys.exit(Main(sys.argv)) |
OLD | NEW |