diff options
author | mmeade <mmeade@chromium.org> | 2015-03-16 11:23:41 -0700 |
---|---|---|
committer | Commit bot <commit-bot@chromium.org> | 2015-03-16 18:24:35 +0000 |
commit | 3f2796443ad61ce8e4817f34586942af4f77ad5e (patch) | |
tree | eaf3f193860bf526120c3b1d2c52b73e2423f1f2 /testing | |
parent | ca5ccceffa70d6a4e20cacaa12c44e4e9d0ebf2c (diff) | |
download | chromium_src-3f2796443ad61ce8e4817f34586942af4f77ad5e.zip chromium_src-3f2796443ad61ce8e4817f34586942af4f77ad5e.tar.gz chromium_src-3f2796443ad61ce8e4817f34586942af4f77ad5e.tar.bz2 |
Adding an easy(ier) to use tool to start legion-based tests. This tool handles all of the isolate archives, building the test controller command line, and running the test controller.
BUG=467618
Review URL: https://codereview.chromium.org/1006383004
Cr-Commit-Position: refs/heads/master@{#320754}
Diffstat (limited to 'testing')
-rwxr-xr-x | testing/legion/tools/legion.py | 159 |
1 files changed, 159 insertions, 0 deletions
diff --git a/testing/legion/tools/legion.py b/testing/legion/tools/legion.py new file mode 100755 index 0000000..7b67133 --- /dev/null +++ b/testing/legion/tools/legion.py @@ -0,0 +1,159 @@ +#!/usr/bin/env python +# Copyright 2015 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. + +"""A helper module to run Legion multi-machine tests. + +Example usage with 1 task machine: +$ testing/legion/tools/legion.py run \ + --controller-isolated out/Release/example_test_controller.isolated \ + --dimension os Ubuntu-14.04 \ + --task-name test-task-name \ + --task task_machine out/Release/example_task_machine.isolated + +Example usage with 2 task machines with the same isolated file: +$ testing/legion/tools/legion.py run \ + --controller-isolated out/Release/example_test_controller.isolated \ + --dimension os Ubuntu-14.04 \ + --task-name test-task-name \ + --task task_machine_1 out/Release/example_task_machine.isolated \ + --task task_machine_2 out/Release/example_task_machine.isolated + +Example usage with 2 task machines with different isolated file: +$ testing/legion/tools/legion.py run \ + --controller-isolated out/Release/example_test_controller.isolated \ + --dimension os Ubuntu-14.04 \ + --task-name test-task-name \ + --task task_machine_1 out/Release/example_task_machine_1.isolated \ + --task task_machine_2 out/Release/example_task_machine_2.isolated +""" + +import argparse +import logging +import os +import subprocess +import sys + + +THIS_DIR = os.path.split(__file__)[0] +SWARMING_DIR = os.path.join(THIS_DIR, '..', '..', '..', 'tools', + 'swarming_client') +ISOLATE_PY = os.path.join(SWARMING_DIR, 'isolate.py') +SWARMING_PY = os.path.join(SWARMING_DIR, 'swarming.py') +LOGGING_LEVELS = ['DEBUG', 'INFO', 'WARNING', 'ERROR'] + + +class Error(Exception): + pass + + +def GetArgs(): + parser = argparse.ArgumentParser(description=__doc__) + parser.add_argument('action', choices=['run', 'trigger'], + help='The swarming action to perform.') + parser.add_argument('-f', '--format-only', action='store_true', + help='If true the .isolated files are archived but ' + 'swarming is not called, only the command line is built.') + parser.add_argument('--controller-isolated', required=True, + help='The isolated file for the test controller.') + parser.add_argument('--isolate-server', help='Optional. The isolated server ' + 'to use.') + parser.add_argument('--swarming-server', help='Optional. The swarming server ' + 'to use.') + parser.add_argument('--task-name', help='Optional. The swarming task name ' + 'to use.') + parser.add_argument('--dimension', action='append', dest='dimensions', + nargs=2, default=[], help='Dimensions to pass to ' + 'swarming.py. This is in the form of --dimension key ' + 'value. The minimum required is --dimension os <OS>') + parser.add_argument('--task', action='append', dest='tasks', + nargs=2, default=[], help='List of task names used in ' + 'the test controller. This is in the form of --task name ' + '.isolated and is passed to the controller as --name ' + '<ISOLATED HASH>.') + parser.add_argument('--controller-var', action='append', + dest='controller_vars', nargs=2, default=[], + help='Command line vars to pass to the controller. These ' + 'are in the form of --controller-var name value and are ' + 'passed to the controller as --name value.') + parser.add_argument('-v', '--verbosity', default=0, action='count') + return parser.parse_args() + + +def RunCommand(cmd, stream_stdout=False): + """Runs the command line and streams stdout if requested.""" + kwargs = { + 'args': cmd, + 'stderr': subprocess.PIPE, + } + if not stream_stdout: + kwargs['stdout'] = subprocess.PIPE + + p = subprocess.Popen(**kwargs) + stdout, stderr = p.communicate() + if p.returncode: + raise Error(stderr) + if not stream_stdout: + logging.debug(stdout) + return stdout + + +def Archive(isolated, isolate_server=None): + """Calls isolate.py archive with the given args.""" + cmd = [ + sys.executable, + ISOLATE_PY, + 'archive', + '--isolated', isolated, + ] + if isolate_server: + cmd.extend(['--isolate-server', isolate_server]) + print ' '.join(cmd) + return RunCommand(cmd).split()[0] # The isolated hash + + +def GetSwarmingCommandLine(args): + """Builds and returns the command line for swarming.py run|trigger.""" + cmd = [ + sys.executable, + SWARMING_PY, + args.action, + args.controller_isolated, + ] + if args.isolate_server: + cmd.extend(['--isolate-server', args.isolate_server]) + if args.swarming_server: + cmd.extend(['--swarming', args.swarming_server]) + if args.task_name: + cmd.extend(['--task-name', args.task_name]) + # swarming.py dimensions + for name, value in args.dimensions: + cmd.extend(['--dimension', name, value]) + + cmd.append('--') + + # Task name/hash values + for name, isolated in args.tasks: + cmd.extend(['--' + name, Archive(isolated, args.isolate_server)]) + # Test controller args + for name, value in args.controller_vars: + cmd.extend(['--' + name, value]) + print ' '.join(cmd) + return cmd + + +def main(): + args = GetArgs() + logging.basicConfig( + format='%(asctime)s %(filename)s:%(lineno)s %(levelname)s] %(message)s', + datefmt='%H:%M:%S', + level=LOGGING_LEVELS[len(LOGGING_LEVELS)-args.verbosity-1]) + cmd = GetSwarmingCommandLine(args) + if not args.format_only: + RunCommand(cmd, True) + return 0 + + +if __name__ == '__main__': + sys.exit(main()) |