Index: tools/bisect-perf-regression.py |
diff --git a/tools/bisect-perf-regression.py b/tools/bisect-perf-regression.py |
index 9e1c71bbed83e049dd0b7d6b4bc0198eb0bf1848..a8790e1db5c95e03af16ce9d4173a94e3ca83f85 100755 |
--- a/tools/bisect-perf-regression.py |
+++ b/tools/bisect-perf-regression.py |
@@ -52,6 +52,7 @@ import zipfile |
sys.path.append(os.path.join(os.path.dirname(__file__), 'telemetry')) |
from auto_bisect import bisect_utils |
+from auto_bisect import builder |
from auto_bisect import math_utils |
from auto_bisect import post_perf_builder_job as bisect_builder |
from auto_bisect import source_control as source_control_module |
@@ -151,13 +152,7 @@ DEPOT_DEPS_NAME = { |
DEPOT_NAMES = DEPOT_DEPS_NAME.keys() |
-CROS_SDK_PATH = os.path.join('..', 'cros', 'chromite', 'bin', 'cros_sdk') |
CROS_CHROMEOS_PATTERN = 'chromeos-base/chromeos-chrome' |
-CROS_TEST_KEY_PATH = os.path.join('..', 'cros', 'chromite', 'ssh_keys', |
- 'testing_rsa') |
-CROS_SCRIPT_KEY_PATH = os.path.join('..', 'cros', 'src', 'scripts', |
- 'mod_for_test_scripts', 'ssh_keys', |
- 'testing_rsa') |
# Possible return values from BisectPerformanceMetrics.SyncBuildAndRunRevision. |
BUILD_RESULT_SUCCEED = 0 |
@@ -444,81 +439,6 @@ def ExtractZip(filename, output_dir, verbose=True): |
zf.getinfo(name).external_attr >> 16L) |
-def SetBuildSystemDefault(build_system, use_goma, goma_dir): |
- """Sets up any environment variables needed to build with the specified build |
- system. |
- |
- Args: |
- build_system: A string specifying build system. Currently only 'ninja' or |
- 'make' are supported. |
- """ |
- if build_system == 'ninja': |
- gyp_var = os.getenv('GYP_GENERATORS', default='') |
- |
- if not gyp_var or not 'ninja' in gyp_var: |
- if gyp_var: |
- os.environ['GYP_GENERATORS'] = gyp_var + ',ninja' |
- else: |
- os.environ['GYP_GENERATORS'] = 'ninja' |
- |
- if bisect_utils.IsWindowsHost(): |
- os.environ['GYP_DEFINES'] = ('component=shared_library ' |
- 'incremental_chrome_dll=1 ' |
- 'disable_nacl=1 fastbuild=1 ' |
- 'chromium_win_pch=0') |
- |
- elif build_system == 'make': |
- os.environ['GYP_GENERATORS'] = 'make' |
- else: |
- raise RuntimeError('%s build not supported.' % build_system) |
- |
- if use_goma: |
- os.environ['GYP_DEFINES'] = '%s %s' % (os.getenv('GYP_DEFINES', default=''), |
- 'use_goma=1') |
- if goma_dir: |
- os.environ['GYP_DEFINES'] += ' gomadir=%s' % goma_dir |
- |
- |
-def BuildWithMake(threads, targets, build_type='Release'): |
- cmd = ['make', 'BUILDTYPE=%s' % build_type] |
- |
- if threads: |
- cmd.append('-j%d' % threads) |
- |
- cmd += targets |
- |
- return_code = bisect_utils.RunProcess(cmd) |
- |
- return not return_code |
- |
- |
-def BuildWithNinja(threads, targets, build_type='Release'): |
- cmd = ['ninja', '-C', os.path.join('out', build_type)] |
- |
- if threads: |
- cmd.append('-j%d' % threads) |
- |
- cmd += targets |
- |
- return_code = bisect_utils.RunProcess(cmd) |
- |
- return not return_code |
- |
- |
-def BuildWithVisualStudio(targets, build_type='Release'): |
- path_to_devenv = os.path.abspath( |
- os.path.join(os.environ['VS100COMNTOOLS'], '..', 'IDE', 'devenv.com')) |
- path_to_sln = os.path.join(os.getcwd(), 'chrome', 'chrome.sln') |
- cmd = [path_to_devenv, '/build', build_type, path_to_sln] |
- |
- for t in targets: |
- cmd.extend(['/Project', t]) |
- |
- return_code = bisect_utils.RunProcess(cmd) |
- |
- return not return_code |
- |
- |
def WriteStringToFile(text, file_name): |
try: |
with open(file_name, 'wb') as f: |
@@ -547,245 +467,6 @@ def ChangeBackslashToSlashInPatch(diff_text): |
return None |
-class Builder(object): |
- """Builder is used by the bisect script to build relevant targets and deploy. |
- """ |
- def __init__(self, opts): |
- """Performs setup for building with target build system. |
- |
- Args: |
- opts: Options parsed from command line. |
- """ |
- if bisect_utils.IsWindowsHost(): |
- if not opts.build_preference: |
- opts.build_preference = 'msvs' |
- |
- if opts.build_preference == 'msvs': |
- if not os.getenv('VS100COMNTOOLS'): |
- raise RuntimeError( |
- 'Path to visual studio could not be determined.') |
- else: |
- SetBuildSystemDefault(opts.build_preference, opts.use_goma, |
- opts.goma_dir) |
- else: |
- if not opts.build_preference: |
- if 'ninja' in os.getenv('GYP_GENERATORS', default=''): |
- opts.build_preference = 'ninja' |
- else: |
- opts.build_preference = 'make' |
- |
- SetBuildSystemDefault(opts.build_preference, opts.use_goma, opts.goma_dir) |
- |
- if not bisect_utils.SetupPlatformBuildEnvironment(opts): |
- raise RuntimeError('Failed to set platform environment.') |
- |
- @staticmethod |
- def FromOpts(opts): |
- builder = None |
- if opts.target_platform == 'cros': |
- builder = CrosBuilder(opts) |
- elif opts.target_platform == 'android': |
- builder = AndroidBuilder(opts) |
- elif opts.target_platform == 'android-chrome': |
- builder = AndroidChromeBuilder(opts) |
- else: |
- builder = DesktopBuilder(opts) |
- return builder |
- |
- def Build(self, depot, opts): |
- raise NotImplementedError() |
- |
- def GetBuildOutputDirectory(self, opts, src_dir=None): |
- """Returns the path to the build directory, relative to the checkout root. |
- |
- Assumes that the current working directory is the checkout root. |
- """ |
- src_dir = src_dir or 'src' |
- if opts.build_preference == 'ninja' or bisect_utils.IsLinuxHost(): |
- return os.path.join(src_dir, 'out') |
- if bisect_utils.IsMacHost(): |
- return os.path.join(src_dir, 'xcodebuild') |
- if bisect_utils.IsWindowsHost(): |
- return os.path.join(src_dir, 'build') |
- raise NotImplementedError('Unexpected platform %s' % sys.platform) |
- |
- |
-class DesktopBuilder(Builder): |
- """DesktopBuilder is used to build Chromium on linux/mac/windows.""" |
- def __init__(self, opts): |
- super(DesktopBuilder, self).__init__(opts) |
- |
- def Build(self, depot, opts): |
- """Builds chromium_builder_perf target using options passed into |
- the script. |
- |
- Args: |
- depot: Current depot being bisected. |
- opts: The options parsed from the command line. |
- |
- Returns: |
- True if build was successful. |
- """ |
- targets = ['chromium_builder_perf'] |
- |
- threads = None |
- if opts.use_goma: |
- threads = 64 |
- |
- build_success = False |
- if opts.build_preference == 'make': |
- build_success = BuildWithMake(threads, targets, opts.target_build_type) |
- elif opts.build_preference == 'ninja': |
- build_success = BuildWithNinja(threads, targets, opts.target_build_type) |
- elif opts.build_preference == 'msvs': |
- assert bisect_utils.IsWindowsHost(), 'msvs is only supported on Windows.' |
- build_success = BuildWithVisualStudio(targets, opts.target_build_type) |
- else: |
- assert False, 'No build system defined.' |
- return build_success |
- |
- |
-class AndroidBuilder(Builder): |
- """AndroidBuilder is used to build on android.""" |
- def __init__(self, opts): |
- super(AndroidBuilder, self).__init__(opts) |
- |
- def _GetTargets(self): |
- return ['chrome_shell_apk', 'cc_perftests_apk', 'android_tools'] |
- |
- def Build(self, depot, opts): |
- """Builds the android content shell and other necessary tools using options |
- passed into the script. |
- |
- Args: |
- depot: Current depot being bisected. |
- opts: The options parsed from the command line. |
- |
- Returns: |
- True if build was successful. |
- """ |
- threads = None |
- if opts.use_goma: |
- threads = 64 |
- |
- build_success = False |
- if opts.build_preference == 'ninja': |
- build_success = BuildWithNinja( |
- threads, self._GetTargets(), opts.target_build_type) |
- else: |
- assert False, 'No build system defined.' |
- |
- return build_success |
- |
- |
-class AndroidChromeBuilder(AndroidBuilder): |
- """AndroidBuilder is used to build on android's chrome.""" |
- def __init__(self, opts): |
- super(AndroidChromeBuilder, self).__init__(opts) |
- |
- def _GetTargets(self): |
- return AndroidBuilder._GetTargets(self) + ['chrome_apk'] |
- |
- |
-class CrosBuilder(Builder): |
- """CrosBuilder is used to build and image ChromeOS/Chromium when cros is the |
- target platform.""" |
- def __init__(self, opts): |
- super(CrosBuilder, self).__init__(opts) |
- |
- def ImageToTarget(self, opts): |
- """Installs latest image to target specified by opts.cros_remote_ip. |
- |
- Args: |
- opts: Program options containing cros_board and cros_remote_ip. |
- |
- Returns: |
- True if successful. |
- """ |
- try: |
- # Keys will most likely be set to 0640 after wiping the chroot. |
- os.chmod(CROS_SCRIPT_KEY_PATH, 0600) |
- os.chmod(CROS_TEST_KEY_PATH, 0600) |
- cmd = [CROS_SDK_PATH, '--', './bin/cros_image_to_target.py', |
- '--remote=%s' % opts.cros_remote_ip, |
- '--board=%s' % opts.cros_board, '--test', '--verbose'] |
- |
- return_code = bisect_utils.RunProcess(cmd) |
- return not return_code |
- except OSError: |
- return False |
- |
- def BuildPackages(self, opts, depot): |
- """Builds packages for cros. |
- |
- Args: |
- opts: Program options containing cros_board. |
- depot: The depot being bisected. |
- |
- Returns: |
- True if successful. |
- """ |
- cmd = [CROS_SDK_PATH] |
- |
- if depot != 'cros': |
- path_to_chrome = os.path.join(os.getcwd(), '..') |
- cmd += ['--chrome_root=%s' % path_to_chrome] |
- |
- cmd += ['--'] |
- |
- if depot != 'cros': |
- cmd += ['CHROME_ORIGIN=LOCAL_SOURCE'] |
- |
- cmd += ['BUILDTYPE=%s' % opts.target_build_type, './build_packages', |
- '--board=%s' % opts.cros_board] |
- return_code = bisect_utils.RunProcess(cmd) |
- |
- return not return_code |
- |
- def BuildImage(self, opts, depot): |
- """Builds test image for cros. |
- |
- Args: |
- opts: Program options containing cros_board. |
- depot: The depot being bisected. |
- |
- Returns: |
- True if successful. |
- """ |
- cmd = [CROS_SDK_PATH] |
- |
- if depot != 'cros': |
- path_to_chrome = os.path.join(os.getcwd(), '..') |
- cmd += ['--chrome_root=%s' % path_to_chrome] |
- |
- cmd += ['--'] |
- |
- if depot != 'cros': |
- cmd += ['CHROME_ORIGIN=LOCAL_SOURCE'] |
- |
- cmd += ['BUILDTYPE=%s' % opts.target_build_type, '--', './build_image', |
- '--board=%s' % opts.cros_board, 'test'] |
- |
- return_code = bisect_utils.RunProcess(cmd) |
- |
- return not return_code |
- |
- def Build(self, depot, opts): |
- """Builds targets using options passed into the script. |
- |
- Args: |
- depot: Current depot being bisected. |
- opts: The options parsed from the command line. |
- |
- Returns: |
- True if build was successful. |
- """ |
- if self.BuildPackages(opts, depot): |
- if self.BuildImage(opts, depot): |
- return self.ImageToTarget(opts) |
- return False |
- |
- |
def _ParseRevisionsFromDEPSFileManually(deps_file_contents): |
"""Parses the vars section of the DEPS file with regex. |
@@ -1171,6 +852,7 @@ def _PrintStepTime(revision_data_sorted): |
print 'Average test time : %s' % datetime.timedelta( |
seconds=int(step_perf_time_avg)) |
+ |
def _FindOtherRegressions(revision_data_sorted, bad_greater_than_good): |
"""Compiles a list of other possible regressions from the revision data. |
@@ -1210,6 +892,7 @@ def _FindOtherRegressions(revision_data_sorted, bad_greater_than_good): |
previous_id = current_id |
return other_regressions |
+ |
class BisectPerformanceMetrics(object): |
"""This class contains functionality to perform a bisection of a range of |
revisions to narrow down where performance regressions may have occurred. |
@@ -1227,7 +910,7 @@ class BisectPerformanceMetrics(object): |
self.depot_cwd = {} |
self.cleanup_commands = [] |
self.warnings = [] |
- self.builder = Builder.FromOpts(opts) |
+ self.builder = builder.Builder.FromOpts(opts) |
# This always starts true since the script grabs latest first. |
self.was_blink = True |
@@ -1440,10 +1123,17 @@ class BisectPerformanceMetrics(object): |
if depot == 'chromium' or depot == 'android-chrome': |
results = self._ParseRevisionsFromDEPSFile(depot) |
os.chdir(cwd) |
- elif depot == 'cros': |
- cmd = [CROS_SDK_PATH, '--', 'portageq-%s' % self.opts.cros_board, |
- 'best_visible', '/build/%s' % self.opts.cros_board, 'ebuild', |
- CROS_CHROMEOS_PATTERN] |
+ |
+ if depot == 'cros': |
+ cmd = [ |
+ bisect_utils.CROS_SDK_PATH, |
+ '--', |
+ 'portageq-%s' % self.opts.cros_board, |
+ 'best_visible', |
+ '/build/%s' % self.opts.cros_board, |
+ 'ebuild', |
+ CROS_CHROMEOS_PATTERN |
+ ] |
output, return_code = bisect_utils.RunProcessAndRetrieveOutput(cmd) |
assert not return_code, ('An error occurred while running ' |
@@ -1475,7 +1165,8 @@ class BisectPerformanceMetrics(object): |
os.chdir(cwd) |
results['chromium'] = output.strip() |
- elif depot == 'v8': |
+ |
+ if depot == 'v8': |
# We can't try to map the trunk revision to bleeding edge yet, because |
# we don't know which direction to try to search in. Have to wait until |
# the bisect has narrowed the results down to 2 v8 rolls. |
@@ -1494,7 +1185,7 @@ class BisectPerformanceMetrics(object): |
Path to backup or restored location as string. otherwise None if it fails. |
""" |
build_dir = os.path.abspath( |
- self.builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) |
+ builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) |
source_dir = os.path.join(build_dir, build_type) |
destination_dir = os.path.join(build_dir, '%s.bak' % build_type) |
if restore: |
@@ -1558,7 +1249,7 @@ class BisectPerformanceMetrics(object): |
# Get Build output directory |
abs_build_dir = os.path.abspath( |
- self.builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) |
+ builder.GetBuildOutputDirectory(self.opts, self.src_cwd)) |
fetch_build_func = lambda: self.GetBuildArchiveForRevision( |
revision, self.opts.gs_bucket, self.opts.target_arch, |
@@ -1916,7 +1607,7 @@ class BisectPerformanceMetrics(object): |
is_telemetry = bisect_utils.IsTelemetryCommand(command_to_run) |
if self.opts.target_platform == 'cros' and is_telemetry: |
args.append('--remote=%s' % self.opts.cros_remote_ip) |
- args.append('--identity=%s' % CROS_TEST_KEY_PATH) |
+ args.append('--identity=%s' % bisect_utils.CROS_TEST_KEY_PATH) |
start_time = time.time() |
@@ -2110,7 +1801,7 @@ class BisectPerformanceMetrics(object): |
""" |
cwd = os.getcwd() |
self.ChangeToDepotWorkingDirectory('cros') |
- cmd = [CROS_SDK_PATH, '--delete'] |
+ cmd = [bisect_utils.CROS_SDK_PATH, '--delete'] |
return_code = bisect_utils.RunProcess(cmd) |
os.chdir(cwd) |
return not return_code |
@@ -2123,7 +1814,7 @@ class BisectPerformanceMetrics(object): |
""" |
cwd = os.getcwd() |
self.ChangeToDepotWorkingDirectory('cros') |
- cmd = [CROS_SDK_PATH, '--create'] |
+ cmd = [bisect_utils.CROS_SDK_PATH, '--create'] |
return_code = bisect_utils.RunProcess(cmd) |
os.chdir(cwd) |
return not return_code |