| 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 import json | 5 import json |
| 6 import re | 6 import re |
| 7 import time | 7 import time |
| 8 import urllib | 8 import urllib |
| 9 | 9 |
| 10 from . import config_validation | 10 from . import config_validation |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 61 | 61 |
| 62 _DIRECTION_OF_IMPROVEMENT_ABORT_REASON = ( | 62 _DIRECTION_OF_IMPROVEMENT_ABORT_REASON = ( |
| 63 'The metric values for the initial "good" and "bad" revisions match the ' | 63 'The metric values for the initial "good" and "bad" revisions match the ' |
| 64 'expected direction of improvement. Thus, likely represent an improvement ' | 64 'expected direction of improvement. Thus, likely represent an improvement ' |
| 65 'and not a regression.') | 65 'and not a regression.') |
| 66 | 66 |
| 67 | 67 |
| 68 class Bisector(object): | 68 class Bisector(object): |
| 69 """This class abstracts an ongoing bisect (or n-sect) job.""" | 69 """This class abstracts an ongoing bisect (or n-sect) job.""" |
| 70 | 70 |
| 71 def __init__(self, api, bisect_config, revision_class, init_revisions=True): | 71 def __init__(self, api, bisect_config, revision_class, init_revisions=True, |
| 72 **flags): |
| 72 """Initializes the state of a new bisect job from a dictionary. | 73 """Initializes the state of a new bisect job from a dictionary. |
| 73 | 74 |
| 74 Note that the initial good_rev and bad_rev MUST resolve to a commit position | 75 Note that the initial good_rev and bad_rev MUST resolve to a commit position |
| 75 in the chromium repo. | 76 in the chromium repo. |
| 76 """ | 77 """ |
| 77 super(Bisector, self).__init__() | 78 super(Bisector, self).__init__() |
| 79 self.flags = flags |
| 78 self._api = api | 80 self._api = api |
| 79 self.result_codes = set() | 81 self.result_codes = set() |
| 80 self.ensure_sync_master_branch() | 82 self.ensure_sync_master_branch() |
| 81 self.bisect_config = bisect_config | 83 self.bisect_config = bisect_config |
| 82 self.config_step() | 84 self.config_step() |
| 83 self._validate_config() | 85 self._validate_config() |
| 84 self.revision_class = revision_class | 86 self.revision_class = revision_class |
| 85 self.last_tested_revision = None | 87 self.last_tested_revision = None |
| 86 | 88 |
| 87 # Test-only properties. | 89 # Test-only properties. |
| (...skipping 647 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 735 return False | 737 return False |
| 736 self.culprit = revision.next_revision | 738 self.culprit = revision.next_revision |
| 737 return True | 739 return True |
| 738 return False | 740 return False |
| 739 | 741 |
| 740 def wait_for_all(self, revision_list): | 742 def wait_for_all(self, revision_list): |
| 741 """Waits for all revisions in list to finish.""" | 743 """Waits for all revisions in list to finish.""" |
| 742 for r in revision_list: | 744 for r in revision_list: |
| 743 self.wait_for(r) | 745 self.wait_for(r) |
| 744 | 746 |
| 745 def wait_for(self, revision): | 747 def wait_for(self, revision, nest_check=True): |
| 746 """Waits for the revision to finish its job.""" | 748 """Waits for the revision to finish its job.""" |
| 747 with self.api.m.step.nest('Waiting for ' + revision.revision_string()): | 749 if nest_check and not self.flags.get( |
| 748 while True: | 750 'do_not_nest_wait_for_revision'): # pragma: no cover |
| 749 revision.update_status() | 751 with self.api.m.step.nest('Waiting for ' + revision.revision_string()): |
| 750 if revision.in_progress: | 752 return self.wait_for(revision, nest_check=False) |
| 751 self.api.m.python.inline( | 753 while True: |
| 752 'sleeping', | 754 revision.update_status() |
| 753 """ | 755 if revision.in_progress: |
| 754 import sys | 756 self.api.m.python.inline( |
| 755 import time | 757 'sleeping', |
| 756 time.sleep(20*60) | 758 """ |
| 757 sys.exit(0) | 759 import sys |
| 758 """) | 760 import time |
| 759 else: | 761 time.sleep(20*60) |
| 760 break | 762 sys.exit(0) |
| 763 """) |
| 764 else: |
| 765 break |
| 761 | 766 |
| 762 def _update_candidate_range(self): | 767 def _update_candidate_range(self): |
| 763 """Updates lkgr and fkbr (last known good/first known bad) revisions. | 768 """Updates lkgr and fkbr (last known good/first known bad) revisions. |
| 764 | 769 |
| 765 lkgr and fkbr are 'pointers' to the appropriate RevisionState objects in | 770 lkgr and fkbr are 'pointers' to the appropriate RevisionState objects in |
| 766 bisectors.revisions.""" | 771 bisectors.revisions.""" |
| 767 for r in self.revisions: | 772 for r in self.revisions: |
| 768 if r.tested: | 773 if r.tested: |
| 769 if r.good: | 774 if r.good: |
| 770 self.lkgr = r | 775 self.lkgr = r |
| (...skipping 169 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 940 }) | 945 }) |
| 941 return revision_rows | 946 return revision_rows |
| 942 | 947 |
| 943 def _get_build_url(self): | 948 def _get_build_url(self): |
| 944 properties = self.api.m.properties | 949 properties = self.api.m.properties |
| 945 bot_url = properties.get('buildbotURL', | 950 bot_url = properties.get('buildbotURL', |
| 946 'http://build.chromium.org/p/chromium/') | 951 'http://build.chromium.org/p/chromium/') |
| 947 builder_name = urllib.quote(properties.get('buildername', '')) | 952 builder_name = urllib.quote(properties.get('buildername', '')) |
| 948 builder_number = str(properties.get('buildnumber', '')) | 953 builder_number = str(properties.get('buildnumber', '')) |
| 949 return '%sbuilders/%s/builds/%s' % (bot_url, builder_name, builder_number) | 954 return '%sbuilders/%s/builds/%s' % (bot_url, builder_name, builder_number) |
| OLD | NEW |