| OLD | NEW |
| 1 # Copyright 2014 The Chromium Authors. All rights reserved. | 1 # Copyright 2014 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 math | 5 import math |
| 6 import os | 6 import os |
| 7 | 7 |
| 8 import bisect_utils | 8 import bisect_utils |
| 9 import math_utils | 9 import math_utils |
| 10 import source_control | |
| 11 import ttest | 10 import ttest |
| 12 | 11 |
| 13 | 12 |
| 14 def ConfidenceScore(good_results_lists, bad_results_lists): | 13 def ConfidenceScore(good_results_lists, bad_results_lists): |
| 15 """Calculates a confidence score. | 14 """Calculates a confidence score. |
| 16 | 15 |
| 17 This score is a percentage which represents our degree of confidence in the | 16 This score is a percentage which represents our degree of confidence in the |
| 18 proposition that the good results and bad results are distinct groups, and | 17 proposition that the good results and bad results are distinct groups, and |
| 19 their differences aren't due to chance alone. | 18 their differences aren't due to chance alone. |
| 20 | 19 |
| (...skipping 21 matching lines...) Expand all Loading... |
| 42 return 0.0 | 41 return 0.0 |
| 43 | 42 |
| 44 # The p-value is approximately the probability of obtaining the given set | 43 # The p-value is approximately the probability of obtaining the given set |
| 45 # of good and bad values just by chance. | 44 # of good and bad values just by chance. |
| 46 _, _, p_value = ttest.WelchsTTest(sample1, sample2) | 45 _, _, p_value = ttest.WelchsTTest(sample1, sample2) |
| 47 return 100.0 * (1.0 - p_value) | 46 return 100.0 * (1.0 - p_value) |
| 48 | 47 |
| 49 | 48 |
| 50 class BisectResults(object): | 49 class BisectResults(object): |
| 51 | 50 |
| 52 def __init__(self, depot_registry): | 51 def __init__(self, depot_registry, source_control): |
| 53 self._depot_registry = depot_registry | 52 self._depot_registry = depot_registry |
| 54 self.revision_data = {} | 53 self.revision_data = {} |
| 55 self.error = None | 54 self.error = None |
| 55 self._source_control = source_control |
| 56 | 56 |
| 57 @staticmethod | 57 @staticmethod |
| 58 def _FindOtherRegressions(revision_data_sorted, bad_greater_than_good): | 58 def _FindOtherRegressions(revision_data_sorted, bad_greater_than_good): |
| 59 """Compiles a list of other possible regressions from the revision data. | 59 """Compiles a list of other possible regressions from the revision data. |
| 60 | 60 |
| 61 Args: | 61 Args: |
| 62 revision_data_sorted: Sorted list of (revision, revision data) pairs. | 62 revision_data_sorted: Sorted list of (revision, revision data) pairs. |
| 63 bad_greater_than_good: Whether the result value at the "bad" revision is | 63 bad_greater_than_good: Whether the result value at the "bad" revision is |
| 64 numerically greater than the result value at the "good" revision. | 64 numerically greater than the result value at the "good" revision. |
| 65 | 65 |
| (...skipping 159 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 225 # <SHA1> | 225 # <SHA1> |
| 226 # etc. | 226 # etc. |
| 227 if l[0] == '/': | 227 if l[0] == '/': |
| 228 last_depot = l | 228 last_depot = l |
| 229 else: | 229 else: |
| 230 contents = l.split(' ') | 230 contents = l.split(' ') |
| 231 if len(contents) > 1: | 231 if len(contents) > 1: |
| 232 changes.append([last_depot, contents[0]]) | 232 changes.append([last_depot, contents[0]]) |
| 233 for c in changes: | 233 for c in changes: |
| 234 os.chdir(c[0]) | 234 os.chdir(c[0]) |
| 235 info = source_control.QueryRevisionInfo(c[1]) | 235 info = self._source_control.QueryRevisionInfo(c[1]) |
| 236 culprit_revisions.append((c[1], info, None)) | 236 culprit_revisions.append((c[1], info, None)) |
| 237 else: | 237 else: |
| 238 for i in xrange(last_broken_revision_index, len(revision_data_sorted)): | 238 for i in xrange(last_broken_revision_index, len(revision_data_sorted)): |
| 239 k, v = revision_data_sorted[i] | 239 k, v = revision_data_sorted[i] |
| 240 if k == first_working_revision: | 240 if k == first_working_revision: |
| 241 break | 241 break |
| 242 self._depot_registry.ChangeToDepotDir(v['depot']) | 242 self._depot_registry.ChangeToDepotDir(v['depot']) |
| 243 info = source_control.QueryRevisionInfo(k) | 243 info = self._source_control.QueryRevisionInfo(k) |
| 244 culprit_revisions.append((k, info, v['depot'])) | 244 culprit_revisions.append((k, info, v['depot'])) |
| 245 os.chdir(cwd) | 245 os.chdir(cwd) |
| 246 | 246 |
| 247 # Check for any other possible regression ranges. | 247 # Check for any other possible regression ranges. |
| 248 other_regressions = self._FindOtherRegressions( | 248 other_regressions = self._FindOtherRegressions( |
| 249 revision_data_sorted, mean_of_bad_runs > mean_of_good_runs) | 249 revision_data_sorted, mean_of_bad_runs > mean_of_good_runs) |
| 250 | 250 |
| 251 return { | 251 return { |
| 252 'first_working_revision': first_working_revision, | 252 'first_working_revision': first_working_revision, |
| 253 'last_broken_revision': last_broken_revision, | 253 'last_broken_revision': last_broken_revision, |
| 254 'culprit_revisions': culprit_revisions, | 254 'culprit_revisions': culprit_revisions, |
| 255 'other_regressions': other_regressions, | 255 'other_regressions': other_regressions, |
| 256 'regression_size': regression_size, | 256 'regression_size': regression_size, |
| 257 'regression_std_err': regression_std_err, | 257 'regression_std_err': regression_std_err, |
| 258 'confidence': confidence, | 258 'confidence': confidence, |
| 259 'revision_data_sorted': revision_data_sorted | 259 'revision_data_sorted': revision_data_sorted |
| 260 } | 260 } |
| OLD | NEW |