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

Side by Side Diff: tools/bisect-perf-regression.py

Issue 429763003: Extract Builder and subclasses to separate module. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebased and added "warning" comments. Created 6 years, 4 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 | Annotate | Revision Log
« no previous file with comments | « tools/auto_bisect/builder.py ('k') | no next file » | 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 (c) 2013 The Chromium Authors. All rights reserved. 2 # Copyright (c) 2013 The Chromium Authors. All rights reserved.
3 # Use of this source code is governed by a BSD-style license that can be 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 """Performance Test Bisect Tool 6 """Performance Test Bisect Tool
7 7
8 This script bisects a series of changelists using binary search. It starts at 8 This script bisects a series of changelists using binary search. It starts at
9 a bad revision where a performance metric has regressed, and asks for a last 9 a bad revision where a performance metric has regressed, and asks for a last
10 known-good revision. It will then binary search across this revision range by 10 known-good revision. It will then binary search across this revision range by
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after
45 import shlex 45 import shlex
46 import shutil 46 import shutil
47 import StringIO 47 import StringIO
48 import sys 48 import sys
49 import time 49 import time
50 import zipfile 50 import zipfile
51 51
52 sys.path.append(os.path.join(os.path.dirname(__file__), 'telemetry')) 52 sys.path.append(os.path.join(os.path.dirname(__file__), 'telemetry'))
53 53
54 from auto_bisect import bisect_utils 54 from auto_bisect import bisect_utils
55 from auto_bisect import builder
55 from auto_bisect import math_utils 56 from auto_bisect import math_utils
56 from auto_bisect import post_perf_builder_job as bisect_builder 57 from auto_bisect import post_perf_builder_job as bisect_builder
57 from auto_bisect import source_control as source_control_module 58 from auto_bisect import source_control as source_control_module
58 from auto_bisect import ttest 59 from auto_bisect import ttest
59 from telemetry.util import cloud_storage 60 from telemetry.util import cloud_storage
60 61
61 # Below is the map of "depot" names to information about each depot. Each depot 62 # Below is the map of "depot" names to information about each depot. Each depot
62 # is a repository, and in the process of bisecting, revision ranges in these 63 # is a repository, and in the process of bisecting, revision ranges in these
63 # repositories may also be bisected. 64 # repositories may also be bisected.
64 # 65 #
(...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after
144 'svn': 'http://skia.googlecode.com/svn/trunk/gyp', 145 'svn': 'http://skia.googlecode.com/svn/trunk/gyp',
145 'depends': None, 146 'depends': None,
146 'from': ['chromium'], 147 'from': ['chromium'],
147 'viewvc': 'https://code.google.com/p/skia/source/detail?r=', 148 'viewvc': 'https://code.google.com/p/skia/source/detail?r=',
148 'deps_var': 'None' 149 'deps_var': 'None'
149 } 150 }
150 } 151 }
151 152
152 DEPOT_NAMES = DEPOT_DEPS_NAME.keys() 153 DEPOT_NAMES = DEPOT_DEPS_NAME.keys()
153 154
154 CROS_SDK_PATH = os.path.join('..', 'cros', 'chromite', 'bin', 'cros_sdk')
155 CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome' 155 CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome'
156 CROS_TEST_KEY_PATH = os.path.join('..', 'cros', 'chromite', 'ssh_keys',
157 'testing_rsa')
158 CROS_SCRIPT_KEY_PATH = os.path.join('..', 'cros', 'src', 'scripts',
159 'mod_for_test_scripts', 'ssh_keys',
160 'testing_rsa')
161 156
162 # Possible return values from BisectPerformanceMetrics.SyncBuildAndRunRevision. 157 # Possible return values from BisectPerformanceMetrics.SyncBuildAndRunRevision.
163 BUILD_RESULT_SUCCEED = 0 158 BUILD_RESULT_SUCCEED = 0
164 BUILD_RESULT_FAIL = 1 159 BUILD_RESULT_FAIL = 1
165 BUILD_RESULT_SKIPPED = 2 160 BUILD_RESULT_SKIPPED = 2
166 161
167 # Maximum time in seconds to wait after posting build request to tryserver. 162 # Maximum time in seconds to wait after posting build request to tryserver.
168 # TODO: Change these values based on the actual time taken by buildbots on 163 # TODO: Change these values based on the actual time taken by buildbots on
169 # the tryserver. 164 # the tryserver.
170 MAX_MAC_BUILD_TIME = 14400 165 MAX_MAC_BUILD_TIME = 14400
(...skipping 266 matching lines...) Expand 10 before | Expand all | Expand 10 after
437 for name in zf.namelist(): 432 for name in zf.namelist():
438 if verbose: 433 if verbose:
439 print 'Extracting %s' % name 434 print 'Extracting %s' % name
440 zf.extract(name, output_dir) 435 zf.extract(name, output_dir)
441 if bisect_utils.IsMacHost(): 436 if bisect_utils.IsMacHost():
442 # Restore permission bits. 437 # Restore permission bits.
443 os.chmod(os.path.join(output_dir, name), 438 os.chmod(os.path.join(output_dir, name),
444 zf.getinfo(name).external_attr >> 16L) 439 zf.getinfo(name).external_attr >> 16L)
445 440
446 441
447 def SetBuildSystemDefault(build_system, use_goma, goma_dir):
448 """Sets up any environment variables needed to build with the specified build
449 system.
450
451 Args:
452 build_system: A string specifying build system. Currently only 'ninja' or
453 'make' are supported.
454 """
455 if build_system == 'ninja':
456 gyp_var = os.getenv('GYP_GENERATORS', default='')
457
458 if not gyp_var or not 'ninja' in gyp_var:
459 if gyp_var:
460 os.environ['GYP_GENERATORS'] = gyp_var + ',ninja'
461 else:
462 os.environ['GYP_GENERATORS'] = 'ninja'
463
464 if bisect_utils.IsWindowsHost():
465 os.environ['GYP_DEFINES'] = ('component=shared_library '
466 'incremental_chrome_dll=1 '
467 'disable_nacl=1 fastbuild=1 '
468 'chromium_win_pch=0')
469
470 elif build_system == 'make':
471 os.environ['GYP_GENERATORS'] = 'make'
472 else:
473 raise RuntimeError('%s build not supported.' % build_system)
474
475 if use_goma:
476 os.environ['GYP_DEFINES'] = '%s %s' % (os.getenv('GYP_DEFINES', default=''),
477 'use_goma=1')
478 if goma_dir:
479 os.environ['GYP_DEFINES'] += ' gomadir=%s' % goma_dir
480
481
482 def BuildWithMake(threads, targets, build_type='Release'):
483 cmd = ['make', 'BUILDTYPE=%s' % build_type]
484
485 if threads:
486 cmd.append('-j%d' % threads)
487
488 cmd += targets
489
490 return_code = bisect_utils.RunProcess(cmd)
491
492 return not return_code
493
494
495 def BuildWithNinja(threads, targets, build_type='Release'):
496 cmd = ['ninja', '-C', os.path.join('out', build_type)]
497
498 if threads:
499 cmd.append('-j%d' % threads)
500
501 cmd += targets
502
503 return_code = bisect_utils.RunProcess(cmd)
504
505 return not return_code
506
507
508 def BuildWithVisualStudio(targets, build_type='Release'):
509 path_to_devenv = os.path.abspath(
510 os.path.join(os.environ['VS100COMNTOOLS'], '..', 'IDE', 'devenv.com'))
511 path_to_sln = os.path.join(os.getcwd(), 'chrome', 'chrome.sln')
512 cmd = [path_to_devenv, '/build', build_type, path_to_sln]
513
514 for t in targets:
515 cmd.extend(['/Project', t])
516
517 return_code = bisect_utils.RunProcess(cmd)
518
519 return not return_code
520
521
522 def WriteStringToFile(text, file_name): 442 def WriteStringToFile(text, file_name):
523 try: 443 try:
524 with open(file_name, 'wb') as f: 444 with open(file_name, 'wb') as f:
525 f.write(text) 445 f.write(text)
526 except IOError: 446 except IOError:
527 raise RuntimeError('Error writing to file [%s]' % file_name ) 447 raise RuntimeError('Error writing to file [%s]' % file_name )
528 448
529 449
530 def ReadStringFromFile(file_name): 450 def ReadStringFromFile(file_name):
531 try: 451 try:
532 with open(file_name) as f: 452 with open(file_name) as f:
533 return f.read() 453 return f.read()
534 except IOError: 454 except IOError:
535 raise RuntimeError('Error reading file [%s]' % file_name ) 455 raise RuntimeError('Error reading file [%s]' % file_name )
536 456
537 457
538 def ChangeBackslashToSlashInPatch(diff_text): 458 def ChangeBackslashToSlashInPatch(diff_text):
539 """Formats file paths in the given text to unix-style paths.""" 459 """Formats file paths in the given text to unix-style paths."""
540 if diff_text: 460 if diff_text:
541 diff_lines = diff_text.split('\n') 461 diff_lines = diff_text.split('\n')
542 for i in range(len(diff_lines)): 462 for i in range(len(diff_lines)):
543 if (diff_lines[i].startswith('--- ') or 463 if (diff_lines[i].startswith('--- ') or
544 diff_lines[i].startswith('+++ ')): 464 diff_lines[i].startswith('+++ ')):
545 diff_lines[i] = diff_lines[i].replace('\\', '/') 465 diff_lines[i] = diff_lines[i].replace('\\', '/')
546 return '\n'.join(diff_lines) 466 return '\n'.join(diff_lines)
547 return None 467 return None
548 468
549 469
550 class Builder(object):
551 """Builder is used by the bisect script to build relevant targets and deploy.
552 """
553 def __init__(self, opts):
554 """Performs setup for building with target build system.
555
556 Args:
557 opts: Options parsed from command line.
558 """
559 if bisect_utils.IsWindowsHost():
560 if not opts.build_preference:
561 opts.build_preference = 'msvs'
562
563 if opts.build_preference == 'msvs':
564 if not os.getenv('VS100COMNTOOLS'):
565 raise RuntimeError(
566 'Path to visual studio could not be determined.')
567 else:
568 SetBuildSystemDefault(opts.build_preference, opts.use_goma,
569 opts.goma_dir)
570 else:
571 if not opts.build_preference:
572 if 'ninja' in os.getenv('GYP_GENERATORS', default=''):
573 opts.build_preference = 'ninja'
574 else:
575 opts.build_preference = 'make'
576
577 SetBuildSystemDefault(opts.build_preference, opts.use_goma, opts.goma_dir)
578
579 if not bisect_utils.SetupPlatformBuildEnvironment(opts):
580 raise RuntimeError('Failed to set platform environment.')
581
582 @staticmethod
583 def FromOpts(opts):
584 builder = None
585 if opts.target_platform == 'cros':
586 builder = CrosBuilder(opts)
587 elif opts.target_platform == 'android':
588 builder = AndroidBuilder(opts)
589 elif opts.target_platform == 'android-chrome':
590 builder = AndroidChromeBuilder(opts)
591 else:
592 builder = DesktopBuilder(opts)
593 return builder
594
595 def Build(self, depot, opts):
596 raise NotImplementedError()
597
598 def GetBuildOutputDirectory(self, opts, src_dir=None):
599 """Returns the path to the build directory, relative to the checkout root.
600
601 Assumes that the current working directory is the checkout root.
602 """
603 src_dir = src_dir or 'src'
604 if opts.build_preference == 'ninja' or bisect_utils.IsLinuxHost():
605 return os.path.join(src_dir, 'out')
606 if bisect_utils.IsMacHost():
607 return os.path.join(src_dir, 'xcodebuild')
608 if bisect_utils.IsWindowsHost():
609 return os.path.join(src_dir, 'build')
610 raise NotImplementedError('Unexpected platform %s' % sys.platform)
611
612
613 class DesktopBuilder(Builder):
614 """DesktopBuilder is used to build Chromium on linux/mac/windows."""
615 def __init__(self, opts):
616 super(DesktopBuilder, self).__init__(opts)
617
618 def Build(self, depot, opts):
619 """Builds chromium_builder_perf target using options passed into
620 the script.
621
622 Args:
623 depot: Current depot being bisected.
624 opts: The options parsed from the command line.
625
626 Returns:
627 True if build was successful.
628 """
629 targets = ['chromium_builder_perf']
630
631 threads = None
632 if opts.use_goma:
633 threads = 64
634
635 build_success = False
636 if opts.build_preference == 'make':
637 build_success = BuildWithMake(threads, targets, opts.target_build_type)
638 elif opts.build_preference == 'ninja':
639 build_success = BuildWithNinja(threads, targets, opts.target_build_type)
640 elif opts.build_preference == 'msvs':
641 assert bisect_utils.IsWindowsHost(), 'msvs is only supported on Windows.'
642 build_success = BuildWithVisualStudio(targets, opts.target_build_type)
643 else:
644 assert False, 'No build system defined.'
645 return build_success
646
647
648 class AndroidBuilder(Builder):
649 """AndroidBuilder is used to build on android."""
650 def __init__(self, opts):
651 super(AndroidBuilder, self).__init__(opts)
652
653 def _GetTargets(self):
654 return ['chrome_shell_apk', 'cc_perftests_apk', 'android_tools']
655
656 def Build(self, depot, opts):
657 """Builds the android content shell and other necessary tools using options
658 passed into the script.
659
660 Args:
661 depot: Current depot being bisected.
662 opts: The options parsed from the command line.
663
664 Returns:
665 True if build was successful.
666 """
667 threads = None
668 if opts.use_goma:
669 threads = 64
670
671 build_success = False
672 if opts.build_preference == 'ninja':
673 build_success = BuildWithNinja(
674 threads, self._GetTargets(), opts.target_build_type)
675 else:
676 assert False, 'No build system defined.'
677
678 return build_success
679
680
681 class AndroidChromeBuilder(AndroidBuilder):
682 """AndroidBuilder is used to build on android's chrome."""
683 def __init__(self, opts):
684 super(AndroidChromeBuilder, self).__init__(opts)
685
686 def _GetTargets(self):
687 return AndroidBuilder._GetTargets(self) + ['chrome_apk']
688
689
690 class CrosBuilder(Builder):
691 """CrosBuilder is used to build and image ChromeOS/Chromium when cros is the
692 target platform."""
693 def __init__(self, opts):
694 super(CrosBuilder, self).__init__(opts)
695
696 def ImageToTarget(self, opts):
697 """Installs latest image to target specified by opts.cros_remote_ip.
698
699 Args:
700 opts: Program options containing cros_board and cros_remote_ip.
701
702 Returns:
703 True if successful.
704 """
705 try:
706 # Keys will most likely be set to 0640 after wiping the chroot.
707 os.chmod(CROS_SCRIPT_KEY_PATH, 0600)
708 os.chmod(CROS_TEST_KEY_PATH, 0600)
709 cmd = [CROS_SDK_PATH, '--', './bin/cros_image_to_target.py',
710 '--remote=%s' % opts.cros_remote_ip,
711 '--board=%s' % opts.cros_board, '--test', '--verbose']
712
713 return_code = bisect_utils.RunProcess(cmd)
714 return not return_code
715 except OSError:
716 return False
717
718 def BuildPackages(self, opts, depot):
719 """Builds packages for cros.
720
721 Args:
722 opts: Program options containing cros_board.
723 depot: The depot being bisected.
724
725 Returns:
726 True if successful.
727 """
728 cmd = [CROS_SDK_PATH]
729
730 if depot != 'cros':
731 path_to_chrome = os.path.join(os.getcwd(), '..')
732 cmd += ['--chrome_root=%s' % path_to_chrome]
733
734 cmd += ['--']
735
736 if depot != 'cros':
737 cmd += ['CHROME_ORIGIN=LOCAL_SOURCE']
738
739 cmd += ['BUILDTYPE=%s' % opts.target_build_type, './build_packages',
740 '--board=%s' % opts.cros_board]
741 return_code = bisect_utils.RunProcess(cmd)
742
743 return not return_code
744
745 def BuildImage(self, opts, depot):
746 """Builds test image for cros.
747
748 Args:
749 opts: Program options containing cros_board.
750 depot: The depot being bisected.
751
752 Returns:
753 True if successful.
754 """
755 cmd = [CROS_SDK_PATH]
756
757 if depot != 'cros':
758 path_to_chrome = os.path.join(os.getcwd(), '..')
759 cmd += ['--chrome_root=%s' % path_to_chrome]
760
761 cmd += ['--']
762
763 if depot != 'cros':
764 cmd += ['CHROME_ORIGIN=LOCAL_SOURCE']
765
766 cmd += ['BUILDTYPE=%s' % opts.target_build_type, '--', './build_image',
767 '--board=%s' % opts.cros_board, 'test']
768
769 return_code = bisect_utils.RunProcess(cmd)
770
771 return not return_code
772
773 def Build(self, depot, opts):
774 """Builds targets using options passed into the script.
775
776 Args:
777 depot: Current depot being bisected.
778 opts: The options parsed from the command line.
779
780 Returns:
781 True if build was successful.
782 """
783 if self.BuildPackages(opts, depot):
784 if self.BuildImage(opts, depot):
785 return self.ImageToTarget(opts)
786 return False
787
788
789 def _ParseRevisionsFromDEPSFileManually(deps_file_contents): 470 def _ParseRevisionsFromDEPSFileManually(deps_file_contents):
790 """Parses the vars section of the DEPS file with regex. 471 """Parses the vars section of the DEPS file with regex.
791 472
792 Args: 473 Args:
793 deps_file_contents: The DEPS file contents as a string. 474 deps_file_contents: The DEPS file contents as a string.
794 475
795 Returns: 476 Returns:
796 A dict in the format {depot:revision} if successful, otherwise None. 477 A dict in the format {depot:revision} if successful, otherwise None.
797 """ 478 """
798 # We'll parse the "vars" section of the DEPS file. 479 # We'll parse the "vars" section of the DEPS file.
(...skipping 365 matching lines...) Expand 10 before | Expand all | Expand 10 after
1164 step_count += 1 845 step_count += 1
1165 if step_count: 846 if step_count:
1166 step_perf_time_avg = step_perf_time_avg / step_count 847 step_perf_time_avg = step_perf_time_avg / step_count
1167 step_build_time_avg = step_build_time_avg / step_count 848 step_build_time_avg = step_build_time_avg / step_count
1168 print 849 print
1169 print 'Average build time : %s' % datetime.timedelta( 850 print 'Average build time : %s' % datetime.timedelta(
1170 seconds=int(step_build_time_avg)) 851 seconds=int(step_build_time_avg))
1171 print 'Average test time : %s' % datetime.timedelta( 852 print 'Average test time : %s' % datetime.timedelta(
1172 seconds=int(step_perf_time_avg)) 853 seconds=int(step_perf_time_avg))
1173 854
855
1174 def _FindOtherRegressions(revision_data_sorted, bad_greater_than_good): 856 def _FindOtherRegressions(revision_data_sorted, bad_greater_than_good):
1175 """Compiles a list of other possible regressions from the revision data. 857 """Compiles a list of other possible regressions from the revision data.
1176 858
1177 Args: 859 Args:
1178 revision_data_sorted: Sorted list of (revision, revision data dict) pairs. 860 revision_data_sorted: Sorted list of (revision, revision data dict) pairs.
1179 bad_greater_than_good: Whether the result value at the "bad" revision is 861 bad_greater_than_good: Whether the result value at the "bad" revision is
1180 numerically greater than the result value at the "good" revision. 862 numerically greater than the result value at the "good" revision.
1181 863
1182 Returns: 864 Returns:
1183 A list of [current_rev, previous_rev, confidence] for other places where 865 A list of [current_rev, previous_rev, confidence] for other places where
(...skipping 19 matching lines...) Expand all
1203 is_same_direction = (prev_less_than_current if 885 is_same_direction = (prev_less_than_current if
1204 bad_greater_than_good else not prev_less_than_current) 886 bad_greater_than_good else not prev_less_than_current)
1205 887
1206 # Only report potential regressions with high confidence. 888 # Only report potential regressions with high confidence.
1207 if is_same_direction and confidence > 50: 889 if is_same_direction and confidence > 50:
1208 other_regressions.append([current_id, previous_id, confidence]) 890 other_regressions.append([current_id, previous_id, confidence])
1209 previous_values.append(current_values) 891 previous_values.append(current_values)
1210 previous_id = current_id 892 previous_id = current_id
1211 return other_regressions 893 return other_regressions
1212 894
895
1213 class BisectPerformanceMetrics(object): 896 class BisectPerformanceMetrics(object):
1214 """This class contains functionality to perform a bisection of a range of 897 """This class contains functionality to perform a bisection of a range of
1215 revisions to narrow down where performance regressions may have occurred. 898 revisions to narrow down where performance regressions may have occurred.
1216 899
1217 The main entry-point is the Run method. 900 The main entry-point is the Run method.
1218 """ 901 """
1219 902
1220 def __init__(self, source_control, opts): 903 def __init__(self, source_control, opts):
1221 super(BisectPerformanceMetrics, self).__init__() 904 super(BisectPerformanceMetrics, self).__init__()
1222 905
1223 self.opts = opts 906 self.opts = opts
1224 self.source_control = source_control 907 self.source_control = source_control
1225 self.src_cwd = os.getcwd() 908 self.src_cwd = os.getcwd()
1226 self.cros_cwd = os.path.join(os.getcwd(), '..', 'cros') 909 self.cros_cwd = os.path.join(os.getcwd(), '..', 'cros')
1227 self.depot_cwd = {} 910 self.depot_cwd = {}
1228 self.cleanup_commands = [] 911 self.cleanup_commands = []
1229 self.warnings = [] 912 self.warnings = []
1230 self.builder = Builder.FromOpts(opts) 913 self.builder = builder.Builder.FromOpts(opts)
1231 914
1232 # This always starts true since the script grabs latest first. 915 # This always starts true since the script grabs latest first.
1233 self.was_blink = True 916 self.was_blink = True
1234 917
1235 for d in DEPOT_NAMES: 918 for d in DEPOT_NAMES:
1236 # The working directory of each depot is just the path to the depot, but 919 # The working directory of each depot is just the path to the depot, but
1237 # since we're already in 'src', we can skip that part. 920 # since we're already in 'src', we can skip that part.
1238 921
1239 self.depot_cwd[d] = os.path.join( 922 self.depot_cwd[d] = os.path.join(
1240 self.src_cwd, DEPOT_DEPS_NAME[d]['src'][4:]) 923 self.src_cwd, DEPOT_DEPS_NAME[d]['src'][4:])
(...skipping 192 matching lines...) Expand 10 before | Expand all | Expand 10 after
1433 A dict in the format {depot:revision} if successful, otherwise None. 1116 A dict in the format {depot:revision} if successful, otherwise None.
1434 """ 1117 """
1435 cwd = os.getcwd() 1118 cwd = os.getcwd()
1436 self.ChangeToDepotWorkingDirectory(depot) 1119 self.ChangeToDepotWorkingDirectory(depot)
1437 1120
1438 results = {} 1121 results = {}
1439 1122
1440 if depot == 'chromium' or depot == 'android-chrome': 1123 if depot == 'chromium' or depot == 'android-chrome':
1441 results = self._ParseRevisionsFromDEPSFile(depot) 1124 results = self._ParseRevisionsFromDEPSFile(depot)
1442 os.chdir(cwd) 1125 os.chdir(cwd)
1443 elif depot == 'cros': 1126
1444 cmd = [CROS_SDK_PATH, '--', 'portageq-%s' % self.opts.cros_board, 1127 if depot == 'cros':
1445 'best_visible', '/build/%s' % self.opts.cros_board, 'ebuild', 1128 cmd = [
1446 CROS_CHROMEOS_PATTERN] 1129 bisect_utils.CROS_SDK_PATH,
1130 '--',
1131 'portageq-%s' % self.opts.cros_board,
1132 'best_visible',
1133 '/build/%s' % self.opts.cros_board,
1134 'ebuild',
1135 CROS_CHROMEOS_PATTERN
1136 ]
1447 output, return_code = bisect_utils.RunProcessAndRetrieveOutput(cmd) 1137 output, return_code = bisect_utils.RunProcessAndRetrieveOutput(cmd)
1448 1138
1449 assert not return_code, ('An error occurred while running ' 1139 assert not return_code, ('An error occurred while running '
1450 '"%s"' % ' '.join(cmd)) 1140 '"%s"' % ' '.join(cmd))
1451 1141
1452 if len(output) > CROS_CHROMEOS_PATTERN: 1142 if len(output) > CROS_CHROMEOS_PATTERN:
1453 output = output[len(CROS_CHROMEOS_PATTERN):] 1143 output = output[len(CROS_CHROMEOS_PATTERN):]
1454 1144
1455 if len(output) > 1: 1145 if len(output) > 1:
1456 output = output.split('_')[0] 1146 output = output.split('_')[0]
(...skipping 11 matching lines...) Expand all
1468 1158
1469 cwd = os.getcwd() 1159 cwd = os.getcwd()
1470 self.ChangeToDepotWorkingDirectory('chromium') 1160 self.ChangeToDepotWorkingDirectory('chromium')
1471 cmd = ['log', '-1', '--format=%H', 1161 cmd = ['log', '-1', '--format=%H',
1472 '--author=chrome-release@google.com', 1162 '--author=chrome-release@google.com',
1473 '--grep=to %s' % version, 'origin/master'] 1163 '--grep=to %s' % version, 'origin/master']
1474 return_code = bisect_utils.CheckRunGit(cmd) 1164 return_code = bisect_utils.CheckRunGit(cmd)
1475 os.chdir(cwd) 1165 os.chdir(cwd)
1476 1166
1477 results['chromium'] = output.strip() 1167 results['chromium'] = output.strip()
1478 elif depot == 'v8': 1168
1169 if depot == 'v8':
1479 # We can't try to map the trunk revision to bleeding edge yet, because 1170 # We can't try to map the trunk revision to bleeding edge yet, because
1480 # we don't know which direction to try to search in. Have to wait until 1171 # we don't know which direction to try to search in. Have to wait until
1481 # the bisect has narrowed the results down to 2 v8 rolls. 1172 # the bisect has narrowed the results down to 2 v8 rolls.
1482 results['v8_bleeding_edge'] = None 1173 results['v8_bleeding_edge'] = None
1483 1174
1484 return results 1175 return results
1485 1176
1486 def BackupOrRestoreOutputdirectory(self, restore=False, build_type='Release'): 1177 def BackupOrRestoreOutputdirectory(self, restore=False, build_type='Release'):
1487 """Backs up or restores build output directory based on restore argument. 1178 """Backs up or restores build output directory based on restore argument.
1488 1179
1489 Args: 1180 Args:
1490 restore: Indicates whether to restore or backup. Default is False(Backup) 1181 restore: Indicates whether to restore or backup. Default is False(Backup)
1491 build_type: Target build type ('Release', 'Debug', 'Release_x64' etc.) 1182 build_type: Target build type ('Release', 'Debug', 'Release_x64' etc.)
1492 1183
1493 Returns: 1184 Returns:
1494 Path to backup or restored location as string. otherwise None if it fails. 1185 Path to backup or restored location as string. otherwise None if it fails.
1495 """ 1186 """
1496 build_dir = os.path.abspath( 1187 build_dir = os.path.abspath(
1497 self.builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) 1188 builder.GetBuildOutputDirectory(self.opts, self.src_cwd))
1498 source_dir = os.path.join(build_dir, build_type) 1189 source_dir = os.path.join(build_dir, build_type)
1499 destination_dir = os.path.join(build_dir, '%s.bak' % build_type) 1190 destination_dir = os.path.join(build_dir, '%s.bak' % build_type)
1500 if restore: 1191 if restore:
1501 source_dir, destination_dir = destination_dir, source_dir 1192 source_dir, destination_dir = destination_dir, source_dir
1502 if os.path.exists(source_dir): 1193 if os.path.exists(source_dir):
1503 RmTreeAndMkDir(destination_dir, skip_makedir=True) 1194 RmTreeAndMkDir(destination_dir, skip_makedir=True)
1504 shutil.move(source_dir, destination_dir) 1195 shutil.move(source_dir, destination_dir)
1505 return destination_dir 1196 return destination_dir
1506 return None 1197 return None
1507 1198
(...skipping 43 matching lines...) Expand 10 before | Expand all | Expand 10 after
1551 if patch: 1242 if patch:
1552 # Get the SHA of the DEPS changes patch. 1243 # Get the SHA of the DEPS changes patch.
1553 patch_sha = GetSHA1HexDigest(patch) 1244 patch_sha = GetSHA1HexDigest(patch)
1554 1245
1555 # Update the DEPS changes patch with a patch to create a new file named 1246 # Update the DEPS changes patch with a patch to create a new file named
1556 # 'DEPS.sha' and add patch_sha evaluated above to it. 1247 # 'DEPS.sha' and add patch_sha evaluated above to it.
1557 patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha}) 1248 patch = '%s\n%s' % (patch, DEPS_SHA_PATCH % {'deps_sha': patch_sha})
1558 1249
1559 # Get Build output directory 1250 # Get Build output directory
1560 abs_build_dir = os.path.abspath( 1251 abs_build_dir = os.path.abspath(
1561 self.builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) 1252 builder.GetBuildOutputDirectory(self.opts, self.src_cwd))
1562 1253
1563 fetch_build_func = lambda: self.GetBuildArchiveForRevision( 1254 fetch_build_func = lambda: self.GetBuildArchiveForRevision(
1564 revision, self.opts.gs_bucket, self.opts.target_arch, 1255 revision, self.opts.gs_bucket, self.opts.target_arch,
1565 patch_sha, abs_build_dir) 1256 patch_sha, abs_build_dir)
1566 1257
1567 # Downloaded archive file path, downloads build archive for given revision. 1258 # Downloaded archive file path, downloads build archive for given revision.
1568 downloaded_file = fetch_build_func() 1259 downloaded_file = fetch_build_func()
1569 1260
1570 # When build archive doesn't exists, post a build request to tryserver 1261 # When build archive doesn't exists, post a build request to tryserver
1571 # and wait for the build to be produced. 1262 # and wait for the build to be produced.
(...skipping 337 matching lines...) Expand 10 before | Expand all | Expand 10 after
1909 1600
1910 if not _GenerateProfileIfNecessary(args): 1601 if not _GenerateProfileIfNecessary(args):
1911 err_text = 'Failed to generate profile for performance test.' 1602 err_text = 'Failed to generate profile for performance test.'
1912 return (err_text, failure_code) 1603 return (err_text, failure_code)
1913 1604
1914 # If running a Telemetry test for Chrome OS, insert the remote IP and 1605 # If running a Telemetry test for Chrome OS, insert the remote IP and
1915 # identity parameters. 1606 # identity parameters.
1916 is_telemetry = bisect_utils.IsTelemetryCommand(command_to_run) 1607 is_telemetry = bisect_utils.IsTelemetryCommand(command_to_run)
1917 if self.opts.target_platform == 'cros' and is_telemetry: 1608 if self.opts.target_platform == 'cros' and is_telemetry:
1918 args.append('--remote=%s' % self.opts.cros_remote_ip) 1609 args.append('--remote=%s' % self.opts.cros_remote_ip)
1919 args.append('--identity=%s' % CROS_TEST_KEY_PATH) 1610 args.append('--identity=%s' % bisect_utils.CROS_TEST_KEY_PATH)
1920 1611
1921 start_time = time.time() 1612 start_time = time.time()
1922 1613
1923 metric_values = [] 1614 metric_values = []
1924 output_of_all_runs = '' 1615 output_of_all_runs = ''
1925 for i in xrange(self.opts.repeat_test_count): 1616 for i in xrange(self.opts.repeat_test_count):
1926 # Can ignore the return code since if the tests fail, it won't return 0. 1617 # Can ignore the return code since if the tests fail, it won't return 0.
1927 current_args = copy.copy(args) 1618 current_args = copy.copy(args)
1928 if is_telemetry: 1619 if is_telemetry:
1929 if i == 0 and reset_on_first_run: 1620 if i == 0 and reset_on_first_run:
(...skipping 173 matching lines...) Expand 10 before | Expand all | Expand 10 after
2103 return True 1794 return True
2104 1795
2105 def PerformCrosChrootCleanup(self): 1796 def PerformCrosChrootCleanup(self):
2106 """Deletes the chroot. 1797 """Deletes the chroot.
2107 1798
2108 Returns: 1799 Returns:
2109 True if successful. 1800 True if successful.
2110 """ 1801 """
2111 cwd = os.getcwd() 1802 cwd = os.getcwd()
2112 self.ChangeToDepotWorkingDirectory('cros') 1803 self.ChangeToDepotWorkingDirectory('cros')
2113 cmd = [CROS_SDK_PATH, '--delete'] 1804 cmd = [bisect_utils.CROS_SDK_PATH, '--delete']
2114 return_code = bisect_utils.RunProcess(cmd) 1805 return_code = bisect_utils.RunProcess(cmd)
2115 os.chdir(cwd) 1806 os.chdir(cwd)
2116 return not return_code 1807 return not return_code
2117 1808
2118 def CreateCrosChroot(self): 1809 def CreateCrosChroot(self):
2119 """Creates a new chroot. 1810 """Creates a new chroot.
2120 1811
2121 Returns: 1812 Returns:
2122 True if successful. 1813 True if successful.
2123 """ 1814 """
2124 cwd = os.getcwd() 1815 cwd = os.getcwd()
2125 self.ChangeToDepotWorkingDirectory('cros') 1816 self.ChangeToDepotWorkingDirectory('cros')
2126 cmd = [CROS_SDK_PATH, '--create'] 1817 cmd = [bisect_utils.CROS_SDK_PATH, '--create']
2127 return_code = bisect_utils.RunProcess(cmd) 1818 return_code = bisect_utils.RunProcess(cmd)
2128 os.chdir(cwd) 1819 os.chdir(cwd)
2129 return not return_code 1820 return not return_code
2130 1821
2131 def PerformPreSyncCleanup(self, revision, depot): 1822 def PerformPreSyncCleanup(self, revision, depot):
2132 """Performs any necessary cleanup before syncing. 1823 """Performs any necessary cleanup before syncing.
2133 1824
2134 Returns: 1825 Returns:
2135 True if successful. 1826 True if successful.
2136 """ 1827 """
(...skipping 1528 matching lines...) Expand 10 before | Expand all | Expand 10 after
3665 # bugs. If you change this, please update the perf dashboard as well. 3356 # bugs. If you change this, please update the perf dashboard as well.
3666 bisect_utils.OutputAnnotationStepStart('Results') 3357 bisect_utils.OutputAnnotationStepStart('Results')
3667 print 'Error: %s' % e.message 3358 print 'Error: %s' % e.message
3668 if opts.output_buildbot_annotations: 3359 if opts.output_buildbot_annotations:
3669 bisect_utils.OutputAnnotationStepClosed() 3360 bisect_utils.OutputAnnotationStepClosed()
3670 return 1 3361 return 1
3671 3362
3672 3363
3673 if __name__ == '__main__': 3364 if __name__ == '__main__':
3674 sys.exit(main()) 3365 sys.exit(main())
OLDNEW
« no previous file with comments | « tools/auto_bisect/builder.py ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698