tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

run_test.py (6990B)


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