1*6777b538SAndroid Build Coastguard Worker#!/usr/bin/env vpython3 2*6777b538SAndroid Build Coastguard Worker# Copyright 2022 The Chromium Authors 3*6777b538SAndroid Build Coastguard Worker# Use of this source code is governed by a BSD-style license that can be 4*6777b538SAndroid Build Coastguard Worker# found in the LICENSE file. 5*6777b538SAndroid Build Coastguard Worker"""Implements commands for running tests E2E on a Fuchsia device.""" 6*6777b538SAndroid Build Coastguard Worker 7*6777b538SAndroid Build Coastguard Workerimport argparse 8*6777b538SAndroid Build Coastguard Workerimport logging 9*6777b538SAndroid Build Coastguard Workerimport os 10*6777b538SAndroid Build Coastguard Workerimport sys 11*6777b538SAndroid Build Coastguard Workerimport tempfile 12*6777b538SAndroid Build Coastguard Worker 13*6777b538SAndroid Build Coastguard Workerfrom contextlib import ExitStack 14*6777b538SAndroid Build Coastguard Workerfrom typing import List 15*6777b538SAndroid Build Coastguard Worker 16*6777b538SAndroid Build Coastguard Workerfrom common import register_common_args, register_device_args, \ 17*6777b538SAndroid Build Coastguard Worker register_log_args, resolve_packages 18*6777b538SAndroid Build Coastguard Workerfrom compatible_utils import running_unattended 19*6777b538SAndroid Build Coastguard Workerfrom ffx_integration import ScopedFfxConfig 20*6777b538SAndroid Build Coastguard Workerfrom flash_device import register_update_args, update 21*6777b538SAndroid Build Coastguard Workerfrom isolate_daemon import IsolateDaemon 22*6777b538SAndroid Build Coastguard Workerfrom log_manager import LogManager, start_system_log 23*6777b538SAndroid Build Coastguard Workerfrom publish_package import publish_packages, register_package_args 24*6777b538SAndroid Build Coastguard Workerfrom run_blink_test import BlinkTestRunner 25*6777b538SAndroid Build Coastguard Workerfrom run_executable_test import create_executable_test_runner, \ 26*6777b538SAndroid Build Coastguard Worker register_executable_test_args 27*6777b538SAndroid Build Coastguard Workerfrom run_telemetry_test import TelemetryTestRunner 28*6777b538SAndroid Build Coastguard Workerfrom run_webpage_test import WebpageTestRunner 29*6777b538SAndroid Build Coastguard Workerfrom serve_repo import register_serve_args, serve_repository 30*6777b538SAndroid Build Coastguard Workerfrom start_emulator import create_emulator_from_args, register_emulator_args 31*6777b538SAndroid Build Coastguard Workerfrom test_connection import test_connection, test_device_connection 32*6777b538SAndroid Build Coastguard Workerfrom test_runner import TestRunner 33*6777b538SAndroid Build Coastguard Worker 34*6777b538SAndroid Build Coastguard Worker 35*6777b538SAndroid Build Coastguard Workerdef _get_test_runner(runner_args: argparse.Namespace, 36*6777b538SAndroid Build Coastguard Worker test_args: List[str]) -> TestRunner: 37*6777b538SAndroid Build Coastguard Worker """Initialize a suitable TestRunner class.""" 38*6777b538SAndroid Build Coastguard Worker 39*6777b538SAndroid Build Coastguard Worker if runner_args.test_type == 'blink': 40*6777b538SAndroid Build Coastguard Worker return BlinkTestRunner(runner_args.out_dir, test_args, 41*6777b538SAndroid Build Coastguard Worker runner_args.target_id) 42*6777b538SAndroid Build Coastguard Worker if runner_args.test_type in ['gpu', 'perf']: 43*6777b538SAndroid Build Coastguard Worker return TelemetryTestRunner(runner_args.test_type, runner_args.out_dir, 44*6777b538SAndroid Build Coastguard Worker test_args, runner_args.target_id) 45*6777b538SAndroid Build Coastguard Worker if runner_args.test_type in ['webpage']: 46*6777b538SAndroid Build Coastguard Worker return WebpageTestRunner(runner_args.out_dir, test_args, 47*6777b538SAndroid Build Coastguard Worker runner_args.target_id) 48*6777b538SAndroid Build Coastguard Worker return create_executable_test_runner(runner_args, test_args) 49*6777b538SAndroid Build Coastguard Worker 50*6777b538SAndroid Build Coastguard Worker 51*6777b538SAndroid Build Coastguard Worker# pylint: disable=too-many-statements 52*6777b538SAndroid Build Coastguard Workerdef main(): 53*6777b538SAndroid Build Coastguard Worker """E2E method for installing packages and running a test.""" 54*6777b538SAndroid Build Coastguard Worker # Always add time stamps to the logs. 55*6777b538SAndroid Build Coastguard Worker logging.basicConfig(format='%(levelname)s %(asctime)s %(message)s') 56*6777b538SAndroid Build Coastguard Worker 57*6777b538SAndroid Build Coastguard Worker parser = argparse.ArgumentParser() 58*6777b538SAndroid Build Coastguard Worker parser.add_argument( 59*6777b538SAndroid Build Coastguard Worker 'test_type', 60*6777b538SAndroid Build Coastguard Worker help='The type of test to run. Options include \'blink\', \'gpu\', ' 61*6777b538SAndroid Build Coastguard Worker 'or in the case of executable tests, the test name.') 62*6777b538SAndroid Build Coastguard Worker parser.add_argument('--device', 63*6777b538SAndroid Build Coastguard Worker '-d', 64*6777b538SAndroid Build Coastguard Worker action='store_true', 65*6777b538SAndroid Build Coastguard Worker default=False, 66*6777b538SAndroid Build Coastguard Worker help='Use an existing device.') 67*6777b538SAndroid Build Coastguard Worker parser.add_argument('--extra-path', 68*6777b538SAndroid Build Coastguard Worker action='append', 69*6777b538SAndroid Build Coastguard Worker help='Extra paths to append to the PATH environment') 70*6777b538SAndroid Build Coastguard Worker 71*6777b538SAndroid Build Coastguard Worker # Register arguments 72*6777b538SAndroid Build Coastguard Worker register_common_args(parser) 73*6777b538SAndroid Build Coastguard Worker register_device_args(parser) 74*6777b538SAndroid Build Coastguard Worker register_emulator_args(parser) 75*6777b538SAndroid Build Coastguard Worker register_executable_test_args(parser) 76*6777b538SAndroid Build Coastguard Worker register_update_args(parser, default_os_check='ignore') 77*6777b538SAndroid Build Coastguard Worker register_log_args(parser) 78*6777b538SAndroid Build Coastguard Worker register_package_args(parser, allow_temp_repo=True) 79*6777b538SAndroid Build Coastguard Worker register_serve_args(parser) 80*6777b538SAndroid Build Coastguard Worker 81*6777b538SAndroid Build Coastguard Worker # Treat unrecognized arguments as test specific arguments. 82*6777b538SAndroid Build Coastguard Worker runner_args, test_args = parser.parse_known_args() 83*6777b538SAndroid Build Coastguard Worker 84*6777b538SAndroid Build Coastguard Worker if not runner_args.out_dir: 85*6777b538SAndroid Build Coastguard Worker raise ValueError('--out-dir must be specified.') 86*6777b538SAndroid Build Coastguard Worker 87*6777b538SAndroid Build Coastguard Worker if runner_args.target_id: 88*6777b538SAndroid Build Coastguard Worker runner_args.device = True 89*6777b538SAndroid Build Coastguard Worker 90*6777b538SAndroid Build Coastguard Worker with ExitStack() as stack: 91*6777b538SAndroid Build Coastguard Worker log_manager = LogManager(runner_args.logs_dir) 92*6777b538SAndroid Build Coastguard Worker if running_unattended(): 93*6777b538SAndroid Build Coastguard Worker if runner_args.extra_path: 94*6777b538SAndroid Build Coastguard Worker os.environ['PATH'] += os.pathsep + os.pathsep.join( 95*6777b538SAndroid Build Coastguard Worker runner_args.extra_path) 96*6777b538SAndroid Build Coastguard Worker 97*6777b538SAndroid Build Coastguard Worker extra_inits = [log_manager] 98*6777b538SAndroid Build Coastguard Worker if runner_args.everlasting: 99*6777b538SAndroid Build Coastguard Worker # Setting the emu.instance_dir to match the named cache, so 100*6777b538SAndroid Build Coastguard Worker # we can keep these files across multiple runs. 101*6777b538SAndroid Build Coastguard Worker extra_inits.append( 102*6777b538SAndroid Build Coastguard Worker ScopedFfxConfig( 103*6777b538SAndroid Build Coastguard Worker 'emu.instance_dir', 104*6777b538SAndroid Build Coastguard Worker os.path.join(os.environ['HOME'], 105*6777b538SAndroid Build Coastguard Worker '.fuchsia_emulator/'))) 106*6777b538SAndroid Build Coastguard Worker stack.enter_context(IsolateDaemon(extra_inits)) 107*6777b538SAndroid Build Coastguard Worker else: 108*6777b538SAndroid Build Coastguard Worker if runner_args.logs_dir: 109*6777b538SAndroid Build Coastguard Worker logging.warning( 110*6777b538SAndroid Build Coastguard Worker 'You are using a --logs-dir, ensure the ffx ' 111*6777b538SAndroid Build Coastguard Worker 'daemon is started with the logs.dir config ' 112*6777b538SAndroid Build Coastguard Worker 'updated. We won\'t restart the daemon randomly' 113*6777b538SAndroid Build Coastguard Worker ' anymore.') 114*6777b538SAndroid Build Coastguard Worker stack.enter_context(log_manager) 115*6777b538SAndroid Build Coastguard Worker 116*6777b538SAndroid Build Coastguard Worker if runner_args.device: 117*6777b538SAndroid Build Coastguard Worker update(runner_args.system_image_dir, runner_args.os_check, 118*6777b538SAndroid Build Coastguard Worker runner_args.target_id, runner_args.serial_num) 119*6777b538SAndroid Build Coastguard Worker # Try to reboot the device if necessary since the ffx may ignore the 120*6777b538SAndroid Build Coastguard Worker # device state after the flash. See 121*6777b538SAndroid Build Coastguard Worker # https://cs.opensource.google/fuchsia/fuchsia/+/main:src/developer/ffx/lib/fastboot/src/common/fastboot.rs;drc=cfba0bdd4f8857adb6409f8ae9e35af52c0da93e;l=454 122*6777b538SAndroid Build Coastguard Worker test_device_connection(runner_args.target_id) 123*6777b538SAndroid Build Coastguard Worker else: 124*6777b538SAndroid Build Coastguard Worker runner_args.target_id = stack.enter_context( 125*6777b538SAndroid Build Coastguard Worker create_emulator_from_args(runner_args)) 126*6777b538SAndroid Build Coastguard Worker test_connection(runner_args.target_id) 127*6777b538SAndroid Build Coastguard Worker 128*6777b538SAndroid Build Coastguard Worker test_runner = _get_test_runner(runner_args, test_args) 129*6777b538SAndroid Build Coastguard Worker package_deps = test_runner.package_deps 130*6777b538SAndroid Build Coastguard Worker 131*6777b538SAndroid Build Coastguard Worker if not runner_args.repo: 132*6777b538SAndroid Build Coastguard Worker # Create a directory that serves as a temporary repository. 133*6777b538SAndroid Build Coastguard Worker runner_args.repo = stack.enter_context( 134*6777b538SAndroid Build Coastguard Worker tempfile.TemporaryDirectory()) 135*6777b538SAndroid Build Coastguard Worker 136*6777b538SAndroid Build Coastguard Worker publish_packages(package_deps.values(), runner_args.repo, 137*6777b538SAndroid Build Coastguard Worker not runner_args.no_repo_init) 138*6777b538SAndroid Build Coastguard Worker 139*6777b538SAndroid Build Coastguard Worker stack.enter_context(serve_repository(runner_args)) 140*6777b538SAndroid Build Coastguard Worker 141*6777b538SAndroid Build Coastguard Worker # Start system logging, after all possible restarts of the ffx daemon 142*6777b538SAndroid Build Coastguard Worker # so that logging will not be interrupted. 143*6777b538SAndroid Build Coastguard Worker start_system_log(log_manager, False, package_deps.values(), 144*6777b538SAndroid Build Coastguard Worker ('--since', 'now'), runner_args.target_id) 145*6777b538SAndroid Build Coastguard Worker 146*6777b538SAndroid Build Coastguard Worker resolve_packages(package_deps.keys(), runner_args.target_id) 147*6777b538SAndroid Build Coastguard Worker return test_runner.run_test().returncode 148*6777b538SAndroid Build Coastguard Worker 149*6777b538SAndroid Build Coastguard Worker 150*6777b538SAndroid Build Coastguard Workerif __name__ == '__main__': 151*6777b538SAndroid Build Coastguard Worker sys.exit(main()) 152