| 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 import contextlib | 5 import contextlib |
| 6 from datetime import datetime | 6 from datetime import datetime |
| 7 import gzip | 7 import gzip |
| 8 import logging | 8 import logging |
| 9 import json | 9 import json |
| 10 import re | 10 import re |
| (...skipping 17 matching lines...) Expand all Loading... |
| 28 r'^%s/([^/]+)/builders/([^/]+)/builds/([\d]+)(?:/.*)?$' % | 28 r'^%s/([^/]+)/builders/([^/]+)/builds/([\d]+)(?:/.*)?$' % |
| 29 _HOST_NAME_PATTERN) | 29 _HOST_NAME_PATTERN) |
| 30 | 30 |
| 31 _MILO_BUILD_URL_PATTERN = re.compile( | 31 _MILO_BUILD_URL_PATTERN = re.compile( |
| 32 r'^https?://luci-milo\.appspot\.com/([^/]+)/([^/]+)/([^/]+)(?:/.*)?$') | 32 r'^https?://luci-milo\.appspot\.com/([^/]+)/([^/]+)/([^/]+)(?:/.*)?$') |
| 33 | 33 |
| 34 _STEP_URL_PATTERN = re.compile( | 34 _STEP_URL_PATTERN = re.compile( |
| 35 r'^%s/([^/]+)/builders/([^/]+)/builds/([\d]+)/steps/([^/]+)(/.*)?$' % | 35 r'^%s/([^/]+)/builders/([^/]+)/builds/([\d]+)/steps/([^/]+)(/.*)?$' % |
| 36 _HOST_NAME_PATTERN) | 36 _HOST_NAME_PATTERN) |
| 37 | 37 |
| 38 _COMMIT_POSITION_PATTERN = re.compile( |
| 39 r'refs/heads/master@{#(\d+)}$', re.IGNORECASE) |
| 40 |
| 38 # These values are buildbot constants used for Build and BuildStep. | 41 # These values are buildbot constants used for Build and BuildStep. |
| 39 # This line was copied from buildbot/master/buildbot/status/results.py. | 42 # This line was copied from buildbot/master/buildbot/status/results.py. |
| 40 SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY, CANCELLED = range(7) | 43 SUCCESS, WARNINGS, FAILURE, SKIPPED, EXCEPTION, RETRY, CANCELLED = range(7) |
| 41 | 44 |
| 42 | 45 |
| 43 def GetRecentCompletedBuilds(master_name, builder_name, http_client): | 46 def GetRecentCompletedBuilds(master_name, builder_name, http_client): |
| 44 """Returns a sorted list of recent completed builds for the given builder. | 47 """Returns a sorted list of recent completed builds for the given builder. |
| 45 | 48 |
| 46 Sorted by completed time, newer builds at beginning of the returned list. | 49 Sorted by completed time, newer builds at beginning of the returned list. |
| 47 """ | 50 """ |
| (...skipping 166 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 214 times = build_data_json.get('times') | 217 times = build_data_json.get('times') |
| 215 if not times or len(times) < 2 or not times[1]: | 218 if not times or len(times) < 2 or not times[1]: |
| 216 return None | 219 return None |
| 217 return datetime.utcfromtimestamp(times[1]) | 220 return datetime.utcfromtimestamp(times[1]) |
| 218 | 221 |
| 219 | 222 |
| 220 def GetBuildResult(build_data_json): | 223 def GetBuildResult(build_data_json): |
| 221 return build_data_json.get('results') | 224 return build_data_json.get('results') |
| 222 | 225 |
| 223 | 226 |
| 227 def _GetCommitPosition(commit_position_line): |
| 228 if commit_position_line: |
| 229 match = _COMMIT_POSITION_PATTERN.match(commit_position_line) |
| 230 if match: |
| 231 return int(match.group(1)) |
| 232 return None |
| 233 |
| 234 |
| 224 def ExtractBuildInfo(master_name, builder_name, build_number, build_data): | 235 def ExtractBuildInfo(master_name, builder_name, build_number, build_data): |
| 225 """Extracts and returns build information as an instance of BuildInfo.""" | 236 """Extracts and returns build information as an instance of BuildInfo.""" |
| 226 build_info = BuildInfo(master_name, builder_name, build_number) | 237 build_info = BuildInfo(master_name, builder_name, build_number) |
| 227 | 238 |
| 228 data_json = json.loads(build_data) | 239 data_json = json.loads(build_data) |
| 229 chromium_revision = GetBuildProperty( | 240 chromium_revision = GetBuildProperty( |
| 230 data_json.get('properties', []), 'got_revision') | 241 data_json.get('properties', []), 'got_revision') |
| 242 commit_position_line = GetBuildProperty( |
| 243 data_json.get('properties', []), 'got_revision_cp') |
| 231 | 244 |
| 232 build_info.build_start_time = GetBuildStartTime(data_json) | 245 build_info.build_start_time = GetBuildStartTime(data_json) |
| 233 build_info.build_end_time = GetBuildEndTime(data_json) | 246 build_info.build_end_time = GetBuildEndTime(data_json) |
| 234 build_info.chromium_revision = chromium_revision | 247 build_info.chromium_revision = chromium_revision |
| 248 build_info.commit_position = _GetCommitPosition(commit_position_line) |
| 235 build_info.completed = data_json.get('currentStep') is None | 249 build_info.completed = data_json.get('currentStep') is None |
| 236 build_info.result = GetBuildResult(data_json) | 250 build_info.result = GetBuildResult(data_json) |
| 237 | 251 |
| 238 changes = data_json.get('sourceStamp', {}).get('changes', []) | 252 changes = data_json.get('sourceStamp', {}).get('changes', []) |
| 239 for change in changes: | 253 for change in changes: |
| 240 if change['revision'] not in build_info.blame_list: | 254 if change['revision'] not in build_info.blame_list: |
| 241 build_info.blame_list.append(change['revision']) | 255 build_info.blame_list.append(change['revision']) |
| 242 | 256 |
| 243 # Step categories: | 257 # Step categories: |
| 244 # 1. A step is passed if it is in SUCCESS or WARNINGS status. | 258 # 1. A step is passed if it is in SUCCESS or WARNINGS status. |
| (...skipping 20 matching lines...) Expand all Loading... |
| 265 # the annotating step like "steps" fail too. Such annotating steps have a | 279 # the annotating step like "steps" fail too. Such annotating steps have a |
| 266 # log with name "preamble". | 280 # log with name "preamble". |
| 267 continue | 281 continue |
| 268 | 282 |
| 269 if step_result in (SUCCESS, WARNINGS): | 283 if step_result in (SUCCESS, WARNINGS): |
| 270 build_info.passed_steps.append(step_name) | 284 build_info.passed_steps.append(step_name) |
| 271 elif step_result == FAILURE: | 285 elif step_result == FAILURE: |
| 272 build_info.failed_steps.append(step_name) | 286 build_info.failed_steps.append(step_name) |
| 273 | 287 |
| 274 return build_info | 288 return build_info |
| OLD | NEW |