blob: 78e570a788c6a1147593ffac1e82324b916f57d8 [file] [log] [blame]
#!/usr/bin/env python
# Copyright (c) 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 Performance Test Bisect Tool
This script is used by a trybot to run the src/tools/bisect-perf-regression.py
script with the parameters specified in run-bisect-perf-regression.cfg. It will
check out a copy of the depot in a subdirectory 'bisect' of the working
directory provided, and run the bisect-perf-regression.py script there.
"""
import imp
import optparse
import os
import subprocess
import sys
def LoadConfigFile(path_to_file):
"""Attempts to load the file 'run-bisect-perf-regression.cfg' as a module
and grab the global config dict.
Args:
path_to_file: Path to the run-bisect-perf-regression.cfg file.
Returns:
The config dict which should be formatted as follows:
{'command': string, 'good_revision': string, 'bad_revision': string
'metric': string}.
Returns None on failure.
"""
try:
local_vars = {}
execfile(os.path.join(path_to_file, 'run-bisect-perf-regression.cfg'),
local_vars)
return local_vars['config']
except:
return None
def RunBisectionScript(config, working_directory, path_to_file, path_to_goma):
"""Attempts to execute src/tools/bisect-perf-regression.py with the parameters
passed in.
Args:
config: A dict containing the parameters to pass to the script.
working_directory: A working directory to provide to the
bisect-perf-regression.py script, where it will store it's own copy of
the depot.
path_to_file: Path to the bisect-perf-regression.py script.
path_to_goma: Path to goma directory.
Returns:
0 on success, otherwise 1.
"""
cmd = ['python', os.path.join(path_to_file, 'bisect-perf-regression.py'),
'-c', config['command'],
'-g', config['good_revision'],
'-b', config['bad_revision'],
'-m', config['metric'],
'--working_directory', working_directory,
'--output_buildbot_annotations']
if config['repeat_count']:
cmd.extend(['-r', config['repeat_count']])
if config['truncate_percent']:
cmd.extend(['-t', config['truncate_percent']])
if config['max_time_minutes']:
cmd.extend(['--repeat_test_max_time', config['max_time_minutes']])
if os.name == 'nt':
cmd.extend(['--build_preference', 'ninja'])
else:
cmd.extend(['--build_preference', 'make'])
goma_file = ''
if path_to_goma:
path_to_goma = os.path.abspath(path_to_goma)
if os.name == 'nt':
os.environ['CC'] = os.path.join(path_to_goma, 'gomacc.exe') + ' cl.exe'
os.environ['CXX'] = os.path.join(path_to_goma, 'gomacc.exe') + ' cl.exe'
goma_file = os.path.join(path_to_goma, 'goma_ctl.bat')
else:
os.environ['PATH'] = os.pathsep.join([path_to_goma, os.environ['PATH']])
goma_file = os.path.join(path_to_goma, 'goma_ctl.sh')
cmd.append('--use_goma')
# Sometimes goma is lingering around if something went bad on a previous
# run. Stop it before starting a new process. Can ignore the return code
# since it will return an error if it wasn't running.
subprocess.call([goma_file, 'stop'])
return_code = subprocess.call([goma_file, 'start'])
if return_code:
print 'Error: goma failed to start.'
print
return return_code
cmd = [str(c) for c in cmd]
return_code = subprocess.call(cmd)
if path_to_goma:
subprocess.call([goma_file, 'stop'])
if return_code:
print 'Error: bisect-perf-regression.py returned with error %d' %\
return_code
print
return return_code
def main():
usage = ('%prog [options] [-- chromium-options]\n'
'Used by a trybot to run the bisection script using the parameters'
' provided in the run-bisect-perf-regression.cfg file.')
parser = optparse.OptionParser(usage=usage)
parser.add_option('-w', '--working_directory',
type='str',
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('-p', '--path_to_goma',
type='str',
help='Path to goma directory. If this is supplied, goma '
'builds will be enabled.')
(opts, args) = parser.parse_args()
if not opts.working_directory:
print 'Error: missing required parameter: --working_directory'
print
parser.print_help()
return 1
path_to_file = os.path.abspath(os.path.dirname(sys.argv[0]))
config = LoadConfigFile(path_to_file)
if not config:
print 'Error: Could not load config file.'
print
return 1
return RunBisectionScript(config, opts.working_directory, path_to_file,
opts.path_to_goma)
if __name__ == '__main__':
sys.exit(main())