| 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 |