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 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 depot_config | 11 from . import depot_config |
| 11 from . import revision_state | 12 from . import revision_state |
| 12 | 13 |
| 13 _DEPS_SHA_PATCH = """ | 14 _DEPS_SHA_PATCH = """ |
| 14 diff --git DEPS.sha DEPS.sha | 15 diff --git DEPS.sha DEPS.sha |
| 15 new file mode 100644 | 16 new file mode 100644 |
| 16 --- /dev/null | 17 --- /dev/null |
| 17 +++ DEPS.sha | 18 +++ DEPS.sha |
| 18 @@ -0,0 +1 @@ | 19 @@ -0,0 +1 @@ |
| 19 +%(deps_sha)s | 20 +%(deps_sha)s |
| (...skipping 48 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 68 """This class abstracts an ongoing bisect (or n-sect) job.""" | 69 """This class abstracts an ongoing bisect (or n-sect) job.""" |
| 69 | 70 |
| 70 def __init__(self, api, bisect_config, revision_class, init_revisions=True): | 71 def __init__(self, api, bisect_config, revision_class, init_revisions=True): |
| 71 """Initializes the state of a new bisect job from a dictionary. | 72 """Initializes the state of a new bisect job from a dictionary. |
| 72 | 73 |
| 73 Note that the initial good_rev and bad_rev MUST resolve to a commit position | 74 Note that the initial good_rev and bad_rev MUST resolve to a commit position |
| 74 in the chromium repo. | 75 in the chromium repo. |
| 75 """ | 76 """ |
| 76 super(Bisector, self).__init__() | 77 super(Bisector, self).__init__() |
| 77 self._api = api | 78 self._api = api |
| 79 self.result_codes = set() | |
| 78 self.ensure_sync_master_branch() | 80 self.ensure_sync_master_branch() |
| 79 self.bisect_config = bisect_config | 81 self.bisect_config = bisect_config |
| 80 self.config_step() | 82 self.config_step() |
| 81 self.revision_class = revision_class | 83 self.revision_class = revision_class |
| 82 self.result_codes = set() | |
| 83 self.last_tested_revision = None | 84 self.last_tested_revision = None |
| 84 | 85 |
| 85 # Test-only properties. | 86 # Test-only properties. |
| 86 # TODO: Replace these with proper mod_test_data. | 87 # TODO: Replace these with proper mod_test_data. |
| 87 self.dummy_builds = bisect_config.get('dummy_builds', False) | 88 self.dummy_builds = bisect_config.get('dummy_builds', False) |
| 88 self.bypass_stats_check = bool(bisect_config.get('bypass_stats_check')) | 89 self.bypass_stats_check = bool(bisect_config.get('bypass_stats_check')) |
| 89 | 90 |
| 90 # Load configuration items. | 91 # Load configuration items. |
| 91 self.test_type = bisect_config.get('test_type', 'perf') | 92 self.test_type = bisect_config.get('test_type', 'perf') |
| 92 self.improvement_direction = int(bisect_config.get( | 93 self.improvement_direction = int(bisect_config.get( |
| (...skipping 89 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 182 results = step_result.stdout | 183 results = step_result.stdout |
| 183 if results is None: | 184 if results is None: |
| 184 assert self.dummy_builds | 185 assert self.dummy_builds |
| 185 return True | 186 return True |
| 186 significantly_different = results['significantly_different'] | 187 significantly_different = results['significantly_different'] |
| 187 step_result.presentation.logs[str(significantly_different)] = [ | 188 step_result.presentation.logs[str(significantly_different)] = [ |
| 188 'See json.output for details'] | 189 'See json.output for details'] |
| 189 return significantly_different | 190 return significantly_different |
| 190 | 191 |
| 191 def config_step(self): | 192 def config_step(self): |
| 192 """Yields a simple echo step that outputs the bisect config.""" | 193 """Validates the config and yields a step that prints the bisect config.""" |
| 193 api = self.api | 194 api = self.api |
| 195 | |
| 194 # bisect_config may come as a FrozenDict (which is not serializable). | 196 # bisect_config may come as a FrozenDict (which is not serializable). |
| 195 bisect_config = dict(self.bisect_config) | 197 bisect_config = dict(self.bisect_config) |
| 196 | 198 |
| 197 def fix_windows_backslashes(s): | 199 def fix_windows_backslashes(s): |
| 198 backslash_regex = re.compile(r'(?<!\\)\\(?!\\)') | 200 backslash_regex = re.compile(r'(?<!\\)\\(?!\\)') |
| 199 return backslash_regex.sub(r'\\', s) | 201 return backslash_regex.sub(r'\\', s) |
| 200 | 202 |
| 201 for k, v in bisect_config.iteritems(): | 203 for k, v in bisect_config.iteritems(): |
| 202 if isinstance(v, basestring): | 204 if isinstance(v, basestring): |
| 203 bisect_config[k] = fix_windows_backslashes(v) | 205 bisect_config[k] = fix_windows_backslashes(v) |
| 206 | |
| 207 step = api.m.step('config', []) | |
| 208 try: | |
| 209 config_validation.validate_config(bisect_config) | |
| 210 except config_validation.ValidationFail as error: | |
| 211 self.surface_result('BAD_CONFIG') | |
| 212 raise self.api.m.step.StepFailure(error.message) | |
|
qyearsley
2016/03/11 01:41:34
Would this provide everything in the buildbot job
RobertoCN
2016/03/14 01:26:23
Just set the step to failed as well before raising
qyearsley
2016/03/18 22:50:19
Done; making it it's own step may make it be clear
| |
| 213 | |
| 204 # We sort the keys to prevent problems with orders changing when | 214 # We sort the keys to prevent problems with orders changing when |
| 205 # recipe_simulation_test compares against expectation files. | 215 # recipe_simulation_test compares against expectation files. |
| 206 config_string = json.dumps(bisect_config, indent=2, sort_keys=True) | 216 config_string = json.dumps(bisect_config, indent=2, sort_keys=True) |
| 207 result = api.m.step('config', []) | |
| 208 config_lines = config_string.splitlines() | 217 config_lines = config_string.splitlines() |
| 209 result.presentation.logs['Bisect job configuration'] = config_lines | 218 step.presentation.logs['Bisect job configuration'] = config_lines |
| 210 | 219 |
| 211 @property | 220 @property |
| 212 def api(self): | 221 def api(self): |
| 213 return self._api | 222 return self._api |
| 214 | 223 |
| 215 def compute_relative_change(self): | 224 def compute_relative_change(self): |
| 216 old_value = float(self.good_rev.mean_value) | 225 old_value = float(self.good_rev.mean_value) |
| 217 new_value = float(self.bad_rev.mean_value) | 226 new_value = float(self.bad_rev.mean_value) |
| 218 | 227 |
| 219 if new_value and not old_value: # pragma: no cover | 228 if new_value and not old_value: # pragma: no cover |
| (...skipping 623 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 843 }) | 852 }) |
| 844 return revision_rows | 853 return revision_rows |
| 845 | 854 |
| 846 def _get_build_url(self): | 855 def _get_build_url(self): |
| 847 properties = self.api.m.properties | 856 properties = self.api.m.properties |
| 848 bot_url = properties.get('buildbotURL', | 857 bot_url = properties.get('buildbotURL', |
| 849 'http://build.chromium.org/p/chromium/') | 858 'http://build.chromium.org/p/chromium/') |
| 850 builder_name = urllib.quote(properties.get('buildername', '')) | 859 builder_name = urllib.quote(properties.get('buildername', '')) |
| 851 builder_number = str(properties.get('buildnumber', '')) | 860 builder_number = str(properties.get('buildnumber', '')) |
| 852 return '%sbuilders/%s/builds/%s' % (bot_url, builder_name, builder_number) | 861 return '%sbuilders/%s/builds/%s' % (bot_url, builder_name, builder_number) |
| OLD | NEW |