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 tempfile | |
| 6 import uuid | 7 import uuid |
| 7 | 8 |
| 8 from . import revision_state | 9 from . import revision_state |
| 9 | 10 |
| 10 | 11 |
| 11 class PerfRevisionState(revision_state.RevisionState): | 12 class PerfRevisionState(revision_state.RevisionState): |
| 12 | 13 |
| 13 """Contains the state and results for one revision in a perf bisect job.""" | 14 """Contains the state and results for one revision in a perf bisect job.""" |
| 14 def __init__(self, *args, **kwargs): | 15 def __init__(self, *args, **kwargs): |
| 15 super(PerfRevisionState, self).__init__(*args, **kwargs) | 16 super(PerfRevisionState, self).__init__(*args, **kwargs) |
| 16 self.values = [] | 17 self.values = [] |
| 17 self.mean_value = None | 18 self.mean_value = None |
| 18 self.std_err = None | 19 self.std_err = None |
| 20 self._test_config = None | |
| 19 | 21 |
| 20 def test_info(self): | 22 def test_info(self): |
| 21 """Returns a dictionary with information that describes this test. | 23 """Returns a dictionary with information that describes this test. |
| 22 | 24 |
| 23 It is meant to be used by the bisector to describe the test being run for | 25 It is meant to be used by the bisector to describe the test being run for |
| 24 each revision evaluated. | 26 each revision evaluated. |
| 25 """ | 27 """ |
| 26 return { | 28 return { |
| 27 'command': self._test_config['command'], | 29 'command': self._test_config['command'], |
| 28 'metric': self._test_config['metric'], | 30 'metric': self._test_config['metric'], |
| 29 } | 31 } |
| 30 | 32 |
| 31 def _read_test_results(self): | 33 def _read_test_results(self): |
| 32 """Gets the test results from GS and checks if the rev is good or bad.""" | 34 """Gets the test results from GS and checks if the rev is good or bad.""" |
| 33 results = self._get_test_results() | 35 results = self._get_test_results() |
| 34 # Results will contain the keys 'results' and 'output' where output is the | 36 # Results will contain the keys 'results' and 'output' where output is the |
| 35 # stdout of the command, and 'results' is itself a dict with the keys: | 37 # stdout of the command, and 'results' is itself a dict with the keys: |
| 36 # 'mean', 'values', 'std_err' | 38 # 'mean', 'values', 'std_err' |
| 37 results = results['results'] | 39 results = results['results'] |
| 38 self.mean_value = results['mean'] | 40 self.mean_value = results['mean'] |
| 39 self.values = results['values'] | 41 self.values = results['values'] |
| 40 self.std_err = results['std_err'] | 42 self.std_err = results['std_err'] |
| 41 # We cannot test the goodness of the initial rev range. | 43 # We cannot test the goodness of the initial rev range. |
| 42 if self.bisector.good_rev != self and self.bisector.bad_rev != self: | 44 if self.bisector.good_rev != self and self.bisector.bad_rev != self: |
| 43 if self._check_revision_good(): | 45 if self._check_revision_good(): |
| 44 self.good = True | 46 self.good = True |
| 45 else: | 47 else: |
| 46 self.bad = True | 48 self.bad = True |
| 47 | 49 |
| 50 def _put_diff_file(self): | |
|
qyearsley
2015/02/22 20:37:55
1. This might be improved with a docstring or a di
RobertoCN
2015/02/24 20:01:14
Diff is the name of a tool to find and list differ
| |
| 51 api = self.bisector.api | |
| 52 file_name = tempfile.gettempdir() + build_name + '.diff' | |
| 53 api.file.write('Saving diff patch for ' + self.revision_string, | |
| 54 file_name, self.deps_patch) | |
| 55 return file_name | |
| 56 | |
| 48 def _request_build(self): | 57 def _request_build(self): |
| 49 """Posts a request to buildbot to build this revision and archive it.""" | 58 """Posts a request to buildbot to build this revision and archive it.""" |
| 50 # TODO: Rewrite using the trigger module. | 59 # TODO: Rewrite using the trigger module. |
| 51 # TODO: Send a diff patch when appropriate | |
| 52 api = self.bisector.api | 60 api = self.bisector.api |
| 53 bot_name = self.bisector.get_builder_bot_for_this_platform() | 61 bot_name = self.bisector.get_builder_bot_for_this_platform() |
| 54 if self.bisector.dummy_builds: | 62 if self.bisector.dummy_builds: |
| 55 self.build_job_name = self.commit_hash + '-build' | 63 self.build_job_name = self.commit_hash + '-build' |
| 56 else: | 64 else: |
| 57 self.build_job_name = uuid.uuid4().hex | 65 self.build_job_name = uuid.uuid4().hex |
| 66 if self.needs_patch: | |
| 67 self.patch_file = self._put_diff_file(build_job_name) | |
| 68 else: | |
| 69 self.patch_file = '/dev/null' | |
| 58 try_cmd = [ | 70 try_cmd = [ |
| 59 'try', | 71 'try', |
| 60 '--bot=%s' % bot_name, | 72 '--bot=%s' % bot_name, |
| 61 '--revision=%s' % self.commit_hash, | 73 '--revision=%s' % self.commit_hash, |
| 62 '--name=%s' % self.build_job_name, | 74 '--name=%s' % self.build_job_name, |
| 63 '--svn_repo=%s' % api.SVN_REPO_URL, | 75 '--svn_repo=%s' % api.SVN_REPO_URL, |
| 64 '--diff', | 76 '--diff', |
| 65 '/dev/null', | 77 self.patch_file, |
| 66 ] | 78 ] |
| 67 api.m.git(*try_cmd, name='Requesting build for %s via git try.' | 79 try: |
| 68 % str(self.commit_hash)) | 80 api.m.git(*try_cmd, name='Requesting build for %s via git try.' |
| 81 % str(self.commit_hash)) | |
| 82 finally: | |
| 83 if self.patch_file != '/dev/null': | |
| 84 try: | |
| 85 api.step('cleaning up patch', 'rm', self.patch_file) | |
| 86 except api.step.StepFailure: | |
| 87 print 'Could not clean up ' + self.patch_file | |
| 69 | 88 |
| 70 def _get_bisect_config_for_tester(self): | 89 def _get_bisect_config_for_tester(self): |
| 71 """Copies the key-value pairs required by a tester bot to a new dict.""" | 90 """Copies the key-value pairs required by a tester bot to a new dict.""" |
| 72 result = {} | 91 result = {} |
| 73 required_test_properties = { | 92 required_test_properties = { |
| 74 'truncate_percent', | 93 'truncate_percent', |
| 75 'metric', | 94 'metric', |
| 76 'max_time_minutes', | 95 'max_time_minutes', |
| 77 'command', | 96 'command', |
| 78 'repeat_count', | 97 'repeat_count', |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 172 True if this revision is closer to the initial good revision's value than | 191 True if this revision is closer to the initial good revision's value than |
| 173 to the initial bad revision's value. False otherwise. | 192 to the initial bad revision's value. False otherwise. |
| 174 """ | 193 """ |
| 175 # TODO: Reevaluate this approach | 194 # TODO: Reevaluate this approach |
| 176 bisector = self.bisector | 195 bisector = self.bisector |
| 177 distance_to_good = abs(self.mean_value - bisector.good_rev.mean_value) | 196 distance_to_good = abs(self.mean_value - bisector.good_rev.mean_value) |
| 178 distance_to_bad = abs(self.mean_value - bisector.bad_rev.mean_value) | 197 distance_to_bad = abs(self.mean_value - bisector.bad_rev.mean_value) |
| 179 if distance_to_good < distance_to_bad: | 198 if distance_to_good < distance_to_bad: |
| 180 return True | 199 return True |
| 181 return False | 200 return False |
| OLD | NEW |