#!/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())