11cb0ef41Sopenharmony_ci# Copyright 2017 the V8 project authors. All rights reserved.
21cb0ef41Sopenharmony_ci# Use of this source code is governed by a BSD-style license that can be
31cb0ef41Sopenharmony_ci# found in the LICENSE file.
41cb0ef41Sopenharmony_ci
51cb0ef41Sopenharmony_cifrom functools import reduce
61cb0ef41Sopenharmony_ci
71cb0ef41Sopenharmony_cifrom collections import OrderedDict, namedtuple
81cb0ef41Sopenharmony_ciimport json
91cb0ef41Sopenharmony_ciimport multiprocessing
101cb0ef41Sopenharmony_ciimport optparse
111cb0ef41Sopenharmony_ciimport os
121cb0ef41Sopenharmony_ciimport shlex
131cb0ef41Sopenharmony_ciimport sys
141cb0ef41Sopenharmony_ciimport traceback
151cb0ef41Sopenharmony_ci
161cb0ef41Sopenharmony_ci
171cb0ef41Sopenharmony_ci
181cb0ef41Sopenharmony_ci# Add testrunner to the path.
191cb0ef41Sopenharmony_cisys.path.insert(
201cb0ef41Sopenharmony_ci  0,
211cb0ef41Sopenharmony_ci  os.path.dirname(
221cb0ef41Sopenharmony_ci    os.path.dirname(os.path.abspath(__file__))))
231cb0ef41Sopenharmony_ci
241cb0ef41Sopenharmony_ci
251cb0ef41Sopenharmony_cifrom testrunner.local import command
261cb0ef41Sopenharmony_cifrom testrunner.local import testsuite
271cb0ef41Sopenharmony_cifrom testrunner.local import utils
281cb0ef41Sopenharmony_cifrom testrunner.test_config import TestConfig
291cb0ef41Sopenharmony_cifrom testrunner.testproc import progress
301cb0ef41Sopenharmony_cifrom testrunner.testproc.rerun import RerunProc
311cb0ef41Sopenharmony_cifrom testrunner.testproc.shard import ShardProc
321cb0ef41Sopenharmony_cifrom testrunner.testproc.sigproc import SignalProc
331cb0ef41Sopenharmony_cifrom testrunner.testproc.timeout import TimeoutProc
341cb0ef41Sopenharmony_cifrom testrunner.testproc import util
351cb0ef41Sopenharmony_ci
361cb0ef41Sopenharmony_ci
371cb0ef41Sopenharmony_ciBASE_DIR = (
381cb0ef41Sopenharmony_ci    os.path.dirname(
391cb0ef41Sopenharmony_ci      os.path.dirname(
401cb0ef41Sopenharmony_ci        os.path.dirname(
411cb0ef41Sopenharmony_ci          os.path.abspath(__file__)))))
421cb0ef41Sopenharmony_ci
431cb0ef41Sopenharmony_ciDEFAULT_OUT_GN = 'out.gn'
441cb0ef41Sopenharmony_ci
451cb0ef41Sopenharmony_ci# Map of test name synonyms to lists of test suites. Should be ordered by
461cb0ef41Sopenharmony_ci# expected runtimes (suites with slow test cases first). These groups are
471cb0ef41Sopenharmony_ci# invoked in separate steps on the bots.
481cb0ef41Sopenharmony_ci# The mapping from names used here to GN targets (which must stay in sync)
491cb0ef41Sopenharmony_ci# is defined in infra/mb/gn_isolate_map.pyl.
501cb0ef41Sopenharmony_ciTEST_MAP = {
511cb0ef41Sopenharmony_ci  # This needs to stay in sync with group("v8_bot_default") in test/BUILD.gn.
521cb0ef41Sopenharmony_ci  "bot_default": [
531cb0ef41Sopenharmony_ci    "debugger",
541cb0ef41Sopenharmony_ci    "mjsunit",
551cb0ef41Sopenharmony_ci    "cctest",
561cb0ef41Sopenharmony_ci    "wasm-spec-tests",
571cb0ef41Sopenharmony_ci    "inspector",
581cb0ef41Sopenharmony_ci    "webkit",
591cb0ef41Sopenharmony_ci    "mkgrokdump",
601cb0ef41Sopenharmony_ci    "wasm-js",
611cb0ef41Sopenharmony_ci    "fuzzer",
621cb0ef41Sopenharmony_ci    "message",
631cb0ef41Sopenharmony_ci    "intl",
641cb0ef41Sopenharmony_ci    "unittests",
651cb0ef41Sopenharmony_ci    "wasm-api-tests",
661cb0ef41Sopenharmony_ci  ],
671cb0ef41Sopenharmony_ci  # This needs to stay in sync with group("v8_default") in test/BUILD.gn.
681cb0ef41Sopenharmony_ci  "default": [
691cb0ef41Sopenharmony_ci    "debugger",
701cb0ef41Sopenharmony_ci    "mjsunit",
711cb0ef41Sopenharmony_ci    "cctest",
721cb0ef41Sopenharmony_ci    "wasm-spec-tests",
731cb0ef41Sopenharmony_ci    "inspector",
741cb0ef41Sopenharmony_ci    "mkgrokdump",
751cb0ef41Sopenharmony_ci    "wasm-js",
761cb0ef41Sopenharmony_ci    "fuzzer",
771cb0ef41Sopenharmony_ci    "message",
781cb0ef41Sopenharmony_ci    "intl",
791cb0ef41Sopenharmony_ci    "unittests",
801cb0ef41Sopenharmony_ci    "wasm-api-tests",
811cb0ef41Sopenharmony_ci  ],
821cb0ef41Sopenharmony_ci  # This needs to stay in sync with group("v8_d8_default") in test/BUILD.gn.
831cb0ef41Sopenharmony_ci  "d8_default": [
841cb0ef41Sopenharmony_ci    "debugger",
851cb0ef41Sopenharmony_ci    "mjsunit",
861cb0ef41Sopenharmony_ci    "webkit",
871cb0ef41Sopenharmony_ci    "message",
881cb0ef41Sopenharmony_ci    "intl",
891cb0ef41Sopenharmony_ci  ],
901cb0ef41Sopenharmony_ci  # This needs to stay in sync with "v8_optimize_for_size" in test/BUILD.gn.
911cb0ef41Sopenharmony_ci  "optimize_for_size": [
921cb0ef41Sopenharmony_ci    "debugger",
931cb0ef41Sopenharmony_ci    "mjsunit",
941cb0ef41Sopenharmony_ci    "cctest",
951cb0ef41Sopenharmony_ci    "inspector",
961cb0ef41Sopenharmony_ci    "webkit",
971cb0ef41Sopenharmony_ci    "intl",
981cb0ef41Sopenharmony_ci  ],
991cb0ef41Sopenharmony_ci  "unittests": [
1001cb0ef41Sopenharmony_ci    "unittests",
1011cb0ef41Sopenharmony_ci  ],
1021cb0ef41Sopenharmony_ci}
1031cb0ef41Sopenharmony_ci
1041cb0ef41Sopenharmony_ci# Increase the timeout for these:
1051cb0ef41Sopenharmony_ciSLOW_ARCHS = [
1061cb0ef41Sopenharmony_ci  "arm",
1071cb0ef41Sopenharmony_ci  "arm64",
1081cb0ef41Sopenharmony_ci  "mips",
1091cb0ef41Sopenharmony_ci  "mipsel",
1101cb0ef41Sopenharmony_ci  "mips64",
1111cb0ef41Sopenharmony_ci  "mips64el",
1121cb0ef41Sopenharmony_ci  "s390",
1131cb0ef41Sopenharmony_ci  "s390x",
1141cb0ef41Sopenharmony_ci  "riscv64",
1151cb0ef41Sopenharmony_ci  "loong64"
1161cb0ef41Sopenharmony_ci]
1171cb0ef41Sopenharmony_ci
1181cb0ef41Sopenharmony_ci
1191cb0ef41Sopenharmony_ciModeConfig = namedtuple(
1201cb0ef41Sopenharmony_ci    'ModeConfig', 'label flags timeout_scalefactor status_mode')
1211cb0ef41Sopenharmony_ci
1221cb0ef41Sopenharmony_ciDEBUG_FLAGS = ["--nohard-abort", "--enable-slow-asserts", "--verify-heap"]
1231cb0ef41Sopenharmony_ciRELEASE_FLAGS = ["--nohard-abort"]
1241cb0ef41Sopenharmony_ci
1251cb0ef41Sopenharmony_ciDEBUG_MODE = ModeConfig(
1261cb0ef41Sopenharmony_ci    label='debug',
1271cb0ef41Sopenharmony_ci    flags=DEBUG_FLAGS,
1281cb0ef41Sopenharmony_ci    timeout_scalefactor=4,
1291cb0ef41Sopenharmony_ci    status_mode="debug",
1301cb0ef41Sopenharmony_ci)
1311cb0ef41Sopenharmony_ci
1321cb0ef41Sopenharmony_ciRELEASE_MODE = ModeConfig(
1331cb0ef41Sopenharmony_ci    label='release',
1341cb0ef41Sopenharmony_ci    flags=RELEASE_FLAGS,
1351cb0ef41Sopenharmony_ci    timeout_scalefactor=1,
1361cb0ef41Sopenharmony_ci    status_mode="release",
1371cb0ef41Sopenharmony_ci)
1381cb0ef41Sopenharmony_ci
1391cb0ef41Sopenharmony_ci# Normal trybot release configuration. There, dchecks are always on which
1401cb0ef41Sopenharmony_ci# implies debug is set. Hence, the status file needs to assume debug-like
1411cb0ef41Sopenharmony_ci# behavior/timeouts.
1421cb0ef41Sopenharmony_ciTRY_RELEASE_MODE = ModeConfig(
1431cb0ef41Sopenharmony_ci    label='release+dchecks',
1441cb0ef41Sopenharmony_ci    flags=RELEASE_FLAGS,
1451cb0ef41Sopenharmony_ci    timeout_scalefactor=4,
1461cb0ef41Sopenharmony_ci    status_mode="debug",
1471cb0ef41Sopenharmony_ci)
1481cb0ef41Sopenharmony_ci
1491cb0ef41Sopenharmony_ciPROGRESS_INDICATORS = {
1501cb0ef41Sopenharmony_ci  'verbose': progress.VerboseProgressIndicator,
1511cb0ef41Sopenharmony_ci  'ci': progress.CIProgressIndicator,
1521cb0ef41Sopenharmony_ci  'dots': progress.DotsProgressIndicator,
1531cb0ef41Sopenharmony_ci  'color': progress.ColorProgressIndicator,
1541cb0ef41Sopenharmony_ci  'mono': progress.MonochromeProgressIndicator,
1551cb0ef41Sopenharmony_ci  'stream': progress.StreamProgressIndicator,
1561cb0ef41Sopenharmony_ci}
1571cb0ef41Sopenharmony_ci
1581cb0ef41Sopenharmony_ciclass TestRunnerError(Exception):
1591cb0ef41Sopenharmony_ci  pass
1601cb0ef41Sopenharmony_ci
1611cb0ef41Sopenharmony_ci
1621cb0ef41Sopenharmony_ciclass BuildConfig(object):
1631cb0ef41Sopenharmony_ci  def __init__(self, build_config):
1641cb0ef41Sopenharmony_ci    # In V8 land, GN's x86 is called ia32.
1651cb0ef41Sopenharmony_ci    if build_config['v8_target_cpu'] == 'x86':
1661cb0ef41Sopenharmony_ci      self.arch = 'ia32'
1671cb0ef41Sopenharmony_ci    else:
1681cb0ef41Sopenharmony_ci      self.arch = build_config['v8_target_cpu']
1691cb0ef41Sopenharmony_ci
1701cb0ef41Sopenharmony_ci    self.asan = build_config['is_asan']
1711cb0ef41Sopenharmony_ci    self.cfi_vptr = build_config['is_cfi']
1721cb0ef41Sopenharmony_ci    self.control_flow_integrity = build_config['v8_control_flow_integrity']
1731cb0ef41Sopenharmony_ci    self.concurrent_marking = build_config['v8_enable_concurrent_marking']
1741cb0ef41Sopenharmony_ci    self.single_generation = build_config['v8_enable_single_generation']
1751cb0ef41Sopenharmony_ci    self.dcheck_always_on = build_config['dcheck_always_on']
1761cb0ef41Sopenharmony_ci    self.gcov_coverage = build_config['is_gcov_coverage']
1771cb0ef41Sopenharmony_ci    self.is_android = build_config['is_android']
1781cb0ef41Sopenharmony_ci    self.is_clang = build_config['is_clang']
1791cb0ef41Sopenharmony_ci    self.is_debug = build_config['is_debug']
1801cb0ef41Sopenharmony_ci    self.is_full_debug = build_config['is_full_debug']
1811cb0ef41Sopenharmony_ci    self.msan = build_config['is_msan']
1821cb0ef41Sopenharmony_ci    self.no_i18n = not build_config['v8_enable_i18n_support']
1831cb0ef41Sopenharmony_ci    self.predictable = build_config['v8_enable_verify_predictable']
1841cb0ef41Sopenharmony_ci    self.simulator_run = (build_config['target_cpu'] !=
1851cb0ef41Sopenharmony_ci                          build_config['v8_target_cpu'])
1861cb0ef41Sopenharmony_ci    self.tsan = build_config['is_tsan']
1871cb0ef41Sopenharmony_ci    # TODO(machenbach): We only have ubsan not ubsan_vptr.
1881cb0ef41Sopenharmony_ci    self.ubsan_vptr = build_config['is_ubsan_vptr']
1891cb0ef41Sopenharmony_ci    self.verify_csa = build_config['v8_enable_verify_csa']
1901cb0ef41Sopenharmony_ci    self.lite_mode = build_config['v8_enable_lite_mode']
1911cb0ef41Sopenharmony_ci    self.pointer_compression = build_config['v8_enable_pointer_compression']
1921cb0ef41Sopenharmony_ci    self.pointer_compression_shared_cage = build_config['v8_enable_pointer_compression_shared_cage']
1931cb0ef41Sopenharmony_ci    self.shared_ro_heap = build_config['v8_enable_shared_ro_heap']
1941cb0ef41Sopenharmony_ci    self.sandbox = build_config['v8_enable_sandbox']
1951cb0ef41Sopenharmony_ci    self.third_party_heap = build_config['v8_enable_third_party_heap']
1961cb0ef41Sopenharmony_ci    self.webassembly = build_config['v8_enable_webassembly']
1971cb0ef41Sopenharmony_ci    self.dict_property_const_tracking = build_config['v8_dict_property_const_tracking']
1981cb0ef41Sopenharmony_ci    # Export only for MIPS target
1991cb0ef41Sopenharmony_ci    if self.arch in ['mips', 'mipsel', 'mips64', 'mips64el']:
2001cb0ef41Sopenharmony_ci      self.mips_arch_variant = build_config['mips_arch_variant']
2011cb0ef41Sopenharmony_ci      self.mips_use_msa = build_config['mips_use_msa']
2021cb0ef41Sopenharmony_ci
2031cb0ef41Sopenharmony_ci  @property
2041cb0ef41Sopenharmony_ci  def use_sanitizer(self):
2051cb0ef41Sopenharmony_ci    return (self.asan or self.cfi_vptr or self.msan or self.tsan or
2061cb0ef41Sopenharmony_ci            self.ubsan_vptr)
2071cb0ef41Sopenharmony_ci
2081cb0ef41Sopenharmony_ci  def __str__(self):
2091cb0ef41Sopenharmony_ci    detected_options = []
2101cb0ef41Sopenharmony_ci
2111cb0ef41Sopenharmony_ci    if self.asan:
2121cb0ef41Sopenharmony_ci      detected_options.append('asan')
2131cb0ef41Sopenharmony_ci    if self.cfi_vptr:
2141cb0ef41Sopenharmony_ci      detected_options.append('cfi_vptr')
2151cb0ef41Sopenharmony_ci    if self.control_flow_integrity:
2161cb0ef41Sopenharmony_ci      detected_options.append('control_flow_integrity')
2171cb0ef41Sopenharmony_ci    if self.dcheck_always_on:
2181cb0ef41Sopenharmony_ci      detected_options.append('dcheck_always_on')
2191cb0ef41Sopenharmony_ci    if self.gcov_coverage:
2201cb0ef41Sopenharmony_ci      detected_options.append('gcov_coverage')
2211cb0ef41Sopenharmony_ci    if self.msan:
2221cb0ef41Sopenharmony_ci      detected_options.append('msan')
2231cb0ef41Sopenharmony_ci    if self.no_i18n:
2241cb0ef41Sopenharmony_ci      detected_options.append('no_i18n')
2251cb0ef41Sopenharmony_ci    if self.predictable:
2261cb0ef41Sopenharmony_ci      detected_options.append('predictable')
2271cb0ef41Sopenharmony_ci    if self.tsan:
2281cb0ef41Sopenharmony_ci      detected_options.append('tsan')
2291cb0ef41Sopenharmony_ci    if self.ubsan_vptr:
2301cb0ef41Sopenharmony_ci      detected_options.append('ubsan_vptr')
2311cb0ef41Sopenharmony_ci    if self.verify_csa:
2321cb0ef41Sopenharmony_ci      detected_options.append('verify_csa')
2331cb0ef41Sopenharmony_ci    if self.lite_mode:
2341cb0ef41Sopenharmony_ci      detected_options.append('lite_mode')
2351cb0ef41Sopenharmony_ci    if self.pointer_compression:
2361cb0ef41Sopenharmony_ci      detected_options.append('pointer_compression')
2371cb0ef41Sopenharmony_ci    if self.pointer_compression_shared_cage:
2381cb0ef41Sopenharmony_ci      detected_options.append('pointer_compression_shared_cage')
2391cb0ef41Sopenharmony_ci    if self.sandbox:
2401cb0ef41Sopenharmony_ci      detected_options.append('sandbox')
2411cb0ef41Sopenharmony_ci    if self.third_party_heap:
2421cb0ef41Sopenharmony_ci      detected_options.append('third_party_heap')
2431cb0ef41Sopenharmony_ci    if self.webassembly:
2441cb0ef41Sopenharmony_ci      detected_options.append('webassembly')
2451cb0ef41Sopenharmony_ci    if self.dict_property_const_tracking:
2461cb0ef41Sopenharmony_ci      detected_options.append('dict_property_const_tracking')
2471cb0ef41Sopenharmony_ci
2481cb0ef41Sopenharmony_ci    return '\n'.join(detected_options)
2491cb0ef41Sopenharmony_ci
2501cb0ef41Sopenharmony_ci
2511cb0ef41Sopenharmony_cidef _do_load_build_config(outdir, verbose=False):
2521cb0ef41Sopenharmony_ci  build_config_path = os.path.join(outdir, "v8_build_config.json")
2531cb0ef41Sopenharmony_ci  if not os.path.exists(build_config_path):
2541cb0ef41Sopenharmony_ci    if verbose:
2551cb0ef41Sopenharmony_ci      print("Didn't find build config: %s" % build_config_path)
2561cb0ef41Sopenharmony_ci    raise TestRunnerError()
2571cb0ef41Sopenharmony_ci
2581cb0ef41Sopenharmony_ci  with open(build_config_path) as f:
2591cb0ef41Sopenharmony_ci    try:
2601cb0ef41Sopenharmony_ci      build_config_json = json.load(f)
2611cb0ef41Sopenharmony_ci    except Exception:  # pragma: no cover
2621cb0ef41Sopenharmony_ci      print("%s exists but contains invalid json. Is your build up-to-date?"
2631cb0ef41Sopenharmony_ci            % build_config_path)
2641cb0ef41Sopenharmony_ci      raise TestRunnerError()
2651cb0ef41Sopenharmony_ci
2661cb0ef41Sopenharmony_ci  return BuildConfig(build_config_json)
2671cb0ef41Sopenharmony_ci
2681cb0ef41Sopenharmony_ci
2691cb0ef41Sopenharmony_ciclass BaseTestRunner(object):
2701cb0ef41Sopenharmony_ci  def __init__(self, basedir=None):
2711cb0ef41Sopenharmony_ci    self.basedir = basedir or BASE_DIR
2721cb0ef41Sopenharmony_ci    self.outdir = None
2731cb0ef41Sopenharmony_ci    self.build_config = None
2741cb0ef41Sopenharmony_ci    self.mode_options = None
2751cb0ef41Sopenharmony_ci    self.target_os = None
2761cb0ef41Sopenharmony_ci    self.infra_staging = False
2771cb0ef41Sopenharmony_ci
2781cb0ef41Sopenharmony_ci  @property
2791cb0ef41Sopenharmony_ci  def framework_name(self):
2801cb0ef41Sopenharmony_ci    """String name of the base-runner subclass, used in test results."""
2811cb0ef41Sopenharmony_ci    raise NotImplementedError()
2821cb0ef41Sopenharmony_ci
2831cb0ef41Sopenharmony_ci  def execute(self, sys_args=None):
2841cb0ef41Sopenharmony_ci    if sys_args is None:  # pragma: no cover
2851cb0ef41Sopenharmony_ci      sys_args = sys.argv[1:]
2861cb0ef41Sopenharmony_ci    try:
2871cb0ef41Sopenharmony_ci      parser = self._create_parser()
2881cb0ef41Sopenharmony_ci      options, args = self._parse_args(parser, sys_args)
2891cb0ef41Sopenharmony_ci      self.infra_staging = options.infra_staging
2901cb0ef41Sopenharmony_ci      if options.swarming:
2911cb0ef41Sopenharmony_ci        # Swarming doesn't print how isolated commands are called. Lets make
2921cb0ef41Sopenharmony_ci        # this less cryptic by printing it ourselves.
2931cb0ef41Sopenharmony_ci        print(' '.join(sys.argv))
2941cb0ef41Sopenharmony_ci
2951cb0ef41Sopenharmony_ci        # TODO(machenbach): Print used Python version until we have switched to
2961cb0ef41Sopenharmony_ci        # Python3 everywhere.
2971cb0ef41Sopenharmony_ci        print('Running with:')
2981cb0ef41Sopenharmony_ci        print(sys.version)
2991cb0ef41Sopenharmony_ci
3001cb0ef41Sopenharmony_ci        # Kill stray processes from previous tasks on swarming.
3011cb0ef41Sopenharmony_ci        util.kill_processes_linux()
3021cb0ef41Sopenharmony_ci
3031cb0ef41Sopenharmony_ci      self._load_build_config(options)
3041cb0ef41Sopenharmony_ci      command.setup(self.target_os, options.device)
3051cb0ef41Sopenharmony_ci
3061cb0ef41Sopenharmony_ci      try:
3071cb0ef41Sopenharmony_ci        self._process_default_options(options)
3081cb0ef41Sopenharmony_ci        self._process_options(options)
3091cb0ef41Sopenharmony_ci      except TestRunnerError:
3101cb0ef41Sopenharmony_ci        parser.print_help()
3111cb0ef41Sopenharmony_ci        raise
3121cb0ef41Sopenharmony_ci
3131cb0ef41Sopenharmony_ci      args = self._parse_test_args(args)
3141cb0ef41Sopenharmony_ci      tests = self._load_testsuite_generators(args, options)
3151cb0ef41Sopenharmony_ci      self._setup_env()
3161cb0ef41Sopenharmony_ci      print(">>> Running tests for %s.%s" % (self.build_config.arch,
3171cb0ef41Sopenharmony_ci                                             self.mode_options.label))
3181cb0ef41Sopenharmony_ci      exit_code = self._do_execute(tests, args, options)
3191cb0ef41Sopenharmony_ci      if exit_code == utils.EXIT_CODE_FAILURES and options.json_test_results:
3201cb0ef41Sopenharmony_ci        print("Force exit code 0 after failures. Json test results file "
3211cb0ef41Sopenharmony_ci              "generated with failure information.")
3221cb0ef41Sopenharmony_ci        exit_code = utils.EXIT_CODE_PASS
3231cb0ef41Sopenharmony_ci      return exit_code
3241cb0ef41Sopenharmony_ci    except TestRunnerError:
3251cb0ef41Sopenharmony_ci      traceback.print_exc()
3261cb0ef41Sopenharmony_ci      return utils.EXIT_CODE_INTERNAL_ERROR
3271cb0ef41Sopenharmony_ci    except KeyboardInterrupt:
3281cb0ef41Sopenharmony_ci      return utils.EXIT_CODE_INTERRUPTED
3291cb0ef41Sopenharmony_ci    except Exception:
3301cb0ef41Sopenharmony_ci      traceback.print_exc()
3311cb0ef41Sopenharmony_ci      return utils.EXIT_CODE_INTERNAL_ERROR
3321cb0ef41Sopenharmony_ci    finally:
3331cb0ef41Sopenharmony_ci      command.tear_down()
3341cb0ef41Sopenharmony_ci
3351cb0ef41Sopenharmony_ci  def _create_parser(self):
3361cb0ef41Sopenharmony_ci    parser = optparse.OptionParser()
3371cb0ef41Sopenharmony_ci    parser.usage = '%prog [options] [tests]'
3381cb0ef41Sopenharmony_ci    parser.description = """TESTS: %s""" % (TEST_MAP["default"])
3391cb0ef41Sopenharmony_ci    self._add_parser_default_options(parser)
3401cb0ef41Sopenharmony_ci    self._add_parser_options(parser)
3411cb0ef41Sopenharmony_ci    return parser
3421cb0ef41Sopenharmony_ci
3431cb0ef41Sopenharmony_ci  def _add_parser_default_options(self, parser):
3441cb0ef41Sopenharmony_ci    parser.add_option("--gn", help="Scan out.gn for the last built"
3451cb0ef41Sopenharmony_ci                      " configuration",
3461cb0ef41Sopenharmony_ci                      default=False, action="store_true")
3471cb0ef41Sopenharmony_ci    parser.add_option("--outdir", help="Base directory with compile output",
3481cb0ef41Sopenharmony_ci                      default="out")
3491cb0ef41Sopenharmony_ci    parser.add_option("--arch",
3501cb0ef41Sopenharmony_ci                      help="The architecture to run tests for")
3511cb0ef41Sopenharmony_ci    parser.add_option("--shell-dir", help="DEPRECATED! Executables from build "
3521cb0ef41Sopenharmony_ci                      "directory will be used")
3531cb0ef41Sopenharmony_ci    parser.add_option("--test-root", help="Root directory of the test suites",
3541cb0ef41Sopenharmony_ci                      default=os.path.join(self.basedir, 'test'))
3551cb0ef41Sopenharmony_ci    parser.add_option("--total-timeout-sec", default=0, type="int",
3561cb0ef41Sopenharmony_ci                      help="How long should fuzzer run")
3571cb0ef41Sopenharmony_ci    parser.add_option("--swarming", default=False, action="store_true",
3581cb0ef41Sopenharmony_ci                      help="Indicates running test driver on swarming.")
3591cb0ef41Sopenharmony_ci    parser.add_option('--infra-staging', help='Use new test runner features',
3601cb0ef41Sopenharmony_ci                      dest='infra_staging', default=None,
3611cb0ef41Sopenharmony_ci                      action='store_true')
3621cb0ef41Sopenharmony_ci    parser.add_option('--no-infra-staging',
3631cb0ef41Sopenharmony_ci                      help='Opt out of new test runner features',
3641cb0ef41Sopenharmony_ci                      dest='infra_staging', default=None,
3651cb0ef41Sopenharmony_ci                      action='store_false')
3661cb0ef41Sopenharmony_ci
3671cb0ef41Sopenharmony_ci    parser.add_option("-j", help="The number of parallel tasks to run",
3681cb0ef41Sopenharmony_ci                      default=0, type=int)
3691cb0ef41Sopenharmony_ci    parser.add_option("-d", "--device",
3701cb0ef41Sopenharmony_ci                      help="The device ID to run Android tests on. If not "
3711cb0ef41Sopenharmony_ci                           "given it will be autodetected.")
3721cb0ef41Sopenharmony_ci
3731cb0ef41Sopenharmony_ci    # Shard
3741cb0ef41Sopenharmony_ci    parser.add_option("--shard-count", default=1, type=int,
3751cb0ef41Sopenharmony_ci                      help="Split tests into this number of shards")
3761cb0ef41Sopenharmony_ci    parser.add_option("--shard-run", default=1, type=int,
3771cb0ef41Sopenharmony_ci                      help="Run this shard from the split up tests.")
3781cb0ef41Sopenharmony_ci
3791cb0ef41Sopenharmony_ci    # Progress
3801cb0ef41Sopenharmony_ci    parser.add_option("-p", "--progress",
3811cb0ef41Sopenharmony_ci                      choices=list(PROGRESS_INDICATORS.keys()), default="mono",
3821cb0ef41Sopenharmony_ci                      help="The style of progress indicator (verbose, dots, "
3831cb0ef41Sopenharmony_ci                           "color, mono)")
3841cb0ef41Sopenharmony_ci    parser.add_option("--json-test-results",
3851cb0ef41Sopenharmony_ci                      help="Path to a file for storing json results.")
3861cb0ef41Sopenharmony_ci    parser.add_option('--slow-tests-cutoff', type="int", default=100,
3871cb0ef41Sopenharmony_ci                      help='Collect N slowest tests')
3881cb0ef41Sopenharmony_ci    parser.add_option("--junitout", help="File name of the JUnit output")
3891cb0ef41Sopenharmony_ci    parser.add_option("--junittestsuite", default="v8tests",
3901cb0ef41Sopenharmony_ci                      help="The testsuite name in the JUnit output file")
3911cb0ef41Sopenharmony_ci    parser.add_option("--exit-after-n-failures", type="int", default=100,
3921cb0ef41Sopenharmony_ci                      help="Exit after the first N failures instead of "
3931cb0ef41Sopenharmony_ci                           "running all tests. Pass 0 to disable this feature.")
3941cb0ef41Sopenharmony_ci    parser.add_option("--ci-test-completion",
3951cb0ef41Sopenharmony_ci                      help="Path to a file for logging test completion in the "
3961cb0ef41Sopenharmony_ci                           "context of CI progress indicator. Ignored if "
3971cb0ef41Sopenharmony_ci                           "progress indicator is other than 'ci'.")
3981cb0ef41Sopenharmony_ci
3991cb0ef41Sopenharmony_ci    # Rerun
4001cb0ef41Sopenharmony_ci    parser.add_option("--rerun-failures-count", default=0, type=int,
4011cb0ef41Sopenharmony_ci                      help="Number of times to rerun each failing test case. "
4021cb0ef41Sopenharmony_ci                           "Very slow tests will be rerun only once.")
4031cb0ef41Sopenharmony_ci    parser.add_option("--rerun-failures-max", default=100, type=int,
4041cb0ef41Sopenharmony_ci                      help="Maximum number of failing test cases to rerun")
4051cb0ef41Sopenharmony_ci
4061cb0ef41Sopenharmony_ci    # Test config
4071cb0ef41Sopenharmony_ci    parser.add_option("--command-prefix", default="",
4081cb0ef41Sopenharmony_ci                      help="Prepended to each shell command used to run a test")
4091cb0ef41Sopenharmony_ci    parser.add_option('--dont-skip-slow-simulator-tests',
4101cb0ef41Sopenharmony_ci                      help='Don\'t skip more slow tests when using a'
4111cb0ef41Sopenharmony_ci                      ' simulator.', default=False, action='store_true',
4121cb0ef41Sopenharmony_ci                      dest='dont_skip_simulator_slow_tests')
4131cb0ef41Sopenharmony_ci    parser.add_option("--extra-flags", action="append", default=[],
4141cb0ef41Sopenharmony_ci                      help="Additional flags to pass to each test command")
4151cb0ef41Sopenharmony_ci    parser.add_option("--isolates", action="store_true", default=False,
4161cb0ef41Sopenharmony_ci                      help="Whether to test isolates")
4171cb0ef41Sopenharmony_ci    parser.add_option("--no-harness", "--noharness",
4181cb0ef41Sopenharmony_ci                      default=False, action="store_true",
4191cb0ef41Sopenharmony_ci                      help="Run without test harness of a given suite")
4201cb0ef41Sopenharmony_ci    parser.add_option("--random-seed", default=0, type=int,
4211cb0ef41Sopenharmony_ci                      help="Default seed for initializing random generator")
4221cb0ef41Sopenharmony_ci    parser.add_option("--run-skipped", help="Also run skipped tests.",
4231cb0ef41Sopenharmony_ci                      default=False, action="store_true")
4241cb0ef41Sopenharmony_ci    parser.add_option("-t", "--timeout", default=60, type=int,
4251cb0ef41Sopenharmony_ci                      help="Timeout for single test in seconds")
4261cb0ef41Sopenharmony_ci    parser.add_option("-v", "--verbose", default=False, action="store_true",
4271cb0ef41Sopenharmony_ci                      help="Verbose output")
4281cb0ef41Sopenharmony_ci    parser.add_option('--regenerate-expected-files', default=False, action='store_true',
4291cb0ef41Sopenharmony_ci                      help='Regenerate expected files')
4301cb0ef41Sopenharmony_ci
4311cb0ef41Sopenharmony_ci    # TODO(machenbach): Temporary options for rolling out new test runner
4321cb0ef41Sopenharmony_ci    # features.
4331cb0ef41Sopenharmony_ci    parser.add_option("--mastername", default='',
4341cb0ef41Sopenharmony_ci                      help="Mastername property from infrastructure. Not "
4351cb0ef41Sopenharmony_ci                           "setting this option indicates manual usage.")
4361cb0ef41Sopenharmony_ci    parser.add_option("--buildername", default='',
4371cb0ef41Sopenharmony_ci                      help="Buildername property from infrastructure. Not "
4381cb0ef41Sopenharmony_ci                           "setting this option indicates manual usage.")
4391cb0ef41Sopenharmony_ci
4401cb0ef41Sopenharmony_ci  def _add_parser_options(self, parser):
4411cb0ef41Sopenharmony_ci    pass
4421cb0ef41Sopenharmony_ci
4431cb0ef41Sopenharmony_ci  def _parse_args(self, parser, sys_args):
4441cb0ef41Sopenharmony_ci    options, args = parser.parse_args(sys_args)
4451cb0ef41Sopenharmony_ci
4461cb0ef41Sopenharmony_ci    if options.arch and ',' in options.arch:  # pragma: no cover
4471cb0ef41Sopenharmony_ci      print('Multiple architectures are deprecated')
4481cb0ef41Sopenharmony_ci      raise TestRunnerError()
4491cb0ef41Sopenharmony_ci
4501cb0ef41Sopenharmony_ci    return options, args
4511cb0ef41Sopenharmony_ci
4521cb0ef41Sopenharmony_ci  def _load_build_config(self, options):
4531cb0ef41Sopenharmony_ci    for outdir in self._possible_outdirs(options):
4541cb0ef41Sopenharmony_ci      try:
4551cb0ef41Sopenharmony_ci        self.build_config = _do_load_build_config(outdir, options.verbose)
4561cb0ef41Sopenharmony_ci
4571cb0ef41Sopenharmony_ci        # In auto-detect mode the outdir is always where we found the build config.
4581cb0ef41Sopenharmony_ci        # This ensures that we'll also take the build products from there.
4591cb0ef41Sopenharmony_ci        self.outdir = outdir
4601cb0ef41Sopenharmony_ci        break
4611cb0ef41Sopenharmony_ci      except TestRunnerError:
4621cb0ef41Sopenharmony_ci        pass
4631cb0ef41Sopenharmony_ci
4641cb0ef41Sopenharmony_ci    if not self.build_config:  # pragma: no cover
4651cb0ef41Sopenharmony_ci      print('Failed to load build config')
4661cb0ef41Sopenharmony_ci      raise TestRunnerError
4671cb0ef41Sopenharmony_ci
4681cb0ef41Sopenharmony_ci    print('Build found: %s' % self.outdir)
4691cb0ef41Sopenharmony_ci    if str(self.build_config):
4701cb0ef41Sopenharmony_ci      print('>>> Autodetected:')
4711cb0ef41Sopenharmony_ci      print(self.build_config)
4721cb0ef41Sopenharmony_ci
4731cb0ef41Sopenharmony_ci    # Represents the OS where tests are run on. Same as host OS except for
4741cb0ef41Sopenharmony_ci    # Android, which is determined by build output.
4751cb0ef41Sopenharmony_ci    if self.build_config.is_android:
4761cb0ef41Sopenharmony_ci      self.target_os = 'android'
4771cb0ef41Sopenharmony_ci    else:
4781cb0ef41Sopenharmony_ci      self.target_os = utils.GuessOS()
4791cb0ef41Sopenharmony_ci
4801cb0ef41Sopenharmony_ci  # Returns possible build paths in order:
4811cb0ef41Sopenharmony_ci  # gn
4821cb0ef41Sopenharmony_ci  # outdir
4831cb0ef41Sopenharmony_ci  # outdir on bots
4841cb0ef41Sopenharmony_ci  def _possible_outdirs(self, options):
4851cb0ef41Sopenharmony_ci    def outdirs():
4861cb0ef41Sopenharmony_ci      if options.gn:
4871cb0ef41Sopenharmony_ci        yield self._get_gn_outdir()
4881cb0ef41Sopenharmony_ci        return
4891cb0ef41Sopenharmony_ci
4901cb0ef41Sopenharmony_ci      yield options.outdir
4911cb0ef41Sopenharmony_ci
4921cb0ef41Sopenharmony_ci      if os.path.basename(options.outdir) != 'build':
4931cb0ef41Sopenharmony_ci        yield os.path.join(options.outdir, 'build')
4941cb0ef41Sopenharmony_ci
4951cb0ef41Sopenharmony_ci    for outdir in outdirs():
4961cb0ef41Sopenharmony_ci      yield os.path.join(self.basedir, outdir)
4971cb0ef41Sopenharmony_ci
4981cb0ef41Sopenharmony_ci  def _get_gn_outdir(self):
4991cb0ef41Sopenharmony_ci    gn_out_dir = os.path.join(self.basedir, DEFAULT_OUT_GN)
5001cb0ef41Sopenharmony_ci    latest_timestamp = -1
5011cb0ef41Sopenharmony_ci    latest_config = None
5021cb0ef41Sopenharmony_ci    for gn_config in os.listdir(gn_out_dir):
5031cb0ef41Sopenharmony_ci      gn_config_dir = os.path.join(gn_out_dir, gn_config)
5041cb0ef41Sopenharmony_ci      if not os.path.isdir(gn_config_dir):
5051cb0ef41Sopenharmony_ci        continue
5061cb0ef41Sopenharmony_ci      if os.path.getmtime(gn_config_dir) > latest_timestamp:
5071cb0ef41Sopenharmony_ci        latest_timestamp = os.path.getmtime(gn_config_dir)
5081cb0ef41Sopenharmony_ci        latest_config = gn_config
5091cb0ef41Sopenharmony_ci    if latest_config:
5101cb0ef41Sopenharmony_ci      print(">>> Latest GN build found: %s" % latest_config)
5111cb0ef41Sopenharmony_ci      return os.path.join(DEFAULT_OUT_GN, latest_config)
5121cb0ef41Sopenharmony_ci
5131cb0ef41Sopenharmony_ci  def _process_default_options(self, options):
5141cb0ef41Sopenharmony_ci    if self.build_config.is_debug:
5151cb0ef41Sopenharmony_ci      self.mode_options = DEBUG_MODE
5161cb0ef41Sopenharmony_ci    elif self.build_config.dcheck_always_on:
5171cb0ef41Sopenharmony_ci      self.mode_options = TRY_RELEASE_MODE
5181cb0ef41Sopenharmony_ci    else:
5191cb0ef41Sopenharmony_ci      self.mode_options = RELEASE_MODE
5201cb0ef41Sopenharmony_ci
5211cb0ef41Sopenharmony_ci    if options.arch and options.arch != self.build_config.arch:
5221cb0ef41Sopenharmony_ci      print('--arch value (%s) inconsistent with build config (%s).' % (
5231cb0ef41Sopenharmony_ci        options.arch, self.build_config.arch))
5241cb0ef41Sopenharmony_ci      raise TestRunnerError()
5251cb0ef41Sopenharmony_ci
5261cb0ef41Sopenharmony_ci    if options.shell_dir:  # pragma: no cover
5271cb0ef41Sopenharmony_ci      print('Warning: --shell-dir is deprecated. Searching for executables in '
5281cb0ef41Sopenharmony_ci            'build directory (%s) instead.' % self.outdir)
5291cb0ef41Sopenharmony_ci
5301cb0ef41Sopenharmony_ci    if options.j == 0:
5311cb0ef41Sopenharmony_ci      if self.build_config.is_android:
5321cb0ef41Sopenharmony_ci        # Adb isn't happy about multi-processed file pushing.
5331cb0ef41Sopenharmony_ci        options.j = 1
5341cb0ef41Sopenharmony_ci      else:
5351cb0ef41Sopenharmony_ci        options.j = multiprocessing.cpu_count()
5361cb0ef41Sopenharmony_ci
5371cb0ef41Sopenharmony_ci    options.command_prefix = shlex.split(options.command_prefix)
5381cb0ef41Sopenharmony_ci    options.extra_flags = sum(list(map(shlex.split, options.extra_flags)), [])
5391cb0ef41Sopenharmony_ci
5401cb0ef41Sopenharmony_ci  def _process_options(self, options):
5411cb0ef41Sopenharmony_ci    pass
5421cb0ef41Sopenharmony_ci
5431cb0ef41Sopenharmony_ci  def _setup_env(self):
5441cb0ef41Sopenharmony_ci    # Use the v8 root as cwd as some test cases use "load" with relative paths.
5451cb0ef41Sopenharmony_ci    os.chdir(self.basedir)
5461cb0ef41Sopenharmony_ci
5471cb0ef41Sopenharmony_ci    # Many tests assume an English interface.
5481cb0ef41Sopenharmony_ci    os.environ['LANG'] = 'en_US.UTF-8'
5491cb0ef41Sopenharmony_ci
5501cb0ef41Sopenharmony_ci    symbolizer_option = self._get_external_symbolizer_option()
5511cb0ef41Sopenharmony_ci
5521cb0ef41Sopenharmony_ci    if self.build_config.asan:
5531cb0ef41Sopenharmony_ci      asan_options = [
5541cb0ef41Sopenharmony_ci          symbolizer_option,
5551cb0ef41Sopenharmony_ci          'allow_user_segv_handler=1',
5561cb0ef41Sopenharmony_ci          'allocator_may_return_null=1',
5571cb0ef41Sopenharmony_ci      ]
5581cb0ef41Sopenharmony_ci      if not utils.GuessOS() in ['macos', 'windows']:
5591cb0ef41Sopenharmony_ci        # LSAN is not available on mac and windows.
5601cb0ef41Sopenharmony_ci        asan_options.append('detect_leaks=1')
5611cb0ef41Sopenharmony_ci      else:
5621cb0ef41Sopenharmony_ci        asan_options.append('detect_leaks=0')
5631cb0ef41Sopenharmony_ci      if utils.GuessOS() == 'windows':
5641cb0ef41Sopenharmony_ci        # https://crbug.com/967663
5651cb0ef41Sopenharmony_ci        asan_options.append('detect_stack_use_after_return=0')
5661cb0ef41Sopenharmony_ci      os.environ['ASAN_OPTIONS'] = ":".join(asan_options)
5671cb0ef41Sopenharmony_ci
5681cb0ef41Sopenharmony_ci    if self.build_config.cfi_vptr:
5691cb0ef41Sopenharmony_ci      os.environ['UBSAN_OPTIONS'] = ":".join([
5701cb0ef41Sopenharmony_ci        'print_stacktrace=1',
5711cb0ef41Sopenharmony_ci        'print_summary=1',
5721cb0ef41Sopenharmony_ci        'symbolize=1',
5731cb0ef41Sopenharmony_ci        symbolizer_option,
5741cb0ef41Sopenharmony_ci      ])
5751cb0ef41Sopenharmony_ci
5761cb0ef41Sopenharmony_ci    if self.build_config.ubsan_vptr:
5771cb0ef41Sopenharmony_ci      os.environ['UBSAN_OPTIONS'] = ":".join([
5781cb0ef41Sopenharmony_ci        'print_stacktrace=1',
5791cb0ef41Sopenharmony_ci        symbolizer_option,
5801cb0ef41Sopenharmony_ci      ])
5811cb0ef41Sopenharmony_ci
5821cb0ef41Sopenharmony_ci    if self.build_config.msan:
5831cb0ef41Sopenharmony_ci      os.environ['MSAN_OPTIONS'] = symbolizer_option
5841cb0ef41Sopenharmony_ci
5851cb0ef41Sopenharmony_ci    if self.build_config.tsan:
5861cb0ef41Sopenharmony_ci      suppressions_file = os.path.join(
5871cb0ef41Sopenharmony_ci          self.basedir,
5881cb0ef41Sopenharmony_ci          'tools',
5891cb0ef41Sopenharmony_ci          'sanitizers',
5901cb0ef41Sopenharmony_ci          'tsan_suppressions.txt')
5911cb0ef41Sopenharmony_ci      os.environ['TSAN_OPTIONS'] = " ".join([
5921cb0ef41Sopenharmony_ci        symbolizer_option,
5931cb0ef41Sopenharmony_ci        'suppressions=%s' % suppressions_file,
5941cb0ef41Sopenharmony_ci        'exit_code=0',
5951cb0ef41Sopenharmony_ci        'report_thread_leaks=0',
5961cb0ef41Sopenharmony_ci        'history_size=7',
5971cb0ef41Sopenharmony_ci        'report_destroy_locked=0',
5981cb0ef41Sopenharmony_ci      ])
5991cb0ef41Sopenharmony_ci
6001cb0ef41Sopenharmony_ci  def _get_external_symbolizer_option(self):
6011cb0ef41Sopenharmony_ci    external_symbolizer_path = os.path.join(
6021cb0ef41Sopenharmony_ci        self.basedir,
6031cb0ef41Sopenharmony_ci        'third_party',
6041cb0ef41Sopenharmony_ci        'llvm-build',
6051cb0ef41Sopenharmony_ci        'Release+Asserts',
6061cb0ef41Sopenharmony_ci        'bin',
6071cb0ef41Sopenharmony_ci        'llvm-symbolizer',
6081cb0ef41Sopenharmony_ci    )
6091cb0ef41Sopenharmony_ci
6101cb0ef41Sopenharmony_ci    if utils.IsWindows():
6111cb0ef41Sopenharmony_ci      # Quote, because sanitizers might confuse colon as option separator.
6121cb0ef41Sopenharmony_ci      external_symbolizer_path = '"%s.exe"' % external_symbolizer_path
6131cb0ef41Sopenharmony_ci
6141cb0ef41Sopenharmony_ci    return 'external_symbolizer_path=%s' % external_symbolizer_path
6151cb0ef41Sopenharmony_ci
6161cb0ef41Sopenharmony_ci  def _parse_test_args(self, args):
6171cb0ef41Sopenharmony_ci    if not args:
6181cb0ef41Sopenharmony_ci      args = self._get_default_suite_names()
6191cb0ef41Sopenharmony_ci
6201cb0ef41Sopenharmony_ci    # Expand arguments with grouped tests. The args should reflect the list
6211cb0ef41Sopenharmony_ci    # of suites as otherwise filters would break.
6221cb0ef41Sopenharmony_ci    def expand_test_group(name):
6231cb0ef41Sopenharmony_ci      return TEST_MAP.get(name, [name])
6241cb0ef41Sopenharmony_ci
6251cb0ef41Sopenharmony_ci    return reduce(list.__add__, list(map(expand_test_group, args)), [])
6261cb0ef41Sopenharmony_ci
6271cb0ef41Sopenharmony_ci  def _args_to_suite_names(self, args, test_root):
6281cb0ef41Sopenharmony_ci    # Use default tests if no test configuration was provided at the cmd line.
6291cb0ef41Sopenharmony_ci    all_names = set(utils.GetSuitePaths(test_root))
6301cb0ef41Sopenharmony_ci    args_names = OrderedDict([(arg.split('/')[0], None) for arg in args]) # set
6311cb0ef41Sopenharmony_ci    return [name for name in args_names if name in all_names]
6321cb0ef41Sopenharmony_ci
6331cb0ef41Sopenharmony_ci  def _get_default_suite_names(self):
6341cb0ef41Sopenharmony_ci    return []
6351cb0ef41Sopenharmony_ci
6361cb0ef41Sopenharmony_ci  def _load_testsuite_generators(self, args, options):
6371cb0ef41Sopenharmony_ci    names = self._args_to_suite_names(args, options.test_root)
6381cb0ef41Sopenharmony_ci    test_config = self._create_test_config(options)
6391cb0ef41Sopenharmony_ci    variables = self._get_statusfile_variables(options)
6401cb0ef41Sopenharmony_ci
6411cb0ef41Sopenharmony_ci    # Head generator with no elements
6421cb0ef41Sopenharmony_ci    test_chain = testsuite.TestGenerator(0, [], [])
6431cb0ef41Sopenharmony_ci    for name in names:
6441cb0ef41Sopenharmony_ci      if options.verbose:
6451cb0ef41Sopenharmony_ci        print('>>> Loading test suite: %s' % name)
6461cb0ef41Sopenharmony_ci      suite = testsuite.TestSuite.Load(
6471cb0ef41Sopenharmony_ci          os.path.join(options.test_root, name), test_config,
6481cb0ef41Sopenharmony_ci          self.framework_name)
6491cb0ef41Sopenharmony_ci
6501cb0ef41Sopenharmony_ci      if self._is_testsuite_supported(suite, options):
6511cb0ef41Sopenharmony_ci        tests = suite.load_tests_from_disk(variables)
6521cb0ef41Sopenharmony_ci        test_chain.merge(tests)
6531cb0ef41Sopenharmony_ci
6541cb0ef41Sopenharmony_ci    return test_chain
6551cb0ef41Sopenharmony_ci
6561cb0ef41Sopenharmony_ci  def _is_testsuite_supported(self, suite, options):
6571cb0ef41Sopenharmony_ci    """A predicate that can be overridden to filter out unsupported TestSuite
6581cb0ef41Sopenharmony_ci    instances (see NumFuzzer for usage)."""
6591cb0ef41Sopenharmony_ci    return True
6601cb0ef41Sopenharmony_ci
6611cb0ef41Sopenharmony_ci  def _get_statusfile_variables(self, options):
6621cb0ef41Sopenharmony_ci    simd_mips = (
6631cb0ef41Sopenharmony_ci      self.build_config.arch in ['mipsel', 'mips', 'mips64', 'mips64el'] and
6641cb0ef41Sopenharmony_ci      self.build_config.mips_arch_variant == "r6" and
6651cb0ef41Sopenharmony_ci      self.build_config.mips_use_msa)
6661cb0ef41Sopenharmony_ci
6671cb0ef41Sopenharmony_ci    mips_arch_variant = (
6681cb0ef41Sopenharmony_ci      self.build_config.arch in ['mipsel', 'mips', 'mips64', 'mips64el'] and
6691cb0ef41Sopenharmony_ci      self.build_config.mips_arch_variant)
6701cb0ef41Sopenharmony_ci
6711cb0ef41Sopenharmony_ci    no_simd_hardware = any(
6721cb0ef41Sopenharmony_ci        i in options.extra_flags for i in ['--noenable-sse3',
6731cb0ef41Sopenharmony_ci                                           '--no-enable-sse3',
6741cb0ef41Sopenharmony_ci                                           '--noenable-ssse3',
6751cb0ef41Sopenharmony_ci                                           '--no-enable-ssse3',
6761cb0ef41Sopenharmony_ci                                           '--noenable-sse4-1',
6771cb0ef41Sopenharmony_ci                                           '--no-enable-sse4_1'])
6781cb0ef41Sopenharmony_ci
6791cb0ef41Sopenharmony_ci    # Set no_simd_hardware on architectures without Simd enabled.
6801cb0ef41Sopenharmony_ci    if self.build_config.arch == 'mips64el' or \
6811cb0ef41Sopenharmony_ci       self.build_config.arch == 'mipsel':
6821cb0ef41Sopenharmony_ci       no_simd_hardware = not simd_mips
6831cb0ef41Sopenharmony_ci
6841cb0ef41Sopenharmony_ci    if self.build_config.arch == 'loong64':
6851cb0ef41Sopenharmony_ci       no_simd_hardware = True
6861cb0ef41Sopenharmony_ci
6871cb0ef41Sopenharmony_ci    # S390 hosts without VEF1 do not support Simd.
6881cb0ef41Sopenharmony_ci    if self.build_config.arch == 's390x' and \
6891cb0ef41Sopenharmony_ci       not self.build_config.simulator_run and \
6901cb0ef41Sopenharmony_ci       not utils.IsS390SimdSupported():
6911cb0ef41Sopenharmony_ci       no_simd_hardware = True
6921cb0ef41Sopenharmony_ci
6931cb0ef41Sopenharmony_ci    # Ppc64 processors earlier than POWER9 do not support Simd instructions
6941cb0ef41Sopenharmony_ci    if self.build_config.arch == 'ppc64' and \
6951cb0ef41Sopenharmony_ci       not self.build_config.simulator_run and \
6961cb0ef41Sopenharmony_ci       utils.GuessPowerProcessorVersion() < 9:
6971cb0ef41Sopenharmony_ci       no_simd_hardware = True
6981cb0ef41Sopenharmony_ci
6991cb0ef41Sopenharmony_ci    return {
7001cb0ef41Sopenharmony_ci      "arch": self.build_config.arch,
7011cb0ef41Sopenharmony_ci      "asan": self.build_config.asan,
7021cb0ef41Sopenharmony_ci      "byteorder": sys.byteorder,
7031cb0ef41Sopenharmony_ci      "cfi_vptr": self.build_config.cfi_vptr,
7041cb0ef41Sopenharmony_ci      "control_flow_integrity": self.build_config.control_flow_integrity,
7051cb0ef41Sopenharmony_ci      "concurrent_marking": self.build_config.concurrent_marking,
7061cb0ef41Sopenharmony_ci      "single_generation": self.build_config.single_generation,
7071cb0ef41Sopenharmony_ci      "dcheck_always_on": self.build_config.dcheck_always_on,
7081cb0ef41Sopenharmony_ci      "deopt_fuzzer": False,
7091cb0ef41Sopenharmony_ci      "endurance_fuzzer": False,
7101cb0ef41Sopenharmony_ci      "gc_fuzzer": False,
7111cb0ef41Sopenharmony_ci      "gc_stress": False,
7121cb0ef41Sopenharmony_ci      "gcov_coverage": self.build_config.gcov_coverage,
7131cb0ef41Sopenharmony_ci      "has_webassembly": self.build_config.webassembly,
7141cb0ef41Sopenharmony_ci      "isolates": options.isolates,
7151cb0ef41Sopenharmony_ci      "is_clang": self.build_config.is_clang,
7161cb0ef41Sopenharmony_ci      "is_full_debug": self.build_config.is_full_debug,
7171cb0ef41Sopenharmony_ci      "mips_arch_variant": mips_arch_variant,
7181cb0ef41Sopenharmony_ci      "mode": self.mode_options.status_mode,
7191cb0ef41Sopenharmony_ci      "msan": self.build_config.msan,
7201cb0ef41Sopenharmony_ci      "no_harness": options.no_harness,
7211cb0ef41Sopenharmony_ci      "no_i18n": self.build_config.no_i18n,
7221cb0ef41Sopenharmony_ci      "no_simd_hardware": no_simd_hardware,
7231cb0ef41Sopenharmony_ci      "novfp3": False,
7241cb0ef41Sopenharmony_ci      "optimize_for_size": "--optimize-for-size" in options.extra_flags,
7251cb0ef41Sopenharmony_ci      "predictable": self.build_config.predictable,
7261cb0ef41Sopenharmony_ci      "simd_mips": simd_mips,
7271cb0ef41Sopenharmony_ci      "simulator_run": self.build_config.simulator_run and
7281cb0ef41Sopenharmony_ci                       not options.dont_skip_simulator_slow_tests,
7291cb0ef41Sopenharmony_ci      "system": self.target_os,
7301cb0ef41Sopenharmony_ci      "third_party_heap": self.build_config.third_party_heap,
7311cb0ef41Sopenharmony_ci      "tsan": self.build_config.tsan,
7321cb0ef41Sopenharmony_ci      "ubsan_vptr": self.build_config.ubsan_vptr,
7331cb0ef41Sopenharmony_ci      "verify_csa": self.build_config.verify_csa,
7341cb0ef41Sopenharmony_ci      "lite_mode": self.build_config.lite_mode,
7351cb0ef41Sopenharmony_ci      "pointer_compression": self.build_config.pointer_compression,
7361cb0ef41Sopenharmony_ci      "pointer_compression_shared_cage": self.build_config.pointer_compression_shared_cage,
7371cb0ef41Sopenharmony_ci      "no_js_shared_memory": (not self.build_config.shared_ro_heap) or
7381cb0ef41Sopenharmony_ci                             (self.build_config.pointer_compression and
7391cb0ef41Sopenharmony_ci                              not self.build_config.pointer_compression_shared_cage),
7401cb0ef41Sopenharmony_ci      "sandbox": self.build_config.sandbox,
7411cb0ef41Sopenharmony_ci      "dict_property_const_tracking": self.build_config.dict_property_const_tracking,
7421cb0ef41Sopenharmony_ci    }
7431cb0ef41Sopenharmony_ci
7441cb0ef41Sopenharmony_ci  def _runner_flags(self):
7451cb0ef41Sopenharmony_ci    """Extra default flags specific to the test runner implementation."""
7461cb0ef41Sopenharmony_ci    return []
7471cb0ef41Sopenharmony_ci
7481cb0ef41Sopenharmony_ci  def _create_test_config(self, options):
7491cb0ef41Sopenharmony_ci    timeout = options.timeout * self._timeout_scalefactor(options)
7501cb0ef41Sopenharmony_ci    return TestConfig(
7511cb0ef41Sopenharmony_ci        command_prefix=options.command_prefix,
7521cb0ef41Sopenharmony_ci        extra_flags=options.extra_flags,
7531cb0ef41Sopenharmony_ci        isolates=options.isolates,
7541cb0ef41Sopenharmony_ci        mode_flags=self.mode_options.flags + self._runner_flags(),
7551cb0ef41Sopenharmony_ci        no_harness=options.no_harness,
7561cb0ef41Sopenharmony_ci        noi18n=self.build_config.no_i18n,
7571cb0ef41Sopenharmony_ci        random_seed=options.random_seed,
7581cb0ef41Sopenharmony_ci        run_skipped=options.run_skipped,
7591cb0ef41Sopenharmony_ci        shell_dir=self.outdir,
7601cb0ef41Sopenharmony_ci        timeout=timeout,
7611cb0ef41Sopenharmony_ci        verbose=options.verbose,
7621cb0ef41Sopenharmony_ci        regenerate_expected_files=options.regenerate_expected_files,
7631cb0ef41Sopenharmony_ci    )
7641cb0ef41Sopenharmony_ci
7651cb0ef41Sopenharmony_ci  def _timeout_scalefactor(self, options):
7661cb0ef41Sopenharmony_ci    """Increases timeout for slow build configurations."""
7671cb0ef41Sopenharmony_ci    factor = self.mode_options.timeout_scalefactor
7681cb0ef41Sopenharmony_ci    if self.build_config.arch in SLOW_ARCHS:
7691cb0ef41Sopenharmony_ci      factor *= 4.5
7701cb0ef41Sopenharmony_ci    if self.build_config.lite_mode:
7711cb0ef41Sopenharmony_ci      factor *= 2
7721cb0ef41Sopenharmony_ci    if self.build_config.predictable:
7731cb0ef41Sopenharmony_ci      factor *= 4
7741cb0ef41Sopenharmony_ci    if self.build_config.tsan:
7751cb0ef41Sopenharmony_ci      factor *= 2
7761cb0ef41Sopenharmony_ci    if self.build_config.use_sanitizer:
7771cb0ef41Sopenharmony_ci      factor *= 1.5
7781cb0ef41Sopenharmony_ci    if self.build_config.is_full_debug:
7791cb0ef41Sopenharmony_ci      factor *= 4
7801cb0ef41Sopenharmony_ci
7811cb0ef41Sopenharmony_ci    return factor
7821cb0ef41Sopenharmony_ci
7831cb0ef41Sopenharmony_ci  # TODO(majeski): remove options & args parameters
7841cb0ef41Sopenharmony_ci  def _do_execute(self, suites, args, options):
7851cb0ef41Sopenharmony_ci    raise NotImplementedError()
7861cb0ef41Sopenharmony_ci
7871cb0ef41Sopenharmony_ci  def _prepare_procs(self, procs):
7881cb0ef41Sopenharmony_ci    procs = list([_f for _f in procs if _f])
7891cb0ef41Sopenharmony_ci    for i in range(0, len(procs) - 1):
7901cb0ef41Sopenharmony_ci      procs[i].connect_to(procs[i + 1])
7911cb0ef41Sopenharmony_ci    procs[0].setup()
7921cb0ef41Sopenharmony_ci
7931cb0ef41Sopenharmony_ci  def _create_shard_proc(self, options):
7941cb0ef41Sopenharmony_ci    myid, count = self._get_shard_info(options)
7951cb0ef41Sopenharmony_ci    if count == 1:
7961cb0ef41Sopenharmony_ci      return None
7971cb0ef41Sopenharmony_ci    return ShardProc(myid - 1, count)
7981cb0ef41Sopenharmony_ci
7991cb0ef41Sopenharmony_ci  def _get_shard_info(self, options):
8001cb0ef41Sopenharmony_ci    """
8011cb0ef41Sopenharmony_ci    Returns pair:
8021cb0ef41Sopenharmony_ci      (id of the current shard [1; number of shards], number of shards)
8031cb0ef41Sopenharmony_ci    """
8041cb0ef41Sopenharmony_ci    # Read gtest shard configuration from environment (e.g. set by swarming).
8051cb0ef41Sopenharmony_ci    # If none is present, use values passed on the command line.
8061cb0ef41Sopenharmony_ci    shard_count = int(
8071cb0ef41Sopenharmony_ci      os.environ.get('GTEST_TOTAL_SHARDS', options.shard_count))
8081cb0ef41Sopenharmony_ci    shard_run = os.environ.get('GTEST_SHARD_INDEX')
8091cb0ef41Sopenharmony_ci    if shard_run is not None:
8101cb0ef41Sopenharmony_ci      # The v8 shard_run starts at 1, while GTEST_SHARD_INDEX starts at 0.
8111cb0ef41Sopenharmony_ci      shard_run = int(shard_run) + 1
8121cb0ef41Sopenharmony_ci    else:
8131cb0ef41Sopenharmony_ci      shard_run = options.shard_run
8141cb0ef41Sopenharmony_ci
8151cb0ef41Sopenharmony_ci    if options.shard_count > 1:
8161cb0ef41Sopenharmony_ci      # Log if a value was passed on the cmd line and it differs from the
8171cb0ef41Sopenharmony_ci      # environment variables.
8181cb0ef41Sopenharmony_ci      if options.shard_count != shard_count:  # pragma: no cover
8191cb0ef41Sopenharmony_ci        print("shard_count from cmd line differs from environment variable "
8201cb0ef41Sopenharmony_ci              "GTEST_TOTAL_SHARDS")
8211cb0ef41Sopenharmony_ci      if (options.shard_run > 1 and
8221cb0ef41Sopenharmony_ci          options.shard_run != shard_run):  # pragma: no cover
8231cb0ef41Sopenharmony_ci        print("shard_run from cmd line differs from environment variable "
8241cb0ef41Sopenharmony_ci              "GTEST_SHARD_INDEX")
8251cb0ef41Sopenharmony_ci
8261cb0ef41Sopenharmony_ci    if shard_run < 1 or shard_run > shard_count:
8271cb0ef41Sopenharmony_ci      # TODO(machenbach): Turn this into an assert. If that's wrong on the
8281cb0ef41Sopenharmony_ci      # bots, printing will be quite useless. Or refactor this code to make
8291cb0ef41Sopenharmony_ci      # sure we get a return code != 0 after testing if we got here.
8301cb0ef41Sopenharmony_ci      print("shard-run not a valid number, should be in [1:shard-count]")
8311cb0ef41Sopenharmony_ci      print("defaulting back to running all tests")
8321cb0ef41Sopenharmony_ci      return 1, 1
8331cb0ef41Sopenharmony_ci
8341cb0ef41Sopenharmony_ci    return shard_run, shard_count
8351cb0ef41Sopenharmony_ci
8361cb0ef41Sopenharmony_ci  def _create_progress_indicators(self, test_count, options):
8371cb0ef41Sopenharmony_ci    procs = [PROGRESS_INDICATORS[options.progress]()]
8381cb0ef41Sopenharmony_ci    if options.junitout:
8391cb0ef41Sopenharmony_ci      procs.append(progress.JUnitTestProgressIndicator(options.junitout,
8401cb0ef41Sopenharmony_ci                                                       options.junittestsuite))
8411cb0ef41Sopenharmony_ci    if options.json_test_results:
8421cb0ef41Sopenharmony_ci      procs.append(progress.JsonTestProgressIndicator(self.framework_name))
8431cb0ef41Sopenharmony_ci
8441cb0ef41Sopenharmony_ci    for proc in procs:
8451cb0ef41Sopenharmony_ci      proc.configure(options)
8461cb0ef41Sopenharmony_ci
8471cb0ef41Sopenharmony_ci    for proc in procs:
8481cb0ef41Sopenharmony_ci      try:
8491cb0ef41Sopenharmony_ci        proc.set_test_count(test_count)
8501cb0ef41Sopenharmony_ci      except AttributeError:
8511cb0ef41Sopenharmony_ci        pass
8521cb0ef41Sopenharmony_ci
8531cb0ef41Sopenharmony_ci    return procs
8541cb0ef41Sopenharmony_ci
8551cb0ef41Sopenharmony_ci  def _create_result_tracker(self, options):
8561cb0ef41Sopenharmony_ci    return progress.ResultsTracker(options.exit_after_n_failures)
8571cb0ef41Sopenharmony_ci
8581cb0ef41Sopenharmony_ci  def _create_timeout_proc(self, options):
8591cb0ef41Sopenharmony_ci    if not options.total_timeout_sec:
8601cb0ef41Sopenharmony_ci      return None
8611cb0ef41Sopenharmony_ci    return TimeoutProc(options.total_timeout_sec)
8621cb0ef41Sopenharmony_ci
8631cb0ef41Sopenharmony_ci  def _create_signal_proc(self):
8641cb0ef41Sopenharmony_ci    return SignalProc()
8651cb0ef41Sopenharmony_ci
8661cb0ef41Sopenharmony_ci  def _create_rerun_proc(self, options):
8671cb0ef41Sopenharmony_ci    if not options.rerun_failures_count:
8681cb0ef41Sopenharmony_ci      return None
8691cb0ef41Sopenharmony_ci    return RerunProc(options.rerun_failures_count,
8701cb0ef41Sopenharmony_ci                     options.rerun_failures_max)
871