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 | 7 |
| 8 from . import bisect_results | 8 from . import bisect_results_json |
| 9 from . import depot_config | 9 from . import depot_config |
| 10 from . import revision_state | 10 from . import revision_state |
| 11 | 11 |
| 12 _DEPS_SHA_PATCH = """ | 12 _DEPS_SHA_PATCH = """ |
| 13 diff --git DEPS.sha DEPS.sha | 13 diff --git DEPS.sha DEPS.sha |
| 14 new file mode 100644 | 14 new file mode 100644 |
| 15 --- /dev/null | 15 --- /dev/null |
| 16 +++ DEPS.sha | 16 +++ DEPS.sha |
| 17 @@ -0,0 +1 @@ | 17 @@ -0,0 +1 @@ |
| 18 +%(deps_sha)s | 18 +%(deps_sha)s |
| (...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 457 result += 'bisector.fkbr: %r\n\n' % self.fkbr | 457 result += 'bisector.fkbr: %r\n\n' % self.fkbr |
| 458 result += self._revision_value_table() | 458 result += self._revision_value_table() |
| 459 if (self.lkgr and self.lkgr.values and self.fkbr and self.fkbr.values): | 459 if (self.lkgr and self.lkgr.values and self.fkbr and self.fkbr.values): |
| 460 result += '\n' + self._t_test_results() | 460 result += '\n' + self._t_test_results() |
| 461 return result | 461 return result |
| 462 | 462 |
| 463 def _revision_value_table(self): | 463 def _revision_value_table(self): |
| 464 """Returns a string table showing revisions and their values.""" | 464 """Returns a string table showing revisions and their values.""" |
| 465 header = [['Revision', 'Values']] | 465 header = [['Revision', 'Values']] |
| 466 rows = [[str(r.commit_pos), str(r.values)] for r in self.revisions] | 466 rows = [[str(r.commit_pos), str(r.values)] for r in self.revisions] |
| 467 return bisect_results.pretty_table(header + rows) | 467 return self._pretty_table(header + rows) |
| 468 | |
| 469 def _pretty_table(self, data): | |
| 470 results = [] | |
| 471 for row in data: | |
| 472 results.append('%-15s' * len(row) % tuple(row)) | |
| 473 return '\n'.join(results) | |
| 468 | 474 |
| 469 def _t_test_results(self): | 475 def _t_test_results(self): |
| 470 """Returns a string showing t-test results for lkgr and fkbr.""" | 476 """Returns a string showing t-test results for lkgr and fkbr.""" |
| 471 t, df, p = self.api.m.math_utils.welchs_t_test( | 477 t, df, p = self.api.m.math_utils.welchs_t_test( |
| 472 self.lkgr.values, self.fkbr.values) | 478 self.lkgr.values, self.fkbr.values) |
| 473 lines = [ | 479 lines = [ |
| 474 'LKGR values: %r' % self.lkgr.values, | 480 'LKGR values: %r' % self.lkgr.values, |
| 475 'FKBR values: %r' % self.fkbr.values, | 481 'FKBR values: %r' % self.fkbr.values, |
| 476 't-statistic: %r' % t, | 482 't-statistic: %r' % t, |
| 477 'deg. of freedom: %r' % df, | 483 'deg. of freedom: %r' % df, |
| 478 'p-value: %r' % p, | 484 'p-value: %r' % p, |
| 479 'Confidence score: %r' % (100 * (1 - p)) | 485 'Confidence score: %r' % (100 * (1 - p)) |
| 480 ] | 486 ] |
| 481 return '\n'.join(lines) | 487 return '\n'.join(lines) |
| 482 | 488 |
| 483 def partial_results(self): | |
| 484 return bisect_results.BisectResults(self, partial=True).as_string() | |
| 485 | |
| 486 def print_result_debug_info(self): | 489 def print_result_debug_info(self): |
| 487 """Prints extra debug info at the end of the bisect process.""" | 490 """Prints extra debug info at the end of the bisect process.""" |
| 488 lines = self._results_debug_message().splitlines() | 491 lines = self._results_debug_message().splitlines() |
| 489 # If we emit a null step then add a log to it, the log should be kept | 492 # If we emit a null step then add a log to it, the log should be kept |
| 490 # longer than 7 days (which is often needed to debug some issues). | 493 # longer than 7 days (which is often needed to debug some issues). |
| 491 self.api.m.step('Debug Info', []) | 494 self.api.m.step('Debug Info', []) |
| 492 self.api.m.step.active_result.presentation.logs['Debug Info'] = lines | 495 self.api.m.step.active_result.presentation.logs['Debug Info'] = lines |
| 493 | 496 |
| 494 def print_result(self): | 497 def post_result(self, halt_on_failure=False): |
| 495 results = bisect_results.BisectResults(self).as_string() | 498 """Posts bisect results to Perf Dashboard.""" |
| 496 self.api.m.python.inline( | 499 results = bisect_results_json.get(self) |
| 497 'Results', | 500 self.api.m.perf_dashboard.set_default_config() |
| 498 """ | 501 self.api.m.perf_dashboard.post_bisect(results, halt_on_failure) |
|
qyearsley
2016/01/11 22:49:43
Nice, I'm glad we can re-use the perf_dashboard re
| |
| 499 import shutil | |
| 500 import sys | |
| 501 shutil.copyfileobj(open(sys.argv[1]), sys.stdout) | |
| 502 """, | |
| 503 args=[self.api.m.raw_io.input(data=results)]) | |
| 504 | 502 |
| 505 def get_revision_to_eval(self): | 503 def get_revision_to_eval(self): |
| 506 """Gets the next RevistionState object in the candidate range. | 504 """Gets the next RevistionState object in the candidate range. |
| 507 | 505 |
| 508 Returns: | 506 Returns: |
| 509 The next Revision object in a list. | 507 The next Revision object in a list. |
| 510 """ | 508 """ |
| 511 self._update_candidate_range() | 509 self._update_candidate_range() |
| 512 candidate_range = [revision for revision in | 510 candidate_range = [revision for revision in |
| 513 self.revisions[self.lkgr.list_index + 1: | 511 self.revisions[self.lkgr.list_index + 1: |
| (...skipping 270 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 784 | 782 |
| 785 def surface_result(self, result_string): | 783 def surface_result(self, result_string): |
| 786 assert result_string in VALID_RESULT_CODES | 784 assert result_string in VALID_RESULT_CODES |
| 787 prefix = 'B4T_' # To avoid collision. Stands for bisect (abbr. `a la i18n). | 785 prefix = 'B4T_' # To avoid collision. Stands for bisect (abbr. `a la i18n). |
| 788 result_code = prefix + result_string | 786 result_code = prefix + result_string |
| 789 assert len(result_code) <= 20 | 787 assert len(result_code) <= 20 |
| 790 if result_code not in self.result_codes: | 788 if result_code not in self.result_codes: |
| 791 self.result_codes.add(result_code) | 789 self.result_codes.add(result_code) |
| 792 properties = self.api.m.step.active_result.presentation.properties | 790 properties = self.api.m.step.active_result.presentation.properties |
| 793 properties['extra_result_code'] = sorted(self.result_codes) | 791 properties['extra_result_code'] = sorted(self.result_codes) |
| 794 | |
| OLD | NEW |