Chromium Code Reviews| OLD | NEW |
|---|---|
| 1 # Copyright 2015 The Chromium Authors. All rights reserved. | 1 # Copyright 2015 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 """An interface for holding state and result of revisions in a bisect job. | 5 """An interface for holding state and result of revisions in a bisect job. |
| 6 | 6 |
| 7 When implementing support for tests other than perf, one should extend this | 7 When implementing support for tests other than perf, one should extend this |
| 8 class so that the bisect module and recipe can use it. | 8 class so that the bisect module and recipe can use it. |
| 9 | 9 |
| 10 See perf_revision_state for an example. | 10 See perf_revision_state for an example. |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 ( | 24 ( |
| 25 NEW, # A revision_state object that has just been initialized. | 25 NEW, # A revision_state object that has just been initialized. |
| 26 BUILDING, # Requested a build for this revision, waiting for it. | 26 BUILDING, # Requested a build for this revision, waiting for it. |
| 27 TESTING, # A test job for this revision was triggered, waiting for it. | 27 TESTING, # A test job for this revision was triggered, waiting for it. |
| 28 TESTED, # The test job completed with non-failing results. | 28 TESTED, # The test job completed with non-failing results. |
| 29 FAILED, # Either the build or the test jobs failed or timed out. | 29 FAILED, # Either the build or the test jobs failed or timed out. |
| 30 ABORTED, # The build or test job was aborted. (For use in multi-secting). | 30 ABORTED, # The build or test job was aborted. (For use in multi-secting). |
| 31 SKIPPED, # A revision that was not built or tested for a special reason, | 31 SKIPPED, # A revision that was not built or tested for a special reason, |
| 32 # such as those ranges that we know are broken, or when nudging | 32 # such as those ranges that we know are broken, or when nudging |
| 33 # revisions. | 33 # revisions. |
| 34 ) = xrange(7) | 34 NEED_MORE_DATA, |
|
qyearsley
2016/01/26 19:26:00
You could add a comment for this status -- still n
RobertoCN
2016/02/01 17:29:51
Done.
| |
| 35 ) = xrange(8) | |
| 35 | 36 |
| 36 def __init__(self, revision_string, bisector, | 37 def __init__(self, revision_string, bisector, |
| 37 dependency_depot_name=None, base_revision=None, | 38 dependency_depot_name=None, base_revision=None, |
| 38 deps_revision=None, cp=None): | 39 deps_revision=None, cp=None): |
| 39 """Creates a new instance to track the state of a revision. | 40 """Creates a new instance to track the state of a revision. |
| 40 | 41 |
| 41 There are two use cases for this constructor: | 42 There are two use cases for this constructor: |
| 42 - Creating a revision state for a chromium revision, OR | 43 - Creating a revision state for a chromium revision, OR |
| 43 - Creating a revision state for a chromium revision plus an explicitly | 44 - Creating a revision state for a chromium revision plus an explicitly |
| 44 specified revision of a dependency repository (a DEPS change). | 45 specified revision of a dependency repository (a DEPS change). |
| (...skipping 63 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 108 else: | 109 else: |
| 109 self.commit_hash, self.commit_pos = self._commit_from_rev_string() | 110 self.commit_hash, self.commit_pos = self._commit_from_rev_string() |
| 110 self.build_url = self.bisector.get_platform_gs_prefix() + self._gs_suffix() | 111 self.build_url = self.bisector.get_platform_gs_prefix() + self._gs_suffix() |
| 111 | 112 |
| 112 @property | 113 @property |
| 113 def tested(self): | 114 def tested(self): |
| 114 return self.status in [RevisionState.TESTED] | 115 return self.status in [RevisionState.TESTED] |
| 115 | 116 |
| 116 @property | 117 @property |
| 117 def in_progress(self): | 118 def in_progress(self): |
| 118 return self.status in (RevisionState.BUILDING, RevisionState.TESTING) | 119 return self.status in (RevisionState.BUILDING, RevisionState.TESTING, |
| 120 RevisionState.NEED_MORE_DATA) | |
| 119 | 121 |
| 120 @property | 122 @property |
| 121 def failed(self): | 123 def failed(self): |
| 122 return self.status == RevisionState.FAILED | 124 return self.status == RevisionState.FAILED |
| 123 | 125 |
| 124 @property | 126 @property |
| 125 def aborted(self): | 127 def aborted(self): |
| 126 return self.status == RevisionState.ABORTED | 128 return self.status == RevisionState.ABORTED |
| 127 | 129 |
| 128 @property | 130 @property |
| (...skipping 12 matching lines...) Expand all Loading... | |
| 141 def bad(self, value): | 143 def bad(self, value): |
| 142 self._good = not value | 144 self._good = not value |
| 143 | 145 |
| 144 def start_job(self): | 146 def start_job(self): |
| 145 """Starts a build, or a test job if the build is available.""" | 147 """Starts a build, or a test job if the build is available.""" |
| 146 if self.status == RevisionState.NEW and not self._is_build_archived(): | 148 if self.status == RevisionState.NEW and not self._is_build_archived(): |
| 147 self._request_build() | 149 self._request_build() |
| 148 self.status = RevisionState.BUILDING | 150 self.status = RevisionState.BUILDING |
| 149 return | 151 return |
| 150 | 152 |
| 151 if self._is_build_archived() and self.status in [RevisionState.NEW, | 153 if self._is_build_archived() and self.status in [ |
| 152 RevisionState.BUILDING]: | 154 RevisionState.NEW, RevisionState.BUILDING, |
| 155 RevisionState.NEED_MORE_DATA]: | |
|
qyearsley
2016/01/26 19:26:00
Below when checking whether status is one of sever
RobertoCN
2016/02/01 17:29:51
Done.
| |
| 153 self._do_test() | 156 self._do_test() |
| 154 self.status = RevisionState.TESTING | 157 self.status = RevisionState.TESTING |
| 155 | 158 |
| 156 def abort(self): # pragma: no cover | 159 def abort(self): # pragma: no cover |
| 157 """Aborts the job. | 160 """Aborts the job. |
| 158 | 161 |
| 159 This method is typically called when the bisect no longer requires it. Such | 162 This method is typically called when the bisect no longer requires it. Such |
| 160 as when a later good revision or an earlier bad revision have been found in | 163 as when a later good revision or an earlier bad revision have been found in |
| 161 parallel. | 164 parallel. |
| 162 """ | 165 """ |
| (...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 236 """Checks on the pending jobs and updates status accordingly. | 239 """Checks on the pending jobs and updates status accordingly. |
| 237 | 240 |
| 238 This method will check for the build to complete and then trigger the test, | 241 This method will check for the build to complete and then trigger the test, |
| 239 or will wait for the test as appropriate. | 242 or will wait for the test as appropriate. |
| 240 | 243 |
| 241 To wait for the test we try to get the buildbot job url from GS, and if | 244 To wait for the test we try to get the buildbot job url from GS, and if |
| 242 available, we query the status of such job. | 245 available, we query the status of such job. |
| 243 """ | 246 """ |
| 244 if self.status == RevisionState.BUILDING and self._is_build_archived(): | 247 if self.status == RevisionState.BUILDING and self._is_build_archived(): |
| 245 self.start_job() | 248 self.start_job() |
| 246 elif self.status == RevisionState.TESTING and self._results_available(): | 249 elif (self.status in (RevisionState.TESTING, RevisionState.NEED_MORE_DATA) |
| 247 self._read_test_results() | 250 and self._results_available()): |
| 251 # if the status is NEED_MORE_DATA, it's a retest, and we should prevent | |
| 252 # the check_revision_good from running again. | |
| 253 self._read_test_results( | |
| 254 check_revision_goodness=self.status == RevisionState.TESTING) | |
| 248 # We assume _read_test_results may have changed the status to a broken | 255 # We assume _read_test_results may have changed the status to a broken |
| 249 # state such as FAILED or ABORTED. | 256 # state such as FAILED or ABORTED. |
| 250 if self.status == RevisionState.TESTING: | 257 if self.status in (RevisionState.TESTING, RevisionState.NEED_MORE_DATA): |
| 251 self.status = RevisionState.TESTED | 258 self.status = RevisionState.TESTED |
| 252 | 259 |
| 253 def _is_build_archived(self): | 260 def _is_build_archived(self): |
| 254 """Checks if the revision is already built and archived.""" | 261 """Checks if the revision is already built and archived.""" |
| 255 if not self.build_archived: | 262 if not self.build_archived: |
| 256 api = self.bisector.api | 263 api = self.bisector.api |
| 257 self.build_archived = api.gsutil_file_exists(self.build_url) | 264 self.build_archived = api.gsutil_file_exists(self.build_url) |
| 258 | 265 |
| 259 if self.bisector.dummy_builds: | 266 if self.bisector.dummy_builds: |
| 260 self.build_archived = self.in_progress | 267 self.build_archived = self.in_progress |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 320 | 327 |
| 321 def _get_hash_from_pos(self, pos): | 328 def _get_hash_from_pos(self, pos): |
| 322 api = self.bisector.api | 329 api = self.bisector.api |
| 323 try: | 330 try: |
| 324 result = api.m.commit_position.chromium_hash_from_commit_position(pos) | 331 result = api.m.commit_position.chromium_hash_from_commit_position(pos) |
| 325 except api.m.step.StepFailure as sf: # pragma: no cover | 332 except api.m.step.StepFailure as sf: # pragma: no cover |
| 326 self.bisector.surface_result('BAD_REV') | 333 self.bisector.surface_result('BAD_REV') |
| 327 api.m.halt('Failed to resolve commit position - ' + sf.reason) | 334 api.m.halt('Failed to resolve commit position - ' + sf.reason) |
| 328 raise | 335 raise |
| 329 return result | 336 return result |
| OLD | NEW |