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

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: Rebased 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
« no previous file with comments | « tools/auto_bisect/PRESUBMIT.py ('k') | tools/auto_bisect/bisect_perf_regression_test.py » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
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 313 matching lines...) Expand 10 before | Expand all | Expand 10 after
1355 if parsed_metric: 1359 if parsed_metric:
1356 metric_values.append(math_utils.Mean(parsed_metric)) 1360 metric_values.append(math_utils.Mean(parsed_metric))
1357 # If we're bisecting on a metric (ie, changes in the mean or 1361 # If we're bisecting on a metric (ie, changes in the mean or
1358 # standard deviation) and no metric values are produced, bail out. 1362 # standard deviation) and no metric values are produced, bail out.
1359 if not metric_values: 1363 if not metric_values:
1360 break 1364 break
1361 elif self._IsBisectModeReturnCode(): 1365 elif self._IsBisectModeReturnCode():
1362 metric_values.append(return_code) 1366 metric_values.append(return_code)
1363 1367
1364 elapsed_minutes = (time.time() - start_time) / 60.0 1368 elapsed_minutes = (time.time() - start_time) / 60.0
1365 time_limit = self.opts.max_time_minutes * test_run_multiplier 1369 time_limit = self.opts.max_time_minutes * test_run_multiplier
1366 if elapsed_minutes >= time_limit: 1370 if elapsed_minutes >= time_limit:
1367 break 1371 break
1368 1372
1369 if metric and len(metric_values) == 0: 1373 if metric and len(metric_values) == 0:
1370 err_text = 'Metric %s was not found in the test output.' % metric 1374 err_text = 'Metric %s was not found in the test output.' % metric
1371 # TODO(qyearsley): Consider also getting and displaying a list of metrics 1375 # TODO(qyearsley): Consider also getting and displaying a list of metrics
1372 # that were found in the output here. 1376 # that were found in the output here.
1373 return (err_text, failure_code, output_of_all_runs) 1377 return (err_text, failure_code, output_of_all_runs)
1374 1378
1375 # If we're bisecting on return codes, we're really just looking for zero vs 1379 # If we're bisecting on return codes, we're really just looking for zero vs
(...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after
1435 def _RunPostSync(self, _depot): 1439 def _RunPostSync(self, _depot):
1436 """Performs any work after syncing. 1440 """Performs any work after syncing.
1437 1441
1438 Args: 1442 Args:
1439 depot: Depot name. 1443 depot: Depot name.
1440 1444
1441 Returns: 1445 Returns:
1442 True if successful. 1446 True if successful.
1443 """ 1447 """
1444 if 'android' in self.opts.target_platform: 1448 if 'android' in self.opts.target_platform:
1445 if not builder.SetupAndroidBuildEnvironment(self.opts, 1449 if not builder.SetupAndroidBuildEnvironment(
1446 path_to_src=self.src_cwd): 1450 self.opts, path_to_src=self.src_cwd):
1447 return False 1451 return False
1448 1452
1449 return self.RunGClientHooks() 1453 return self.RunGClientHooks()
1450 1454
1451 @staticmethod 1455 @staticmethod
1452 def ShouldSkipRevision(depot, revision): 1456 def ShouldSkipRevision(depot, revision):
1453 """Checks whether a particular revision can be safely skipped. 1457 """Checks whether a particular revision can be safely skipped.
1454 1458
1455 Some commits can be safely skipped (such as a DEPS roll for the repos 1459 Some commits can be safely skipped (such as a DEPS roll for the repos
1456 still using .DEPS.git), since the tool is git based those changes 1460 still using .DEPS.git), since the tool is git based those changes
(...skipping 84 matching lines...) Expand 10 before | Expand all | Expand 10 after
1541 1545
1542 # A value other than 0 indicates that the test couldn't be run, and results 1546 # A value other than 0 indicates that the test couldn't be run, and results
1543 # should also include an error message. 1547 # should also include an error message.
1544 if results[1] != 0: 1548 if results[1] != 0:
1545 return results 1549 return results
1546 1550
1547 external_revisions = self._Get3rdPartyRevisions(depot) 1551 external_revisions = self._Get3rdPartyRevisions(depot)
1548 1552
1549 if not external_revisions is None: 1553 if not external_revisions is None:
1550 return (results[0], results[1], external_revisions, 1554 return (results[0], results[1], external_revisions,
1551 time.time() - after_build_time, after_build_time - 1555 time.time() - after_build_time, after_build_time -
1552 start_build_time) 1556 start_build_time)
1553 else: 1557 else:
1554 return ('Failed to parse DEPS file for external revisions.', 1558 return ('Failed to parse DEPS file for external revisions.',
1555 BUILD_RESULT_FAIL) 1559 BUILD_RESULT_FAIL)
1556 1560
1557 def _SyncRevision(self, depot, revision, sync_client): 1561 def _SyncRevision(self, depot, revision, sync_client):
1558 """Syncs depot to particular revision. 1562 """Syncs depot to particular revision.
1559 1563
1560 Args: 1564 Args:
1561 depot: The depot that's being used at the moment (src, webkit, etc.) 1565 depot: The depot that's being used at the moment (src, webkit, etc.)
1562 revision: The revision to sync to. 1566 revision: The revision to sync to.
1563 sync_client: Program used to sync, e.g. "gclient". Can be None. 1567 sync_client: Program used to sync, e.g. "gclient". Can be None.
1564 1568
1565 Returns: 1569 Returns:
1566 True if successful, False otherwise. 1570 True if successful, False otherwise.
1567 """ 1571 """
1568 self.depot_registry.ChangeToDepotDir(depot) 1572 self.depot_registry.ChangeToDepotDir(depot)
1569 1573
1570 if sync_client: 1574 if sync_client:
1571 self.PerformPreBuildCleanup() 1575 self.PerformPreBuildCleanup()
1572 1576
1573 # When using gclient to sync, you need to specify the depot you 1577 # When using gclient to sync, you need to specify the depot you
1574 # want so that all the dependencies sync properly as well. 1578 # want so that all the dependencies sync properly as well.
1575 # i.e. gclient sync src@<SHA1> 1579 # i.e. gclient sync src@<SHA1>
1576 if sync_client == 'gclient' and revision: 1580 if sync_client == 'gclient' and revision:
1577 revision = '%s@%s' % (bisect_utils.DEPOT_DEPS_NAME[depot]['src'], 1581 revision = '%s@%s' % (bisect_utils.DEPOT_DEPS_NAME[depot]['src'],
1578 revision) 1582 revision)
1579 if depot == 'chromium' and self.opts.target_platform == 'android-chrome': 1583 if depot == 'chromium' and self.opts.target_platform == 'android-chrome':
1580 return self._SyncRevisionsForAndroidChrome(revision) 1584 return self._SyncRevisionsForAndroidChrome(revision)
1581 1585
1582 return source_control.SyncToRevision(revision, sync_client) 1586 return source_control.SyncToRevision(revision, sync_client)
1583 1587
1584 def _SyncRevisionsForAndroidChrome(self, revision): 1588 def _SyncRevisionsForAndroidChrome(self, revision):
1585 """Syncs android-chrome and chromium repos to particular revision. 1589 """Syncs android-chrome and chromium repos to particular revision.
1586 1590
1587 This is a special case for android-chrome as the gclient sync for chromium 1591 This is a special case for android-chrome as the gclient sync for chromium
1588 overwrites the android-chrome revision to TOT. Therefore both the repos 1592 overwrites the android-chrome revision to TOT. Therefore both the repos
(...skipping 21 matching lines...) Expand all
1610 current_value: The value of the metric being checked. 1614 current_value: The value of the metric being checked.
1611 known_bad_value: The reference value for a "failed" run. 1615 known_bad_value: The reference value for a "failed" run.
1612 known_good_value: The reference value for a "passed" run. 1616 known_good_value: The reference value for a "passed" run.
1613 1617
1614 Returns: 1618 Returns:
1615 True if the current_value is closer to the known_good_value than the 1619 True if the current_value is closer to the known_good_value than the
1616 known_bad_value. 1620 known_bad_value.
1617 """ 1621 """
1618 if self.opts.bisect_mode == bisect_utils.BISECT_MODE_STD_DEV: 1622 if self.opts.bisect_mode == bisect_utils.BISECT_MODE_STD_DEV:
1619 dist_to_good_value = abs(current_value['std_dev'] - 1623 dist_to_good_value = abs(current_value['std_dev'] -
1620 known_good_value['std_dev']) 1624 known_good_value['std_dev'])
1621 dist_to_bad_value = abs(current_value['std_dev'] - 1625 dist_to_bad_value = abs(current_value['std_dev'] -
1622 known_bad_value['std_dev']) 1626 known_bad_value['std_dev'])
1623 else: 1627 else:
1624 dist_to_good_value = abs(current_value['mean'] - known_good_value['mean']) 1628 dist_to_good_value = abs(current_value['mean'] - known_good_value['mean'])
1625 dist_to_bad_value = abs(current_value['mean'] - known_bad_value['mean']) 1629 dist_to_bad_value = abs(current_value['mean'] - known_bad_value['mean'])
1626 1630
1627 return dist_to_good_value < dist_to_bad_value 1631 return dist_to_good_value < dist_to_bad_value
1628 1632
1629 def _GetV8BleedingEdgeFromV8TrunkIfMappable( 1633 def _GetV8BleedingEdgeFromV8TrunkIfMappable(
1630 self, revision, bleeding_edge_branch): 1634 self, revision, bleeding_edge_branch):
1631 """Gets v8 bleeding edge revision mapped to v8 revision in trunk. 1635 """Gets v8 bleeding edge revision mapped to v8 revision in trunk.
1632 1636
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after
1687 return re_results.group('git_revision') 1691 return re_results.group('git_revision')
1688 except (IndexError, ValueError): 1692 except (IndexError, ValueError):
1689 pass 1693 pass
1690 if not git_revision: 1694 if not git_revision:
1691 # Wasn't successful, try the old way of looking for "Prepare push to" 1695 # Wasn't successful, try the old way of looking for "Prepare push to"
1692 git_revision = source_control.ResolveToRevision( 1696 git_revision = source_control.ResolveToRevision(
1693 int(commit_position) - 1, 'v8_bleeding_edge', 1697 int(commit_position) - 1, 'v8_bleeding_edge',
1694 bisect_utils.DEPOT_DEPS_NAME, -1, cwd=v8_bleeding_edge_dir) 1698 bisect_utils.DEPOT_DEPS_NAME, -1, cwd=v8_bleeding_edge_dir)
1695 1699
1696 if git_revision: 1700 if git_revision:
1697 revision_info = source_control.QueryRevisionInfo(git_revision, 1701 revision_info = source_control.QueryRevisionInfo(
1698 cwd=v8_bleeding_edge_dir) 1702 git_revision, cwd=v8_bleeding_edge_dir)
1699 1703
1700 if 'Prepare push to trunk' in revision_info['subject']: 1704 if 'Prepare push to trunk' in revision_info['subject']:
1701 return git_revision 1705 return git_revision
1702 return None 1706 return None
1703 1707
1704 def _GetNearestV8BleedingEdgeFromTrunk( 1708 def _GetNearestV8BleedingEdgeFromTrunk(
1705 self, revision, v8_branch, bleeding_edge_branch, search_forward=True): 1709 self, revision, v8_branch, bleeding_edge_branch, search_forward=True):
1706 """Gets the nearest V8 roll and maps to bleeding edge revision. 1710 """Gets the nearest V8 roll and maps to bleeding edge revision.
1707 1711
1708 V8 is a bit tricky to bisect since it isn't just rolled out like blink. 1712 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
1765 1769
1766 # Support for the chromium revisions with external V8 repo. 1770 # Support for the chromium revisions with external V8 repo.
1767 # ie https://chromium.googlesource.com/external/v8.git 1771 # ie https://chromium.googlesource.com/external/v8.git
1768 cmd = ['config', '--get', 'remote.origin.url'] 1772 cmd = ['config', '--get', 'remote.origin.url']
1769 v8_repo_url = bisect_utils.CheckRunGit(cmd, cwd=cwd) 1773 v8_repo_url = bisect_utils.CheckRunGit(cmd, cwd=cwd)
1770 1774
1771 if 'external/v8.git' in v8_repo_url: 1775 if 'external/v8.git' in v8_repo_url:
1772 v8_branch = 'origin/master' 1776 v8_branch = 'origin/master'
1773 bleeding_edge_branch = 'origin/bleeding_edge' 1777 bleeding_edge_branch = 'origin/bleeding_edge'
1774 1778
1775 r1 = self._GetNearestV8BleedingEdgeFromTrunk(min_revision_state.revision, 1779 r1 = self._GetNearestV8BleedingEdgeFromTrunk(
1776 v8_branch, bleeding_edge_branch, search_forward=True) 1780 min_revision_state.revision,
1777 r2 = self._GetNearestV8BleedingEdgeFromTrunk(max_revision_state.revision, 1781 v8_branch,
1778 v8_branch, bleeding_edge_branch, search_forward=False) 1782 bleeding_edge_branch,
1783 search_forward=True)
1784 r2 = self._GetNearestV8BleedingEdgeFromTrunk(
1785 max_revision_state.revision,
1786 v8_branch,
1787 bleeding_edge_branch,
1788 search_forward=False)
1779 min_revision_state.external['v8_bleeding_edge'] = r1 1789 min_revision_state.external['v8_bleeding_edge'] = r1
1780 max_revision_state.external['v8_bleeding_edge'] = r2 1790 max_revision_state.external['v8_bleeding_edge'] = r2
1781 1791
1782 if (not self._GetV8BleedingEdgeFromV8TrunkIfMappable( 1792 if (not self._GetV8BleedingEdgeFromV8TrunkIfMappable(
1783 min_revision_state.revision, bleeding_edge_branch) 1793 min_revision_state.revision, bleeding_edge_branch)
1784 or not self._GetV8BleedingEdgeFromV8TrunkIfMappable( 1794 or not self._GetV8BleedingEdgeFromV8TrunkIfMappable(
1785 max_revision_state.revision, bleeding_edge_branch)): 1795 max_revision_state.revision, bleeding_edge_branch)):
1786 self.warnings.append( 1796 self.warnings.append(
1787 'Trunk revisions in V8 did not map directly to bleeding_edge. ' 1797 'Trunk revisions in V8 did not map directly to bleeding_edge. '
1788 'Attempted to expand the range to find V8 rolls which did map ' 1798 'Attempted to expand the range to find V8 rolls which did map '
1789 'directly to bleeding_edge revisions, but results might not be ' 1799 'directly to bleeding_edge revisions, but results might not be '
1790 'valid.') 1800 'valid.')
1791 1801
1792 def _FindNextDepotToBisect( 1802 def _FindNextDepotToBisect(
1793 self, current_depot, min_revision_state, max_revision_state): 1803 self, current_depot, min_revision_state, max_revision_state):
1794 """Decides which depot the script should dive into next (if any). 1804 """Decides which depot the script should dive into next (if any).
1795 1805
1796 Args: 1806 Args:
1797 current_depot: Current depot being bisected. 1807 current_depot: Current depot being bisected.
1798 min_revision_state: State of the earliest revision in the bisect range. 1808 min_revision_state: State of the earliest revision in the bisect range.
1799 max_revision_state: State of the latest revision in the bisect range. 1809 max_revision_state: State of the latest revision in the bisect range.
1800 1810
1801 Returns: 1811 Returns:
1802 Name of the depot to bisect next, or None. 1812 Name of the depot to bisect next, or None.
1803 """ 1813 """
1804 external_depot = None 1814 external_depot = None
1805 for next_depot in bisect_utils.DEPOT_NAMES: 1815 for next_depot in bisect_utils.DEPOT_NAMES:
1806 if bisect_utils.DEPOT_DEPS_NAME[next_depot].has_key('platform'): 1816 if ('platform' in bisect_utils.DEPOT_DEPS_NAME[next_depot] and
1807 if bisect_utils.DEPOT_DEPS_NAME[next_depot]['platform'] != os.name: 1817 bisect_utils.DEPOT_DEPS_NAME[next_depot]['platform'] != os.name):
1808 continue 1818 continue
1809 1819
1810 if not (bisect_utils.DEPOT_DEPS_NAME[next_depot]['recurse'] 1820 if not (bisect_utils.DEPOT_DEPS_NAME[next_depot]['recurse']
1811 and min_revision_state.depot 1821 and min_revision_state.depot
1812 in bisect_utils.DEPOT_DEPS_NAME[next_depot]['from']): 1822 in bisect_utils.DEPOT_DEPS_NAME[next_depot]['from']):
1813 continue 1823 continue
1814 1824
1815 if current_depot == 'v8': 1825 if current_depot == 'v8':
1816 # We grab the bleeding_edge info here rather than earlier because we 1826 # We grab the bleeding_edge info here rather than earlier because we
1817 # finally have the revision range. From that we can search forwards and 1827 # finally have the revision range. From that we can search forwards and
1818 # backwards to try to match trunk revisions to bleeding_edge. 1828 # backwards to try to match trunk revisions to bleeding_edge.
(...skipping 24 matching lines...) Expand all
1843 Returns: 1853 Returns:
1844 A list containing the revisions between |start_revision| and 1854 A list containing the revisions between |start_revision| and
1845 |end_revision| inclusive. 1855 |end_revision| inclusive.
1846 """ 1856 """
1847 # Change into working directory of external library to run 1857 # Change into working directory of external library to run
1848 # subsequent commands. 1858 # subsequent commands.
1849 self.depot_registry.ChangeToDepotDir(current_depot) 1859 self.depot_registry.ChangeToDepotDir(current_depot)
1850 1860
1851 # V8 (and possibly others) is merged in periodically. Bisecting 1861 # V8 (and possibly others) is merged in periodically. Bisecting
1852 # this directory directly won't give much good info. 1862 # this directory directly won't give much good info.
1853 if bisect_utils.DEPOT_DEPS_NAME[current_depot].has_key('custom_deps'): 1863 if 'custom_deps' in bisect_utils.DEPOT_DEPS_NAME[current_depot]:
1854 config_path = os.path.join(self.src_cwd, '..') 1864 config_path = os.path.join(self.src_cwd, '..')
1855 if bisect_utils.RunGClientAndCreateConfig( 1865 if bisect_utils.RunGClientAndCreateConfig(
1856 self.opts, bisect_utils.DEPOT_DEPS_NAME[current_depot]['custom_deps'], 1866 self.opts, bisect_utils.DEPOT_DEPS_NAME[current_depot]['custom_deps'],
1857 cwd=config_path): 1867 cwd=config_path):
1858 return [] 1868 return []
1859 if bisect_utils.RunGClient( 1869 if bisect_utils.RunGClient(
1860 ['sync', '--revision', previous_revision], cwd=self.src_cwd): 1870 ['sync', '--revision', previous_revision], cwd=self.src_cwd):
1861 return [] 1871 return []
1862 1872
1863 if current_depot == 'v8_bleeding_edge': 1873 if current_depot == 'v8_bleeding_edge':
1864 self.depot_registry.ChangeToDepotDir('chromium') 1874 self.depot_registry.ChangeToDepotDir('chromium')
1865 1875
1866 shutil.move('v8', 'v8.bak') 1876 shutil.move('v8', 'v8.bak')
1867 shutil.move('v8_bleeding_edge', 'v8') 1877 shutil.move('v8_bleeding_edge', 'v8')
1868 1878
1869 self.cleanup_commands.append(['mv', 'v8', 'v8_bleeding_edge']) 1879 self.cleanup_commands.append(['mv', 'v8', 'v8_bleeding_edge'])
1870 self.cleanup_commands.append(['mv', 'v8.bak', 'v8']) 1880 self.cleanup_commands.append(['mv', 'v8.bak', 'v8'])
1871 1881
1872 self.depot_registry.SetDepotDir('v8_bleeding_edge', 1882 self.depot_registry.SetDepotDir(
1873 os.path.join(self.src_cwd, 'v8')) 1883 'v8_bleeding_edge', os.path.join(self.src_cwd, 'v8'))
1874 self.depot_registry.SetDepotDir('v8', os.path.join(self.src_cwd, 1884 self.depot_registry.SetDepotDir(
1875 'v8.bak')) 1885 'v8', os.path.join(self.src_cwd, 'v8.bak'))
1876 1886
1877 self.depot_registry.ChangeToDepotDir(current_depot) 1887 self.depot_registry.ChangeToDepotDir(current_depot)
1878 1888
1879 depot_revision_list = self.GetRevisionList(current_depot, 1889 depot_revision_list = self.GetRevisionList(current_depot,
1880 end_revision, 1890 end_revision,
1881 start_revision) 1891 start_revision)
1882 1892
1883 self.depot_registry.ChangeToDepotDir('chromium') 1893 self.depot_registry.ChangeToDepotDir('chromium')
1884 1894
1885 return depot_revision_list 1895 return depot_revision_list
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
1953 bisect_utils.FILE_DEPS_GIT, oldest_deps_change, bad_revision) 1963 bisect_utils.FILE_DEPS_GIT, oldest_deps_change, bad_revision)
1954 1964
1955 if len(changes_to_deps) != len(changes_to_gitdeps): 1965 if len(changes_to_deps) != len(changes_to_gitdeps):
1956 # Grab the timestamp of the last DEPS change 1966 # Grab the timestamp of the last DEPS change
1957 cmd = ['log', '--format=%ct', '-1', changes_to_deps[0]] 1967 cmd = ['log', '--format=%ct', '-1', changes_to_deps[0]]
1958 output = bisect_utils.CheckRunGit(cmd) 1968 output = bisect_utils.CheckRunGit(cmd)
1959 commit_time = int(output) 1969 commit_time = int(output)
1960 1970
1961 # Try looking for a commit that touches the .DEPS.git file in the 1971 # Try looking for a commit that touches the .DEPS.git file in the
1962 # next 15 minutes after the DEPS file change. 1972 # next 15 minutes after the DEPS file change.
1963 cmd = ['log', '--format=%H', '-1', 1973 cmd = [
1964 '--before=%d' % (commit_time + 900), '--after=%d' % commit_time, 1974 'log', '--format=%H', '-1',
1965 'origin/master', '--', bisect_utils.FILE_DEPS_GIT] 1975 '--before=%d' % (commit_time + 900),
1976 '--after=%d' % commit_time,
1977 'origin/master', '--', bisect_utils.FILE_DEPS_GIT
1978 ]
1966 output = bisect_utils.CheckRunGit(cmd) 1979 output = bisect_utils.CheckRunGit(cmd)
1967 output = output.strip() 1980 output = output.strip()
1968 if output: 1981 if output:
1969 self.warnings.append('Detected change to DEPS and modified ' 1982 self.warnings.append(
1983 'Detected change to DEPS and modified '
1970 'revision range to include change to .DEPS.git') 1984 'revision range to include change to .DEPS.git')
1971 return (output, good_revision) 1985 return (output, good_revision)
1972 else: 1986 else:
1973 self.warnings.append('Detected change to DEPS but couldn\'t find ' 1987 self.warnings.append(
1988 'Detected change to DEPS but couldn\'t find '
1974 'matching change to .DEPS.git') 1989 'matching change to .DEPS.git')
1975 return (bad_revision, good_revision) 1990 return (bad_revision, good_revision)
1976 1991
1977 def CheckIfRevisionsInProperOrder( 1992 def CheckIfRevisionsInProperOrder(
1978 self, target_depot, good_revision, bad_revision): 1993 self, target_depot, good_revision, bad_revision):
1979 """Checks that |good_revision| is an earlier revision than |bad_revision|. 1994 """Checks that |good_revision| is an earlier revision than |bad_revision|.
1980 1995
1981 Args: 1996 Args:
1982 good_revision: Number/tag of the known good revision. 1997 good_revision: Number/tag of the known good revision.
1983 bad_revision: Number/tag of the known bad revision. 1998 bad_revision: Number/tag of the known bad revision.
(...skipping 10 matching lines...) Expand all
1994 'depot %s', good_position, bad_position, target_depot) 2009 'depot %s', good_position, bad_position, target_depot)
1995 good_position = source_control.GetCommitTime(good_revision, cwd=cwd) 2010 good_position = source_control.GetCommitTime(good_revision, cwd=cwd)
1996 bad_position = source_control.GetCommitTime(bad_revision, cwd=cwd) 2011 bad_position = source_control.GetCommitTime(bad_revision, cwd=cwd)
1997 2012
1998 return good_position <= bad_position 2013 return good_position <= bad_position
1999 2014
2000 def CanPerformBisect(self, good_revision, bad_revision): 2015 def CanPerformBisect(self, good_revision, bad_revision):
2001 """Checks whether a given revision is bisectable. 2016 """Checks whether a given revision is bisectable.
2002 2017
2003 Checks for following: 2018 Checks for following:
2004 1. Non-bisectable revsions for android bots (refer to crbug.com/385324). 2019 1. Non-bisectable revisions for android bots (refer to crbug.com/385324).
2005 2. Non-bisectable revsions for Windows bots (refer to crbug.com/405274). 2020 2. Non-bisectable revisions for Windows bots (refer to crbug.com/405274).
2006 2021
2007 Args: 2022 Args:
2008 good_revision: Known good revision. 2023 good_revision: Known good revision.
2009 bad_revision: Known bad revision. 2024 bad_revision: Known bad revision.
2010 2025
2011 Returns: 2026 Returns:
2012 A dictionary indicating the result. If revision is not bisectable, 2027 A dictionary indicating the result. If revision is not bisectable,
2013 this will contain the field "error", otherwise None. 2028 this will contain the field "error", otherwise None.
2014 """ 2029 """
2015 if self.opts.target_platform == 'android': 2030 if self.opts.target_platform == 'android':
(...skipping 29 matching lines...) Expand all
2045 performance tests again with and without the CL, adding the results to 2060 performance tests again with and without the CL, adding the results to
2046 the over bisect results. 2061 the over bisect results.
2047 2062
2048 Args: 2063 Args:
2049 results: BisectResults from the bisect. 2064 results: BisectResults from the bisect.
2050 target_depot: The target depot we're bisecting. 2065 target_depot: The target depot we're bisecting.
2051 command_to_run: Specify the command to execute the performance test. 2066 command_to_run: Specify the command to execute the performance test.
2052 metric: The performance metric to monitor. 2067 metric: The performance metric to monitor.
2053 """ 2068 """
2054 run_results_tot, run_results_reverted = self._RevertCulpritCLAndRetest( 2069 run_results_tot, run_results_reverted = self._RevertCulpritCLAndRetest(
2055 results, target_depot, command_to_run, metric) 2070 results, target_depot, command_to_run, metric)
2056 2071
2057 results.AddRetestResults(run_results_tot, run_results_reverted) 2072 results.AddRetestResults(run_results_tot, run_results_reverted)
2058 2073
2059 if len(results.culprit_revisions) != 1: 2074 if len(results.culprit_revisions) != 1:
2060 return 2075 return
2061 2076
2062 # Cleanup reverted files if anything is left. 2077 # Cleanup reverted files if anything is left.
2063 _, _, culprit_depot = results.culprit_revisions[0] 2078 _, _, culprit_depot = results.culprit_revisions[0]
2064 bisect_utils.CheckRunGit(['reset', '--hard', 'HEAD'], 2079 bisect_utils.CheckRunGit(
2080 ['reset', '--hard', 'HEAD'],
2065 cwd=self.depot_registry.GetDepotDir(culprit_depot)) 2081 cwd=self.depot_registry.GetDepotDir(culprit_depot))
2066 2082
2067 def _RevertCL(self, culprit_revision, culprit_depot): 2083 def _RevertCL(self, culprit_revision, culprit_depot):
2068 """Reverts the specified revision in the specified depot.""" 2084 """Reverts the specified revision in the specified depot."""
2069 if self.opts.output_buildbot_annotations: 2085 if self.opts.output_buildbot_annotations:
2070 bisect_utils.OutputAnnotationStepStart( 2086 bisect_utils.OutputAnnotationStepStart(
2071 'Reverting culprit CL: %s' % culprit_revision) 2087 'Reverting culprit CL: %s' % culprit_revision)
2072 _, return_code = bisect_utils.RunGit( 2088 _, return_code = bisect_utils.RunGit(
2073 ['revert', '--no-commit', culprit_revision], 2089 ['revert', '--no-commit', culprit_revision],
2074 cwd=self.depot_registry.GetDepotDir(culprit_depot)) 2090 cwd=self.depot_registry.GetDepotDir(culprit_depot))
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after
2125 'Culprit CL is in another depot, attempting to revert and build' 2141 'Culprit CL is in another depot, attempting to revert and build'
2126 ' locally to retest. This may not match the performance of official' 2142 ' locally to retest. This may not match the performance of official'
2127 ' builds.') 2143 ' builds.')
2128 2144
2129 run_results_reverted = self._RunTestWithAnnotations( 2145 run_results_reverted = self._RunTestWithAnnotations(
2130 'Re-Testing ToT with reverted culprit', 2146 'Re-Testing ToT with reverted culprit',
2131 'Failed to run reverted CL.', 2147 'Failed to run reverted CL.',
2132 head_revision, target_depot, command_to_run, metric, force_build) 2148 head_revision, target_depot, command_to_run, metric, force_build)
2133 2149
2134 # Clear the reverted file(s). 2150 # Clear the reverted file(s).
2135 bisect_utils.RunGit(['reset', '--hard', 'HEAD'], 2151 bisect_utils.RunGit(
2152 ['reset', '--hard', 'HEAD'],
2136 cwd=self.depot_registry.GetDepotDir(culprit_depot)) 2153 cwd=self.depot_registry.GetDepotDir(culprit_depot))
2137 2154
2138 # Retesting with the reverted CL failed, so bail out of retesting against 2155 # Retesting with the reverted CL failed, so bail out of retesting against
2139 # ToT. 2156 # ToT.
2140 if run_results_reverted[1]: 2157 if run_results_reverted[1]:
2141 return (None, None) 2158 return (None, None)
2142 2159
2143 run_results_tot = self._RunTestWithAnnotations( 2160 run_results_tot = self._RunTestWithAnnotations(
2144 'Re-Testing ToT', 2161 'Re-Testing ToT',
2145 'Failed to run ToT.', 2162 'Failed to run ToT.',
2146 head_revision, target_depot, command_to_run, metric, force_build) 2163 head_revision, target_depot, command_to_run, metric, force_build)
2147 2164
2148 return (run_results_tot, run_results_reverted) 2165 return (run_results_tot, run_results_reverted)
2149 2166
2150 def _RunTestWithAnnotations(self, step_text, error_text, head_revision, 2167 def _RunTestWithAnnotations(
2168 self, step_text, error_text, head_revision,
2151 target_depot, command_to_run, metric, force_build): 2169 target_depot, command_to_run, metric, force_build):
2152 """Runs the performance test and outputs start/stop annotations. 2170 """Runs the performance test and outputs start/stop annotations.
2153 2171
2154 Args: 2172 Args:
2155 results: BisectResults from the bisect. 2173 results: BisectResults from the bisect.
2156 target_depot: The target depot we're bisecting. 2174 target_depot: The target depot we're bisecting.
2157 command_to_run: Specify the command to execute the performance test. 2175 command_to_run: Specify the command to execute the performance test.
2158 metric: The performance metric to monitor. 2176 metric: The performance metric to monitor.
2159 force_build: Whether to force a build locally. 2177 force_build: Whether to force a build locally.
2160 2178
(...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after
2323 2341
2324 # Check how likely it is that the good and bad results are different 2342 # Check how likely it is that the good and bad results are different
2325 # beyond chance-induced variation. 2343 # beyond chance-induced variation.
2326 confidence_error = False 2344 confidence_error = False
2327 if not self.opts.debug_ignore_regression_confidence: 2345 if not self.opts.debug_ignore_regression_confidence:
2328 confidence_error = _CheckRegressionConfidenceError(good_revision, 2346 confidence_error = _CheckRegressionConfidenceError(good_revision,
2329 bad_revision, 2347 bad_revision,
2330 known_good_value, 2348 known_good_value,
2331 known_bad_value) 2349 known_bad_value)
2332 if confidence_error: 2350 if confidence_error:
2351 # If there is no significant difference between "good" and "bad"
2352 # revision results, then the "bad revision" is considered "good".
2353 # TODO(qyearsley): Remove this if it is not necessary.
2354 bad_revision_state.passed = True
2333 self.warnings.append(confidence_error) 2355 self.warnings.append(confidence_error)
2334 bad_revision_state.passed = True # Marking the 'bad' revision as good.
2335 return BisectResults(bisect_state, self.depot_registry, self.opts, 2356 return BisectResults(bisect_state, self.depot_registry, self.opts,
2336 self.warnings) 2357 self.warnings)
2337 2358
2338 while True: 2359 while True:
2339 if not revision_states: 2360 if not revision_states:
2340 break 2361 break
2341 2362
2342 if max_revision - min_revision <= 1: 2363 if max_revision - min_revision <= 1:
2343 min_revision_state = revision_states[min_revision] 2364 min_revision_state = revision_states[min_revision]
2344 max_revision_state = revision_states[max_revision] 2365 max_revision_state = revision_states[max_revision]
2345 current_depot = min_revision_state.depot 2366 current_depot = min_revision_state.depot
2346 # TODO(sergiyb): Under which conditions can first two branches be hit? 2367 # TODO(sergiyb): Under which conditions can first two branches be hit?
2347 if min_revision_state.passed == '?': 2368 if min_revision_state.passed == '?':
2348 next_revision_index = min_revision 2369 next_revision_index = min_revision
2349 elif max_revision_state.passed == '?': 2370 elif max_revision_state.passed == '?':
2350 next_revision_index = max_revision 2371 next_revision_index = max_revision
2351 elif current_depot in ['android-chrome', 'chromium', 'v8']: 2372 elif current_depot in ['android-chrome', 'chromium', 'v8']:
2352 previous_revision = revision_states[min_revision].revision 2373 previous_revision = revision_states[min_revision].revision
2353 # If there were changes to any of the external libraries we track, 2374 # If there were changes to any of the external libraries we track,
2354 # should bisect the changes there as well. 2375 # should bisect the changes there as well.
2355 external_depot = self._FindNextDepotToBisect( 2376 external_depot = self._FindNextDepotToBisect(
2356 current_depot, min_revision_state, max_revision_state) 2377 current_depot, min_revision_state, max_revision_state)
2357 # If there was no change in any of the external depots, the search 2378 # If there was no change in any of the external depots, the search
2358 # is over. 2379 # is over.
2359 if not external_depot: 2380 if not external_depot:
2360 if current_depot == 'v8': 2381 if current_depot == 'v8':
2361 self.warnings.append('Unfortunately, V8 bisection couldn\'t ' 2382 self.warnings.append(
2383 'Unfortunately, V8 bisection couldn\'t '
2362 'continue any further. The script can only bisect into ' 2384 'continue any further. The script can only bisect into '
2363 'V8\'s bleeding_edge repository if both the current and ' 2385 'V8\'s bleeding_edge repository if both the current and '
2364 'previous revisions in trunk map directly to revisions in ' 2386 'previous revisions in trunk map directly to revisions in '
2365 'bleeding_edge.') 2387 'bleeding_edge.')
2366 break 2388 break
2367 2389
2368 earliest_revision = max_revision_state.external[external_depot] 2390 earliest_revision = max_revision_state.external[external_depot]
2369 latest_revision = min_revision_state.external[external_depot] 2391 latest_revision = min_revision_state.external[external_depot]
2370 2392
2371 new_revision_list = self.PrepareToBisectOnDepot( 2393 new_revision_list = self.PrepareToBisectOnDepot(
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after
2441 2463
2442 # If the build is broken, remove it and redo search. 2464 # If the build is broken, remove it and redo search.
2443 revision_states.pop(next_revision_index) 2465 revision_states.pop(next_revision_index)
2444 2466
2445 max_revision -= 1 2467 max_revision -= 1
2446 2468
2447 if self.opts.output_buildbot_annotations: 2469 if self.opts.output_buildbot_annotations:
2448 self.printer.PrintPartialResults(bisect_state) 2470 self.printer.PrintPartialResults(bisect_state)
2449 bisect_utils.OutputAnnotationStepClosed() 2471 bisect_utils.OutputAnnotationStepClosed()
2450 2472
2451
2452 self._ConfidenceExtraTestRuns(min_revision_state, max_revision_state, 2473 self._ConfidenceExtraTestRuns(min_revision_state, max_revision_state,
2453 command_to_run, metric) 2474 command_to_run, metric)
2454 results = BisectResults(bisect_state, self.depot_registry, self.opts, 2475 results = BisectResults(bisect_state, self.depot_registry, self.opts,
2455 self.warnings) 2476 self.warnings)
2456 2477
2457 self._GatherResultsFromRevertedCulpritCL( 2478 self._GatherResultsFromRevertedCulpritCL(
2458 results, target_depot, command_to_run, metric) 2479 results, target_depot, command_to_run, metric)
2459 2480
2460 return results 2481 return results
2461 else: 2482 else:
(...skipping 343 matching lines...) Expand 10 before | Expand all | Expand 10 after
2805 else: 2826 else:
2806 print 'Could not confirm bug is closed, proceeding.' 2827 print 'Could not confirm bug is closed, proceeding.'
2807 if opts.output_buildbot_annotations: 2828 if opts.output_buildbot_annotations:
2808 bisect_utils.OutputAnnotationStepClosed() 2829 bisect_utils.OutputAnnotationStepClosed()
2809 if issue_closed: 2830 if issue_closed:
2810 results = BisectResults(abort_reason='the bug is closed.') 2831 results = BisectResults(abort_reason='the bug is closed.')
2811 bisect_test = BisectPerformanceMetrics(opts, os.getcwd()) 2832 bisect_test = BisectPerformanceMetrics(opts, os.getcwd())
2812 bisect_test.printer.FormatAndPrintResults(results) 2833 bisect_test.printer.FormatAndPrintResults(results)
2813 return 0 2834 return 0
2814 2835
2815
2816 if opts.extra_src: 2836 if opts.extra_src:
2817 extra_src = bisect_utils.LoadExtraSrc(opts.extra_src) 2837 extra_src = bisect_utils.LoadExtraSrc(opts.extra_src)
2818 if not extra_src: 2838 if not extra_src:
2819 raise RuntimeError('Invalid or missing --extra_src.') 2839 raise RuntimeError('Invalid or missing --extra_src.')
2820 bisect_utils.AddAdditionalDepotInfo(extra_src.GetAdditionalDepotInfo()) 2840 bisect_utils.AddAdditionalDepotInfo(extra_src.GetAdditionalDepotInfo())
2821 2841
2822 if opts.working_directory: 2842 if opts.working_directory:
2823 custom_deps = bisect_utils.DEFAULT_GCLIENT_CUSTOM_DEPS 2843 custom_deps = bisect_utils.DEFAULT_GCLIENT_CUSTOM_DEPS
2824 if opts.no_custom_deps: 2844 if opts.no_custom_deps:
2825 custom_deps = None 2845 custom_deps = None
(...skipping 30 matching lines...) Expand all
2856 # bugs. If you change this, please update the perf dashboard as well. 2876 # bugs. If you change this, please update the perf dashboard as well.
2857 bisect_utils.OutputAnnotationStepStart('Results') 2877 bisect_utils.OutputAnnotationStepStart('Results')
2858 print 'Runtime Error: %s' % e 2878 print 'Runtime Error: %s' % e
2859 if opts.output_buildbot_annotations: 2879 if opts.output_buildbot_annotations:
2860 bisect_utils.OutputAnnotationStepClosed() 2880 bisect_utils.OutputAnnotationStepClosed()
2861 return 1 2881 return 1
2862 2882
2863 2883
2864 if __name__ == '__main__': 2884 if __name__ == '__main__':
2865 sys.exit(main()) 2885 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/auto_bisect/PRESUBMIT.py ('k') | tools/auto_bisect/bisect_perf_regression_test.py » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698