#!/usr/bin/python # Copyright 2015 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. import argparse 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_droid user. logging.basicConfig(level=logging.INFO) import common # Unfortunately, autotest depends on external packages for assorted # functionality regardless of whether or not it is needed in a particular # context. # Since we can't depend on people to import these utilities in any principled # way, we dynamically download code before any autotest imports. try: import chromite.lib.terminal # pylint: disable=unused-import import django.http # pylint: disable=unused-import except ImportError: # Ensure the chromite site-package is installed. import subprocess build_externals_path = os.path.join( os.path.dirname(os.path.dirname(os.path.realpath(__file__))), 'utils', 'build_externals.py') subprocess.check_call([build_externals_path, 'chromiterepo', 'django']) # Restart the script so python now finds the autotest site-packages. sys.exit(os.execv(__file__, sys.argv)) from autotest_lib.client.common_lib import utils from autotest_lib.server.hosts import adb_host from autotest_lib.site_utils import test_runner_utils from autotest_lib.site_utils import tester_feedback 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. """ parser = argparse.ArgumentParser(description='Run remote tests.') parser.add_argument('-s', '--serials', metavar='SERIALS', help='Comma separate list of device serials under ' 'test.') parser.add_argument('-f', '--fastboot_serial', metavar='FB_SERIALS', help='Comma separate list of fastboot serials under ' 'test.', default=None) parser.add_argument('-r', '--remote', metavar='REMOTE', default='localhost', help='hostname[:port] if the ADB device is connected ' 'to a remote machine. Ensure this workstation ' 'is configured for passwordless ssh access as ' 'users "root" or "adb"') parser.add_argument('-i', '--interactive', action='store_true', help='Enable interactive feedback requests from tests.') test_runner_utils.add_common_args(parser) return parser.parse_args(argv) def main(argv): """ Entry point for test_droid script. @param argv: arguments list """ arguments = _parse_arguments_internal(argv) serials = arguments.serials if serials is None: result = utils.run(['adb', 'devices']) devices = adb_host.ADBHost.parse_device_serials(result.stdout) if len(devices) != 1: logging.error('could not detect exactly one device; please select ' 'one with -s: %s', devices) return 1 serials = devices[0] results_directory = test_runner_utils.create_results_directory( arguments.results_dir) arguments.results_dir = results_directory autotest_path = os.path.dirname(os.path.dirname( os.path.realpath(__file__))) site_utils_path = os.path.join(autotest_path, 'site_utils') realpath = os.path.realpath(__file__) site_utils_path = os.path.realpath(site_utils_path) host_attributes = {'serials' : serials, 'os_type' : 'android'} if arguments.fastboot_serial: host_attributes['fastboot_serial'] = arguments.fastboot_serial fb_service = None try: # Start the feedback service if needed. if arguments.interactive: fb_service = tester_feedback.FeedbackService() fb_service.start() if arguments.args: arguments.args += ' ' else: arguments.args = '' arguments.args += ( 'feedback=interactive feedback_args=localhost:%d' % fb_service.server_port) return test_runner_utils.perform_run_from_autotest_root( autotest_path, argv, arguments.tests, arguments.remote, args=arguments.args, ignore_deps=not arguments.enforce_deps, results_directory=results_directory, iterations=arguments.iterations, fast_mode=arguments.fast_mode, debug=arguments.debug, host_attributes=host_attributes, pretend=arguments.pretend) finally: if fb_service is not None: fb_service.stop() if __name__ == '__main__': sys.exit(main(sys.argv[1:]))