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 |