Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(226)

Side by Side Diff: tools/auto_bisect/bisect_perf_regression.py

Issue 1001033004: Fix style in tools/auto_bisect. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 5 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 2 # Copyright 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 """Chromium auto-bisect tool 6 """Chromium auto-bisect tool
7 7
8 This script bisects a range of commits using binary search. It starts by getting 8 This script bisects a range of commits using binary search. It starts by getting
9 reference values for the specified "good" and "bad" commits. Then, for revisions 9 reference values for the specified "good" and "bad" commits. Then, for revisions
10 in between, it will get builds, run tests and classify intermediate revisions as 10 in between, it will get builds, run tests and classify intermediate revisions as
(...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 # Git master branch name. 121 # Git master branch name.
122 BISECT_MASTER_BRANCH = 'master' 122 BISECT_MASTER_BRANCH = 'master'
123 # File to store 'git diff' content. 123 # File to store 'git diff' content.
124 BISECT_PATCH_FILE = 'deps_patch.txt' 124 BISECT_PATCH_FILE = 'deps_patch.txt'
125 # SVN repo where the bisect try jobs are submitted. 125 # SVN repo where the bisect try jobs are submitted.
126 PERF_SVN_REPO_URL = 'svn://svn.chromium.org/chrome-try/try-perf' 126 PERF_SVN_REPO_URL = 'svn://svn.chromium.org/chrome-try/try-perf'
127 FULL_SVN_REPO_URL = 'svn://svn.chromium.org/chrome-try/try' 127 FULL_SVN_REPO_URL = 'svn://svn.chromium.org/chrome-try/try'
128 ANDROID_CHROME_SVN_REPO_URL = ('svn://svn.chromium.org/chrome-try-internal/' 128 ANDROID_CHROME_SVN_REPO_URL = ('svn://svn.chromium.org/chrome-try-internal/'
129 'try-perf') 129 'try-perf')
130 130
131
131 class RunGitError(Exception): 132 class RunGitError(Exception):
132 133
133 def __str__(self): 134 def __str__(self):
134 return '%s\nError executing git command.' % self.args[0] 135 return '%s\nError executing git command.' % self.args[0]
135 136
136 137
137 def GetSHA1HexDigest(contents): 138 def GetSHA1HexDigest(contents):
138 """Returns SHA1 hex digest of the given string.""" 139 """Returns SHA1 hex digest of the given string."""
139 return hashlib.sha1(contents).hexdigest() 140 return hashlib.sha1(contents).hexdigest()
140 141
(...skipping 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
454 current_arg_split = current_arg.split('=') 455 current_arg_split = current_arg.split('=')
455 456
456 # Check 2 cases, --arg=<val> and --arg <val> 457 # Check 2 cases, --arg=<val> and --arg <val>
457 if len(current_arg_split) == 2: 458 if len(current_arg_split) == 2:
458 arg_dict[arg_to_parse] = current_arg_split[1] 459 arg_dict[arg_to_parse] = current_arg_split[1]
459 elif i + 1 < len(command_args): 460 elif i + 1 < len(command_args):
460 arg_dict[arg_to_parse] = command_args[i+1] 461 arg_dict[arg_to_parse] = command_args[i+1]
461 462
462 path_to_generate = os.path.join('tools', 'perf', 'generate_profile') 463 path_to_generate = os.path.join('tools', 'perf', 'generate_profile')
463 464
464 if arg_dict.has_key('--profile-dir') and arg_dict.has_key('--browser'): 465 if '--profile-dir' in arg_dict and '--browser' in arg_dict:
465 profile_path, profile_type = os.path.split(arg_dict['--profile-dir']) 466 profile_path, profile_type = os.path.split(arg_dict['--profile-dir'])
466 return not bisect_utils.RunProcess(['python', path_to_generate, 467 return not bisect_utils.RunProcess(
467 '--profile-type-to-generate', profile_type, 468 [
468 '--browser', arg_dict['--browser'], '--output-dir', profile_path]) 469 'python', path_to_generate,
470 '--profile-type-to-generate', profile_type,
471 '--browser', arg_dict['--browser'],
472 '--output-dir', profile_path
473 ])
469 return False 474 return False
470 return True 475 return True
471 476
472 477
473 def _CheckRegressionConfidenceError( 478 def _CheckRegressionConfidenceError(
474 good_revision, 479 good_revision,
475 bad_revision, 480 bad_revision,
476 known_good_value, 481 known_good_value,
477 known_bad_value): 482 known_bad_value):
478 """Checks whether we can be confident beyond a certain degree that the given 483 """Checks whether we can be confident beyond a certain degree that the given
479 metrics represent a regression. 484 metrics represent a regression.
480 485
481 Args: 486 Args:
482 good_revision: string representing the commit considered 'good' 487 good_revision: string representing the commit considered 'good'
483 bad_revision: Same as above for 'bad'. 488 bad_revision: Same as above for 'bad'.
484 known_good_value: A dict with at least: 'values', 'mean' and 'std_err' 489 known_good_value: A dict with at least: 'values', 'mean' and 'std_err'
485 known_bad_value: Same as above. 490 known_bad_value: Same as above.
486 491
487 Returns: 492 Returns:
488 False if there is no error (i.e. we can be confident there's a regressioni), 493 False if there is no error (i.e. we can be confident there's a regression),
489 a string containing the details of the lack of confidence otherwise. 494 a string containing the details of the lack of confidence otherwise.
490 """ 495 """
491 error = False 496 error = False
492 # Adding good and bad values to a parameter list. 497 # Adding good and bad values to a parameter list.
493 confidence_params = [] 498 confidence_params = []
494 for l in [known_bad_value['values'], known_good_value['values']]: 499 for l in [known_bad_value['values'], known_good_value['values']]:
495 # Flatten if needed, by averaging the values in each nested list 500 # Flatten if needed, by averaging the values in each nested list
496 if isinstance(l, list) and all([isinstance(x, list) for x in l]): 501 if isinstance(l, list) and all([isinstance(x, list) for x in l]):
497 averages = map(math_utils.Mean, l) 502 averages = map(math_utils.Mean, l)
498 confidence_params.append(averages) 503 confidence_params.append(averages)
(...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after
569 if returncode: 574 if returncode:
570 raise RunGitError('Deleting branch failed, %s', output) 575 raise RunGitError('Deleting branch failed, %s', output)
571 576
572 # Check if the tree is dirty: make sure the index is up to date and then 577 # Check if the tree is dirty: make sure the index is up to date and then
573 # run diff-index. 578 # run diff-index.
574 bisect_utils.RunGit(['update-index', '--refresh', '-q']) 579 bisect_utils.RunGit(['update-index', '--refresh', '-q'])
575 output, returncode = bisect_utils.RunGit(['diff-index', 'HEAD']) 580 output, returncode = bisect_utils.RunGit(['diff-index', 'HEAD'])
576 if output: 581 if output:
577 raise RunGitError('Cannot send a try job with a dirty tree.') 582 raise RunGitError('Cannot send a try job with a dirty tree.')
578 583
579 # Create/check out the telemetry-tryjob branch, and edit the configs 584 # Create and check out the telemetry-tryjob branch, and edit the configs
580 # for the tryjob there. 585 # for the try job there.
581 output, returncode = bisect_utils.RunGit(['checkout', '-b', new_branch]) 586 output, returncode = bisect_utils.RunGit(['checkout', '-b', new_branch])
582 if returncode: 587 if returncode:
583 raise RunGitError('Failed to checkout branch: %s.' % output) 588 raise RunGitError('Failed to checkout branch: %s.' % output)
584 589
585 output, returncode = bisect_utils.RunGit( 590 output, returncode = bisect_utils.RunGit(
586 ['branch', '--set-upstream-to', parent_branch]) 591 ['branch', '--set-upstream-to', parent_branch])
587 if returncode: 592 if returncode:
588 raise RunGitError('Error in git branch --set-upstream-to') 593 raise RunGitError('Error in git branch --set-upstream-to')
589 594
590 595
591 def _StartBuilderTryJob( 596 def _StartBuilderTryJob(
592 builder_type, git_revision, builder_name, job_name, patch=None): 597 builder_type, git_revision, builder_name, job_name, patch=None):
593 """Attempts to run a try job from the current directory. 598 """Attempts to run a try job from the current directory.
594 599
595 Args: 600 Args:
596 builder_type: One of the builder types in fetch_build, e.g. "perf". 601 builder_type: One of the builder types in fetch_build, e.g. "perf".
597 git_revision: A git commit hash. 602 git_revision: A git commit hash.
598 builder_name: Name of the bisect bot to be used for try job. 603 builder_name: Name of the bisect bot to be used for try job.
599 bisect_job_name: Try job name, used to identify which bisect 604 bisect_job_name: Try job name, used to identify which bisect
600 job was responsible for requesting a build. 605 job was responsible for requesting a build.
601 patch: A DEPS patch (used while bisecting dependency repositories), 606 patch: A DEPS patch (used while bisecting dependency repositories),
602 or None if we're bisecting the top-level repository. 607 or None if we're bisecting the top-level repository.
603 """ 608 """
604 # TODO(prasadv, qyearsley): Make this a method of BuildArchive 609 # TODO(prasadv, qyearsley): Make this a method of BuildArchive
605 # (which may be renamed to BuilderTryBot or Builder). 610 # (which may be renamed to BuilderTryBot or Builder).
606 try: 611 try:
607 # Temporary branch for running tryjob. 612 # Temporary branch for running a try job.
608 _PrepareBisectBranch(BISECT_MASTER_BRANCH, BISECT_TRYJOB_BRANCH) 613 _PrepareBisectBranch(BISECT_MASTER_BRANCH, BISECT_TRYJOB_BRANCH)
609 patch_content = '/dev/null' 614 patch_content = '/dev/null'
610 # Create a temporary patch file. 615 # Create a temporary patch file.
611 if patch: 616 if patch:
612 WriteStringToFile(patch, BISECT_PATCH_FILE) 617 WriteStringToFile(patch, BISECT_PATCH_FILE)
613 patch_content = BISECT_PATCH_FILE 618 patch_content = BISECT_PATCH_FILE
614 619
615 try_command = [ 620 try_command = [
616 'try', 621 'try',
617 '--bot=%s' % builder_name, 622 '--bot=%s' % builder_name,
618 '--revision=%s' % git_revision, 623 '--revision=%s' % git_revision,
619 '--name=%s' % job_name, 624 '--name=%s' % job_name,
620 '--svn_repo=%s' % _TryJobSvnRepo(builder_type), 625 '--svn_repo=%s' % _TryJobSvnRepo(builder_type),
621 '--diff=%s' % patch_content, 626 '--diff=%s' % patch_content,
622 ] 627 ]
623 # Execute try job to build revision. 628 # Execute try job to build revision.
624 print try_command 629 print try_command
625 output, return_code = bisect_utils.RunGit(try_command) 630 output, return_code = bisect_utils.RunGit(try_command)
626 631
627 command_string = ' '.join(['git'] + try_command) 632 command_string = ' '.join(['git'] + try_command)
628 if return_code: 633 if return_code:
629 raise RunGitError('Could not execute tryjob: %s.\n' 634 raise RunGitError('Could not execute try job: %s.\n'
630 'Error: %s' % (command_string, output)) 635 'Error: %s' % (command_string, output))
631 logging.info('Try job successfully submitted.\n TryJob Details: %s\n%s', 636 logging.info('Try job successfully submitted.\n TryJob Details: %s\n%s',
632 command_string, output) 637 command_string, output)
633 finally: 638 finally:
634 # Delete patch file if exists. 639 # Delete patch file if exists.
635 try: 640 try:
636 os.remove(BISECT_PATCH_FILE) 641 os.remove(BISECT_PATCH_FILE)
637 except OSError as e: 642 except OSError as e:
638 if e.errno != errno.ENOENT: 643 if e.errno != errno.ENOENT:
639 raise 644 raise
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after
740 results[depot_name] = None 745 results[depot_name] = None
741 return results 746 return results
742 except ImportError: 747 except ImportError:
743 deps_file_contents = ReadStringFromFile(deps_file) 748 deps_file_contents = ReadStringFromFile(deps_file)
744 parse_results = _ParseRevisionsFromDEPSFileManually(deps_file_contents) 749 parse_results = _ParseRevisionsFromDEPSFileManually(deps_file_contents)
745 results = {} 750 results = {}
746 for depot_name, depot_revision in parse_results.iteritems(): 751 for depot_name, depot_revision in parse_results.iteritems():
747 depot_revision = depot_revision.strip('@') 752 depot_revision = depot_revision.strip('@')
748 logging.warn(depot_name, depot_revision) 753 logging.warn(depot_name, depot_revision)
749 for cur_name, cur_data in bisect_utils.DEPOT_DEPS_NAME.iteritems(): 754 for cur_name, cur_data in bisect_utils.DEPOT_DEPS_NAME.iteritems():
750 if (cur_data.has_key('deps_var') and 755 if cur_data.get('deps_var') == depot_name:
751 cur_data['deps_var'] == depot_name):
752 src_name = cur_name 756 src_name = cur_name
753 results[src_name] = depot_revision 757 results[src_name] = depot_revision
754 break 758 break
755 return results 759 return results
756 760
757 def _Get3rdPartyRevisions(self, depot): 761 def _Get3rdPartyRevisions(self, depot):
758 """Parses the DEPS file to determine WebKit/v8/etc... versions. 762 """Parses the DEPS file to determine WebKit/v8/etc... versions.
759 763
760 Args: 764 Args:
761 depot: A depot name. Should be in the DEPOT_NAMES list. 765 depot: A depot name. Should be in the DEPOT_NAMES list.
(...skipping 154 matching lines...) Expand 10 before | Expand all | Expand 10 after
916 extra_src=self.opts.extra_src) 920 extra_src=self.opts.extra_src)
917 921
918 try: 922 try:
919 _StartBuilderTryJob(self.opts.builder_type, git_revision, builder_name, 923 _StartBuilderTryJob(self.opts.builder_type, git_revision, builder_name,
920 job_name=build_request_id, patch=deps_patch) 924 job_name=build_request_id, patch=deps_patch)
921 except RunGitError as e: 925 except RunGitError as e:
922 logging.warn('Failed to post builder try job for revision: [%s].\n' 926 logging.warn('Failed to post builder try job for revision: [%s].\n'
923 'Error: %s', git_revision, e) 927 'Error: %s', git_revision, e)
924 return None 928 return None
925 929
926 # Get the buildbot master url to monitor build status. 930 # Get the buildbot master URL to monitor build status.
927 buildbot_server_url = fetch_build.GetBuildBotUrl( 931 buildbot_server_url = fetch_build.GetBuildBotUrl(
928 builder_type=self.opts.builder_type, 932 builder_type=self.opts.builder_type,
929 target_arch=self.opts.target_arch, 933 target_arch=self.opts.target_arch,
930 target_platform=self.opts.target_platform, 934 target_platform=self.opts.target_platform,
931 extra_src=self.opts.extra_src) 935 extra_src=self.opts.extra_src)
932 936
933 archive_filename, error_msg = _WaitUntilBuildIsReady( 937 archive_filename, error_msg = _WaitUntilBuildIsReady(
934 fetch_build_func, builder_name, build_request_id, build_timeout, 938 fetch_build_func, builder_name, build_request_id, build_timeout,
935 buildbot_server_url) 939 buildbot_server_url)
936 if not archive_filename: 940 if not archive_filename:
(...skipping 83 matching lines...) Expand 10 before | Expand all | Expand 10 after
1020 """Checks if build can be downloaded based on target platform and depot.""" 1024 """Checks if build can be downloaded based on target platform and depot."""
1021 if (self.opts.target_platform in ['chromium', 'android', 'android-chrome'] 1025 if (self.opts.target_platform in ['chromium', 'android', 'android-chrome']
1022 and self.opts.builder_type): 1026 and self.opts.builder_type):
1023 # In case of android-chrome platform, download archives only for 1027 # In case of android-chrome platform, download archives only for
1024 # android-chrome depot; for other depots such as chromium, v8, skia 1028 # android-chrome depot; for other depots such as chromium, v8, skia
1025 # etc., build the binary locally. 1029 # etc., build the binary locally.
1026 if self.opts.target_platform == 'android-chrome': 1030 if self.opts.target_platform == 'android-chrome':
1027 return depot == 'android-chrome' 1031 return depot == 'android-chrome'
1028 else: 1032 else:
1029 return (depot == 'chromium' or 1033 return (depot == 'chromium' or
1030 'chromium' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'] or 1034 'chromium' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'] or
1031 'v8' in bisect_utils.DEPOT_DEPS_NAME[depot]['from']) 1035 'v8' in bisect_utils.DEPOT_DEPS_NAME[depot]['from'])
1032 return False 1036 return False
1033 1037
1034 def UpdateDepsContents(self, deps_contents, depot, git_revision, deps_key): 1038 def UpdateDepsContents(self, deps_contents, depot, git_revision, deps_key):
1035 """Returns modified version of DEPS file contents. 1039 """Returns modified version of DEPS file contents.
1036 1040
1037 Args: 1041 Args:
1038 deps_contents: DEPS file content. 1042 deps_contents: DEPS file content.
1039 depot: Current depot being bisected. 1043 depot: Current depot being bisected.
1040 git_revision: A git hash to be updated in DEPS. 1044 git_revision: A git hash to be updated in DEPS.
1041 deps_key: Key in vars section of DEPS file to be searched. 1045 deps_key: Key in vars section of DEPS file to be searched.
(...skipping 309 matching lines...) Expand 10 before | Expand all | Expand 10 after
1351 if parsed_metric: 1355 if parsed_metric:
1352 metric_values.append(math_utils.Mean(parsed_metric)) 1356 metric_values.append(math_utils.Mean(parsed_metric))
1353 # If we're bisecting on a metric (ie, changes in the mean or 1357 # If we're bisecting on a metric (ie, changes in the mean or
1354 # standard deviation) and no metric values are produced, bail out. 1358 # standard deviation) and no metric values are produced, bail out.
1355 if not metric_values: 1359 if not metric_values:
1356 break 1360 break
1357 elif self._IsBisectModeReturnCode(): 1361 elif self._IsBisectModeReturnCode():
1358 metric_values.append(return_code) 1362 metric_values.append(return_code)
1359 1363
1360 elapsed_minutes = (time.time() - start_time) / 60.0 1364 elapsed_minutes = (time.time() - start_time) / 60.0
1361 time_limit = self.opts.max_time_minutes * test_run_multiplier 1365 time_limit = self.opts.max_time_minutes * test_run_multiplier
1362 if elapsed_minutes >= time_limit: 1366 if elapsed_minutes >= time_limit:
1363 break 1367 break
1364 1368
1365 if metric and len(metric_values) == 0: 1369 if metric and len(metric_values) == 0:
1366 err_text = 'Metric %s was not found in the test output.' % metric 1370 err_text = 'Metric %s was not found in the test output.' % metric
1367 # TODO(qyearsley): Consider also getting and displaying a list of metrics 1371 # TODO(qyearsley): Consider also getting and displaying a list of metrics
1368 # that were found in the output here. 1372 # that were found in the output here.
1369 return (err_text, failure_code, output_of_all_runs) 1373 return (err_text, failure_code, output_of_all_runs)
1370 1374
1371 # If we're bisecting on return codes, we're really just looking for zero vs 1375 # If we're bisecting on return codes, we're really just looking for zero vs
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
1423 def _RunPostSync(self, _depot): 1427 def _RunPostSync(self, _depot):
1424 """Performs any work after syncing. 1428 """Performs any work after syncing.
1425 1429
1426 Args: 1430 Args:
1427 depot: Depot name. 1431 depot: Depot name.
1428 1432
1429 Returns: 1433 Returns:
1430 True if successful. 1434 True if successful.
1431 """ 1435 """
1432 if 'android' in self.opts.target_platform: 1436 if 'android' in self.opts.target_platform:
1433 if not builder.SetupAndroidBuildEnvironment(self.opts, 1437 if not builder.SetupAndroidBuildEnvironment(
1434 path_to_src=self.src_cwd): 1438 self.opts, path_to_src=self.src_cwd):
1435 return False 1439 return False
1436 1440
1437 return self.RunGClientHooks() 1441 return self.RunGClientHooks()
1438 1442
1439 @staticmethod 1443 @staticmethod
1440 def ShouldSkipRevision(depot, revision): 1444 def ShouldSkipRevision(depot, revision):
1441 """Checks whether a particular revision can be safely skipped. 1445 """Checks whether a particular revision can be safely skipped.
1442 1446
1443 Some commits can be safely skipped (such as a DEPS roll for the repos 1447 Some commits can be safely skipped (such as a DEPS roll for the repos
1444 still using .DEPS.git), since the tool is git based those changes 1448 still using .DEPS.git), since the tool is git based those changes
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1529 1533
1530 # A value other than 0 indicates that the test couldn't be run, and results 1534 # A value other than 0 indicates that the test couldn't be run, and results
1531 # should also include an error message. 1535 # should also include an error message.
1532 if results[1] != 0: 1536 if results[1] != 0:
1533 return results 1537 return results
1534 1538
1535 external_revisions = self._Get3rdPartyRevisions(depot) 1539 external_revisions = self._Get3rdPartyRevisions(depot)
1536 1540
1537 if not external_revisions is None: 1541 if not external_revisions is None:
1538 return (results[0], results[1], external_revisions, 1542 return (results[0], results[1], external_revisions,
1539 time.time() - after_build_time, after_build_time - 1543 time.time() - after_build_time, after_build_time -
1540 start_build_time) 1544 start_build_time)
1541 else: 1545 else:
1542 return ('Failed to parse DEPS file for external revisions.', 1546 return ('Failed to parse DEPS file for external revisions.',
1543 BUILD_RESULT_FAIL) 1547 BUILD_RESULT_FAIL)
1544 1548
1545 def _SyncRevision(self, depot, revision, sync_client): 1549 def _SyncRevision(self, depot, revision, sync_client):
1546 """Syncs depot to particular revision. 1550 """Syncs depot to particular revision.
1547 1551
1548 Args: 1552 Args:
1549 depot: The depot that's being used at the moment (src, webkit, etc.) 1553 depot: The depot that's being used at the moment (src, webkit, etc.)
1550 revision: The revision to sync to. 1554 revision: The revision to sync to.
1551 sync_client: Program used to sync, e.g. "gclient". Can be None. 1555 sync_client: Program used to sync, e.g. "gclient". Can be None.
1552 1556
1553 Returns: 1557 Returns:
1554 True if successful, False otherwise. 1558 True if successful, False otherwise.
1555 """ 1559 """
1556 self.depot_registry.ChangeToDepotDir(depot) 1560 self.depot_registry.ChangeToDepotDir(depot)
1557 1561
1558 if sync_client: 1562 if sync_client:
1559 self.PerformPreBuildCleanup() 1563 self.PerformPreBuildCleanup()
1560 1564
1561 # When using gclient to sync, you need to specify the depot you 1565 # When using gclient to sync, you need to specify the depot you
1562 # want so that all the dependencies sync properly as well. 1566 # want so that all the dependencies sync properly as well.
1563 # i.e. gclient sync src@<SHA1> 1567 # i.e. gclient sync src@<SHA1>
1564 if sync_client == 'gclient' and revision: 1568 if sync_client == 'gclient' and revision:
1565 revision = '%s@%s' % (bisect_utils.DEPOT_DEPS_NAME[depot]['src'], 1569 revision = '%s@%s' % (bisect_utils.DEPOT_DEPS_NAME[depot]['src'],
1566 revision) 1570 revision)
1567 if depot == 'chromium' and self.opts.target_platform == 'android-chrome': 1571 if depot == 'chromium' and self.opts.target_platform == 'android-chrome':
1568 return self._SyncRevisionsForAndroidChrome(revision) 1572 return self._SyncRevisionsForAndroidChrome(revision)
1569 1573
1570 return source_control.SyncToRevision(revision, sync_client) 1574 return source_control.SyncToRevision(revision, sync_client)
1571 1575
1572 def _SyncRevisionsForAndroidChrome(self, revision): 1576 def _SyncRevisionsForAndroidChrome(self, revision):
1573 """Syncs android-chrome and chromium repos to particular revision. 1577 """Syncs android-chrome and chromium repos to particular revision.
1574 1578
1575 This is a special case for android-chrome as the gclient sync for chromium 1579 This is a special case for android-chrome as the gclient sync for chromium
1576 overwrites the android-chrome revision to TOT. Therefore both the repos 1580 overwrites the android-chrome revision to TOT. Therefore both the repos
(...skipping 21 matching lines...) Expand all
1598 current_value: The value of the metric being checked. 1602 current_value: The value of the metric being checked.
1599 known_bad_value: The reference value for a "failed" run. 1603 known_bad_value: The reference value for a "failed" run.
1600 known_good_value: The reference value for a "passed" run. 1604 known_good_value: The reference value for a "passed" run.
1601 1605
1602 Returns: 1606 Returns:
1603 True if the current_value is closer to the known_good_value than the 1607 True if the current_value is closer to the known_good_value than the
1604 known_bad_value. 1608 known_bad_value.
1605 """ 1609 """
1606 if self.opts.bisect_mode == bisect_utils.BISECT_MODE_STD_DEV: 1610 if self.opts.bisect_mode == bisect_utils.BISECT_MODE_STD_DEV:
1607 dist_to_good_value = abs(current_value['std_dev'] - 1611 dist_to_good_value = abs(current_value['std_dev'] -
1608 known_good_value['std_dev']) 1612 known_good_value['std_dev'])
1609 dist_to_bad_value = abs(current_value['std_dev'] - 1613 dist_to_bad_value = abs(current_value['std_dev'] -
1610 known_bad_value['std_dev']) 1614 known_bad_value['std_dev'])
1611 else: 1615 else:
1612 dist_to_good_value = abs(current_value['mean'] - known_good_value['mean']) 1616 dist_to_good_value = abs(current_value['mean'] - known_good_value['mean'])
1613 dist_to_bad_value = abs(current_value['mean'] - known_bad_value['mean']) 1617 dist_to_bad_value = abs(current_value['mean'] - known_bad_value['mean'])
1614 1618
1615 return dist_to_good_value < dist_to_bad_value 1619 return dist_to_good_value < dist_to_bad_value
1616 1620
1617 def _GetV8BleedingEdgeFromV8TrunkIfMappable( 1621 def _GetV8BleedingEdgeFromV8TrunkIfMappable(
1618 self, revision, bleeding_edge_branch): 1622 self, revision, bleeding_edge_branch):
1619 """Gets v8 bleeding edge revision mapped to v8 revision in trunk. 1623 """Gets v8 bleeding edge revision mapped to v8 revision in trunk.
1620 1624
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1675 return re_results.group('git_revision') 1679 return re_results.group('git_revision')
1676 except (IndexError, ValueError): 1680 except (IndexError, ValueError):
1677 pass 1681 pass
1678 if not git_revision: 1682 if not git_revision:
1679 # Wasn't successful, try the old way of looking for "Prepare push to" 1683 # Wasn't successful, try the old way of looking for "Prepare push to"
1680 git_revision = source_control.ResolveToRevision( 1684 git_revision = source_control.ResolveToRevision(
1681 int(commit_position) - 1, 'v8_bleeding_edge', 1685 int(commit_position) - 1, 'v8_bleeding_edge',
1682 bisect_utils.DEPOT_DEPS_NAME, -1, cwd=v8_bleeding_edge_dir) 1686 bisect_utils.DEPOT_DEPS_NAME, -1, cwd=v8_bleeding_edge_dir)
1683 1687
1684 if git_revision: 1688 if git_revision:
1685 revision_info = source_control.QueryRevisionInfo(git_revision, 1689 revision_info = source_control.QueryRevisionInfo(
1686 cwd=v8_bleeding_edge_dir) 1690 git_revision, cwd=v8_bleeding_edge_dir)
1687 1691
1688 if 'Prepare push to trunk' in revision_info['subject']: 1692 if 'Prepare push to trunk' in revision_info['subject']:
1689 return git_revision 1693 return git_revision
1690 return None 1694 return None
1691 1695
1692 def _GetNearestV8BleedingEdgeFromTrunk( 1696 def _GetNearestV8BleedingEdgeFromTrunk(
1693 self, revision, v8_branch, bleeding_edge_branch, search_forward=True): 1697 self, revision, v8_branch, bleeding_edge_branch, search_forward=True):
1694 """Gets the nearest V8 roll and maps to bleeding edge revision. 1698 """Gets the nearest V8 roll and maps to bleeding edge revision.
1695 1699
1696 V8 is a bit tricky to bisect since it isn't just rolled out like blink. 1700 V8 is a bit tricky to bisect since it isn't just rolled out like blink.
(...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after
1753 1757
1754 # Support for the chromium revisions with external V8 repo. 1758 # Support for the chromium revisions with external V8 repo.
1755 # ie https://chromium.googlesource.com/external/v8.git 1759 # ie https://chromium.googlesource.com/external/v8.git
1756 cmd = ['config', '--get', 'remote.origin.url'] 1760 cmd = ['config', '--get', 'remote.origin.url']
1757 v8_repo_url = bisect_utils.CheckRunGit(cmd, cwd=cwd) 1761 v8_repo_url = bisect_utils.CheckRunGit(cmd, cwd=cwd)
1758 1762
1759 if 'external/v8.git' in v8_repo_url: 1763 if 'external/v8.git' in v8_repo_url:
1760 v8_branch = 'origin/master' 1764 v8_branch = 'origin/master'
1761 bleeding_edge_branch = 'origin/bleeding_edge' 1765 bleeding_edge_branch = 'origin/bleeding_edge'
1762 1766
1763 r1 = self._GetNearestV8BleedingEdgeFromTrunk(min_revision_state.revision, 1767 r1 = self._GetNearestV8BleedingEdgeFromTrunk(
1764 v8_branch, bleeding_edge_branch, search_forward=True) 1768 min_revision_state.revision,
1765 r2 = self._GetNearestV8BleedingEdgeFromTrunk(max_revision_state.revision, 1769 v8_branch,
1766 v8_branch, bleeding_edge_branch, search_forward=False) 1770 bleeding_edge_branch,
1771 search_forward=True)
1772 r2 = self._GetNearestV8BleedingEdgeFromTrunk(
1773 max_revision_state.revision,
1774 v8_branch,
1775 bleeding_edge_branch,
1776 search_forward=False)
1767 min_revision_state.external['v8_bleeding_edge'] = r1 1777 min_revision_state.external['v8_bleeding_edge'] = r1
1768 max_revision_state.external['v8_bleeding_edge'] = r2 1778 max_revision_state.external['v8_bleeding_edge'] = r2
1769 1779
1770 if (not self._GetV8BleedingEdgeFromV8TrunkIfMappable( 1780 if (not self._GetV8BleedingEdgeFromV8TrunkIfMappable(
1771 min_revision_state.revision, bleeding_edge_branch) 1781 min_revision_state.revision, bleeding_edge_branch)
1772 or not self._GetV8BleedingEdgeFromV8TrunkIfMappable( 1782 or not self._GetV8BleedingEdgeFromV8TrunkIfMappable(
1773 max_revision_state.revision, bleeding_edge_branch)): 1783 max_revision_state.revision, bleeding_edge_branch)):
1774 self.warnings.append( 1784 self.warnings.append(
1775 'Trunk revisions in V8 did not map directly to bleeding_edge. ' 1785 'Trunk revisions in V8 did not map directly to bleeding_edge. '
1776 'Attempted to expand the range to find V8 rolls which did map ' 1786 'Attempted to expand the range to find V8 rolls which did map '
1777 'directly to bleeding_edge revisions, but results might not be ' 1787 'directly to bleeding_edge revisions, but results might not be '
1778 'valid.') 1788 'valid.')
1779 1789
1780 def _FindNextDepotToBisect( 1790 def _FindNextDepotToBisect(
1781 self, current_depot, min_revision_state, max_revision_state): 1791 self, current_depot, min_revision_state, max_revision_state):
1782 """Decides which depot the script should dive into next (if any). 1792 """Decides which depot the script should dive into next (if any).
1783 1793
1784 Args: 1794 Args:
1785 current_depot: Current depot being bisected. 1795 current_depot: Current depot being bisected.
1786 min_revision_state: State of the earliest revision in the bisect range. 1796 min_revision_state: State of the earliest revision in the bisect range.
1787 max_revision_state: State of the latest revision in the bisect range. 1797 max_revision_state: State of the latest revision in the bisect range.
1788 1798
1789 Returns: 1799 Returns:
1790 Name of the depot to bisect next, or None. 1800 Name of the depot to bisect next, or None.
1791 """ 1801 """
1792 external_depot = None 1802 external_depot = None
1793 for next_depot in bisect_utils.DEPOT_NAMES: 1803 for next_depot in bisect_utils.DEPOT_NAMES:
1794 if bisect_utils.DEPOT_DEPS_NAME[next_depot].has_key('platform'): 1804 if ('platform' in bisect_utils.DEPOT_DEPS_NAME[next_depot] and
1795 if bisect_utils.DEPOT_DEPS_NAME[next_depot]['platform'] != os.name: 1805 bisect_utils.DEPOT_DEPS_NAME[next_depot]['platform'] != os.name):
1796 continue 1806 continue
1797 1807
1798 if not (bisect_utils.DEPOT_DEPS_NAME[next_depot]['recurse'] 1808 if not (bisect_utils.DEPOT_DEPS_NAME[next_depot]['recurse']
1799 and min_revision_state.depot 1809 and min_revision_state.depot
1800 in bisect_utils.DEPOT_DEPS_NAME[next_depot]['from']): 1810 in bisect_utils.DEPOT_DEPS_NAME[next_depot]['from']):
1801 continue 1811 continue
1802 1812
1803 if current_depot == 'v8': 1813 if current_depot == 'v8':
1804 # We grab the bleeding_edge info here rather than earlier because we 1814 # We grab the bleeding_edge info here rather than earlier because we
1805 # finally have the revision range. From that we can search forwards and 1815 # finally have the revision range. From that we can search forwards and
1806 # backwards to try to match trunk revisions to bleeding_edge. 1816 # backwards to try to match trunk revisions to bleeding_edge.
(...skipping 24 matching lines...) Expand all
1831 Returns: 1841 Returns:
1832 A list containing the revisions between |start_revision| and 1842 A list containing the revisions between |start_revision| and
1833 |end_revision| inclusive. 1843 |end_revision| inclusive.
1834 """ 1844 """
1835 # Change into working directory of external library to run 1845 # Change into working directory of external library to run
1836 # subsequent commands. 1846 # subsequent commands.
1837 self.depot_registry.ChangeToDepotDir(current_depot) 1847 self.depot_registry.ChangeToDepotDir(current_depot)
1838 1848
1839 # V8 (and possibly others) is merged in periodically. Bisecting 1849 # V8 (and possibly others) is merged in periodically. Bisecting
1840 # this directory directly won't give much good info. 1850 # this directory directly won't give much good info.
1841 if bisect_utils.DEPOT_DEPS_NAME[current_depot].has_key('custom_deps'): 1851 if 'custom_deps' in bisect_utils.DEPOT_DEPS_NAME[current_depot]:
1842 config_path = os.path.join(self.src_cwd, '..') 1852 config_path = os.path.join(self.src_cwd, '..')
1843 if bisect_utils.RunGClientAndCreateConfig( 1853 if bisect_utils.RunGClientAndCreateConfig(
1844 self.opts, bisect_utils.DEPOT_DEPS_NAME[current_depot]['custom_deps'], 1854 self.opts, bisect_utils.DEPOT_DEPS_NAME[current_depot]['custom_deps'],
1845 cwd=config_path): 1855 cwd=config_path):
1846 return [] 1856 return []
1847 if bisect_utils.RunGClient( 1857 if bisect_utils.RunGClient(
1848 ['sync', '--revision', previous_revision], cwd=self.src_cwd): 1858 ['sync', '--revision', previous_revision], cwd=self.src_cwd):
1849 return [] 1859 return []
1850 1860
1851 if current_depot == 'v8_bleeding_edge': 1861 if current_depot == 'v8_bleeding_edge':
1852 self.depot_registry.ChangeToDepotDir('chromium') 1862 self.depot_registry.ChangeToDepotDir('chromium')
1853 1863
1854 shutil.move('v8', 'v8.bak') 1864 shutil.move('v8', 'v8.bak')
1855 shutil.move('v8_bleeding_edge', 'v8') 1865 shutil.move('v8_bleeding_edge', 'v8')
1856 1866
1857 self.cleanup_commands.append(['mv', 'v8', 'v8_bleeding_edge']) 1867 self.cleanup_commands.append(['mv', 'v8', 'v8_bleeding_edge'])
1858 self.cleanup_commands.append(['mv', 'v8.bak', 'v8']) 1868 self.cleanup_commands.append(['mv', 'v8.bak', 'v8'])
1859 1869
1860 self.depot_registry.SetDepotDir('v8_bleeding_edge', 1870 self.depot_registry.SetDepotDir(
1861 os.path.join(self.src_cwd, 'v8')) 1871 'v8_bleeding_edge', os.path.join(self.src_cwd, 'v8'))
1862 self.depot_registry.SetDepotDir('v8', os.path.join(self.src_cwd, 1872 self.depot_registry.SetDepotDir(
1863 'v8.bak')) 1873 'v8', os.path.join(self.src_cwd, 'v8.bak'))
1864 1874
1865 self.depot_registry.ChangeToDepotDir(current_depot) 1875 self.depot_registry.ChangeToDepotDir(current_depot)
1866 1876
1867 depot_revision_list = self.GetRevisionList(current_depot, 1877 depot_revision_list = self.GetRevisionList(current_depot,
1868 end_revision, 1878 end_revision,
1869 start_revision) 1879 start_revision)
1870 1880
1871 self.depot_registry.ChangeToDepotDir('chromium') 1881 self.depot_registry.ChangeToDepotDir('chromium')
1872 1882
1873 return depot_revision_list 1883 return depot_revision_list
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1941 bisect_utils.FILE_DEPS_GIT, oldest_deps_change, bad_revision) 1951 bisect_utils.FILE_DEPS_GIT, oldest_deps_change, bad_revision)
1942 1952
1943 if len(changes_to_deps) != len(changes_to_gitdeps): 1953 if len(changes_to_deps) != len(changes_to_gitdeps):
1944 # Grab the timestamp of the last DEPS change 1954 # Grab the timestamp of the last DEPS change
1945 cmd = ['log', '--format=%ct', '-1', changes_to_deps[0]] 1955 cmd = ['log', '--format=%ct', '-1', changes_to_deps[0]]
1946 output = bisect_utils.CheckRunGit(cmd) 1956 output = bisect_utils.CheckRunGit(cmd)
1947 commit_time = int(output) 1957 commit_time = int(output)
1948 1958
1949 # Try looking for a commit that touches the .DEPS.git file in the 1959 # Try looking for a commit that touches the .DEPS.git file in the
1950 # next 15 minutes after the DEPS file change. 1960 # next 15 minutes after the DEPS file change.
1951 cmd = ['log', '--format=%H', '-1', 1961 cmd = [
1952 '--before=%d' % (commit_time + 900), '--after=%d' % commit_time, 1962 'log', '--format=%H', '-1',
1953 'origin/master', '--', bisect_utils.FILE_DEPS_GIT] 1963 '--before=%d' % (commit_time + 900),
1964 '--after=%d' % commit_time,
1965 'origin/master', '--', bisect_utils.FILE_DEPS_GIT
1966 ]
1954 output = bisect_utils.CheckRunGit(cmd) 1967 output = bisect_utils.CheckRunGit(cmd)
1955 output = output.strip() 1968 output = output.strip()
1956 if output: 1969 if output:
1957 self.warnings.append('Detected change to DEPS and modified ' 1970 self.warnings.append(
1971 'Detected change to DEPS and modified '
1958 'revision range to include change to .DEPS.git') 1972 'revision range to include change to .DEPS.git')
1959 return (output, good_revision) 1973 return (output, good_revision)
1960 else: 1974 else:
1961 self.warnings.append('Detected change to DEPS but couldn\'t find ' 1975 self.warnings.append(
1976 'Detected change to DEPS but couldn\'t find '
1962 'matching change to .DEPS.git') 1977 'matching change to .DEPS.git')
1963 return (bad_revision, good_revision) 1978 return (bad_revision, good_revision)
1964 1979
1965 def CheckIfRevisionsInProperOrder( 1980 def CheckIfRevisionsInProperOrder(
1966 self, target_depot, good_revision, bad_revision): 1981 self, target_depot, good_revision, bad_revision):
1967 """Checks that |good_revision| is an earlier revision than |bad_revision|. 1982 """Checks that |good_revision| is an earlier revision than |bad_revision|.
1968 1983
1969 Args: 1984 Args:
1970 good_revision: Number/tag of the known good revision. 1985 good_revision: Number/tag of the known good revision.
1971 bad_revision: Number/tag of the known bad revision. 1986 bad_revision: Number/tag of the known bad revision.
1972 1987
1973 Returns: 1988 Returns:
1974 True if the revisions are in the proper order (good earlier than bad). 1989 True if the revisions are in the proper order (good earlier than bad).
1975 """ 1990 """
1976 cwd = self.depot_registry.GetDepotDir(target_depot) 1991 cwd = self.depot_registry.GetDepotDir(target_depot)
1977 good_position = source_control.GetCommitPosition(good_revision, cwd) 1992 good_position = source_control.GetCommitPosition(good_revision, cwd)
1978 bad_position = source_control.GetCommitPosition(bad_revision, cwd) 1993 bad_position = source_control.GetCommitPosition(bad_revision, cwd)
1979 # Compare commit timestamp for repos that don't support commit position. 1994 # Compare commit timestamp for repos that don't support commit position.
1980 if not (bad_position and good_position): 1995 if not (bad_position and good_position):
1981 good_position = source_control.GetCommitTime(good_revision, cwd=cwd) 1996 good_position = source_control.GetCommitTime(good_revision, cwd=cwd)
1982 bad_position = source_control.GetCommitTime(bad_revision, cwd=cwd) 1997 bad_position = source_control.GetCommitTime(bad_revision, cwd=cwd)
1983 1998
1984 return good_position <= bad_position 1999 return good_position <= bad_position
1985 2000
1986 def CanPerformBisect(self, good_revision, bad_revision): 2001 def CanPerformBisect(self, good_revision, bad_revision):
1987 """Checks whether a given revision is bisectable. 2002 """Checks whether a given revision is bisectable.
1988 2003
1989 Checks for following: 2004 Checks for following:
1990 1. Non-bisectable revsions for android bots (refer to crbug.com/385324). 2005 1. Non-bisectable revisions for android bots (refer to crbug.com/385324).
1991 2. Non-bisectable revsions for Windows bots (refer to crbug.com/405274). 2006 2. Non-bisectable revisions for Windows bots (refer to crbug.com/405274).
1992 2007
1993 Args: 2008 Args:
1994 good_revision: Known good revision. 2009 good_revision: Known good revision.
1995 bad_revision: Known bad revision. 2010 bad_revision: Known bad revision.
1996 2011
1997 Returns: 2012 Returns:
1998 A dictionary indicating the result. If revision is not bisectable, 2013 A dictionary indicating the result. If revision is not bisectable,
1999 this will contain the field "error", otherwise None. 2014 this will contain the field "error", otherwise None.
2000 """ 2015 """
2001 if self.opts.target_platform == 'android': 2016 if self.opts.target_platform == 'android':
(...skipping 29 matching lines...) Expand all
2031 performance tests again with and without the CL, adding the results to 2046 performance tests again with and without the CL, adding the results to
2032 the over bisect results. 2047 the over bisect results.
2033 2048
2034 Args: 2049 Args:
2035 results: BisectResults from the bisect. 2050 results: BisectResults from the bisect.
2036 target_depot: The target depot we're bisecting. 2051 target_depot: The target depot we're bisecting.
2037 command_to_run: Specify the command to execute the performance test. 2052 command_to_run: Specify the command to execute the performance test.
2038 metric: The performance metric to monitor. 2053 metric: The performance metric to monitor.
2039 """ 2054 """
2040 run_results_tot, run_results_reverted = self._RevertCulpritCLAndRetest( 2055 run_results_tot, run_results_reverted = self._RevertCulpritCLAndRetest(
2041 results, target_depot, command_to_run, metric) 2056 results, target_depot, command_to_run, metric)
2042 2057
2043 results.AddRetestResults(run_results_tot, run_results_reverted) 2058 results.AddRetestResults(run_results_tot, run_results_reverted)
2044 2059
2045 if len(results.culprit_revisions) != 1: 2060 if len(results.culprit_revisions) != 1:
2046 return 2061 return
2047 2062
2048 # Cleanup reverted files if anything is left. 2063 # Cleanup reverted files if anything is left.
2049 _, _, culprit_depot = results.culprit_revisions[0] 2064 _, _, culprit_depot = results.culprit_revisions[0]
2050 bisect_utils.CheckRunGit(['reset', '--hard', 'HEAD'], 2065 bisect_utils.CheckRunGit(
2066 ['reset', '--hard', 'HEAD'],
2051 cwd=self.depot_registry.GetDepotDir(culprit_depot)) 2067 cwd=self.depot_registry.GetDepotDir(culprit_depot))
2052 2068
2053 def _RevertCL(self, culprit_revision, culprit_depot): 2069 def _RevertCL(self, culprit_revision, culprit_depot):
2054 """Reverts the specified revision in the specified depot.""" 2070 """Reverts the specified revision in the specified depot."""
2055 if self.opts.output_buildbot_annotations: 2071 if self.opts.output_buildbot_annotations:
2056 bisect_utils.OutputAnnotationStepStart( 2072 bisect_utils.OutputAnnotationStepStart(
2057 'Reverting culprit CL: %s' % culprit_revision) 2073 'Reverting culprit CL: %s' % culprit_revision)
2058 _, return_code = bisect_utils.RunGit( 2074 _, return_code = bisect_utils.RunGit(
2059 ['revert', '--no-commit', culprit_revision], 2075 ['revert', '--no-commit', culprit_revision],
2060 cwd=self.depot_registry.GetDepotDir(culprit_depot)) 2076 cwd=self.depot_registry.GetDepotDir(culprit_depot))
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2111 'Culprit CL is in another depot, attempting to revert and build' 2127 'Culprit CL is in another depot, attempting to revert and build'
2112 ' locally to retest. This may not match the performance of official' 2128 ' locally to retest. This may not match the performance of official'
2113 ' builds.') 2129 ' builds.')
2114 2130
2115 run_results_reverted = self._RunTestWithAnnotations( 2131 run_results_reverted = self._RunTestWithAnnotations(
2116 'Re-Testing ToT with reverted culprit', 2132 'Re-Testing ToT with reverted culprit',
2117 'Failed to run reverted CL.', 2133 'Failed to run reverted CL.',
2118 head_revision, target_depot, command_to_run, metric, force_build) 2134 head_revision, target_depot, command_to_run, metric, force_build)
2119 2135
2120 # Clear the reverted file(s). 2136 # Clear the reverted file(s).
2121 bisect_utils.RunGit(['reset', '--hard', 'HEAD'], 2137 bisect_utils.RunGit(
2138 ['reset', '--hard', 'HEAD'],
2122 cwd=self.depot_registry.GetDepotDir(culprit_depot)) 2139 cwd=self.depot_registry.GetDepotDir(culprit_depot))
2123 2140
2124 # Retesting with the reverted CL failed, so bail out of retesting against 2141 # Retesting with the reverted CL failed, so bail out of retesting against
2125 # ToT. 2142 # ToT.
2126 if run_results_reverted[1]: 2143 if run_results_reverted[1]:
2127 return (None, None) 2144 return (None, None)
2128 2145
2129 run_results_tot = self._RunTestWithAnnotations( 2146 run_results_tot = self._RunTestWithAnnotations(
2130 'Re-Testing ToT', 2147 'Re-Testing ToT',
2131 'Failed to run ToT.', 2148 'Failed to run ToT.',
2132 head_revision, target_depot, command_to_run, metric, force_build) 2149 head_revision, target_depot, command_to_run, metric, force_build)
2133 2150
2134 return (run_results_tot, run_results_reverted) 2151 return (run_results_tot, run_results_reverted)
2135 2152
2136 def _RunTestWithAnnotations(self, step_text, error_text, head_revision, 2153 def _RunTestWithAnnotations(
2154 self, step_text, error_text, head_revision,
2137 target_depot, command_to_run, metric, force_build): 2155 target_depot, command_to_run, metric, force_build):
2138 """Runs the performance test and outputs start/stop annotations. 2156 """Runs the performance test and outputs start/stop annotations.
2139 2157
2140 Args: 2158 Args:
2141 results: BisectResults from the bisect. 2159 results: BisectResults from the bisect.
2142 target_depot: The target depot we're bisecting. 2160 target_depot: The target depot we're bisecting.
2143 command_to_run: Specify the command to execute the performance test. 2161 command_to_run: Specify the command to execute the performance test.
2144 metric: The performance metric to monitor. 2162 metric: The performance metric to monitor.
2145 force_build: Whether to force a build locally. 2163 force_build: Whether to force a build locally.
2146 2164
(...skipping 163 matching lines...) Expand 10 before | Expand all | Expand 10 after
2310 # Check how likely it is that the good and bad results are different 2328 # Check how likely it is that the good and bad results are different
2311 # beyond chance-induced variation. 2329 # beyond chance-induced variation.
2312 confidence_error = False 2330 confidence_error = False
2313 if not self.opts.debug_ignore_regression_confidence: 2331 if not self.opts.debug_ignore_regression_confidence:
2314 confidence_error = _CheckRegressionConfidenceError(good_revision, 2332 confidence_error = _CheckRegressionConfidenceError(good_revision,
2315 bad_revision, 2333 bad_revision,
2316 known_good_value, 2334 known_good_value,
2317 known_bad_value) 2335 known_bad_value)
2318 if confidence_error: 2336 if confidence_error:
2319 self.warnings.append(confidence_error) 2337 self.warnings.append(confidence_error)
2320 bad_revision_state.passed = True # Marking the 'bad' revision as good. 2338 # Marking the 'bad' revision as good BECAUSE XXX ...
RobertoCN 2015/03/12 20:57:03 because if there is no confidence that there's a r
qyearsley 2015/03/12 21:09:03 Ah, thanks for catching this, I meant to expand on
RobertoCN 2015/03/13 22:46:17 I don't remember there being any real need for thi
2339 bad_revision_state.passed = True
2321 return BisectResults(bisect_state, self.depot_registry, self.opts, 2340 return BisectResults(bisect_state, self.depot_registry, self.opts,
2322 self.warnings) 2341 self.warnings)
2323 2342
2324 while True: 2343 while True:
2325 if not revision_states: 2344 if not revision_states:
2326 break 2345 break
2327 2346
2328 if max_revision - min_revision <= 1: 2347 if max_revision - min_revision <= 1:
2329 min_revision_state = revision_states[min_revision] 2348 min_revision_state = revision_states[min_revision]
2330 max_revision_state = revision_states[max_revision] 2349 max_revision_state = revision_states[max_revision]
2331 current_depot = min_revision_state.depot 2350 current_depot = min_revision_state.depot
2332 # TODO(sergiyb): Under which conditions can first two branches be hit? 2351 # TODO(sergiyb): Under which conditions can first two branches be hit?
2333 if min_revision_state.passed == '?': 2352 if min_revision_state.passed == '?':
2334 next_revision_index = min_revision 2353 next_revision_index = min_revision
2335 elif max_revision_state.passed == '?': 2354 elif max_revision_state.passed == '?':
2336 next_revision_index = max_revision 2355 next_revision_index = max_revision
2337 elif current_depot in ['android-chrome', 'chromium', 'v8']: 2356 elif current_depot in ['android-chrome', 'chromium', 'v8']:
2338 previous_revision = revision_states[min_revision].revision 2357 previous_revision = revision_states[min_revision].revision
2339 # If there were changes to any of the external libraries we track, 2358 # If there were changes to any of the external libraries we track,
2340 # should bisect the changes there as well. 2359 # should bisect the changes there as well.
2341 external_depot = self._FindNextDepotToBisect( 2360 external_depot = self._FindNextDepotToBisect(
2342 current_depot, min_revision_state, max_revision_state) 2361 current_depot, min_revision_state, max_revision_state)
2343 # If there was no change in any of the external depots, the search 2362 # If there was no change in any of the external depots, the search
2344 # is over. 2363 # is over.
2345 if not external_depot: 2364 if not external_depot:
2346 if current_depot == 'v8': 2365 if current_depot == 'v8':
2347 self.warnings.append('Unfortunately, V8 bisection couldn\'t ' 2366 self.warnings.append(
2367 'Unfortunately, V8 bisection couldn\'t '
2348 'continue any further. The script can only bisect into ' 2368 'continue any further. The script can only bisect into '
2349 'V8\'s bleeding_edge repository if both the current and ' 2369 'V8\'s bleeding_edge repository if both the current and '
2350 'previous revisions in trunk map directly to revisions in ' 2370 'previous revisions in trunk map directly to revisions in '
2351 'bleeding_edge.') 2371 'bleeding_edge.')
2352 break 2372 break
2353 2373
2354 earliest_revision = max_revision_state.external[external_depot] 2374 earliest_revision = max_revision_state.external[external_depot]
2355 latest_revision = min_revision_state.external[external_depot] 2375 latest_revision = min_revision_state.external[external_depot]
2356 2376
2357 new_revision_list = self.PrepareToBisectOnDepot( 2377 new_revision_list = self.PrepareToBisectOnDepot(
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2427 2447
2428 # If the build is broken, remove it and redo search. 2448 # If the build is broken, remove it and redo search.
2429 revision_states.pop(next_revision_index) 2449 revision_states.pop(next_revision_index)
2430 2450
2431 max_revision -= 1 2451 max_revision -= 1
2432 2452
2433 if self.opts.output_buildbot_annotations: 2453 if self.opts.output_buildbot_annotations:
2434 self.printer.PrintPartialResults(bisect_state) 2454 self.printer.PrintPartialResults(bisect_state)
2435 bisect_utils.OutputAnnotationStepClosed() 2455 bisect_utils.OutputAnnotationStepClosed()
2436 2456
2437
2438 self._ConfidenceExtraTestRuns(min_revision_state, max_revision_state, 2457 self._ConfidenceExtraTestRuns(min_revision_state, max_revision_state,
2439 command_to_run, metric) 2458 command_to_run, metric)
2440 results = BisectResults(bisect_state, self.depot_registry, self.opts, 2459 results = BisectResults(bisect_state, self.depot_registry, self.opts,
2441 self.warnings) 2460 self.warnings)
2442 2461
2443 self._GatherResultsFromRevertedCulpritCL( 2462 self._GatherResultsFromRevertedCulpritCL(
2444 results, target_depot, command_to_run, metric) 2463 results, target_depot, command_to_run, metric)
2445 2464
2446 return results 2465 return results
2447 else: 2466 else:
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
2791 else: 2810 else:
2792 print 'Could not confirm bug is closed, proceeding.' 2811 print 'Could not confirm bug is closed, proceeding.'
2793 if opts.output_buildbot_annotations: 2812 if opts.output_buildbot_annotations:
2794 bisect_utils.OutputAnnotationStepClosed() 2813 bisect_utils.OutputAnnotationStepClosed()
2795 if issue_closed: 2814 if issue_closed:
2796 results = BisectResults(abort_reason='the bug is closed.') 2815 results = BisectResults(abort_reason='the bug is closed.')
2797 bisect_test = BisectPerformanceMetrics(opts, os.getcwd()) 2816 bisect_test = BisectPerformanceMetrics(opts, os.getcwd())
2798 bisect_test.printer.FormatAndPrintResults(results) 2817 bisect_test.printer.FormatAndPrintResults(results)
2799 return 0 2818 return 0
2800 2819
2801
2802 if opts.extra_src: 2820 if opts.extra_src:
2803 extra_src = bisect_utils.LoadExtraSrc(opts.extra_src) 2821 extra_src = bisect_utils.LoadExtraSrc(opts.extra_src)
2804 if not extra_src: 2822 if not extra_src:
2805 raise RuntimeError('Invalid or missing --extra_src.') 2823 raise RuntimeError('Invalid or missing --extra_src.')
2806 bisect_utils.AddAdditionalDepotInfo(extra_src.GetAdditionalDepotInfo()) 2824 bisect_utils.AddAdditionalDepotInfo(extra_src.GetAdditionalDepotInfo())
2807 2825
2808 if opts.working_directory: 2826 if opts.working_directory:
2809 custom_deps = bisect_utils.DEFAULT_GCLIENT_CUSTOM_DEPS 2827 custom_deps = bisect_utils.DEFAULT_GCLIENT_CUSTOM_DEPS
2810 if opts.no_custom_deps: 2828 if opts.no_custom_deps:
2811 custom_deps = None 2829 custom_deps = None
(...skipping 30 matching lines...) Expand all
2842 # bugs. If you change this, please update the perf dashboard as well. 2860 # bugs. If you change this, please update the perf dashboard as well.
2843 bisect_utils.OutputAnnotationStepStart('Results') 2861 bisect_utils.OutputAnnotationStepStart('Results')
2844 print 'Runtime Error: %s' % e 2862 print 'Runtime Error: %s' % e
2845 if opts.output_buildbot_annotations: 2863 if opts.output_buildbot_annotations:
2846 bisect_utils.OutputAnnotationStepClosed() 2864 bisect_utils.OutputAnnotationStepClosed()
2847 return 1 2865 return 1
2848 2866
2849 2867
2850 if __name__ == '__main__': 2868 if __name__ == '__main__':
2851 sys.exit(main()) 2869 sys.exit(main())
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698