blob: 64f0c919cd2aabcdc177701d7e3b5c84ce0a4231 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright (c) 2013 The Chromium OS Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
from __future__ import absolute_import
from __future__ import division
from __future__ import print_function
import argparse
import pathlib
import os
import sys
import logging
# Turn the logging level to INFO before importing other autotest
# code, to avoid having failed import logging messages confuse the
# test_that user.
logging.basicConfig(level=logging.INFO)
from autotest_lib.client.common_lib import logging_manager
from autotest_lib.server import server_logging_config
from autotest_lib.site_utils import test_runner_utils
def validate_arguments(arguments):
"""
Validates parsed arguments.
@param arguments: arguments object, as parsed by ParseArguments
@raises: ValueError if arguments were invalid.
"""
if arguments.remote == ':lab:':
if arguments.args:
raise ValueError('--args flag not supported when running against '
':lab:')
if arguments.pretend:
raise ValueError('--pretend flag not supported when running '
'against :lab:')
if arguments.ssh_verbosity:
raise ValueError('--ssh_verbosity flag not supported when running '
'against :lab:')
if not arguments.board or arguments.build == test_runner_utils.NO_BUILD:
raise ValueError('--board and --build are both required when '
'running against :lab:')
else:
if arguments.web:
raise ValueError('--web flag not supported when running locally')
def parse_arguments(argv):
"""
Parse command line arguments
@param argv: argument list to parse
@returns: parsed arguments
@raises SystemExit if arguments are malformed, or required arguments
are not present.
"""
return _parse_arguments_internal(argv)[0]
def _parse_arguments_internal(argv):
"""
Parse command line arguments
@param argv: argument list to parse
@returns: tuple of parsed arguments and argv suitable for remote runs
@raises SystemExit if arguments are malformed, or required arguments
are not present.
"""
local_parser, remote_argv = parse_local_arguments(argv)
parser = argparse.ArgumentParser(description='Run remote tests.',
parents=[local_parser])
parser.add_argument('remote', metavar='REMOTE',
help='hostname[:port] for remote device. Specify '
':lab: to run in test lab. When tests are run in '
'the lab, test_that will use the client autotest '
'package for the build specified with --build, '
'and the lab server code rather than local '
'changes.')
test_runner_utils.add_common_args(parser)
parser.add_argument('-b', '--board', metavar='BOARD',
action='store',
help='Board for which the test will run. '
'Default: %(default)s')
parser.add_argument('-m',
'--model',
metavar='MODEL',
help='Specific model the test will run against. '
'Matches the model:FAKE_MODEL label for the host.')
parser.add_argument('-i', '--build', metavar='BUILD',
default=test_runner_utils.NO_BUILD,
help='Build to test. Device will be reimaged if '
'necessary. Omit flag to skip reimage and test '
'against already installed DUT image. Examples: '
'link-paladin/R34-5222.0.0-rc2, '
'lumpy-release/R34-5205.0.0')
parser.add_argument('-p', '--pool', metavar='POOL', default='suites',
help='Pool to use when running tests in the lab. '
'Default is "suites"')
parser.add_argument(
'--autotest_dir',
metavar='AUTOTEST_DIR',
help='Use AUTOTEST_DIR instead of normal board sysroot '
'copy of autotest.')
parser.add_argument('--allow-chrome-crashes',
action='store_true',
default=False,
dest='allow_chrome_crashes',
help='Ignore chrome crashes when producing test '
'report. This flag gets passed along to the '
'report generation tool.')
parser.add_argument('--ssh_private_key', action='store',
default=test_runner_utils.TEST_KEY_PATH,
help='Path to the private ssh key.')
parser.add_argument('--companion_hosts',
action='store',
default=None,
help='Companion duts for the test.')
return parser.parse_args(argv), remote_argv
def parse_local_arguments(argv):
"""
Strips out arguments that are not to be passed through to runs.
Add any arguments that should not be passed to remote test_that runs here.
@param argv: argument list to parse.
@returns: tuple of local argument parser and remaining argv.
"""
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('-w', '--web', dest='web', default=None,
help='Address of a webserver to receive test requests.')
parser.add_argument('-x', '--max_runtime_mins', type=int,
dest='max_runtime_mins', default=20,
help='Default time allowed for the tests to complete.')
parser.add_argument('--no-retries', '--no-retry',
dest='retry', action='store_false', default=True,
help='For local runs only, ignore any retries '
'specified in the control files.')
_, remaining_argv = parser.parse_known_args(argv)
return parser, remaining_argv
def _main_for_all_run(argv, arguments):
"""
Effective entry point test runs.
@param argv: Script command line arguments.
@param arguments: Parsed command line arguments.
"""
results_directory = test_runner_utils.create_results_directory(
arguments.results_dir, arguments.board)
test_runner_utils.add_ssh_identity(results_directory,
arguments.ssh_private_key)
arguments.results_dir = results_directory
# TODO, maybe need to force a board/model specification.
autotest_path = pathlib.Path(__file__).parent.parent.resolve()
return test_runner_utils.perform_run_from_autotest_root(
autotest_path,
argv,
arguments.tests,
arguments.remote,
build=arguments.build,
board=arguments.board,
model=arguments.model,
args=arguments.args,
ignore_deps=not arguments.enforce_deps,
results_directory=results_directory,
ssh_verbosity=arguments.ssh_verbosity,
ssh_options=arguments.ssh_options,
iterations=arguments.iterations,
fast_mode=arguments.fast_mode,
debug=arguments.debug,
allow_chrome_crashes=arguments.allow_chrome_crashes,
pretend=arguments.pretend,
job_retry=arguments.retry,
companion_hosts=arguments.companion_hosts)
def main(argv=None):
"""
Entry point for test_that script.
@param argv: arguments list
"""
if argv is None:
argv = sys.argv[1:]
arguments, remote_argv = _parse_arguments_internal(argv)
try:
validate_arguments(arguments)
except ValueError as err:
print(('Invalid arguments. %s' % str(err)), file=sys.stderr)
return 1
_main_for_all_run(argv, arguments)
if __name__ == '__main__':
sys.exit(main(sys.argv[1:]))