OLD | NEW |
1 #!/usr/bin/env python | 1 #!/usr/bin/env python |
2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. | 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved. |
3 # Use of this source code is governed by a BSD-style license that can be | 3 # Use of this source code is governed by a BSD-style license that can be |
4 # found in the LICENSE file. | 4 # found in the LICENSE file. |
5 | 5 |
6 """Performance Test Bisect Tool | 6 """Performance Test Bisect Tool |
7 | 7 |
8 This script bisects a series of changelists using binary search. It starts at | 8 This script bisects a series of changelists using binary search. It starts at |
9 a bad revision where a performance metric has regressed, and asks for a last | 9 a bad revision where a performance metric has regressed, and asks for a last |
10 known-good revision. It will then binary search across this revision range by | 10 known-good revision. It will then binary search across this revision range by |
(...skipping 2192 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
2203 Returns: | 2203 Returns: |
2204 A tuple with the new bad and good revisions. | 2204 A tuple with the new bad and good revisions. |
2205 """ | 2205 """ |
2206 # DONOT perform nudge because at revision 291563 .DEPS.git was removed | 2206 # DONOT perform nudge because at revision 291563 .DEPS.git was removed |
2207 # and source contain only DEPS file for dependency changes. | 2207 # and source contain only DEPS file for dependency changes. |
2208 if good_svn_revision >= 291563: | 2208 if good_svn_revision >= 291563: |
2209 return (bad_revision, good_revision) | 2209 return (bad_revision, good_revision) |
2210 | 2210 |
2211 if self.source_control.IsGit() and self.opts.target_platform == 'chromium': | 2211 if self.source_control.IsGit() and self.opts.target_platform == 'chromium': |
2212 changes_to_deps = self.source_control.QueryFileRevisionHistory( | 2212 changes_to_deps = self.source_control.QueryFileRevisionHistory( |
2213 'DEPS', good_revision, bad_revision) | 2213 FILE_DEPS, good_revision, bad_revision) |
2214 | 2214 |
2215 if changes_to_deps: | 2215 if changes_to_deps: |
2216 # DEPS file was changed, search from the oldest change to DEPS file to | 2216 # DEPS file was changed, search from the oldest change to DEPS file to |
2217 # bad_revision to see if there are matching .DEPS.git changes. | 2217 # bad_revision to see if there are matching .DEPS.git changes. |
2218 oldest_deps_change = changes_to_deps[-1] | 2218 oldest_deps_change = changes_to_deps[-1] |
2219 changes_to_gitdeps = self.source_control.QueryFileRevisionHistory( | 2219 changes_to_gitdeps = self.source_control.QueryFileRevisionHistory( |
2220 bisect_utils.FILE_DEPS_GIT, oldest_deps_change, bad_revision) | 2220 bisect_utils.FILE_DEPS_GIT, oldest_deps_change, bad_revision) |
2221 | 2221 |
2222 if len(changes_to_deps) != len(changes_to_gitdeps): | 2222 if len(changes_to_deps) != len(changes_to_gitdeps): |
2223 # Grab the timestamp of the last DEPS change | 2223 # Grab the timestamp of the last DEPS change |
(...skipping 22 matching lines...) Expand all Loading... |
2246 """Checks that |good_revision| is an earlier revision than |bad_revision|. | 2246 """Checks that |good_revision| is an earlier revision than |bad_revision|. |
2247 | 2247 |
2248 Args: | 2248 Args: |
2249 good_revision: Number/tag of the known good revision. | 2249 good_revision: Number/tag of the known good revision. |
2250 bad_revision: Number/tag of the known bad revision. | 2250 bad_revision: Number/tag of the known bad revision. |
2251 | 2251 |
2252 Returns: | 2252 Returns: |
2253 True if the revisions are in the proper order (good earlier than bad). | 2253 True if the revisions are in the proper order (good earlier than bad). |
2254 """ | 2254 """ |
2255 if self.source_control.IsGit() and target_depot != 'cros': | 2255 if self.source_control.IsGit() and target_depot != 'cros': |
2256 cmd = ['log', '--format=%ct', '-1', good_revision] | |
2257 cwd = self._GetDepotDirectory(target_depot) | 2256 cwd = self._GetDepotDirectory(target_depot) |
2258 | 2257 |
| 2258 cmd = ['log', '--format=%ct', '-1', good_revision] |
2259 output = bisect_utils.CheckRunGit(cmd, cwd=cwd) | 2259 output = bisect_utils.CheckRunGit(cmd, cwd=cwd) |
2260 good_commit_time = int(output) | 2260 good_commit_time = int(output) |
2261 | 2261 |
2262 cmd = ['log', '--format=%ct', '-1', bad_revision] | 2262 cmd = ['log', '--format=%ct', '-1', bad_revision] |
2263 output = bisect_utils.CheckRunGit(cmd, cwd=cwd) | 2263 output = bisect_utils.CheckRunGit(cmd, cwd=cwd) |
2264 bad_commit_time = int(output) | 2264 bad_commit_time = int(output) |
2265 | 2265 |
2266 return good_commit_time <= bad_commit_time | 2266 return good_commit_time <= bad_commit_time |
2267 else: | 2267 else: |
2268 # CrOS and SVN use integers. | 2268 # CrOS and SVN use integers. |
(...skipping 1015 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3284 | 3284 |
3285 if not opts.cros_board: | 3285 if not opts.cros_board: |
3286 raise RuntimeError('missing required parameter: --cros_board') | 3286 raise RuntimeError('missing required parameter: --cros_board') |
3287 | 3287 |
3288 if not opts.cros_remote_ip: | 3288 if not opts.cros_remote_ip: |
3289 raise RuntimeError('missing required parameter: --cros_remote_ip') | 3289 raise RuntimeError('missing required parameter: --cros_remote_ip') |
3290 | 3290 |
3291 if not opts.working_directory: | 3291 if not opts.working_directory: |
3292 raise RuntimeError('missing required parameter: --working_directory') | 3292 raise RuntimeError('missing required parameter: --working_directory') |
3293 | 3293 |
3294 metric_values = opts.metric.split('/') | 3294 if opts.bisect_mode != BISECT_MODE_RETURN_CODE: |
3295 if (len(metric_values) != 2 and | 3295 metric_values = opts.metric.split('/') |
3296 opts.bisect_mode != BISECT_MODE_RETURN_CODE): | 3296 if len(metric_values) != 2: |
3297 raise RuntimeError('Invalid metric specified: [%s]' % opts.metric) | 3297 raise RuntimeError('Invalid metric specified: [%s]' % opts.metric) |
| 3298 opts.metric = metric_values |
3298 | 3299 |
3299 opts.metric = metric_values | |
3300 opts.repeat_test_count = min(max(opts.repeat_test_count, 1), 100) | 3300 opts.repeat_test_count = min(max(opts.repeat_test_count, 1), 100) |
3301 opts.max_time_minutes = min(max(opts.max_time_minutes, 1), 60) | 3301 opts.max_time_minutes = min(max(opts.max_time_minutes, 1), 60) |
3302 opts.truncate_percent = min(max(opts.truncate_percent, 0), 25) | 3302 opts.truncate_percent = min(max(opts.truncate_percent, 0), 25) |
3303 opts.truncate_percent = opts.truncate_percent / 100.0 | 3303 opts.truncate_percent = opts.truncate_percent / 100.0 |
3304 | 3304 |
3305 for k, v in opts.__dict__.iteritems(): | 3305 for k, v in opts.__dict__.iteritems(): |
3306 assert hasattr(self, k), 'Invalid %s attribute in BisectOptions.' % k | 3306 assert hasattr(self, k), 'Invalid %s attribute in BisectOptions.' % k |
3307 setattr(self, k, v) | 3307 setattr(self, k, v) |
3308 except RuntimeError, e: | 3308 except RuntimeError, e: |
3309 output_string = StringIO.StringIO() | 3309 output_string = StringIO.StringIO() |
(...skipping 10 matching lines...) Expand all Loading... |
3320 values: a dict containing options to set. | 3320 values: a dict containing options to set. |
3321 | 3321 |
3322 Returns: | 3322 Returns: |
3323 An instance of BisectOptions. | 3323 An instance of BisectOptions. |
3324 """ | 3324 """ |
3325 opts = BisectOptions() | 3325 opts = BisectOptions() |
3326 for k, v in values.iteritems(): | 3326 for k, v in values.iteritems(): |
3327 assert hasattr(opts, k), 'Invalid %s attribute in BisectOptions.' % k | 3327 assert hasattr(opts, k), 'Invalid %s attribute in BisectOptions.' % k |
3328 setattr(opts, k, v) | 3328 setattr(opts, k, v) |
3329 | 3329 |
3330 if opts.metric: | 3330 if opts.metric and opts.bisect_mode != BISECT_MODE_RETURN_CODE: |
3331 metric_values = opts.metric.split('/') | 3331 metric_values = opts.metric.split('/') |
3332 if len(metric_values) != 2: | 3332 if len(metric_values) != 2: |
3333 raise RuntimeError('Invalid metric specified: [%s]' % opts.metric) | 3333 raise RuntimeError('Invalid metric specified: [%s]' % opts.metric) |
3334 opts.metric = metric_values | 3334 opts.metric = metric_values |
3335 | 3335 |
3336 opts.repeat_test_count = min(max(opts.repeat_test_count, 1), 100) | 3336 opts.repeat_test_count = min(max(opts.repeat_test_count, 1), 100) |
3337 opts.max_time_minutes = min(max(opts.max_time_minutes, 1), 60) | 3337 opts.max_time_minutes = min(max(opts.max_time_minutes, 1), 60) |
3338 opts.truncate_percent = min(max(opts.truncate_percent, 0), 25) | 3338 opts.truncate_percent = min(max(opts.truncate_percent, 0), 25) |
3339 opts.truncate_percent = opts.truncate_percent / 100.0 | 3339 opts.truncate_percent = opts.truncate_percent / 100.0 |
3340 | 3340 |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
3398 # bugs. If you change this, please update the perf dashboard as well. | 3398 # bugs. If you change this, please update the perf dashboard as well. |
3399 bisect_utils.OutputAnnotationStepStart('Results') | 3399 bisect_utils.OutputAnnotationStepStart('Results') |
3400 print 'Error: %s' % e.message | 3400 print 'Error: %s' % e.message |
3401 if opts.output_buildbot_annotations: | 3401 if opts.output_buildbot_annotations: |
3402 bisect_utils.OutputAnnotationStepClosed() | 3402 bisect_utils.OutputAnnotationStepClosed() |
3403 return 1 | 3403 return 1 |
3404 | 3404 |
3405 | 3405 |
3406 if __name__ == '__main__': | 3406 if __name__ == '__main__': |
3407 sys.exit(main()) | 3407 sys.exit(main()) |
OLD | NEW |