Chromium Code Reviews| 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..8da84f8f6bb7d1e14962f047da32d9ecd7c2e7ce |
| --- /dev/null |
| +++ b/tools/auto_bisect/configs/try.py |
| @@ -0,0 +1,145 @@ |
| +#!/usr/bin/env python |
| + |
| +"""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.dirname(__file__) |
|
Sergiy Byelozyorov
2014/10/21 19:24:42
SCRIPT_DIR = os.path.abspath(os.path.dirname(__fil
qyearsley
2014/10/23 02:51:01
Ah, yes, right.
|
| +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 job with sample config %s' % 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): |
| + logging.debug('Running %s', command) |
| + # Note: check_output will raise a subprocess.CalledProcessError when |
| + # the return-code is non-zero. |
| + return subprocess.check_output(command) |
| + |
| + |
| +if __name__ == '__main__': |
| + sys.exit(main(sys.argv)) |