blob: e1e6aeb6121502fc18699b90506d44a3a1410030 [file] [log] [blame]
#!/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())