#!/usr/bin/env python # Copyright 2013 The Chromium Authors. All rights reserved. # Use of this source code is governed by a BSD-style license that can be # found in the LICENSE file. """Run Manual Test Bisect Tool An example usage: tools/run-bisect-manual-test.py -g 201281 -b 201290 On Linux platform, follow the instructions in this document https://chromium.googlesource.com/chromium/src/+/master/docs/linux_suid_sandbox_development.md to setup the sandbox manually before running the script. Otherwise the script fails to launch Chrome and exits with an error. This script serves a similar function to bisect-builds.py, except it uses the bisect_perf_regression.py. This means that that it can obtain builds of Chromium for revisions where builds aren't available in cloud storage. """ import os import subprocess import sys CROS_BOARD_ENV = 'BISECT_CROS_BOARD' CROS_IP_ENV = 'BISECT_CROS_IP' _TOOLS_DIR = os.path.abspath(os.path.dirname(__file__)) _BISECT_SCRIPT_PATH = os.path.join( _TOOLS_DIR, 'auto_bisect', 'bisect_perf_regression.py') sys.path.append(os.path.join(_TOOLS_DIR, 'perf')) from chrome_telemetry_build import chromium_config sys.path.append(chromium_config.GetTelemetryDir()) from telemetry.internal.browser import browser_options def _RunBisectionScript(options): """Attempts to execute the bisect script (bisect_perf_regression.py). Args: options: The configuration options to pass to the bisect script. Returns: An exit code; 0 for success, 1 for failure. """ script_path = os.path.join(options.working_directory, 'bisect', 'src', 'tools','bisect-manual-test.py') abs_script_path = os.path.abspath(script_path) test_command = ('python %s --browser=%s --chrome-root=.' % (abs_script_path, options.browser_type)) cmd = ['python', _BISECT_SCRIPT_PATH, '-c', test_command, '-g', options.good_revision, '-b', options.bad_revision, '-m', 'manual_test/manual_test', '-r', '1', '--working_directory', options.working_directory, '--build_preference', 'ninja', '--no_custom_deps', '--builder_type', options.builder_type] if options.extra_src: cmd.extend(['--extra_src', options.extra_src]) if 'cros' in options.browser_type: cmd.extend(['--target_platform', 'cros']) if os.environ[CROS_BOARD_ENV] and os.environ[CROS_IP_ENV]: cmd.extend(['--cros_board', os.environ[CROS_BOARD_ENV]]) cmd.extend(['--cros_remote_ip', os.environ[CROS_IP_ENV]]) else: print ('Error: Cros build selected, but BISECT_CROS_IP or' 'BISECT_CROS_BOARD undefined.\n') return 1 elif 'android-chrome' == options.browser_type: if not options.extra_src: print 'Error: Missing --extra_src to run bisect for android-chrome.' sys.exit(-1) cmd.extend(['--target_platform', 'android-chrome']) elif 'android' in options.browser_type: cmd.extend(['--target_platform', 'android']) elif not options.target_build_type: cmd.extend(['--target_build_type', options.browser_type.title()]) if options.target_build_type: cmd.extend(['--target_build_type', options.target_build_type]) if options.goma_threads: cmd.extend(['--use_goma', '--goma_threads', options.goma_threads]) cmd = [str(c) for c in cmd] return_code = subprocess.call(cmd) if return_code: print 'Error: bisect_perf_regression.py had exit code %d.' % return_code print return return_code def main(): """Does a bisect based on the command-line arguments passed in. The user will be prompted to classify each revision as good or bad. """ usage = ('%prog [options]\n' 'Used to run the bisection script with a manual test.') options = browser_options.BrowserFinderOptions('release') parser = options.CreateParser(usage) parser.add_option('-b', '--bad_revision', type='str', help='A bad revision to start bisection. ' + 'Must be later than good revision. May be either a git' + ' or svn revision.') parser.add_option('-g', '--good_revision', type='str', help='A revision to start bisection where performance' + ' test is known to pass. Must be earlier than the ' + 'bad revision. May be either a git or svn revision.') parser.add_option('-w', '--working_directory', type='str', default='..', help='A working directory to supply to the bisection ' 'script, which will use it as the location to checkout ' 'a copy of the chromium depot.') parser.add_option('--extra_src', type='str', help='Path to extra source file. If this is supplied, ' 'bisect script will use this to override default behavior.') parser.add_option('--target_build_type', type='choice', choices=['Release', 'Debug'], help='The target build type. Choices are "Release" ' 'or "Debug".') parser.add_option('--goma_threads', default=64, type='int', help='Number of goma threads to use. 0 will disable goma.') parser.add_option('--builder_type', default='', choices=['perf', 'full', 'android-chrome-perf', ''], help='Type of builder to get build from. This allows ' 'script to use cached builds. By default (empty), binaries ' 'are built locally.') options, _ = parser.parse_args() error_msg = '' if not options.good_revision: error_msg += 'Error: missing required parameter: --good_revision\n' if not options.bad_revision: error_msg += 'Error: missing required parameter: --bad_revision\n' if error_msg: print error_msg parser.print_help() return 1 if 'android' not in options.browser_type and sys.platform.startswith('linux'): if not os.environ.get('CHROME_DEVEL_SANDBOX'): print 'SUID sandbox has not been setup.'\ ' See https://chromium.googlesource.com/chromium/src/'\ '+/master/docs/linux_suid_sandbox_development.md.' return 1 return _RunBisectionScript(options) if __name__ == '__main__': sys.exit(main())