#!/usr/bin/env python3
#
# Copyright 2020 The Chromium Authors
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.
"""This script facilitates running tests for lacros on Linux.

  In order to run lacros tests on Linux, please first follow bit.ly/3juQVNJ
  to setup build directory with the lacros-chrome-on-linux build configuration,
  and corresponding test targets are built successfully.

Example usages

  ./build/lacros/test_runner.py test out/lacros/url_unittests
  ./build/lacros/test_runner.py test out/lacros/browser_tests

  The commands above run url_unittests and browser_tests respecitively, and more
  specifically, url_unitests is executed directly while browser_tests is
  executed with the latest version of prebuilt ash-chrome, and the behavior is
  controlled by |_TARGETS_REQUIRE_ASH_CHROME|, and it's worth noting that the
  list is maintained manually, so if you see something is wrong, please upload a
  CL to fix it.

  ./build/lacros/test_runner.py test out/lacros/browser_tests \\
      --gtest_filter=BrowserTest.Title

  The above command only runs 'BrowserTest.Title', and any argument accepted by
  the underlying test binary can be specified in the command.

  ./build/lacros/test_runner.py test out/lacros/browser_tests \\
    --ash-chrome-version=793554

  The above command runs tests with a given version of ash-chrome, which is
  useful to reproduce test failures, the version corresponds to the commit
  position of commits on the master branch, and a list of prebuilt versions can
  be found at: gs://ash-chromium-on-linux-prebuilts/x86_64.

  ./testing/xvfb.py ./build/lacros/test_runner.py test out/lacros/browser_tests

  The above command starts ash-chrome with xvfb instead of an X11 window, and
  it's useful when running tests without a display attached, such as sshing.

  For version skew testing when passing --ash-chrome-path-override, the runner
  will try to find the ash major version and Lacros major version. If ash is
  newer(major version larger), the runner will not run any tests and just
  returns success.

Interactively debugging tests

  Any of the previous examples accept the switches
    --gdb
    --lldb
  to run the tests in the corresponding debugger.
"""

import argparse
import json
import os
import logging
import re
import shutil
import signal
import subprocess
import sys
import tempfile
import time
import zipfile

_SRC_ROOT = os.path.abspath(
    os.path.join(os.path.dirname(__file__), os.path.pardir, os.path.pardir))
sys.path.append(os.path.join(_SRC_ROOT, 'third_party', 'depot_tools'))


# The cipd path for prebuilt ash chrome.
_ASH_CIPD_PATH = 'chromium/testing/linux-ash-chromium/x86_64/ash.zip'


# Directory to cache downloaded ash-chrome versions to avoid re-downloading.
_PREBUILT_ASH_CHROME_DIR = os.path.join(os.path.dirname(__file__),
                                        'prebuilt_ash_chrome')

# File path to the asan symbolizer executable.
_ASAN_SYMBOLIZER_PATH = os.path.join(_SRC_ROOT, 'tools', 'valgrind', 'asan',
                                     'asan_symbolize.py')

# Number of seconds to wait for ash-chrome to start.
ASH_CHROME_TIMEOUT_SECONDS = (
    300 if os.environ.get('ASH_WRAPPER', None) else 10)

# List of targets that require ash-chrome as a Wayland server in order to run.
_TARGETS_REQUIRE_ASH_CHROME = [
    'app_shell_unittests',
    'aura_unittests',
    'browser_tests',
    'components_unittests',
    'compositor_unittests',
    'content_unittests',
    'dbus_unittests',
    'extensions_unittests',
    'media_unittests',
    'message_center_unittests',
    'snapshot_unittests',
    'sync_integration_tests',
    'unit_tests',
    'views_unittests',
    'wm_unittests',

    # regex patterns.
    '.*_browsertests',
    '.*interactive_ui_tests'
]

# List of targets that require ash-chrome to support crosapi mojo APIs.
_TARGETS_REQUIRE_MOJO_CROSAPI = [
    # TODO(jamescook): Add 'browser_tests' after multiple crosapi connections
    # are allowed. For now we only enable crosapi in targets that run tests
    # serially.
    'interactive_ui_tests',
    'lacros_chrome_browsertests',
    'lacros_chrome_browsertests_run_in_series'
]

# Default test filter file for each target. These filter files will be
# used by default if no other filter file get specified.
_DEFAULT_FILTER_FILES_MAPPING = {
    'browser_tests': 'linux-lacros.browser_tests.filter',
    'components_unittests': 'linux-lacros.components_unittests.filter',
    'content_browsertests': 'linux-lacros.content_browsertests.filter',
    'interactive_ui_tests': 'linux-lacros.interactive_ui_tests.filter',
    'lacros_chrome_browsertests':
    'linux-lacros.lacros_chrome_browsertests.filter',
    'sync_integration_tests': 'linux-lacros.sync_integration_tests.filter',
    'unit_tests': 'linux-lacros.unit_tests.filter',
}


def _GetAshChromeDirPath(version):
  """Returns a path to the dir storing the downloaded version of ash-chrome."""
  return os.path.join(_PREBUILT_ASH_CHROME_DIR, version)


def _remove_unused_ash_chrome_versions(version_to_skip):
  """Removes unused ash-chrome versions to save disk space.

  Currently, when an ash-chrome zip is downloaded and unpacked, the atime/mtime
  of the dir and the files are NOW instead of the time when they were built, but
  there is no garanteen it will always be the behavior in the future, so avoid
  removing the current version just in case.

  Args:
    version_to_skip (str): the version to skip removing regardless of its age.
  """
  days = 7
  expiration_duration = 60 * 60 * 24 * days

  for f in os.listdir(_PREBUILT_ASH_CHROME_DIR):
    if f == version_to_skip:
      continue

    p = os.path.join(_PREBUILT_ASH_CHROME_DIR, f)
    if os.path.isfile(p):
      # The prebuilt ash-chrome dir is NOT supposed to contain any files, remove
      # them to keep the directory clean.
      os.remove(p)
      continue
    chrome_path = os.path.join(p, 'test_ash_chrome')
    if not os.path.exists(chrome_path):
      chrome_path = p
    age = time.time() - os.path.getatime(chrome_path)
    if age > expiration_duration:
      logging.info(
          'Removing ash-chrome: "%s" as it hasn\'t been used in the '
          'past %d days', p, days)
      shutil.rmtree(p)


def _GetLatestVersionOfAshChrome():
  '''Get the latest ash chrome version.

  Get the package version info with canary ref.

  Returns:
    A string with the chrome version.

  Raises:
    RuntimeError: if we can not get the version.
  '''
  cp = subprocess.run(
      ['cipd', 'describe', _ASH_CIPD_PATH, '-version', 'canary'],
      capture_output=True)
  assert (cp.returncode == 0)
  groups = re.search(r'version:(?P<version>[\d\.]+)', str(cp.stdout))
  if not groups:
    raise RuntimeError('Can not find the version. Error message: %s' %
                       cp.stdout)
  return groups.group('version')


def _DownloadAshChromeFromCipd(path, version):
  '''Download the ash chrome with the requested version.

  Args:
    path: string for the downloaded ash chrome folder.
    version: string for the ash chrome version.

  Returns:
    A string representing the path for the downloaded ash chrome.
  '''
  with tempfile.TemporaryDirectory() as temp_dir:
    ensure_file_path = os.path.join(temp_dir, 'ensure_file.txt')
    f = open(ensure_file_path, 'w+')
    f.write(_ASH_CIPD_PATH + ' version:' + version)
    f.close()
    subprocess.run(
        ['cipd', 'ensure', '-ensure-file', ensure_file_path, '-root', path])


def _DoubleCheckDownloadedAshChrome(path, version):
  '''Check the downloaded ash is the expected version.

  Double check by running the chrome binary with --version.

  Args:
    path: string for the downloaded ash chrome folder.
    version: string for the expected ash chrome version.

  Raises:
    RuntimeError if no test_ash_chrome binary can be found.
  '''
  test_ash_chrome = os.path.join(path, 'test_ash_chrome')
  if not os.path.exists(test_ash_chrome):
    raise RuntimeError('Can not find test_ash_chrome binary under %s' % path)
  cp = subprocess.run([test_ash_chrome, '--version'], capture_output=True)
  assert (cp.returncode == 0)
  if str(cp.stdout).find(version) == -1:
    logging.warning(
        'The downloaded ash chrome version is %s, but the '
        'expected ash chrome is %s. There is a version mismatch. Please '
        'file a bug to OS>Lacros so someone can take a look.' %
        (cp.stdout, version))


def _DownloadAshChromeIfNecessary(version):
  """Download a given version of ash-chrome if not already exists.

  Args:
    version: A string representing the version, such as "793554".

  Raises:
      RuntimeError: If failed to download the specified version, for example,
          if the version is not present on gcs.
  """

  def IsAshChromeDirValid(ash_chrome_dir):
    # This function assumes that once 'chrome' is present, other dependencies
    # will be present as well, it's not always true, for example, if the test
    # runner process gets killed in the middle of unzipping (~2 seconds), but
    # it's unlikely for the assumption to break in practice.
    return os.path.isdir(ash_chrome_dir) and os.path.isfile(
        os.path.join(ash_chrome_dir, 'test_ash_chrome'))

  ash_chrome_dir = _GetAshChromeDirPath(version)
  if IsAshChromeDirValid(ash_chrome_dir):
    return

  shutil.rmtree(ash_chrome_dir, ignore_errors=True)
  os.makedirs(ash_chrome_dir)
  _DownloadAshChromeFromCipd(ash_chrome_dir, version)
  _DoubleCheckDownloadedAshChrome(ash_chrome_dir, version)
  _remove_unused_ash_chrome_versions(version)


def _WaitForAshChromeToStart(tmp_xdg_dir, lacros_mojo_socket_file,
                             enable_mojo_crosapi, ash_ready_file):
  """Waits for Ash-Chrome to be up and running and returns a boolean indicator.

  Determine whether ash-chrome is up and running by checking whether two files
  (lock file + socket) have been created in the |XDG_RUNTIME_DIR| and the lacros
  mojo socket file has been created if enabling the mojo "crosapi" interface.
  TODO(crbug.com/1107966): Figure out a more reliable hook to determine the
  status of ash-chrome, likely through mojo connection.

  Args:
    tmp_xdg_dir (str): Path to the XDG_RUNTIME_DIR.
    lacros_mojo_socket_file (str): Path to the lacros mojo socket file.
    enable_mojo_crosapi (bool): Whether to bootstrap the crosapi mojo interface
        between ash and the lacros test binary.
    ash_ready_file (str): Path to a non-existing file. After ash is ready for
        testing, the file will be created.

  Returns:
    A boolean indicating whether Ash-chrome is up and running.
  """

  def IsAshChromeReady(tmp_xdg_dir, lacros_mojo_socket_file,
                       enable_mojo_crosapi, ash_ready_file):
    # There should be 2 wayland files.
    if len(os.listdir(tmp_xdg_dir)) < 2:
      return False
    if enable_mojo_crosapi and not os.path.exists(lacros_mojo_socket_file):
      return False
    return os.path.exists(ash_ready_file)

  time_counter = 0
  while not IsAshChromeReady(tmp_xdg_dir, lacros_mojo_socket_file,
                             enable_mojo_crosapi, ash_ready_file):
    time.sleep(0.5)
    time_counter += 0.5
    if time_counter > ASH_CHROME_TIMEOUT_SECONDS:
      break

  return IsAshChromeReady(tmp_xdg_dir, lacros_mojo_socket_file,
                          enable_mojo_crosapi, ash_ready_file)


def _ExtractAshMajorVersion(file_path):
  """Extract major version from file_path.

  File path like this:
  ../../lacros_version_skew_tests_v94.0.4588.0/test_ash_chrome

  Returns:
    int representing the major version. Or 0 if it can't extract
        major version.
  """
  m = re.search(
      'lacros_version_skew_tests_v(?P<version>[0-9]+).[0-9]+.[0-9]+.[0-9]+/',
      file_path)
  if (m and 'version' in m.groupdict().keys()):
    return int(m.group('version'))
  logging.warning('Can not find the ash version in %s.' % file_path)
  # Returns ash major version as 0, so we can still run tests.
  # This is likely happen because user is running in local environments.
  return 0


def _FindLacrosMajorVersionFromMetadata():
  # This handles the logic on bots. When running on bots,
  # we don't copy source files to test machines. So we build a
  # metadata.json file which contains version information.
  if not os.path.exists('metadata.json'):
    logging.error('Can not determine current version.')
    # Returns 0 so it can't run any tests.
    return 0
  version = ''
  with open('metadata.json', 'r') as file:
    content = json.load(file)
    version = content['content']['version']
  return int(version[:version.find('.')])


def _FindLacrosMajorVersion():
  """Returns the major version in the current checkout.

  It would try to read src/chrome/VERSION. If it's not available,
  then try to read metadata.json.

  Returns:
    int representing the major version. Or 0 if it fails to
    determine the version.
  """
  version_file = os.path.abspath(
      os.path.join(os.path.abspath(os.path.dirname(__file__)),
                   '../../chrome/VERSION'))
  # This is mostly happens for local development where
  # src/chrome/VERSION exists.
  if os.path.exists(version_file):
    lines = open(version_file, 'r').readlines()
    return int(lines[0][lines[0].find('=') + 1:-1])
  return _FindLacrosMajorVersionFromMetadata()


def _ParseSummaryOutput(forward_args):
  """Find the summary output file path.

  Args:
    forward_args (list): Args to be forwarded to the test command.

  Returns:
    None if not found, or str representing the output file path.
  """
  logging.warning(forward_args)
  for arg in forward_args:
    if arg.startswith('--test-launcher-summary-output='):
      return arg[len('--test-launcher-summary-output='):]
  return None


def _IsRunningOnBots(forward_args):
  """Detects if the script is running on bots or not.

  Args:
    forward_args (list): Args to be forwarded to the test command.

  Returns:
    True if the script is running on bots. Otherwise returns False.
  """
  return '--test-launcher-bot-mode' in forward_args


def _KillNicely(proc, timeout_secs=2, first_wait_secs=0):
  """Kills a subprocess nicely.

  Args:
    proc: The subprocess to kill.
    timeout_secs: The timeout to wait in seconds.
    first_wait_secs: The grace period before sending first SIGTERM in seconds.
  """
  if not proc:
    return

  if first_wait_secs:
    try:
      proc.wait(first_wait_secs)
      return
    except subprocess.TimeoutExpired:
      pass

  if proc.poll() is None:
    proc.terminate()
    try:
      proc.wait(timeout_secs)
    except subprocess.TimeoutExpired:
      proc.kill()
      proc.wait()


def _ClearDir(dirpath):
  """Deletes everything within the directory.

  Args:
    dirpath: The path of the directory.
  """
  for e in os.scandir(dirpath):
    if e.is_dir():
      shutil.rmtree(e.path)
    elif e.is_file():
      os.remove(e.path)


def _LaunchDebugger(args, forward_args, test_env):
  """Launches the requested debugger.

  This is used to wrap the test invocation in a debugger. It returns the
  created Popen class of the debugger process.

  Args:
      args (dict): Args for this script.
      forward_args (list): Args to be forwarded to the test command.
      test_env (dict): Computed environment variables for the test.
  """
  logging.info('Starting debugger.')

  # Force the tests into single-process-test mode for debugging unless manually
  # specified. Otherwise the tests will run in a child process that the debugger
  # won't be attached to and the debugger won't do anything.
  if not ("--single-process" in forward_args
          or "--single-process-tests" in forward_args):
    forward_args += ["--single-process-tests"]

    # Adding --single-process-tests can cause some tests to fail when they're
    # run in the same process. Forcing the user to specify a filter will prevent
    # a later error.
    if not [i for i in forward_args if i.startswith("--gtest_filter")]:
      logging.error("""Interactive debugging requested without --gtest_filter

This script adds --single-process-tests to support interactive debugging but
some tests will fail in this mode unless run independently. To debug a test
specify a --gtest_filter=Foo.Bar to name the test you want to debug.
""")
      sys.exit(1)

  # This code attempts to source the debugger configuration file. Some
  # users will have this in their init but sourcing it more than once is
  # harmless and helps people that haven't configured it.
  if args.gdb:
    gdbinit_file = os.path.normpath(
        os.path.join(os.path.realpath(__file__), "../../../tools/gdb/gdbinit"))
    debugger_command = [
        'gdb', '--init-eval-command', 'source ' + gdbinit_file, '--args'
    ]
  else:
    lldbinit_dir = os.path.normpath(
        os.path.join(os.path.realpath(__file__), "../../../tools/lldb"))
    debugger_command = [
        'lldb', '-O',
        "script sys.path[:0] = ['%s']" % lldbinit_dir, '-O',
        'script import lldbinit', '--'
    ]
  debugger_command += [args.command] + forward_args
  return subprocess.Popen(debugger_command, env=test_env)


def _RunTestWithAshChrome(args, forward_args):
  """Runs tests with ash-chrome.

  Args:
    args (dict): Args for this script.
    forward_args (list): Args to be forwarded to the test command.
  """
  if args.ash_chrome_path_override:
    ash_chrome_file = args.ash_chrome_path_override
    ash_major_version = _ExtractAshMajorVersion(ash_chrome_file)
    lacros_major_version = _FindLacrosMajorVersion()
    if ash_major_version > lacros_major_version:
      logging.warning('''Not running any tests, because we do not \
support version skew testing for Lacros M%s against ash M%s''' %
                      (lacros_major_version, ash_major_version))
      # Create an empty output.json file so result adapter can read
      # the file. Or else result adapter will report no file found
      # and result infra failure.
      output_json = _ParseSummaryOutput(forward_args)
      if output_json:
        with open(output_json, 'w') as f:
          f.write("""{"all_tests":[],"disabled_tests":[],"global_tags":[],
"per_iteration_data":[],"test_locations":{}}""")
      # Although we don't run any tests, this is considered as success.
      return 0
    if not os.path.exists(ash_chrome_file):
      logging.error("""Can not find ash chrome at %s. Did you download \
the ash from CIPD? If you don't plan to build your own ash, you need \
to download first. Example commandlines:
 $ cipd auth-login
 $ echo "chromium/testing/linux-ash-chromium/x86_64/ash.zip \
version:92.0.4515.130" > /tmp/ensure-file.txt
 $ cipd ensure -ensure-file /tmp/ensure-file.txt \
-root lacros_version_skew_tests_v92.0.4515.130
 Then you can use --ash-chrome-path-override=\
lacros_version_skew_tests_v92.0.4515.130/test_ash_chrome
""" % ash_chrome_file)
      return 1
  elif args.ash_chrome_path:
    ash_chrome_file = args.ash_chrome_path
  else:
    ash_chrome_version = (args.ash_chrome_version
                          or _GetLatestVersionOfAshChrome())
    _DownloadAshChromeIfNecessary(ash_chrome_version)
    logging.info('Ash-chrome version: %s', ash_chrome_version)

    ash_chrome_file = os.path.join(_GetAshChromeDirPath(ash_chrome_version),
                                   'test_ash_chrome')
  try:
    # Starts Ash-Chrome.
    tmp_xdg_dir_name = tempfile.mkdtemp()
    tmp_ash_data_dir_name = tempfile.mkdtemp()

    # Please refer to below file for how mojo connection is set up in testing.
    # //chrome/browser/ash/crosapi/test_mojo_connection_manager.h
    lacros_mojo_socket_file = '%s/lacros.sock' % tmp_ash_data_dir_name
    lacros_mojo_socket_arg = ('--lacros-mojo-socket-for-testing=%s' %
                              lacros_mojo_socket_file)
    ash_ready_file = '%s/ash_ready.txt' % tmp_ash_data_dir_name
    enable_mojo_crosapi = any(t == os.path.basename(args.command)
                              for t in _TARGETS_REQUIRE_MOJO_CROSAPI)
    ash_wayland_socket_name = 'wayland-exo'

    ash_process = None
    ash_env = os.environ.copy()
    ash_env['XDG_RUNTIME_DIR'] = tmp_xdg_dir_name
    ash_cmd = [
        ash_chrome_file,
        '--user-data-dir=%s' % tmp_ash_data_dir_name,
        '--enable-wayland-server',
        '--no-startup-window',
        '--disable-input-event-activation-protection',
        '--disable-lacros-keep-alive',
        '--disable-login-lacros-opening',
        '--enable-field-trial-config',
        '--enable-features=LacrosSupport,LacrosPrimary,LacrosOnly',
        '--ash-ready-file-path=%s' % ash_ready_file,
        '--wayland-server-socket=%s' % ash_wayland_socket_name,
    ]
    if '--enable-pixel-output-in-tests' not in forward_args:
      ash_cmd.append('--disable-gl-drawing-for-tests')

    if enable_mojo_crosapi:
      ash_cmd.append(lacros_mojo_socket_arg)

    # Users can specify a wrapper for the ash binary to do things like
    # attaching debuggers. For example, this will open a new terminal window
    # and run GDB.
    #   $ export ASH_WRAPPER="gnome-terminal -- gdb --ex=r --args"
    ash_wrapper = os.environ.get('ASH_WRAPPER', None)
    if ash_wrapper:
      logging.info('Running ash with "ASH_WRAPPER": %s', ash_wrapper)
      ash_cmd = list(ash_wrapper.split()) + ash_cmd

    ash_process_has_started = False
    total_tries = 3
    num_tries = 0
    ash_start_time = None

    # Create a log file if the user wanted to have one.
    ash_log = None
    ash_log_path = None

    run_tests_in_debugger = args.gdb or args.lldb

    if args.ash_logging_path:
      ash_log_path = args.ash_logging_path
    # Put ash logs in a separate file on bots.
    # For asan builds, the ash log is not symbolized. In order to
    # read the stack strace, we don't redirect logs to another file.
    elif _IsRunningOnBots(forward_args) and not args.combine_ash_logs_on_bots:
      summary_file = _ParseSummaryOutput(forward_args)
      if summary_file:
        ash_log_path = os.path.join(os.path.dirname(summary_file),
                                    'ash_chrome.log')
    elif run_tests_in_debugger:
      # The debugger is unusable when all Ash logs are getting dumped to the
      # same terminal. Redirect to a log file if there isn't one specified.
      logging.info("Running in the debugger and --ash-logging-path is not " +
                   "specified, defaulting to the current directory.")
      ash_log_path = 'ash_chrome.log'

    if ash_log_path:
      ash_log = open(ash_log_path, 'a')
      logging.info('Writing ash-chrome logs to: %s', ash_log_path)

    ash_stdout = ash_log or None
    test_stdout = None

    # Setup asan symbolizer.
    ash_symbolize_process = None
    test_symbolize_process = None
    should_symbolize = False
    if args.asan_symbolize_output and os.path.exists(_ASAN_SYMBOLIZER_PATH):
      should_symbolize = True
      ash_symbolize_stdout = ash_stdout
      ash_stdout = subprocess.PIPE
      test_stdout = subprocess.PIPE

    while not ash_process_has_started and num_tries < total_tries:
      num_tries += 1
      ash_start_time = time.monotonic()
      logging.info('Starting ash-chrome.')
      ash_process = subprocess.Popen(ash_cmd,
                                     env=ash_env,
                                     stdout=ash_stdout,
                                     stderr=subprocess.STDOUT)

      if should_symbolize:
        logging.info('Symbolizing ash logs with asan symbolizer.')
        ash_symbolize_process = subprocess.Popen([_ASAN_SYMBOLIZER_PATH],
                                                 stdin=ash_process.stdout,
                                                 stdout=ash_symbolize_stdout,
                                                 stderr=subprocess.STDOUT)
        # Allow ash_process to receive a SIGPIPE if symbolize process exits.
        ash_process.stdout.close()

      ash_process_has_started = _WaitForAshChromeToStart(
          tmp_xdg_dir_name, lacros_mojo_socket_file, enable_mojo_crosapi,
          ash_ready_file)
      if ash_process_has_started:
        break

      logging.warning('Starting ash-chrome timed out after %ds',
                      ASH_CHROME_TIMEOUT_SECONDS)
      logging.warning('Are you using test_ash_chrome?')
      logging.warning('Printing the output of "ps aux" for debugging:')
      subprocess.call(['ps', 'aux'])
      _KillNicely(ash_process)
      _KillNicely(ash_symbolize_process, first_wait_secs=1)

      # Clean up for retry.
      _ClearDir(tmp_xdg_dir_name)
      _ClearDir(tmp_ash_data_dir_name)

    if not ash_process_has_started:
      raise RuntimeError('Timed out waiting for ash-chrome to start')

    ash_elapsed_time = time.monotonic() - ash_start_time
    logging.info('Started ash-chrome in %.3fs on try %d.', ash_elapsed_time,
                 num_tries)

    # Starts tests.
    if enable_mojo_crosapi:
      forward_args.append(lacros_mojo_socket_arg)

    forward_args.append('--ash-chrome-path=' + ash_chrome_file)
    test_env = os.environ.copy()
    test_env['WAYLAND_DISPLAY'] = ash_wayland_socket_name
    test_env['EGL_PLATFORM'] = 'surfaceless'
    test_env['XDG_RUNTIME_DIR'] = tmp_xdg_dir_name

    if run_tests_in_debugger:
      test_process = _LaunchDebugger(args, forward_args, test_env)
    else:
      logging.info('Starting test process.')
      test_process = subprocess.Popen([args.command] + forward_args,
                                      env=test_env,
                                      stdout=test_stdout,
                                      stderr=subprocess.STDOUT)
      if should_symbolize:
        logging.info('Symbolizing test logs with asan symbolizer.')
        test_symbolize_process = subprocess.Popen([_ASAN_SYMBOLIZER_PATH],
                                                  stdin=test_process.stdout)
        # Allow test_process to receive a SIGPIPE if symbolize process exits.
        test_process.stdout.close()
    return test_process.wait()

  finally:
    _KillNicely(ash_process)
    # Give symbolizer processes time to finish writing with first_wait_secs.
    _KillNicely(ash_symbolize_process, first_wait_secs=1)
    _KillNicely(test_symbolize_process, first_wait_secs=1)

    shutil.rmtree(tmp_xdg_dir_name, ignore_errors=True)
    shutil.rmtree(tmp_ash_data_dir_name, ignore_errors=True)


def _RunTestDirectly(args, forward_args):
  """Runs tests by invoking the test command directly.

  args (dict): Args for this script.
  forward_args (list): Args to be forwarded to the test command.
  """
  try:
    p = None
    p = subprocess.Popen([args.command] + forward_args)
    return p.wait()
  finally:
    _KillNicely(p)


def _HandleSignal(sig, _):
  """Handles received signals to make sure spawned test process are killed.

  sig (int): An integer representing the received signal, for example SIGTERM.
  """
  logging.warning('Received signal: %d, killing spawned processes', sig)

  # Don't do any cleanup here, instead, leave it to the finally blocks.
  # Assumption is based on https://docs.python.org/3/library/sys.html#sys.exit:
  # cleanup actions specified by finally clauses of try statements are honored.

  # https://tldp.org/LDP/abs/html/exitcodes.html:
  # Exit code 128+n -> Fatal error signal "n".
  sys.exit(128 + sig)


def _ExpandFilterFileIfNeeded(test_target, forward_args):
  if (test_target in _DEFAULT_FILTER_FILES_MAPPING.keys() and not any(
      [arg.startswith('--test-launcher-filter-file') for arg in forward_args])):
    file_path = os.path.abspath(
        os.path.join(os.path.dirname(__file__), '..', '..', 'testing',
                     'buildbot', 'filters',
                     _DEFAULT_FILTER_FILES_MAPPING[test_target]))
    forward_args.append(f'--test-launcher-filter-file={file_path}')


def _RunTest(args, forward_args):
  """Runs tests with given args.

  args (dict): Args for this script.
  forward_args (list): Args to be forwarded to the test command.

  Raises:
      RuntimeError: If the given test binary doesn't exist or the test runner
          doesn't know how to run it.
  """

  if not os.path.isfile(args.command):
    raise RuntimeError('Specified test command: "%s" doesn\'t exist' %
                       args.command)

  test_target = os.path.basename(args.command)
  _ExpandFilterFileIfNeeded(test_target, forward_args)

  # |_TARGETS_REQUIRE_ASH_CHROME| may not always be accurate as it is updated
  # with a best effort only, therefore, allow the invoker to override the
  # behavior with a specified ash-chrome version, which makes sure that
  # automated CI/CQ builders would always work correctly.
  requires_ash_chrome = any(
      re.match(t, test_target) for t in _TARGETS_REQUIRE_ASH_CHROME)
  if not requires_ash_chrome and not args.ash_chrome_version:
    return _RunTestDirectly(args, forward_args)

  return _RunTestWithAshChrome(args, forward_args)


def Main():
  for sig in (signal.SIGTERM, signal.SIGINT):
    signal.signal(sig, _HandleSignal)

  logging.basicConfig(level=logging.INFO)
  arg_parser = argparse.ArgumentParser()
  arg_parser.usage = __doc__

  subparsers = arg_parser.add_subparsers()

  test_parser = subparsers.add_parser('test', help='Run tests')
  test_parser.set_defaults(func=_RunTest)

  test_parser.add_argument(
      'command',
      help='A single command to invoke the tests, for example: '
      '"./url_unittests". Any argument unknown to this test runner script will '
      'be forwarded to the command, for example: "--gtest_filter=Suite.Test"')

  version_group = test_parser.add_mutually_exclusive_group()
  version_group.add_argument(
      '--ash-chrome-version',
      type=str,
      help='Version of an prebuilt ash-chrome to use for testing, for example: '
      '"793554", and the version corresponds to the commit position of commits '
      'on the main branch. If not specified, will use the latest version '
      'available')
  version_group.add_argument(
      '--ash-chrome-path',
      type=str,
      help='Path to an locally built ash-chrome to use for testing. '
      'In general you should build //chrome/test:test_ash_chrome.')

  debugger_group = test_parser.add_mutually_exclusive_group()
  debugger_group.add_argument('--gdb',
                              action='store_true',
                              help='Run the test in GDB.')
  debugger_group.add_argument('--lldb',
                              action='store_true',
                              help='Run the test in LLDB.')

  # This is for version skew testing. The current CI/CQ builder builds
  # an ash chrome and pass it using --ash-chrome-path. In order to use the same
  # builder for version skew testing, we use a new argument to override
  # the ash chrome.
  test_parser.add_argument(
      '--ash-chrome-path-override',
      type=str,
      help='The same as --ash-chrome-path. But this will override '
      '--ash-chrome-path or --ash-chrome-version if any of these '
      'arguments exist.')
  test_parser.add_argument(
      '--ash-logging-path',
      type=str,
      help='File & path to ash-chrome logging output while running Lacros '
      'browser tests. If not provided, no output will be generated.')
  test_parser.add_argument('--combine-ash-logs-on-bots',
                           action='store_true',
                           help='Whether to combine ash logs on bots.')
  test_parser.add_argument(
      '--asan-symbolize-output',
      action='store_true',
      help='Whether to run subprocess log outputs through the asan symbolizer.')

  args = arg_parser.parse_known_args()
  if not hasattr(args[0], "func"):
    # No command specified.
    print(__doc__)
    sys.exit(1)

  return args[0].func(args[0], args[1])


if __name__ == '__main__':
  sys.exit(Main())
