| 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 2224 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2235 | 2235 |
| 2236 cmd = ['log', '--format=%ct', '-1', bad_revision] | 2236 cmd = ['log', '--format=%ct', '-1', bad_revision] |
| 2237 output = bisect_utils.CheckRunGit(cmd, cwd=cwd) | 2237 output = bisect_utils.CheckRunGit(cmd, cwd=cwd) |
| 2238 bad_commit_time = int(output) | 2238 bad_commit_time = int(output) |
| 2239 | 2239 |
| 2240 return good_commit_time <= bad_commit_time | 2240 return good_commit_time <= bad_commit_time |
| 2241 else: | 2241 else: |
| 2242 # CrOS and SVN use integers. | 2242 # CrOS and SVN use integers. |
| 2243 return int(good_revision) <= int(bad_revision) | 2243 return int(good_revision) <= int(bad_revision) |
| 2244 | 2244 |
| 2245 def CanPerformBisect(self, revision_to_check): | 2245 def CanPerformBisect(self, good_revision, bad_revision): |
| 2246 """Checks whether a given revision is bisectable. | 2246 """Checks whether a given revision is bisectable. |
| 2247 | 2247 |
| 2248 Note: At present it checks whether a given revision is bisectable on | 2248 Checks for following: |
| 2249 android bots(refer crbug.com/385324). | 2249 1. Non-bisectable revsions for android bots (refer to crbug.com/385324). |
| 2250 2. Non-bisectable revsions for Windows bots (refer to crbug.com/405274). |
| 2250 | 2251 |
| 2251 Args: | 2252 Args: |
| 2252 revision_to_check: Known good revision. | 2253 good_revision: Known good revision. |
| 2254 bad_revision: Known bad revision. |
| 2253 | 2255 |
| 2254 Returns: | 2256 Returns: |
| 2255 A dictionary indicating the result. If revision is not bisectable, | 2257 A dictionary indicating the result. If revision is not bisectable, |
| 2256 this will contain the field "error", otherwise None. | 2258 this will contain the field "error", otherwise None. |
| 2257 """ | 2259 """ |
| 2258 if self.opts.target_platform == 'android': | 2260 if self.opts.target_platform == 'android': |
| 2259 revision_to_check = self.source_control.SVNFindRev(revision_to_check) | 2261 revision_to_check = self.source_control.SVNFindRev(good_revision) |
| 2260 if (bisect_utils.IsStringInt(revision_to_check) | 2262 if (bisect_utils.IsStringInt(good_revision) |
| 2261 and revision_to_check < 265549): | 2263 and good_revision < 265549): |
| 2262 return {'error': ( | 2264 return {'error': ( |
| 2263 'Bisect cannot continue for the given revision range.\n' | 2265 'Bisect cannot continue for the given revision range.\n' |
| 2264 'It is impossible to bisect Android regressions ' | 2266 'It is impossible to bisect Android regressions ' |
| 2265 'prior to r265549, which allows the bisect bot to ' | 2267 'prior to r265549, which allows the bisect bot to ' |
| 2266 'rely on Telemetry to do apk installation of the most recently ' | 2268 'rely on Telemetry to do apk installation of the most recently ' |
| 2267 'built local ChromeShell(refer to crbug.com/385324).\n' | 2269 'built local ChromeShell(refer to crbug.com/385324).\n' |
| 2268 'Please try bisecting revisions greater than or equal to r265549.')} | 2270 'Please try bisecting revisions greater than or equal to r265549.')} |
| 2271 |
| 2272 if bisect_utils.IsWindowsHost(): |
| 2273 good_revision = self.source_control.SVNFindRev(good_revision) |
| 2274 bad_revision = self.source_control.SVNFindRev(bad_revision) |
| 2275 if (bisect_utils.IsStringInt(good_revision) and |
| 2276 bisect_utils.IsStringInt(bad_revision)): |
| 2277 if (289987 <= good_revision < 290716 or |
| 2278 289987 <= bad_revision < 290716): |
| 2279 return {'error': ('Oops! Revision between r289987 and r290716 are ' |
| 2280 'marked as dead zone for Windows due to ' |
| 2281 'crbug.com/405274. Please try another range.')} |
| 2282 |
| 2269 return None | 2283 return None |
| 2270 | 2284 |
| 2271 def Run(self, command_to_run, bad_revision_in, good_revision_in, metric): | 2285 def Run(self, command_to_run, bad_revision_in, good_revision_in, metric): |
| 2272 """Given known good and bad revisions, run a binary search on all | 2286 """Given known good and bad revisions, run a binary search on all |
| 2273 intermediate revisions to determine the CL where the performance regression | 2287 intermediate revisions to determine the CL where the performance regression |
| 2274 occurred. | 2288 occurred. |
| 2275 | 2289 |
| 2276 Args: | 2290 Args: |
| 2277 command_to_run: Specify the command to execute the performance test. | 2291 command_to_run: Specify the command to execute the performance test. |
| 2278 good_revision: Number/tag of the known good revision. | 2292 good_revision: Number/tag of the known good revision. |
| (...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 2345 if not self.CheckIfRevisionsInProperOrder( | 2359 if not self.CheckIfRevisionsInProperOrder( |
| 2346 target_depot, good_revision, bad_revision): | 2360 target_depot, good_revision, bad_revision): |
| 2347 results['error'] = ('bad_revision < good_revision, did you swap these ' | 2361 results['error'] = ('bad_revision < good_revision, did you swap these ' |
| 2348 'by mistake?') | 2362 'by mistake?') |
| 2349 return results | 2363 return results |
| 2350 bad_revision, good_revision = self.NudgeRevisionsIfDEPSChange( | 2364 bad_revision, good_revision = self.NudgeRevisionsIfDEPSChange( |
| 2351 bad_revision, good_revision, good_revision_in) | 2365 bad_revision, good_revision, good_revision_in) |
| 2352 if self.opts.output_buildbot_annotations: | 2366 if self.opts.output_buildbot_annotations: |
| 2353 bisect_utils.OutputAnnotationStepStart('Gathering Revisions') | 2367 bisect_utils.OutputAnnotationStepStart('Gathering Revisions') |
| 2354 | 2368 |
| 2355 cannot_bisect = self.CanPerformBisect(good_revision) | 2369 cannot_bisect = self.CanPerformBisect(good_revision, bad_revision) |
| 2356 if cannot_bisect: | 2370 if cannot_bisect: |
| 2357 results['error'] = cannot_bisect.get('error') | 2371 results['error'] = cannot_bisect.get('error') |
| 2358 return results | 2372 return results |
| 2359 | 2373 |
| 2360 print 'Gathering revision range for bisection.' | 2374 print 'Gathering revision range for bisection.' |
| 2361 # Retrieve a list of revisions to do bisection on. | 2375 # Retrieve a list of revisions to do bisection on. |
| 2362 src_revision_list = self.GetRevisionList( | 2376 src_revision_list = self.GetRevisionList( |
| 2363 target_depot, bad_revision, good_revision) | 2377 target_depot, bad_revision, good_revision) |
| 2364 | 2378 |
| 2365 if self.opts.output_buildbot_annotations: | 2379 if self.opts.output_buildbot_annotations: |
| (...skipping 993 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 3359 # bugs. If you change this, please update the perf dashboard as well. | 3373 # bugs. If you change this, please update the perf dashboard as well. |
| 3360 bisect_utils.OutputAnnotationStepStart('Results') | 3374 bisect_utils.OutputAnnotationStepStart('Results') |
| 3361 print 'Error: %s' % e.message | 3375 print 'Error: %s' % e.message |
| 3362 if opts.output_buildbot_annotations: | 3376 if opts.output_buildbot_annotations: |
| 3363 bisect_utils.OutputAnnotationStepClosed() | 3377 bisect_utils.OutputAnnotationStepClosed() |
| 3364 return 1 | 3378 return 1 |
| 3365 | 3379 |
| 3366 | 3380 |
| 3367 if __name__ == '__main__': | 3381 if __name__ == '__main__': |
| 3368 sys.exit(main()) | 3382 sys.exit(main()) |
| OLD | NEW |