| Index: tools/auto_bisect/configs/try.py
|
| diff --git a/tools/auto_bisect/configs/try.py b/tools/auto_bisect/configs/try.py
|
| new file mode 100755
|
| index 0000000000000000000000000000000000000000..e60f6def064deb85107684ec6b8420038d702a35
|
| --- /dev/null
|
| +++ b/tools/auto_bisect/configs/try.py
|
| @@ -0,0 +1,157 @@
|
| +#!/usr/bin/env python
|
| +# Copyright 2014 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.
|
| +
|
| +"""Starts bisect try jobs on multiple platforms using known-good configs.
|
| +
|
| +The purpose of this script is to serve as an integration test for the
|
| +auto-bisect project by starting try jobs for various config types and
|
| +various platforms.
|
| +
|
| +The known-good configs are in this same directory as this script. They
|
| +are expected to all end in ".cfg" and start with the name of the platform
|
| +followed by a dot.
|
| +
|
| +You can specify --full to try running each config on all applicable bots;
|
| +the default behavior is to try each config on only one bot.
|
| +"""
|
| +
|
| +import argparse
|
| +import logging
|
| +import os
|
| +import subprocess
|
| +import sys
|
| +
|
| +SCRIPT_DIR = os.path.abspath(os.path.dirname(__file__))
|
| +BISECT_CONFIG = os.path.join(SCRIPT_DIR, os.path.pardir, 'bisect.cfg')
|
| +PERF_TEST_CONFIG = os.path.join(
|
| + SCRIPT_DIR, os.path.pardir, os.path.pardir, 'run-perf-test.cfg')
|
| +PLATFORM_BOT_MAP = {
|
| + 'linux': ['linux_perf_bot'],
|
| + 'mac': ['mac_perf_bisect', 'mac_10_9_perf_bisect'],
|
| + 'win': ['win_perf_bisect', 'win_8_perf_bisect', 'win_xp_perf_bisect'],
|
| + 'android': [
|
| + 'android_nexus4_perf_bisect',
|
| + 'android_nexus5_perf_bisect',
|
| + 'android_nexus7_perf_bisect',
|
| + 'android_nexus10_perf_bisect',
|
| + ],
|
| +}
|
| +SVN_URL = 'svn://svn.chromium.org/chrome-try/try-perf'
|
| +AUTO_COMMIT_MESSAGE = 'Automatic commit for bisect try job.'
|
| +
|
| +
|
| +def main(argv):
|
| + parser = argparse.ArgumentParser(description=__doc__)
|
| + parser.add_argument('--full', action='store_true',
|
| + help='Run each config on all applicable bots.')
|
| + parser.add_argument('--filter',
|
| + help='Filter for config filenames to use. Only configs '
|
| + 'containing the given substring will be tried.')
|
| + parser.add_argument('--verbose', '-v', action='store_true')
|
| + args = parser.parse_args(argv[1:])
|
| + _SetupLogging(args.verbose)
|
| + source_configs = _SourceConfigs(args.filter)
|
| + logging.debug('Source configs: %s', source_configs)
|
| + try:
|
| + _StartTryJobs(source_configs, args.full)
|
| + except subprocess.CalledProcessError as error:
|
| + print str(error)
|
| + print error.output
|
| +
|
| +
|
| +def _SetupLogging(verbose):
|
| + level = logging.INFO
|
| + if verbose:
|
| + level = logging.DEBUG
|
| + logging.basicConfig(level=level)
|
| +
|
| +
|
| +def _SourceConfigs(name_filter):
|
| + """Gets a list of paths to sample configs to try."""
|
| + files = os.listdir(SCRIPT_DIR)
|
| + files = [os.path.join(SCRIPT_DIR, name) for name in files]
|
| + files = [name for name in files if name.endswith('.cfg')]
|
| + if name_filter:
|
| + files = [name for name in files if name_filter in name]
|
| + return files
|
| +
|
| +
|
| +def _StartTryJobs(source_configs, full_mode=False):
|
| + """Tries each of the given sample configs on one or more try bots."""
|
| + for source_config in source_configs:
|
| + dest_config = _DestConfig(source_config)
|
| + bot_names = _BotNames(source_config, full_mode=full_mode)
|
| + _StartTry(source_config, dest_config, bot_names)
|
| +
|
| +
|
| +def _DestConfig(source_config):
|
| + """Returns the path that a sample config should be copied to."""
|
| + if 'bisect' in source_config:
|
| + return BISECT_CONFIG
|
| + assert 'perf_test' in source_config, source_config
|
| + return PERF_TEST_CONFIG
|
| +
|
| +
|
| +def _BotNames(source_config, full_mode=False):
|
| + """Returns try bot names to use for the given config file name."""
|
| + platform = os.path.basename(source_config).split('.')[0]
|
| + assert platform in PLATFORM_BOT_MAP
|
| + bot_names = PLATFORM_BOT_MAP[platform]
|
| + if full_mode:
|
| + return bot_names
|
| + return [bot_names[0]]
|
| +
|
| +
|
| +def _StartTry(source_config, dest_config, bot_names):
|
| + """Sends a try job with the given config to the given try bots.
|
| +
|
| + Args:
|
| + source_config: Path of the sample config to copy over.
|
| + dest_config: Destination path to copy sample to, e.g. "./bisect.cfg".
|
| + bot_names: List of try bot builder names.
|
| + """
|
| + assert os.path.exists(source_config)
|
| + assert os.path.exists(dest_config)
|
| + assert _LastCommitMessage() != AUTO_COMMIT_MESSAGE
|
| +
|
| + # Copy the sample config over and commit it.
|
| + _Run(['cp', source_config, dest_config])
|
| + _Run(['git', 'commit', '--all', '-m', AUTO_COMMIT_MESSAGE])
|
| +
|
| + try:
|
| + # Start the try job.
|
| + job_name = 'Automatically-started (%s)' % os.path.basename(source_config)
|
| + try_command = ['git', 'try', '--svn_repo', SVN_URL, '-n', job_name]
|
| + for bot_name in bot_names:
|
| + try_command.extend(['-b', bot_name])
|
| + print _Run(try_command)
|
| + finally:
|
| + # Revert the immediately-previous commit which was made just above.
|
| + assert _LastCommitMessage() == AUTO_COMMIT_MESSAGE
|
| + _Run(['git', 'reset', '--hard', 'HEAD~1'])
|
| +
|
| +
|
| +def _LastCommitMessage():
|
| + return _Run(['git', 'log', '--format=%s', '-1']).strip()
|
| +
|
| +
|
| +def _Run(command):
|
| + """Runs a command in a subprocess.
|
| +
|
| + Args:
|
| + command: The command given as an args list.
|
| +
|
| + Returns:
|
| + The output of the command.
|
| +
|
| + Raises:
|
| + subprocess.CalledProcessError: The return-code was non-zero.
|
| + """
|
| + logging.debug('Running %s', command)
|
| + return subprocess.check_output(command)
|
| +
|
| +
|
| +if __name__ == '__main__':
|
| + sys.exit(main(sys.argv))
|
|
|