xref: /aosp_15_r20/art/test/testrunner/testrunner.py (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*795d594fSAndroid Build Coastguard Worker#
3*795d594fSAndroid Build Coastguard Worker# [VPYTHON:BEGIN]
4*795d594fSAndroid Build Coastguard Worker# python_version: "3.8"
5*795d594fSAndroid Build Coastguard Worker# [VPYTHON:END]
6*795d594fSAndroid Build Coastguard Worker#
7*795d594fSAndroid Build Coastguard Worker# Copyright 2017, The Android Open Source Project
8*795d594fSAndroid Build Coastguard Worker#
9*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
10*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
11*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at
12*795d594fSAndroid Build Coastguard Worker#
13*795d594fSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
14*795d594fSAndroid Build Coastguard Worker#
15*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
16*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
17*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
19*795d594fSAndroid Build Coastguard Worker# limitations under the License.
20*795d594fSAndroid Build Coastguard Worker
21*795d594fSAndroid Build Coastguard Worker"""ART Run-Test TestRunner
22*795d594fSAndroid Build Coastguard Worker
23*795d594fSAndroid Build Coastguard WorkerThe testrunner runs the ART run-tests by simply invoking the script.
24*795d594fSAndroid Build Coastguard WorkerIt fetches the list of eligible tests from art/test directory, and list of
25*795d594fSAndroid Build Coastguard Workerdisabled tests from art/test/knownfailures.json. It runs the tests by
26*795d594fSAndroid Build Coastguard Workerinvoking art/test/run-test script and checks the exit value to decide if the
27*795d594fSAndroid Build Coastguard Workertest passed or failed.
28*795d594fSAndroid Build Coastguard Worker
29*795d594fSAndroid Build Coastguard WorkerBefore invoking the script, first build all the tests dependencies.
30*795d594fSAndroid Build Coastguard WorkerThere are two major build targets for building target and host tests
31*795d594fSAndroid Build Coastguard Workerdependencies:
32*795d594fSAndroid Build Coastguard Worker1) test-art-host-run-test
33*795d594fSAndroid Build Coastguard Worker2) test-art-target-run-test
34*795d594fSAndroid Build Coastguard Worker
35*795d594fSAndroid Build Coastguard WorkerThere are various options to invoke the script which are:
36*795d594fSAndroid Build Coastguard Worker-t: Either the test name as in art/test or the test name including the variant
37*795d594fSAndroid Build Coastguard Worker    information. Eg, "-t 001-HelloWorld",
38*795d594fSAndroid Build Coastguard Worker    "-t test-art-host-run-test-debug-prebuild-optimizing-relocate-ntrace-cms-checkjni-picimage-ndebuggable-no-jvmti-001-HelloWorld32"
39*795d594fSAndroid Build Coastguard Worker-j: Number of thread workers to be used. Eg - "-j64"
40*795d594fSAndroid Build Coastguard Worker--dry-run: Instead of running the test name, just print its name.
41*795d594fSAndroid Build Coastguard Worker--verbose
42*795d594fSAndroid Build Coastguard Worker-b / --build-dependencies: to build the dependencies before running the test
43*795d594fSAndroid Build Coastguard Worker
44*795d594fSAndroid Build Coastguard WorkerTo specify any specific variants for the test, use --<<variant-name>>.
45*795d594fSAndroid Build Coastguard WorkerFor eg, for compiler type as optimizing, use --optimizing.
46*795d594fSAndroid Build Coastguard Worker
47*795d594fSAndroid Build Coastguard Worker
48*795d594fSAndroid Build Coastguard WorkerIn the end, the script will print the failed and skipped tests if any.
49*795d594fSAndroid Build Coastguard Worker
50*795d594fSAndroid Build Coastguard Worker"""
51*795d594fSAndroid Build Coastguard Workerimport argparse
52*795d594fSAndroid Build Coastguard Workerimport collections
53*795d594fSAndroid Build Coastguard Worker
54*795d594fSAndroid Build Coastguard Worker# b/140161314 diagnostics.
55*795d594fSAndroid Build Coastguard Workertry:
56*795d594fSAndroid Build Coastguard Worker  import concurrent.futures
57*795d594fSAndroid Build Coastguard Workerexcept Exception:
58*795d594fSAndroid Build Coastguard Worker  import sys
59*795d594fSAndroid Build Coastguard Worker  sys.stdout.write("\n\n" + sys.executable + " " + sys.version + "\n\n")
60*795d594fSAndroid Build Coastguard Worker  sys.stdout.flush()
61*795d594fSAndroid Build Coastguard Worker  raise
62*795d594fSAndroid Build Coastguard Worker
63*795d594fSAndroid Build Coastguard Workerimport csv
64*795d594fSAndroid Build Coastguard Workerimport datetime
65*795d594fSAndroid Build Coastguard Workerimport fnmatch
66*795d594fSAndroid Build Coastguard Workerimport itertools
67*795d594fSAndroid Build Coastguard Workerimport json
68*795d594fSAndroid Build Coastguard Workerimport multiprocessing
69*795d594fSAndroid Build Coastguard Workerimport os
70*795d594fSAndroid Build Coastguard Workerimport re
71*795d594fSAndroid Build Coastguard Workerimport shlex
72*795d594fSAndroid Build Coastguard Workerimport shutil
73*795d594fSAndroid Build Coastguard Workerimport signal
74*795d594fSAndroid Build Coastguard Workerimport subprocess
75*795d594fSAndroid Build Coastguard Workerimport sys
76*795d594fSAndroid Build Coastguard Workerimport tempfile
77*795d594fSAndroid Build Coastguard Workerimport threading
78*795d594fSAndroid Build Coastguard Workerimport time
79*795d594fSAndroid Build Coastguard Worker
80*795d594fSAndroid Build Coastguard Workerimport env
81*795d594fSAndroid Build Coastguard Workerfrom target_config import target_config
82*795d594fSAndroid Build Coastguard Workerfrom device_config import device_config
83*795d594fSAndroid Build Coastguard Workerfrom typing import Dict, Set, List
84*795d594fSAndroid Build Coastguard Workerfrom functools import lru_cache
85*795d594fSAndroid Build Coastguard Workerfrom pathlib import Path
86*795d594fSAndroid Build Coastguard Worker
87*795d594fSAndroid Build Coastguard Worker# TODO: make it adjustable per tests and for buildbots
88*795d594fSAndroid Build Coastguard Worker#
89*795d594fSAndroid Build Coastguard Worker# Note: this needs to be larger than run-test timeouts, as long as this script
90*795d594fSAndroid Build Coastguard Worker#       does not push the value to run-test. run-test is somewhat complicated:
91*795d594fSAndroid Build Coastguard Worker#                      base: 25m  (large for ASAN)
92*795d594fSAndroid Build Coastguard Worker#        + timeout handling:  2m
93*795d594fSAndroid Build Coastguard Worker#        +   gcstress extra: 20m
94*795d594fSAndroid Build Coastguard Worker#        -----------------------
95*795d594fSAndroid Build Coastguard Worker#                            47m
96*795d594fSAndroid Build Coastguard Workertimeout = 3600 # 60 minutes
97*795d594fSAndroid Build Coastguard Worker
98*795d594fSAndroid Build Coastguard Workerif env.ART_TEST_RUN_ON_ARM_FVP:
99*795d594fSAndroid Build Coastguard Worker  # Increase timeout to 600 minutes due to the emulation overhead on FVP.
100*795d594fSAndroid Build Coastguard Worker  timeout = 36000
101*795d594fSAndroid Build Coastguard Worker
102*795d594fSAndroid Build Coastguard Worker# DISABLED_TEST_CONTAINER holds information about the disabled tests. It is a map
103*795d594fSAndroid Build Coastguard Worker# that has key as the test name (like 001-HelloWorld), and value as set of
104*795d594fSAndroid Build Coastguard Worker# variants that the test is disabled for.
105*795d594fSAndroid Build Coastguard WorkerDISABLED_TEST_CONTAINER = {}
106*795d594fSAndroid Build Coastguard Worker
107*795d594fSAndroid Build Coastguard Worker# The Dict contains the list of all possible variants for a given type. For example,
108*795d594fSAndroid Build Coastguard Worker# for key TARGET, the value would be target and host. The list is used to parse
109*795d594fSAndroid Build Coastguard Worker# the test name given as the argument to run.
110*795d594fSAndroid Build Coastguard WorkerVARIANT_TYPE_DICT: Dict[str, Set[str]] = {}
111*795d594fSAndroid Build Coastguard Worker
112*795d594fSAndroid Build Coastguard Worker# The set of all variant sets that are incompatible and will always be skipped.
113*795d594fSAndroid Build Coastguard WorkerNONFUNCTIONAL_VARIANT_SETS = set()
114*795d594fSAndroid Build Coastguard Worker
115*795d594fSAndroid Build Coastguard Worker# The set contains all the variants of each time.
116*795d594fSAndroid Build Coastguard WorkerTOTAL_VARIANTS_SET: Set[str] = set()
117*795d594fSAndroid Build Coastguard Worker
118*795d594fSAndroid Build Coastguard Worker# The colors are used in the output. When a test passes, COLOR_PASS is used,
119*795d594fSAndroid Build Coastguard Worker# and so on.
120*795d594fSAndroid Build Coastguard WorkerCOLOR_ERROR = '\033[91m'
121*795d594fSAndroid Build Coastguard WorkerCOLOR_PASS = '\033[92m'
122*795d594fSAndroid Build Coastguard WorkerCOLOR_SKIP = '\033[93m'
123*795d594fSAndroid Build Coastguard WorkerCOLOR_NORMAL = '\033[0m'
124*795d594fSAndroid Build Coastguard Worker
125*795d594fSAndroid Build Coastguard Worker# The set contains the list of all the possible run tests that are in art/test
126*795d594fSAndroid Build Coastguard Worker# directory.
127*795d594fSAndroid Build Coastguard WorkerRUN_TEST_SET = set()
128*795d594fSAndroid Build Coastguard Worker
129*795d594fSAndroid Build Coastguard Workerfailed_tests = []
130*795d594fSAndroid Build Coastguard Workerskipped_tests = []
131*795d594fSAndroid Build Coastguard Worker
132*795d594fSAndroid Build Coastguard Worker# Flags
133*795d594fSAndroid Build Coastguard Workern_thread = 0
134*795d594fSAndroid Build Coastguard Workertotal_test_count = 0
135*795d594fSAndroid Build Coastguard Workerverbose = False
136*795d594fSAndroid Build Coastguard Workerdry_run = False
137*795d594fSAndroid Build Coastguard Workerignore_skips = False
138*795d594fSAndroid Build Coastguard Workerbuild = False
139*795d594fSAndroid Build Coastguard Workerdist = False
140*795d594fSAndroid Build Coastguard Workergdb = False
141*795d594fSAndroid Build Coastguard Workergdb_arg = ''
142*795d594fSAndroid Build Coastguard Workerdump_cfg = ''
143*795d594fSAndroid Build Coastguard Workergdb_dex2oat = False
144*795d594fSAndroid Build Coastguard Workergdb_dex2oat_args = ''
145*795d594fSAndroid Build Coastguard Workercsv_result = None
146*795d594fSAndroid Build Coastguard Workercsv_writer = None
147*795d594fSAndroid Build Coastguard Workerruntime_option = ''
148*795d594fSAndroid Build Coastguard Workerwith_agent: List[str] = []
149*795d594fSAndroid Build Coastguard Workerrun_test_option: List[str] = []
150*795d594fSAndroid Build Coastguard Workerdex2oat_jobs = -1   # -1 corresponds to default threads for dex2oat
151*795d594fSAndroid Build Coastguard Workerrun_all_configs = False
152*795d594fSAndroid Build Coastguard Worker
153*795d594fSAndroid Build Coastguard Worker# Dict containing extra arguments
154*795d594fSAndroid Build Coastguard Workerextra_arguments: Dict[str, List[str]] = { "host" : [], "target" : [] }
155*795d594fSAndroid Build Coastguard Worker
156*795d594fSAndroid Build Coastguard Worker# Dict to store user requested test variants.
157*795d594fSAndroid Build Coastguard Worker# key: variant_type.
158*795d594fSAndroid Build Coastguard Worker# value: set of variants user wants to run of type <key>.
159*795d594fSAndroid Build Coastguard Worker_user_input_variants: collections.defaultdict = collections.defaultdict(set)
160*795d594fSAndroid Build Coastguard Worker
161*795d594fSAndroid Build Coastguard Worker
162*795d594fSAndroid Build Coastguard Workerclass ChildProcessTracker(object):
163*795d594fSAndroid Build Coastguard Worker  """Keeps track of forked child processes to be able to kill them."""
164*795d594fSAndroid Build Coastguard Worker
165*795d594fSAndroid Build Coastguard Worker  def __init__(self):
166*795d594fSAndroid Build Coastguard Worker    self.procs = {}             # dict from pid to subprocess.Popen object
167*795d594fSAndroid Build Coastguard Worker    self.mutex = threading.Lock()
168*795d594fSAndroid Build Coastguard Worker
169*795d594fSAndroid Build Coastguard Worker  def wait(self, proc, timeout):
170*795d594fSAndroid Build Coastguard Worker    """Waits on the given subprocess and makes it available to kill_all meanwhile.
171*795d594fSAndroid Build Coastguard Worker
172*795d594fSAndroid Build Coastguard Worker    Args:
173*795d594fSAndroid Build Coastguard Worker      proc: The subprocess.Popen object to wait on.
174*795d594fSAndroid Build Coastguard Worker      timeout: Timeout passed on to proc.communicate.
175*795d594fSAndroid Build Coastguard Worker
176*795d594fSAndroid Build Coastguard Worker    Returns: A tuple of the process stdout output and its return value.
177*795d594fSAndroid Build Coastguard Worker    """
178*795d594fSAndroid Build Coastguard Worker    with self.mutex:
179*795d594fSAndroid Build Coastguard Worker      if self.procs is not None:
180*795d594fSAndroid Build Coastguard Worker        self.procs[proc.pid] = proc
181*795d594fSAndroid Build Coastguard Worker      else:
182*795d594fSAndroid Build Coastguard Worker        os.killpg(proc.pid, signal.SIGKILL) # kill_all has already been called.
183*795d594fSAndroid Build Coastguard Worker    try:
184*795d594fSAndroid Build Coastguard Worker      output = proc.communicate(timeout=timeout)[0]
185*795d594fSAndroid Build Coastguard Worker      return_value = proc.wait()
186*795d594fSAndroid Build Coastguard Worker      return output, return_value
187*795d594fSAndroid Build Coastguard Worker    finally:
188*795d594fSAndroid Build Coastguard Worker      with self.mutex:
189*795d594fSAndroid Build Coastguard Worker        if self.procs is not None:
190*795d594fSAndroid Build Coastguard Worker          del self.procs[proc.pid]
191*795d594fSAndroid Build Coastguard Worker
192*795d594fSAndroid Build Coastguard Worker  def kill_all(self):
193*795d594fSAndroid Build Coastguard Worker    """Kills all currently running processes and any future ones."""
194*795d594fSAndroid Build Coastguard Worker    with self.mutex:
195*795d594fSAndroid Build Coastguard Worker      for pid in self.procs:
196*795d594fSAndroid Build Coastguard Worker        os.killpg(pid, signal.SIGKILL)
197*795d594fSAndroid Build Coastguard Worker      self.procs = None # Make future wait() calls kill their processes immediately.
198*795d594fSAndroid Build Coastguard Worker
199*795d594fSAndroid Build Coastguard Workerchild_process_tracker = ChildProcessTracker()
200*795d594fSAndroid Build Coastguard Worker
201*795d594fSAndroid Build Coastguard Workerdef setup_csv_result():
202*795d594fSAndroid Build Coastguard Worker  """Set up the CSV output if required."""
203*795d594fSAndroid Build Coastguard Worker  global csv_writer
204*795d594fSAndroid Build Coastguard Worker  csv_writer = csv.writer(csv_result)
205*795d594fSAndroid Build Coastguard Worker  # Write the header.
206*795d594fSAndroid Build Coastguard Worker  csv_writer.writerow(['target', 'run', 'prebuild', 'compiler', 'relocate', 'trace', 'gc',
207*795d594fSAndroid Build Coastguard Worker                       'jni', 'image', 'debuggable', 'jvmti', 'test', 'address_size', 'result'])
208*795d594fSAndroid Build Coastguard Worker
209*795d594fSAndroid Build Coastguard Worker
210*795d594fSAndroid Build Coastguard Workerdef send_csv_result(test, result):
211*795d594fSAndroid Build Coastguard Worker  """
212*795d594fSAndroid Build Coastguard Worker  Write a line into the CSV results file if one is available.
213*795d594fSAndroid Build Coastguard Worker  """
214*795d594fSAndroid Build Coastguard Worker  if csv_writer is not None:
215*795d594fSAndroid Build Coastguard Worker    csv_writer.writerow(extract_test_name(test) + [result])
216*795d594fSAndroid Build Coastguard Worker
217*795d594fSAndroid Build Coastguard Workerdef close_csv_file():
218*795d594fSAndroid Build Coastguard Worker  global csv_result
219*795d594fSAndroid Build Coastguard Worker  global csv_writer
220*795d594fSAndroid Build Coastguard Worker  if csv_result is not None:
221*795d594fSAndroid Build Coastguard Worker    csv_writer = None
222*795d594fSAndroid Build Coastguard Worker    csv_result.flush()
223*795d594fSAndroid Build Coastguard Worker    csv_result.close()
224*795d594fSAndroid Build Coastguard Worker    csv_result = None
225*795d594fSAndroid Build Coastguard Worker
226*795d594fSAndroid Build Coastguard Workerdef gather_test_info():
227*795d594fSAndroid Build Coastguard Worker  """The method gathers test information about the test to be run which includes
228*795d594fSAndroid Build Coastguard Worker  generating the list of total tests from the art/test directory and the list
229*795d594fSAndroid Build Coastguard Worker  of disabled test. It also maps various variants to types.
230*795d594fSAndroid Build Coastguard Worker  """
231*795d594fSAndroid Build Coastguard Worker  global TOTAL_VARIANTS_SET
232*795d594fSAndroid Build Coastguard Worker  # TODO: Avoid duplication of the variant names in different lists.
233*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['run'] = {'ndebug', 'debug'}
234*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['target'] = {'target', 'host', 'jvm'}
235*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['trace'] = {'trace', 'ntrace', 'stream'}
236*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image'}
237*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['debuggable'] = {'ndebuggable', 'debuggable'}
238*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['gc'] = {'gcstress', 'gcverify', 'cms'}
239*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'prebuild'}
240*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['relocate'] = {'relocate', 'no-relocate'}
241*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['jni'] = {'jni', 'forcecopy', 'checkjni'}
242*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['address_sizes'] = {'64', '32'}
243*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['jvmti'] = {'no-jvmti', 'jvmti-stress', 'redefine-stress', 'trace-stress',
244*795d594fSAndroid Build Coastguard Worker                                'field-stress', 'step-stress'}
245*795d594fSAndroid Build Coastguard Worker  VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'jit-on-first-use',
246*795d594fSAndroid Build Coastguard Worker                                   'optimizing', 'speed-profile', 'baseline'}
247*795d594fSAndroid Build Coastguard Worker
248*795d594fSAndroid Build Coastguard Worker  for v_type in VARIANT_TYPE_DICT:
249*795d594fSAndroid Build Coastguard Worker    TOTAL_VARIANTS_SET = TOTAL_VARIANTS_SET.union(VARIANT_TYPE_DICT.get(v_type))
250*795d594fSAndroid Build Coastguard Worker
251*795d594fSAndroid Build Coastguard Worker  test_dir = env.ANDROID_BUILD_TOP + '/art/test'
252*795d594fSAndroid Build Coastguard Worker  for f in os.listdir(test_dir):
253*795d594fSAndroid Build Coastguard Worker    if fnmatch.fnmatch(f, '[0-9]*'):
254*795d594fSAndroid Build Coastguard Worker      RUN_TEST_SET.add(f)
255*795d594fSAndroid Build Coastguard Worker
256*795d594fSAndroid Build Coastguard Worker
257*795d594fSAndroid Build Coastguard Workerdef setup_test_env():
258*795d594fSAndroid Build Coastguard Worker  """The method sets default value for the various variants of the tests if they
259*795d594fSAndroid Build Coastguard Worker  are already not set.
260*795d594fSAndroid Build Coastguard Worker  """
261*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_BISECTION:
262*795d594fSAndroid Build Coastguard Worker    env.ART_TEST_RUN_TEST_NO_PREBUILD = True
263*795d594fSAndroid Build Coastguard Worker    env.ART_TEST_RUN_TEST_PREBUILD = False
264*795d594fSAndroid Build Coastguard Worker    # Bisection search writes to standard output.
265*795d594fSAndroid Build Coastguard Worker    env.ART_TEST_QUIET = False
266*795d594fSAndroid Build Coastguard Worker
267*795d594fSAndroid Build Coastguard Worker  global _user_input_variants
268*795d594fSAndroid Build Coastguard Worker  global run_all_configs
269*795d594fSAndroid Build Coastguard Worker  # These are the default variant-options we will use if nothing in the group is specified.
270*795d594fSAndroid Build Coastguard Worker  default_variants = {
271*795d594fSAndroid Build Coastguard Worker      'target': {'host', 'target'},
272*795d594fSAndroid Build Coastguard Worker      'prebuild': {'prebuild'},
273*795d594fSAndroid Build Coastguard Worker      'jvmti': { 'no-jvmti'},
274*795d594fSAndroid Build Coastguard Worker      'compiler': {'optimizing',
275*795d594fSAndroid Build Coastguard Worker                   'jit',
276*795d594fSAndroid Build Coastguard Worker                   'interpreter',
277*795d594fSAndroid Build Coastguard Worker                   'interp-ac',
278*795d594fSAndroid Build Coastguard Worker                   'speed-profile'},
279*795d594fSAndroid Build Coastguard Worker      'relocate': {'no-relocate'},
280*795d594fSAndroid Build Coastguard Worker      'trace': {'ntrace'},
281*795d594fSAndroid Build Coastguard Worker      'gc': {'cms'},
282*795d594fSAndroid Build Coastguard Worker      'jni': {'checkjni'},
283*795d594fSAndroid Build Coastguard Worker      'image': {'picimage'},
284*795d594fSAndroid Build Coastguard Worker      'debuggable': {'ndebuggable'},
285*795d594fSAndroid Build Coastguard Worker      'run': {'debug'},
286*795d594fSAndroid Build Coastguard Worker      # address_sizes_target depends on the target so it is dealt with below.
287*795d594fSAndroid Build Coastguard Worker  }
288*795d594fSAndroid Build Coastguard Worker  # We want to pull these early since the full VARIANT_TYPE_DICT has a few additional ones we don't
289*795d594fSAndroid Build Coastguard Worker  # want to pick up if we pass --all.
290*795d594fSAndroid Build Coastguard Worker  default_variants_keys = default_variants.keys()
291*795d594fSAndroid Build Coastguard Worker  if run_all_configs:
292*795d594fSAndroid Build Coastguard Worker    default_variants = VARIANT_TYPE_DICT
293*795d594fSAndroid Build Coastguard Worker
294*795d594fSAndroid Build Coastguard Worker  for key in default_variants_keys:
295*795d594fSAndroid Build Coastguard Worker    if not _user_input_variants[key]:
296*795d594fSAndroid Build Coastguard Worker      _user_input_variants[key] = default_variants[key]
297*795d594fSAndroid Build Coastguard Worker
298*795d594fSAndroid Build Coastguard Worker  _user_input_variants['address_sizes_target'] = collections.defaultdict(set)
299*795d594fSAndroid Build Coastguard Worker  if not _user_input_variants['address_sizes']:
300*795d594fSAndroid Build Coastguard Worker    _user_input_variants['address_sizes_target']['target'].add(
301*795d594fSAndroid Build Coastguard Worker        env.ART_PHONY_TEST_TARGET_SUFFIX)
302*795d594fSAndroid Build Coastguard Worker    _user_input_variants['address_sizes_target']['host'].add(
303*795d594fSAndroid Build Coastguard Worker        env.ART_PHONY_TEST_HOST_SUFFIX)
304*795d594fSAndroid Build Coastguard Worker    if env.ART_TEST_RUN_TEST_2ND_ARCH:
305*795d594fSAndroid Build Coastguard Worker      _user_input_variants['address_sizes_target']['host'].add(
306*795d594fSAndroid Build Coastguard Worker          env.ART_2ND_PHONY_TEST_HOST_SUFFIX)
307*795d594fSAndroid Build Coastguard Worker      _user_input_variants['address_sizes_target']['target'].add(
308*795d594fSAndroid Build Coastguard Worker          env.ART_2ND_PHONY_TEST_TARGET_SUFFIX)
309*795d594fSAndroid Build Coastguard Worker  else:
310*795d594fSAndroid Build Coastguard Worker    _user_input_variants['address_sizes_target']['host'] = _user_input_variants['address_sizes']
311*795d594fSAndroid Build Coastguard Worker    _user_input_variants['address_sizes_target']['target'] = _user_input_variants['address_sizes']
312*795d594fSAndroid Build Coastguard Worker
313*795d594fSAndroid Build Coastguard Worker  global n_thread
314*795d594fSAndroid Build Coastguard Worker  if 'target' in _user_input_variants['target']:
315*795d594fSAndroid Build Coastguard Worker    device_name = get_device_name()
316*795d594fSAndroid Build Coastguard Worker    if n_thread == 0:
317*795d594fSAndroid Build Coastguard Worker      # Use only part of the cores since fully loading the device tends to lead to timeouts.
318*795d594fSAndroid Build Coastguard Worker      fraction = 1.0 if env.ART_TEST_ON_VM else 0.75
319*795d594fSAndroid Build Coastguard Worker      n_thread = max(1, int(get_target_cpu_count() * fraction))
320*795d594fSAndroid Build Coastguard Worker      if device_name == 'fugu':
321*795d594fSAndroid Build Coastguard Worker        n_thread = 1
322*795d594fSAndroid Build Coastguard Worker  else:
323*795d594fSAndroid Build Coastguard Worker    device_name = "host"
324*795d594fSAndroid Build Coastguard Worker    if n_thread == 0:
325*795d594fSAndroid Build Coastguard Worker      n_thread = get_host_cpu_count()
326*795d594fSAndroid Build Coastguard Worker  print_text("Concurrency: {} ({})\n".format(n_thread, device_name))
327*795d594fSAndroid Build Coastguard Worker
328*795d594fSAndroid Build Coastguard Worker  global extra_arguments
329*795d594fSAndroid Build Coastguard Worker  for target in _user_input_variants['target']:
330*795d594fSAndroid Build Coastguard Worker    extra_arguments[target] = find_extra_device_arguments(target)
331*795d594fSAndroid Build Coastguard Worker
332*795d594fSAndroid Build Coastguard Worker  if not sys.stdout.isatty():
333*795d594fSAndroid Build Coastguard Worker    global COLOR_ERROR
334*795d594fSAndroid Build Coastguard Worker    global COLOR_PASS
335*795d594fSAndroid Build Coastguard Worker    global COLOR_SKIP
336*795d594fSAndroid Build Coastguard Worker    global COLOR_NORMAL
337*795d594fSAndroid Build Coastguard Worker    COLOR_ERROR = ''
338*795d594fSAndroid Build Coastguard Worker    COLOR_PASS = ''
339*795d594fSAndroid Build Coastguard Worker    COLOR_SKIP = ''
340*795d594fSAndroid Build Coastguard Worker    COLOR_NORMAL = ''
341*795d594fSAndroid Build Coastguard Worker
342*795d594fSAndroid Build Coastguard Workerdef find_extra_device_arguments(target):
343*795d594fSAndroid Build Coastguard Worker  """
344*795d594fSAndroid Build Coastguard Worker  Gets any extra arguments from the device_config.
345*795d594fSAndroid Build Coastguard Worker  """
346*795d594fSAndroid Build Coastguard Worker  device_name = target
347*795d594fSAndroid Build Coastguard Worker  if target == 'target':
348*795d594fSAndroid Build Coastguard Worker    device_name = get_device_name()
349*795d594fSAndroid Build Coastguard Worker  return device_config.get(device_name, { 'run-test-args' : [] })['run-test-args']
350*795d594fSAndroid Build Coastguard Worker
351*795d594fSAndroid Build Coastguard Workerdef get_device_name():
352*795d594fSAndroid Build Coastguard Worker  """
353*795d594fSAndroid Build Coastguard Worker  Gets the value of ro.product.name from remote device (unless running on a VM).
354*795d594fSAndroid Build Coastguard Worker  """
355*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_RUN_FROM_SOONG:
356*795d594fSAndroid Build Coastguard Worker    return "target"  # We can't use adb during build.
357*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_ON_VM:
358*795d594fSAndroid Build Coastguard Worker    return subprocess.Popen(f"{env.ART_SSH_CMD} uname -a".split(),
359*795d594fSAndroid Build Coastguard Worker                            stdout = subprocess.PIPE,
360*795d594fSAndroid Build Coastguard Worker                            universal_newlines=True).stdout.read().strip()
361*795d594fSAndroid Build Coastguard Worker
362*795d594fSAndroid Build Coastguard Worker  proc = subprocess.Popen(['adb', 'shell', 'getprop', 'ro.product.name'],
363*795d594fSAndroid Build Coastguard Worker                          stderr=subprocess.STDOUT,
364*795d594fSAndroid Build Coastguard Worker                          stdout = subprocess.PIPE,
365*795d594fSAndroid Build Coastguard Worker                          universal_newlines=True)
366*795d594fSAndroid Build Coastguard Worker  # only wait 2 seconds.
367*795d594fSAndroid Build Coastguard Worker  timeout_val = 2
368*795d594fSAndroid Build Coastguard Worker
369*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_RUN_ON_ARM_FVP:
370*795d594fSAndroid Build Coastguard Worker    # Increase timeout to 200 seconds due to the emulation overhead on FVP.
371*795d594fSAndroid Build Coastguard Worker    timeout_val = 200
372*795d594fSAndroid Build Coastguard Worker
373*795d594fSAndroid Build Coastguard Worker  output = proc.communicate(timeout = timeout_val)[0]
374*795d594fSAndroid Build Coastguard Worker  success = not proc.wait()
375*795d594fSAndroid Build Coastguard Worker  if success:
376*795d594fSAndroid Build Coastguard Worker    return output.strip()
377*795d594fSAndroid Build Coastguard Worker  else:
378*795d594fSAndroid Build Coastguard Worker    print_text("Unable to determine device type!\n")
379*795d594fSAndroid Build Coastguard Worker    print_text("Continuing anyway.\n")
380*795d594fSAndroid Build Coastguard Worker    return "UNKNOWN_TARGET"
381*795d594fSAndroid Build Coastguard Worker
382*795d594fSAndroid Build Coastguard Workerdef run_tests(tests):
383*795d594fSAndroid Build Coastguard Worker  """This method generates variants of the tests to be run and executes them.
384*795d594fSAndroid Build Coastguard Worker
385*795d594fSAndroid Build Coastguard Worker  Args:
386*795d594fSAndroid Build Coastguard Worker    tests: The set of tests to be run.
387*795d594fSAndroid Build Coastguard Worker  """
388*795d594fSAndroid Build Coastguard Worker  args_all = []
389*795d594fSAndroid Build Coastguard Worker
390*795d594fSAndroid Build Coastguard Worker  # jvm does not run with all these combinations,
391*795d594fSAndroid Build Coastguard Worker  # or at least it doesn't make sense for most of them.
392*795d594fSAndroid Build Coastguard Worker  # TODO: support some jvm variants like jvmti ?
393*795d594fSAndroid Build Coastguard Worker  target_input_variants = _user_input_variants['target']
394*795d594fSAndroid Build Coastguard Worker  uncombinated_target_input_variants = []
395*795d594fSAndroid Build Coastguard Worker  if 'jvm' in target_input_variants:
396*795d594fSAndroid Build Coastguard Worker    _user_input_variants['target'].remove('jvm')
397*795d594fSAndroid Build Coastguard Worker    uncombinated_target_input_variants.append('jvm')
398*795d594fSAndroid Build Coastguard Worker
399*795d594fSAndroid Build Coastguard Worker  global total_test_count
400*795d594fSAndroid Build Coastguard Worker  total_test_count = len(tests)
401*795d594fSAndroid Build Coastguard Worker  if target_input_variants:
402*795d594fSAndroid Build Coastguard Worker    for variant_type in VARIANT_TYPE_DICT:
403*795d594fSAndroid Build Coastguard Worker      if not (variant_type == 'target' or 'address_sizes' in variant_type):
404*795d594fSAndroid Build Coastguard Worker        total_test_count *= len(_user_input_variants[variant_type])
405*795d594fSAndroid Build Coastguard Worker  target_address_combinations = 0
406*795d594fSAndroid Build Coastguard Worker  for target in target_input_variants:
407*795d594fSAndroid Build Coastguard Worker    for address_size in _user_input_variants['address_sizes_target'][target]:
408*795d594fSAndroid Build Coastguard Worker      target_address_combinations += 1
409*795d594fSAndroid Build Coastguard Worker  target_address_combinations += len(uncombinated_target_input_variants)
410*795d594fSAndroid Build Coastguard Worker  total_test_count *= target_address_combinations
411*795d594fSAndroid Build Coastguard Worker
412*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_WITH_STRACE:
413*795d594fSAndroid Build Coastguard Worker    args_all += ['--strace']
414*795d594fSAndroid Build Coastguard Worker
415*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_RUN_TEST_ALWAYS_CLEAN:
416*795d594fSAndroid Build Coastguard Worker    args_all += ['--always-clean']
417*795d594fSAndroid Build Coastguard Worker
418*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_BISECTION:
419*795d594fSAndroid Build Coastguard Worker    args_all += ['--bisection-search']
420*795d594fSAndroid Build Coastguard Worker
421*795d594fSAndroid Build Coastguard Worker  if gdb:
422*795d594fSAndroid Build Coastguard Worker    args_all += ['--gdb']
423*795d594fSAndroid Build Coastguard Worker    if gdb_arg:
424*795d594fSAndroid Build Coastguard Worker      args_all += ['--gdb-arg', gdb_arg]
425*795d594fSAndroid Build Coastguard Worker
426*795d594fSAndroid Build Coastguard Worker  if dump_cfg:
427*795d594fSAndroid Build Coastguard Worker    args_all += ['--dump-cfg', dump_cfg]
428*795d594fSAndroid Build Coastguard Worker  if gdb_dex2oat:
429*795d594fSAndroid Build Coastguard Worker    args_all += ['--gdb-dex2oat']
430*795d594fSAndroid Build Coastguard Worker    if gdb_dex2oat_args:
431*795d594fSAndroid Build Coastguard Worker      args_all += ['--gdb-dex2oat-args', f'{gdb_dex2oat_args}']
432*795d594fSAndroid Build Coastguard Worker
433*795d594fSAndroid Build Coastguard Worker  args_all += run_test_option
434*795d594fSAndroid Build Coastguard Worker
435*795d594fSAndroid Build Coastguard Worker  if runtime_option:
436*795d594fSAndroid Build Coastguard Worker    for opt in runtime_option:
437*795d594fSAndroid Build Coastguard Worker      args_all += ['--runtime-option', opt]
438*795d594fSAndroid Build Coastguard Worker  if with_agent:
439*795d594fSAndroid Build Coastguard Worker    for opt in with_agent:
440*795d594fSAndroid Build Coastguard Worker      args_all += ['--with-agent', opt]
441*795d594fSAndroid Build Coastguard Worker
442*795d594fSAndroid Build Coastguard Worker  if dex2oat_jobs != -1:
443*795d594fSAndroid Build Coastguard Worker    args_all += ['--dex2oat-jobs', str(dex2oat_jobs)]
444*795d594fSAndroid Build Coastguard Worker
445*795d594fSAndroid Build Coastguard Worker  def iter_config(tests, input_variants, user_input_variants):
446*795d594fSAndroid Build Coastguard Worker    config = itertools.product(tests, input_variants, user_input_variants['run'],
447*795d594fSAndroid Build Coastguard Worker                                 user_input_variants['prebuild'], user_input_variants['compiler'],
448*795d594fSAndroid Build Coastguard Worker                                 user_input_variants['relocate'], user_input_variants['trace'],
449*795d594fSAndroid Build Coastguard Worker                                 user_input_variants['gc'], user_input_variants['jni'],
450*795d594fSAndroid Build Coastguard Worker                                 user_input_variants['image'],
451*795d594fSAndroid Build Coastguard Worker                                 user_input_variants['debuggable'], user_input_variants['jvmti'])
452*795d594fSAndroid Build Coastguard Worker    return config
453*795d594fSAndroid Build Coastguard Worker
454*795d594fSAndroid Build Coastguard Worker  # [--host, --target] combines with all the other user input variants.
455*795d594fSAndroid Build Coastguard Worker  config = iter_config(tests, target_input_variants, _user_input_variants)
456*795d594fSAndroid Build Coastguard Worker  # [--jvm] currently combines with nothing else. most of the extra flags we'd insert
457*795d594fSAndroid Build Coastguard Worker  # would be unrecognizable by the 'java' binary, so avoid inserting any extra flags for now.
458*795d594fSAndroid Build Coastguard Worker  uncombinated_config = iter_config(tests, uncombinated_target_input_variants, { 'run': [''],
459*795d594fSAndroid Build Coastguard Worker      'prebuild': [''], 'compiler': [''],
460*795d594fSAndroid Build Coastguard Worker      'relocate': [''], 'trace': [''],
461*795d594fSAndroid Build Coastguard Worker      'gc': [''], 'jni': [''],
462*795d594fSAndroid Build Coastguard Worker      'image': [''],
463*795d594fSAndroid Build Coastguard Worker      'debuggable': [''], 'jvmti': ['']})
464*795d594fSAndroid Build Coastguard Worker
465*795d594fSAndroid Build Coastguard Worker  def start_combination(executor, config_tuple, global_options, address_size):
466*795d594fSAndroid Build Coastguard Worker      test, target, run, prebuild, compiler, relocate, trace, gc, \
467*795d594fSAndroid Build Coastguard Worker      jni, image, debuggable, jvmti = config_tuple
468*795d594fSAndroid Build Coastguard Worker
469*795d594fSAndroid Build Coastguard Worker      # NB The order of components here should match the order of
470*795d594fSAndroid Build Coastguard Worker      # components in the regex parser in parse_test_name.
471*795d594fSAndroid Build Coastguard Worker      test_name = 'test-art-'
472*795d594fSAndroid Build Coastguard Worker      test_name += target + '-run-test-'
473*795d594fSAndroid Build Coastguard Worker      test_name += run + '-'
474*795d594fSAndroid Build Coastguard Worker      test_name += prebuild + '-'
475*795d594fSAndroid Build Coastguard Worker      test_name += compiler + '-'
476*795d594fSAndroid Build Coastguard Worker      test_name += relocate + '-'
477*795d594fSAndroid Build Coastguard Worker      test_name += trace + '-'
478*795d594fSAndroid Build Coastguard Worker      test_name += gc + '-'
479*795d594fSAndroid Build Coastguard Worker      test_name += jni + '-'
480*795d594fSAndroid Build Coastguard Worker      test_name += image + '-'
481*795d594fSAndroid Build Coastguard Worker      test_name += debuggable + '-'
482*795d594fSAndroid Build Coastguard Worker      test_name += jvmti + '-'
483*795d594fSAndroid Build Coastguard Worker      test_name += test
484*795d594fSAndroid Build Coastguard Worker      test_name += address_size
485*795d594fSAndroid Build Coastguard Worker
486*795d594fSAndroid Build Coastguard Worker      variant_set = {target, run, prebuild, compiler, relocate, trace, gc, jni,
487*795d594fSAndroid Build Coastguard Worker                     image, debuggable, jvmti, address_size}
488*795d594fSAndroid Build Coastguard Worker
489*795d594fSAndroid Build Coastguard Worker      args_test = global_options.copy()
490*795d594fSAndroid Build Coastguard Worker
491*795d594fSAndroid Build Coastguard Worker      if target == 'host':
492*795d594fSAndroid Build Coastguard Worker        args_test += ['--host']
493*795d594fSAndroid Build Coastguard Worker      elif target == 'jvm':
494*795d594fSAndroid Build Coastguard Worker        args_test += ['--jvm']
495*795d594fSAndroid Build Coastguard Worker
496*795d594fSAndroid Build Coastguard Worker      # Honor ART_TEST_CHROOT, ART_TEST_ANDROID_ROOT, ART_TEST_ANDROID_ART_ROOT,
497*795d594fSAndroid Build Coastguard Worker      # ART_TEST_ANDROID_I18N_ROOT, and ART_TEST_ANDROID_TZDATA_ROOT but only
498*795d594fSAndroid Build Coastguard Worker      # for target tests.
499*795d594fSAndroid Build Coastguard Worker      if target == 'target':
500*795d594fSAndroid Build Coastguard Worker        if env.ART_TEST_CHROOT:
501*795d594fSAndroid Build Coastguard Worker          args_test += ['--chroot', env.ART_TEST_CHROOT]
502*795d594fSAndroid Build Coastguard Worker        if env.ART_TEST_ANDROID_ROOT:
503*795d594fSAndroid Build Coastguard Worker          args_test += ['--android-root', env.ART_TEST_ANDROID_ROOT]
504*795d594fSAndroid Build Coastguard Worker        if env.ART_TEST_ANDROID_I18N_ROOT:
505*795d594fSAndroid Build Coastguard Worker            args_test += ['--android-i18n-root', env.ART_TEST_ANDROID_I18N_ROOT]
506*795d594fSAndroid Build Coastguard Worker        if env.ART_TEST_ANDROID_ART_ROOT:
507*795d594fSAndroid Build Coastguard Worker          args_test += ['--android-art-root', env.ART_TEST_ANDROID_ART_ROOT]
508*795d594fSAndroid Build Coastguard Worker        if env.ART_TEST_ANDROID_TZDATA_ROOT:
509*795d594fSAndroid Build Coastguard Worker          args_test += ['--android-tzdata-root', env.ART_TEST_ANDROID_TZDATA_ROOT]
510*795d594fSAndroid Build Coastguard Worker
511*795d594fSAndroid Build Coastguard Worker      if run == 'ndebug':
512*795d594fSAndroid Build Coastguard Worker        args_test += ['-O']
513*795d594fSAndroid Build Coastguard Worker
514*795d594fSAndroid Build Coastguard Worker      if prebuild == 'prebuild':
515*795d594fSAndroid Build Coastguard Worker        args_test += ['--prebuild']
516*795d594fSAndroid Build Coastguard Worker      elif prebuild == 'no-prebuild':
517*795d594fSAndroid Build Coastguard Worker        args_test += ['--no-prebuild']
518*795d594fSAndroid Build Coastguard Worker
519*795d594fSAndroid Build Coastguard Worker      if compiler == 'optimizing':
520*795d594fSAndroid Build Coastguard Worker        args_test += ['--optimizing']
521*795d594fSAndroid Build Coastguard Worker      elif compiler == 'interpreter':
522*795d594fSAndroid Build Coastguard Worker        args_test += ['--interpreter']
523*795d594fSAndroid Build Coastguard Worker      elif compiler == 'interp-ac':
524*795d594fSAndroid Build Coastguard Worker        args_test += ['--switch-interpreter', '--verify-soft-fail']
525*795d594fSAndroid Build Coastguard Worker      elif compiler == 'jit':
526*795d594fSAndroid Build Coastguard Worker        args_test += ['--jit']
527*795d594fSAndroid Build Coastguard Worker      elif compiler == 'jit-on-first-use':
528*795d594fSAndroid Build Coastguard Worker        args_test += ['--jit', '--runtime-option', '-Xjitthreshold:0']
529*795d594fSAndroid Build Coastguard Worker      elif compiler == 'speed-profile':
530*795d594fSAndroid Build Coastguard Worker        args_test += ['--random-profile']
531*795d594fSAndroid Build Coastguard Worker      elif compiler == 'baseline':
532*795d594fSAndroid Build Coastguard Worker        args_test += ['--baseline']
533*795d594fSAndroid Build Coastguard Worker
534*795d594fSAndroid Build Coastguard Worker      if relocate == 'relocate':
535*795d594fSAndroid Build Coastguard Worker        args_test += ['--relocate']
536*795d594fSAndroid Build Coastguard Worker      elif relocate == 'no-relocate':
537*795d594fSAndroid Build Coastguard Worker        args_test += ['--no-relocate']
538*795d594fSAndroid Build Coastguard Worker
539*795d594fSAndroid Build Coastguard Worker      if trace == 'trace':
540*795d594fSAndroid Build Coastguard Worker        args_test += ['--trace']
541*795d594fSAndroid Build Coastguard Worker      elif trace == 'stream':
542*795d594fSAndroid Build Coastguard Worker        args_test += ['--trace', '--stream']
543*795d594fSAndroid Build Coastguard Worker
544*795d594fSAndroid Build Coastguard Worker      if gc == 'gcverify':
545*795d594fSAndroid Build Coastguard Worker        args_test += ['--gcverify']
546*795d594fSAndroid Build Coastguard Worker      elif gc == 'gcstress':
547*795d594fSAndroid Build Coastguard Worker        args_test += ['--gcstress']
548*795d594fSAndroid Build Coastguard Worker
549*795d594fSAndroid Build Coastguard Worker      if jni == 'forcecopy':
550*795d594fSAndroid Build Coastguard Worker        args_test += ['--runtime-option', '-Xjniopts:forcecopy']
551*795d594fSAndroid Build Coastguard Worker      elif jni == 'checkjni':
552*795d594fSAndroid Build Coastguard Worker        args_test += ['--runtime-option', '-Xcheck:jni']
553*795d594fSAndroid Build Coastguard Worker
554*795d594fSAndroid Build Coastguard Worker      if image == 'no-image':
555*795d594fSAndroid Build Coastguard Worker        args_test += ['--no-image']
556*795d594fSAndroid Build Coastguard Worker
557*795d594fSAndroid Build Coastguard Worker      if debuggable == 'debuggable':
558*795d594fSAndroid Build Coastguard Worker        args_test += ['--debuggable', '--runtime-option', '-Xopaque-jni-ids:true']
559*795d594fSAndroid Build Coastguard Worker
560*795d594fSAndroid Build Coastguard Worker      if jvmti == 'jvmti-stress':
561*795d594fSAndroid Build Coastguard Worker        args_test += ['--jvmti-trace-stress', '--jvmti-redefine-stress', '--jvmti-field-stress']
562*795d594fSAndroid Build Coastguard Worker      elif jvmti == 'field-stress':
563*795d594fSAndroid Build Coastguard Worker        args_test += ['--jvmti-field-stress']
564*795d594fSAndroid Build Coastguard Worker      elif jvmti == 'trace-stress':
565*795d594fSAndroid Build Coastguard Worker        args_test += ['--jvmti-trace-stress']
566*795d594fSAndroid Build Coastguard Worker      elif jvmti == 'redefine-stress':
567*795d594fSAndroid Build Coastguard Worker        args_test += ['--jvmti-redefine-stress']
568*795d594fSAndroid Build Coastguard Worker      elif jvmti == 'step-stress':
569*795d594fSAndroid Build Coastguard Worker        args_test += ['--jvmti-step-stress']
570*795d594fSAndroid Build Coastguard Worker
571*795d594fSAndroid Build Coastguard Worker      if address_size == '64':
572*795d594fSAndroid Build Coastguard Worker        args_test += ['--64']
573*795d594fSAndroid Build Coastguard Worker
574*795d594fSAndroid Build Coastguard Worker      # Run the run-test script using the prebuilt python.
575*795d594fSAndroid Build Coastguard Worker      python3_bin = env.ANDROID_BUILD_TOP + "/prebuilts/build-tools/path/linux-x86/python3"
576*795d594fSAndroid Build Coastguard Worker      run_test_sh = str(Path(__file__).parent.parent / 'run-test')
577*795d594fSAndroid Build Coastguard Worker      if not os.path.exists(python3_bin):
578*795d594fSAndroid Build Coastguard Worker        python3_bin = sys.executable  # Fallback to current python if we are in a sandbox.
579*795d594fSAndroid Build Coastguard Worker      args_test = [python3_bin, run_test_sh] + args_test + extra_arguments[target] + [test]
580*795d594fSAndroid Build Coastguard Worker      return executor.submit(run_test, args_test, test, variant_set, test_name)
581*795d594fSAndroid Build Coastguard Worker
582*795d594fSAndroid Build Coastguard Worker  global n_thread
583*795d594fSAndroid Build Coastguard Worker  with concurrent.futures.ThreadPoolExecutor(max_workers=n_thread) as executor:
584*795d594fSAndroid Build Coastguard Worker    test_futures = []
585*795d594fSAndroid Build Coastguard Worker    for config_tuple in config:
586*795d594fSAndroid Build Coastguard Worker      target = config_tuple[1]
587*795d594fSAndroid Build Coastguard Worker      for address_size in _user_input_variants['address_sizes_target'][target]:
588*795d594fSAndroid Build Coastguard Worker        test_futures.append(start_combination(executor, config_tuple, args_all, address_size))
589*795d594fSAndroid Build Coastguard Worker
590*795d594fSAndroid Build Coastguard Worker    for config_tuple in uncombinated_config:
591*795d594fSAndroid Build Coastguard Worker      test_futures.append(
592*795d594fSAndroid Build Coastguard Worker          start_combination(executor, config_tuple, args_all, ""))  # no address size
593*795d594fSAndroid Build Coastguard Worker
594*795d594fSAndroid Build Coastguard Worker    try:
595*795d594fSAndroid Build Coastguard Worker      tests_done = 0
596*795d594fSAndroid Build Coastguard Worker      for test_future in concurrent.futures.as_completed(f for f in test_futures if f):
597*795d594fSAndroid Build Coastguard Worker        (test, status, failure_info, test_time) = test_future.result()
598*795d594fSAndroid Build Coastguard Worker        tests_done += 1
599*795d594fSAndroid Build Coastguard Worker        print_test_info(tests_done, test, status, failure_info, test_time)
600*795d594fSAndroid Build Coastguard Worker        if failure_info and not env.ART_TEST_KEEP_GOING:
601*795d594fSAndroid Build Coastguard Worker          for f in test_futures:
602*795d594fSAndroid Build Coastguard Worker            f.cancel()
603*795d594fSAndroid Build Coastguard Worker          break
604*795d594fSAndroid Build Coastguard Worker    except KeyboardInterrupt:
605*795d594fSAndroid Build Coastguard Worker      for f in test_futures:
606*795d594fSAndroid Build Coastguard Worker        f.cancel()
607*795d594fSAndroid Build Coastguard Worker      child_process_tracker.kill_all()
608*795d594fSAndroid Build Coastguard Worker    executor.shutdown(True)
609*795d594fSAndroid Build Coastguard Worker
610*795d594fSAndroid Build Coastguard Workerdef _popen(**kwargs):
611*795d594fSAndroid Build Coastguard Worker  if sys.version_info.major == 3 and sys.version_info.minor >= 6:
612*795d594fSAndroid Build Coastguard Worker    return subprocess.Popen(encoding=sys.stdout.encoding, **kwargs)
613*795d594fSAndroid Build Coastguard Worker  return subprocess.Popen(**kwargs)
614*795d594fSAndroid Build Coastguard Worker
615*795d594fSAndroid Build Coastguard Workerdef run_test(args, test, test_variant, test_name):
616*795d594fSAndroid Build Coastguard Worker  """Runs the test.
617*795d594fSAndroid Build Coastguard Worker
618*795d594fSAndroid Build Coastguard Worker  It invokes art/test/run-test script to run the test. The output of the script
619*795d594fSAndroid Build Coastguard Worker  is checked, and if it ends with "Succeeded!", it assumes that the tests
620*795d594fSAndroid Build Coastguard Worker  passed, otherwise, put it in the list of failed test. Before actually running
621*795d594fSAndroid Build Coastguard Worker  the test, it also checks if the test is placed in the list of disabled tests,
622*795d594fSAndroid Build Coastguard Worker  and if yes, it skips running it, and adds the test in the list of skipped
623*795d594fSAndroid Build Coastguard Worker  tests.
624*795d594fSAndroid Build Coastguard Worker
625*795d594fSAndroid Build Coastguard Worker  Args:
626*795d594fSAndroid Build Coastguard Worker    args: The command to be used to invoke the script
627*795d594fSAndroid Build Coastguard Worker    test: The name of the test without the variant information.
628*795d594fSAndroid Build Coastguard Worker    test_variant: The set of variant for the test.
629*795d594fSAndroid Build Coastguard Worker    test_name: The name of the test along with the variants.
630*795d594fSAndroid Build Coastguard Worker
631*795d594fSAndroid Build Coastguard Worker  Returns: a tuple of testname, status, optional failure info, and test time.
632*795d594fSAndroid Build Coastguard Worker  """
633*795d594fSAndroid Build Coastguard Worker  try:
634*795d594fSAndroid Build Coastguard Worker    command = ' '.join(args)
635*795d594fSAndroid Build Coastguard Worker
636*795d594fSAndroid Build Coastguard Worker    if is_test_disabled(test, test_variant):
637*795d594fSAndroid Build Coastguard Worker      test_skipped = True
638*795d594fSAndroid Build Coastguard Worker      test_time = datetime.timedelta()
639*795d594fSAndroid Build Coastguard Worker    else:
640*795d594fSAndroid Build Coastguard Worker      test_skipped = False
641*795d594fSAndroid Build Coastguard Worker      test_start_time = time.monotonic()
642*795d594fSAndroid Build Coastguard Worker      if verbose:
643*795d594fSAndroid Build Coastguard Worker        print_text("Starting %s at %s\n" % (test_name, test_start_time))
644*795d594fSAndroid Build Coastguard Worker      environ = dict(os.environ)
645*795d594fSAndroid Build Coastguard Worker      environ["FULL_TEST_NAME"] = test_name
646*795d594fSAndroid Build Coastguard Worker      if gdb or gdb_dex2oat:
647*795d594fSAndroid Build Coastguard Worker        proc = _popen(
648*795d594fSAndroid Build Coastguard Worker          args=args,
649*795d594fSAndroid Build Coastguard Worker          env=environ,
650*795d594fSAndroid Build Coastguard Worker          stderr=subprocess.STDOUT,
651*795d594fSAndroid Build Coastguard Worker          universal_newlines=True,
652*795d594fSAndroid Build Coastguard Worker          start_new_session=True
653*795d594fSAndroid Build Coastguard Worker        )
654*795d594fSAndroid Build Coastguard Worker      else:
655*795d594fSAndroid Build Coastguard Worker        proc = _popen(
656*795d594fSAndroid Build Coastguard Worker          args=args,
657*795d594fSAndroid Build Coastguard Worker          env=environ,
658*795d594fSAndroid Build Coastguard Worker          stderr=subprocess.STDOUT,
659*795d594fSAndroid Build Coastguard Worker          stdout = subprocess.PIPE,
660*795d594fSAndroid Build Coastguard Worker          universal_newlines=True,
661*795d594fSAndroid Build Coastguard Worker          start_new_session=True,
662*795d594fSAndroid Build Coastguard Worker        )
663*795d594fSAndroid Build Coastguard Worker      script_output, return_value = child_process_tracker.wait(proc, timeout)
664*795d594fSAndroid Build Coastguard Worker      test_passed = not return_value
665*795d594fSAndroid Build Coastguard Worker      test_time_seconds = time.monotonic() - test_start_time
666*795d594fSAndroid Build Coastguard Worker      test_time = datetime.timedelta(seconds=test_time_seconds)
667*795d594fSAndroid Build Coastguard Worker
668*795d594fSAndroid Build Coastguard Worker    if not test_skipped:
669*795d594fSAndroid Build Coastguard Worker      if test_passed:
670*795d594fSAndroid Build Coastguard Worker        return (test_name, 'PASS', None, test_time)
671*795d594fSAndroid Build Coastguard Worker      else:
672*795d594fSAndroid Build Coastguard Worker        failed_tests.append((test_name, str(command) + "\n" + script_output))
673*795d594fSAndroid Build Coastguard Worker        return (test_name, 'FAIL', ('%s\n%s') % (command, script_output), test_time)
674*795d594fSAndroid Build Coastguard Worker    elif not dry_run:
675*795d594fSAndroid Build Coastguard Worker      skipped_tests.append(test_name)
676*795d594fSAndroid Build Coastguard Worker      return (test_name, 'SKIP', None, test_time)
677*795d594fSAndroid Build Coastguard Worker    else:
678*795d594fSAndroid Build Coastguard Worker      return (test_name, 'PASS', None, test_time)
679*795d594fSAndroid Build Coastguard Worker  except subprocess.TimeoutExpired as e:
680*795d594fSAndroid Build Coastguard Worker    if verbose:
681*795d594fSAndroid Build Coastguard Worker      print_text("Timeout of %s at %s\n" % (test_name, time.monotonic()))
682*795d594fSAndroid Build Coastguard Worker    test_time_seconds = time.monotonic() - test_start_time
683*795d594fSAndroid Build Coastguard Worker    test_time = datetime.timedelta(seconds=test_time_seconds)
684*795d594fSAndroid Build Coastguard Worker    failed_tests.append((test_name, 'Timed out in %d seconds' % timeout))
685*795d594fSAndroid Build Coastguard Worker
686*795d594fSAndroid Build Coastguard Worker    # HACK(b/142039427): Print extra backtraces on timeout.
687*795d594fSAndroid Build Coastguard Worker    if "-target-" in test_name and not env.ART_TEST_ON_VM:
688*795d594fSAndroid Build Coastguard Worker      for i in range(8):
689*795d594fSAndroid Build Coastguard Worker        proc_name = "dalvikvm" + test_name[-2:]
690*795d594fSAndroid Build Coastguard Worker        pidof = subprocess.run(["adb", "shell", "pidof", proc_name], stdout=subprocess.PIPE)
691*795d594fSAndroid Build Coastguard Worker        for pid in pidof.stdout.decode("ascii").split():
692*795d594fSAndroid Build Coastguard Worker          if i >= 4:
693*795d594fSAndroid Build Coastguard Worker            print_text("Backtrace of %s at %s\n" % (pid, time.monotonic()))
694*795d594fSAndroid Build Coastguard Worker            subprocess.run(["adb", "shell", "debuggerd", pid])
695*795d594fSAndroid Build Coastguard Worker            time.sleep(10)
696*795d594fSAndroid Build Coastguard Worker          task_dir = "/proc/%s/task" % pid
697*795d594fSAndroid Build Coastguard Worker          tids = subprocess.run(["adb", "shell", "ls", task_dir], stdout=subprocess.PIPE)
698*795d594fSAndroid Build Coastguard Worker          for tid in tids.stdout.decode("ascii").split():
699*795d594fSAndroid Build Coastguard Worker            for status in ["stat", "status"]:
700*795d594fSAndroid Build Coastguard Worker              filename = "%s/%s/%s" % (task_dir, tid, status)
701*795d594fSAndroid Build Coastguard Worker              print_text("Content of %s\n" % (filename))
702*795d594fSAndroid Build Coastguard Worker              subprocess.run(["adb", "shell", "cat", filename])
703*795d594fSAndroid Build Coastguard Worker        time.sleep(60)
704*795d594fSAndroid Build Coastguard Worker
705*795d594fSAndroid Build Coastguard Worker    # The python documentation states that it is necessary to actually kill the process.
706*795d594fSAndroid Build Coastguard Worker    os.killpg(proc.pid, signal.SIGKILL)
707*795d594fSAndroid Build Coastguard Worker    script_output = proc.communicate()
708*795d594fSAndroid Build Coastguard Worker
709*795d594fSAndroid Build Coastguard Worker    return (test_name, 'TIMEOUT', 'Timed out in %d seconds\n%s' % (timeout, command), test_time)
710*795d594fSAndroid Build Coastguard Worker  except Exception as e:
711*795d594fSAndroid Build Coastguard Worker    failed_tests.append((test_name, str(e)))
712*795d594fSAndroid Build Coastguard Worker    return (test_name, 'FAIL', ('%s\n%s\n\n') % (command, str(e)), datetime.timedelta())
713*795d594fSAndroid Build Coastguard Worker
714*795d594fSAndroid Build Coastguard Worker@lru_cache
715*795d594fSAndroid Build Coastguard Workerdef get_console_width(default=100):
716*795d594fSAndroid Build Coastguard Worker  # NB: The command may fail if we are running under 'nohup'.
717*795d594fSAndroid Build Coastguard Worker  proc = subprocess.run(['stty', 'size'], capture_output=True)
718*795d594fSAndroid Build Coastguard Worker  return int(proc.stdout.decode("utf8").split()[1]) if proc.returncode == 0 else default
719*795d594fSAndroid Build Coastguard Worker
720*795d594fSAndroid Build Coastguard Workerdef print_test_info(test_count, test_name, result, failed_test_info="",
721*795d594fSAndroid Build Coastguard Worker                    test_time=datetime.timedelta()):
722*795d594fSAndroid Build Coastguard Worker  """Print the continous test information
723*795d594fSAndroid Build Coastguard Worker
724*795d594fSAndroid Build Coastguard Worker  If verbose is set to True, it continuously prints test status information
725*795d594fSAndroid Build Coastguard Worker  on a new line.
726*795d594fSAndroid Build Coastguard Worker  If verbose is set to False, it keeps on erasing test
727*795d594fSAndroid Build Coastguard Worker  information by overriding it with the latest test information. Also,
728*795d594fSAndroid Build Coastguard Worker  in this case it stictly makes sure that the information length doesn't
729*795d594fSAndroid Build Coastguard Worker  exceed the console width. It does so by shortening the test_name.
730*795d594fSAndroid Build Coastguard Worker
731*795d594fSAndroid Build Coastguard Worker  When a test fails, it prints the output of the run-test script and
732*795d594fSAndroid Build Coastguard Worker  command used to invoke the script. It doesn't override the failing
733*795d594fSAndroid Build Coastguard Worker  test information in either of the cases.
734*795d594fSAndroid Build Coastguard Worker  """
735*795d594fSAndroid Build Coastguard Worker
736*795d594fSAndroid Build Coastguard Worker  info = ''
737*795d594fSAndroid Build Coastguard Worker  if not verbose:
738*795d594fSAndroid Build Coastguard Worker    # Without --verbose, the testrunner erases passing test info. It
739*795d594fSAndroid Build Coastguard Worker    # does that by overriding the printed text with white spaces all across
740*795d594fSAndroid Build Coastguard Worker    # the console width.
741*795d594fSAndroid Build Coastguard Worker    info = '\r' + ' ' * get_console_width() + '\r'
742*795d594fSAndroid Build Coastguard Worker  try:
743*795d594fSAndroid Build Coastguard Worker    percent = (test_count * 100) / total_test_count
744*795d594fSAndroid Build Coastguard Worker    progress_info = ('[ %d%% %d/%d ]') % (
745*795d594fSAndroid Build Coastguard Worker      percent,
746*795d594fSAndroid Build Coastguard Worker      test_count,
747*795d594fSAndroid Build Coastguard Worker      total_test_count)
748*795d594fSAndroid Build Coastguard Worker    if test_time.total_seconds() != 0 and verbose:
749*795d594fSAndroid Build Coastguard Worker      info += '(%s)' % str(test_time)
750*795d594fSAndroid Build Coastguard Worker
751*795d594fSAndroid Build Coastguard Worker
752*795d594fSAndroid Build Coastguard Worker    if result == 'FAIL' or result == 'TIMEOUT':
753*795d594fSAndroid Build Coastguard Worker      if not verbose:
754*795d594fSAndroid Build Coastguard Worker        info += ('%s %s %s\n') % (
755*795d594fSAndroid Build Coastguard Worker          progress_info,
756*795d594fSAndroid Build Coastguard Worker          test_name,
757*795d594fSAndroid Build Coastguard Worker          COLOR_ERROR + result + COLOR_NORMAL)
758*795d594fSAndroid Build Coastguard Worker      else:
759*795d594fSAndroid Build Coastguard Worker        info += ('%s %s %s\n%s\n') % (
760*795d594fSAndroid Build Coastguard Worker          progress_info,
761*795d594fSAndroid Build Coastguard Worker          test_name,
762*795d594fSAndroid Build Coastguard Worker          COLOR_ERROR + result + COLOR_NORMAL,
763*795d594fSAndroid Build Coastguard Worker          failed_test_info)
764*795d594fSAndroid Build Coastguard Worker    else:
765*795d594fSAndroid Build Coastguard Worker      result_text = ''
766*795d594fSAndroid Build Coastguard Worker      if result == 'PASS':
767*795d594fSAndroid Build Coastguard Worker        result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL
768*795d594fSAndroid Build Coastguard Worker      elif result == 'SKIP':
769*795d594fSAndroid Build Coastguard Worker        result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL
770*795d594fSAndroid Build Coastguard Worker
771*795d594fSAndroid Build Coastguard Worker      if verbose:
772*795d594fSAndroid Build Coastguard Worker        info += ('%s %s %s\n') % (
773*795d594fSAndroid Build Coastguard Worker          progress_info,
774*795d594fSAndroid Build Coastguard Worker          test_name,
775*795d594fSAndroid Build Coastguard Worker          result_text)
776*795d594fSAndroid Build Coastguard Worker      else:
777*795d594fSAndroid Build Coastguard Worker        total_output_length = 2 # Two spaces
778*795d594fSAndroid Build Coastguard Worker        total_output_length += len(progress_info)
779*795d594fSAndroid Build Coastguard Worker        total_output_length += len(result)
780*795d594fSAndroid Build Coastguard Worker        allowed_test_length = get_console_width() - total_output_length
781*795d594fSAndroid Build Coastguard Worker        test_name_len = len(test_name)
782*795d594fSAndroid Build Coastguard Worker        if allowed_test_length < test_name_len:
783*795d594fSAndroid Build Coastguard Worker          test_name = ('...%s') % (
784*795d594fSAndroid Build Coastguard Worker            test_name[-(allowed_test_length - 3):])
785*795d594fSAndroid Build Coastguard Worker        info += ('%s %s %s') % (
786*795d594fSAndroid Build Coastguard Worker          progress_info,
787*795d594fSAndroid Build Coastguard Worker          test_name,
788*795d594fSAndroid Build Coastguard Worker          result_text)
789*795d594fSAndroid Build Coastguard Worker    send_csv_result(test_name, result)
790*795d594fSAndroid Build Coastguard Worker    print_text(info)
791*795d594fSAndroid Build Coastguard Worker  except Exception as e:
792*795d594fSAndroid Build Coastguard Worker    print_text(('%s\n%s\n') % (test_name, str(e)))
793*795d594fSAndroid Build Coastguard Worker    failed_tests.append(test_name)
794*795d594fSAndroid Build Coastguard Worker
795*795d594fSAndroid Build Coastguard Workerdef verify_knownfailure_entry(entry):
796*795d594fSAndroid Build Coastguard Worker  supported_field = {
797*795d594fSAndroid Build Coastguard Worker      'tests' : (list, str),
798*795d594fSAndroid Build Coastguard Worker      'test_patterns' : (list,),
799*795d594fSAndroid Build Coastguard Worker      'description' : (list, str),
800*795d594fSAndroid Build Coastguard Worker      'bug' : (str,),
801*795d594fSAndroid Build Coastguard Worker      'variant' : (str,),
802*795d594fSAndroid Build Coastguard Worker      'devices': (list, str),
803*795d594fSAndroid Build Coastguard Worker      'env_vars' : (dict,),
804*795d594fSAndroid Build Coastguard Worker  }
805*795d594fSAndroid Build Coastguard Worker  for field in entry:
806*795d594fSAndroid Build Coastguard Worker    field_type = type(entry[field])
807*795d594fSAndroid Build Coastguard Worker    if field_type not in supported_field[field]:
808*795d594fSAndroid Build Coastguard Worker      raise ValueError('%s is not supported type for %s\n%s' % (
809*795d594fSAndroid Build Coastguard Worker          str(field_type),
810*795d594fSAndroid Build Coastguard Worker          field,
811*795d594fSAndroid Build Coastguard Worker          str(entry)))
812*795d594fSAndroid Build Coastguard Worker
813*795d594fSAndroid Build Coastguard Workerdef get_disabled_test_info(device_name):
814*795d594fSAndroid Build Coastguard Worker  """Generate set of known failures.
815*795d594fSAndroid Build Coastguard Worker
816*795d594fSAndroid Build Coastguard Worker  It parses the art/test/knownfailures.json file to generate the list of
817*795d594fSAndroid Build Coastguard Worker  disabled tests.
818*795d594fSAndroid Build Coastguard Worker
819*795d594fSAndroid Build Coastguard Worker  Returns:
820*795d594fSAndroid Build Coastguard Worker    The method returns a dict of tests mapped to the variants list
821*795d594fSAndroid Build Coastguard Worker    for which the test should not be run.
822*795d594fSAndroid Build Coastguard Worker  """
823*795d594fSAndroid Build Coastguard Worker  known_failures_file = Path(__file__).parent.parent / 'knownfailures.json'
824*795d594fSAndroid Build Coastguard Worker  with open(known_failures_file) as known_failures_json:
825*795d594fSAndroid Build Coastguard Worker    known_failures_info = json.loads(known_failures_json.read())
826*795d594fSAndroid Build Coastguard Worker
827*795d594fSAndroid Build Coastguard Worker  disabled_test_info = {}
828*795d594fSAndroid Build Coastguard Worker  for failure in known_failures_info:
829*795d594fSAndroid Build Coastguard Worker    verify_knownfailure_entry(failure)
830*795d594fSAndroid Build Coastguard Worker    tests = failure.get('tests', [])
831*795d594fSAndroid Build Coastguard Worker    if isinstance(tests, str):
832*795d594fSAndroid Build Coastguard Worker      tests = [tests]
833*795d594fSAndroid Build Coastguard Worker    patterns = failure.get("test_patterns", [])
834*795d594fSAndroid Build Coastguard Worker    if (not isinstance(patterns, list)):
835*795d594fSAndroid Build Coastguard Worker      raise ValueError("test_patterns is not a list in %s" % failure)
836*795d594fSAndroid Build Coastguard Worker
837*795d594fSAndroid Build Coastguard Worker    tests += [f for f in RUN_TEST_SET if any(re.match(pat, f) is not None for pat in patterns)]
838*795d594fSAndroid Build Coastguard Worker    variants = parse_variants(failure.get('variant'))
839*795d594fSAndroid Build Coastguard Worker
840*795d594fSAndroid Build Coastguard Worker    # Treat a '"devices": "<foo>"' equivalent to 'target' variant if
841*795d594fSAndroid Build Coastguard Worker    # "foo" is present in "devices".
842*795d594fSAndroid Build Coastguard Worker    device_names = failure.get('devices', [])
843*795d594fSAndroid Build Coastguard Worker    if isinstance(device_names, str):
844*795d594fSAndroid Build Coastguard Worker      device_names = [device_names]
845*795d594fSAndroid Build Coastguard Worker    if len(device_names) != 0:
846*795d594fSAndroid Build Coastguard Worker      if device_name in device_names:
847*795d594fSAndroid Build Coastguard Worker        variants.add('target')
848*795d594fSAndroid Build Coastguard Worker      else:
849*795d594fSAndroid Build Coastguard Worker        # Skip adding test info as device_name is not present in "devices" entry.
850*795d594fSAndroid Build Coastguard Worker        continue
851*795d594fSAndroid Build Coastguard Worker
852*795d594fSAndroid Build Coastguard Worker    env_vars = failure.get('env_vars')
853*795d594fSAndroid Build Coastguard Worker
854*795d594fSAndroid Build Coastguard Worker    if check_env_vars(env_vars):
855*795d594fSAndroid Build Coastguard Worker      for test in tests:
856*795d594fSAndroid Build Coastguard Worker        if test not in RUN_TEST_SET:
857*795d594fSAndroid Build Coastguard Worker          if env.ART_TEST_RUN_FROM_SOONG:
858*795d594fSAndroid Build Coastguard Worker            continue  # Soong can see only sub-set of the tests within the shard.
859*795d594fSAndroid Build Coastguard Worker          raise ValueError('%s is not a valid run-test' % (
860*795d594fSAndroid Build Coastguard Worker              test))
861*795d594fSAndroid Build Coastguard Worker        if test in disabled_test_info:
862*795d594fSAndroid Build Coastguard Worker          disabled_test_info[test] = disabled_test_info[test].union(variants)
863*795d594fSAndroid Build Coastguard Worker        else:
864*795d594fSAndroid Build Coastguard Worker          disabled_test_info[test] = variants
865*795d594fSAndroid Build Coastguard Worker
866*795d594fSAndroid Build Coastguard Worker  return disabled_test_info
867*795d594fSAndroid Build Coastguard Worker
868*795d594fSAndroid Build Coastguard Workerdef gather_disabled_test_info():
869*795d594fSAndroid Build Coastguard Worker  global DISABLED_TEST_CONTAINER
870*795d594fSAndroid Build Coastguard Worker  device_name = get_device_name() if 'target' in _user_input_variants['target'] else None
871*795d594fSAndroid Build Coastguard Worker  DISABLED_TEST_CONTAINER = get_disabled_test_info(device_name)
872*795d594fSAndroid Build Coastguard Worker
873*795d594fSAndroid Build Coastguard Workerdef check_env_vars(env_vars):
874*795d594fSAndroid Build Coastguard Worker  """Checks if the env variables are set as required to run the test.
875*795d594fSAndroid Build Coastguard Worker
876*795d594fSAndroid Build Coastguard Worker  Returns:
877*795d594fSAndroid Build Coastguard Worker    True if all the env variables are set as required, otherwise False.
878*795d594fSAndroid Build Coastguard Worker  """
879*795d594fSAndroid Build Coastguard Worker
880*795d594fSAndroid Build Coastguard Worker  if not env_vars:
881*795d594fSAndroid Build Coastguard Worker    return True
882*795d594fSAndroid Build Coastguard Worker  for key in env_vars:
883*795d594fSAndroid Build Coastguard Worker    if env.get_env(key) != env_vars.get(key):
884*795d594fSAndroid Build Coastguard Worker      return False
885*795d594fSAndroid Build Coastguard Worker  return True
886*795d594fSAndroid Build Coastguard Worker
887*795d594fSAndroid Build Coastguard Worker
888*795d594fSAndroid Build Coastguard Workerdef is_test_disabled(test, variant_set):
889*795d594fSAndroid Build Coastguard Worker  """Checks if the test along with the variant_set is disabled.
890*795d594fSAndroid Build Coastguard Worker
891*795d594fSAndroid Build Coastguard Worker  Args:
892*795d594fSAndroid Build Coastguard Worker    test: The name of the test as in art/test directory.
893*795d594fSAndroid Build Coastguard Worker    variant_set: Variants to be used for the test.
894*795d594fSAndroid Build Coastguard Worker  Returns:
895*795d594fSAndroid Build Coastguard Worker    True, if the test is disabled.
896*795d594fSAndroid Build Coastguard Worker  """
897*795d594fSAndroid Build Coastguard Worker  if dry_run:
898*795d594fSAndroid Build Coastguard Worker    return True
899*795d594fSAndroid Build Coastguard Worker  if test in env.EXTRA_DISABLED_TESTS:
900*795d594fSAndroid Build Coastguard Worker    return True
901*795d594fSAndroid Build Coastguard Worker  if ignore_skips:
902*795d594fSAndroid Build Coastguard Worker    return False
903*795d594fSAndroid Build Coastguard Worker  variants_list = DISABLED_TEST_CONTAINER.get(test, {})
904*795d594fSAndroid Build Coastguard Worker  for variants in variants_list:
905*795d594fSAndroid Build Coastguard Worker    variants_present = True
906*795d594fSAndroid Build Coastguard Worker    for variant in variants:
907*795d594fSAndroid Build Coastguard Worker      if variant not in variant_set:
908*795d594fSAndroid Build Coastguard Worker        variants_present = False
909*795d594fSAndroid Build Coastguard Worker        break
910*795d594fSAndroid Build Coastguard Worker    if variants_present:
911*795d594fSAndroid Build Coastguard Worker      return True
912*795d594fSAndroid Build Coastguard Worker  for bad_combo in NONFUNCTIONAL_VARIANT_SETS:
913*795d594fSAndroid Build Coastguard Worker    if bad_combo.issubset(variant_set):
914*795d594fSAndroid Build Coastguard Worker      return True
915*795d594fSAndroid Build Coastguard Worker  return False
916*795d594fSAndroid Build Coastguard Worker
917*795d594fSAndroid Build Coastguard Worker
918*795d594fSAndroid Build Coastguard Workerdef parse_variants(variants):
919*795d594fSAndroid Build Coastguard Worker  """Parse variants fetched from art/test/knownfailures.json.
920*795d594fSAndroid Build Coastguard Worker  """
921*795d594fSAndroid Build Coastguard Worker  if not variants:
922*795d594fSAndroid Build Coastguard Worker    variants = ''
923*795d594fSAndroid Build Coastguard Worker    for variant in TOTAL_VARIANTS_SET:
924*795d594fSAndroid Build Coastguard Worker      variants += variant
925*795d594fSAndroid Build Coastguard Worker      variants += '|'
926*795d594fSAndroid Build Coastguard Worker    variants = variants[:-1]
927*795d594fSAndroid Build Coastguard Worker  variant_list = set()
928*795d594fSAndroid Build Coastguard Worker  or_variants = variants.split('|')
929*795d594fSAndroid Build Coastguard Worker  for or_variant in or_variants:
930*795d594fSAndroid Build Coastguard Worker    and_variants = or_variant.split('&')
931*795d594fSAndroid Build Coastguard Worker    variant = set()
932*795d594fSAndroid Build Coastguard Worker    for and_variant in and_variants:
933*795d594fSAndroid Build Coastguard Worker      and_variant = and_variant.strip()
934*795d594fSAndroid Build Coastguard Worker      if and_variant not in TOTAL_VARIANTS_SET:
935*795d594fSAndroid Build Coastguard Worker        raise ValueError('%s is not a valid variant' % (
936*795d594fSAndroid Build Coastguard Worker            and_variant))
937*795d594fSAndroid Build Coastguard Worker      variant.add(and_variant)
938*795d594fSAndroid Build Coastguard Worker    variant_list.add(frozenset(variant))
939*795d594fSAndroid Build Coastguard Worker  return variant_list
940*795d594fSAndroid Build Coastguard Worker
941*795d594fSAndroid Build Coastguard Workerdef print_text(output, error=False):
942*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_RUN_FROM_SOONG and not error:
943*795d594fSAndroid Build Coastguard Worker    return  # Be quiet during build.
944*795d594fSAndroid Build Coastguard Worker  sys.stdout.write(output)
945*795d594fSAndroid Build Coastguard Worker  sys.stdout.flush()
946*795d594fSAndroid Build Coastguard Worker
947*795d594fSAndroid Build Coastguard Workerdef print_analysis():
948*795d594fSAndroid Build Coastguard Worker  if not verbose:
949*795d594fSAndroid Build Coastguard Worker    # Without --verbose, the testrunner erases passing test info. It
950*795d594fSAndroid Build Coastguard Worker    # does that by overriding the printed text with white spaces all across
951*795d594fSAndroid Build Coastguard Worker    # the console width.
952*795d594fSAndroid Build Coastguard Worker    eraser_text = '\r' + ' ' * get_console_width() + '\r'
953*795d594fSAndroid Build Coastguard Worker    print_text(eraser_text)
954*795d594fSAndroid Build Coastguard Worker
955*795d594fSAndroid Build Coastguard Worker  # Prints information about the total tests run.
956*795d594fSAndroid Build Coastguard Worker  # E.g., "2/38 (5%) tests passed".
957*795d594fSAndroid Build Coastguard Worker  passed_test_count = total_test_count - len(skipped_tests) - len(failed_tests)
958*795d594fSAndroid Build Coastguard Worker  passed_test_information = ('%d/%d (%d%%) %s passed.\n') % (
959*795d594fSAndroid Build Coastguard Worker      passed_test_count,
960*795d594fSAndroid Build Coastguard Worker      total_test_count,
961*795d594fSAndroid Build Coastguard Worker      (passed_test_count*100)/total_test_count,
962*795d594fSAndroid Build Coastguard Worker      'tests' if passed_test_count > 1 else 'test')
963*795d594fSAndroid Build Coastguard Worker  print_text(passed_test_information)
964*795d594fSAndroid Build Coastguard Worker
965*795d594fSAndroid Build Coastguard Worker  # Prints the list of skipped tests, if any.
966*795d594fSAndroid Build Coastguard Worker  if skipped_tests:
967*795d594fSAndroid Build Coastguard Worker    print_text(COLOR_SKIP + 'SKIPPED TESTS: ' + COLOR_NORMAL + '\n')
968*795d594fSAndroid Build Coastguard Worker    for test in skipped_tests:
969*795d594fSAndroid Build Coastguard Worker      print_text(test + '\n')
970*795d594fSAndroid Build Coastguard Worker    print_text('\n')
971*795d594fSAndroid Build Coastguard Worker
972*795d594fSAndroid Build Coastguard Worker  # Prints the list of failed tests, if any.
973*795d594fSAndroid Build Coastguard Worker  if failed_tests:
974*795d594fSAndroid Build Coastguard Worker    print_text(COLOR_ERROR + 'FAILED: ' + COLOR_NORMAL + '\n', error=True)
975*795d594fSAndroid Build Coastguard Worker    for test_info in failed_tests:
976*795d594fSAndroid Build Coastguard Worker      print_text(('%s\n%s\n' % (test_info[0], test_info[1])), error=True)
977*795d594fSAndroid Build Coastguard Worker    print_text(COLOR_ERROR + '----------' + COLOR_NORMAL + '\n')
978*795d594fSAndroid Build Coastguard Worker    for failed_test in sorted([test_info[0] for test_info in failed_tests]):
979*795d594fSAndroid Build Coastguard Worker      print_text(('%s\n' % (failed_test)))
980*795d594fSAndroid Build Coastguard Worker
981*795d594fSAndroid Build Coastguard Workertest_name_matcher = None
982*795d594fSAndroid Build Coastguard Workerdef extract_test_name(test_name):
983*795d594fSAndroid Build Coastguard Worker  """Parses the test name and returns all the parts"""
984*795d594fSAndroid Build Coastguard Worker  global test_name_matcher
985*795d594fSAndroid Build Coastguard Worker  if test_name_matcher is None:
986*795d594fSAndroid Build Coastguard Worker    regex = '^test-art-'
987*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['target']) + ')-'
988*795d594fSAndroid Build Coastguard Worker    regex += 'run-test-'
989*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['run']) + ')-'
990*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['prebuild']) + ')-'
991*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['compiler']) + ')-'
992*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['relocate']) + ')-'
993*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['trace']) + ')-'
994*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['gc']) + ')-'
995*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['jni']) + ')-'
996*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['image']) + ')-'
997*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['debuggable']) + ')-'
998*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['jvmti']) + ')-'
999*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(RUN_TEST_SET) + ')'
1000*795d594fSAndroid Build Coastguard Worker    regex += '(' + '|'.join(VARIANT_TYPE_DICT['address_sizes']) + ')$'
1001*795d594fSAndroid Build Coastguard Worker    test_name_matcher = re.compile(regex)
1002*795d594fSAndroid Build Coastguard Worker  match = test_name_matcher.match(test_name)
1003*795d594fSAndroid Build Coastguard Worker  if match:
1004*795d594fSAndroid Build Coastguard Worker    return list(match.groups())
1005*795d594fSAndroid Build Coastguard Worker  raise ValueError(test_name + " is not a valid test")
1006*795d594fSAndroid Build Coastguard Worker
1007*795d594fSAndroid Build Coastguard Workerdef parse_test_name(test_name):
1008*795d594fSAndroid Build Coastguard Worker  """Parses the testname provided by the user.
1009*795d594fSAndroid Build Coastguard Worker  It supports two types of test_name:
1010*795d594fSAndroid Build Coastguard Worker  1) Like 001-HelloWorld. In this case, it will just verify if the test actually
1011*795d594fSAndroid Build Coastguard Worker  exists and if it does, it returns the testname.
1012*795d594fSAndroid Build Coastguard Worker  2) Like test-art-host-run-test-debug-prebuild-interpreter-no-relocate-ntrace-cms-checkjni-picimage-ndebuggable-no-jvmti-001-HelloWorld32
1013*795d594fSAndroid Build Coastguard Worker  In this case, it will parse all the variants and check if they are placed
1014*795d594fSAndroid Build Coastguard Worker  correctly. If yes, it will set the various VARIANT_TYPES to use the
1015*795d594fSAndroid Build Coastguard Worker  variants required to run the test. Again, it returns the test_name
1016*795d594fSAndroid Build Coastguard Worker  without the variant information like 001-HelloWorld.
1017*795d594fSAndroid Build Coastguard Worker  """
1018*795d594fSAndroid Build Coastguard Worker  test_set = set()
1019*795d594fSAndroid Build Coastguard Worker  for test in RUN_TEST_SET:
1020*795d594fSAndroid Build Coastguard Worker    if test.startswith(test_name):
1021*795d594fSAndroid Build Coastguard Worker      test_set.add(test)
1022*795d594fSAndroid Build Coastguard Worker  if test_set:
1023*795d594fSAndroid Build Coastguard Worker    return test_set
1024*795d594fSAndroid Build Coastguard Worker
1025*795d594fSAndroid Build Coastguard Worker  parsed = extract_test_name(test_name)
1026*795d594fSAndroid Build Coastguard Worker  _user_input_variants['target'].add(parsed[0])
1027*795d594fSAndroid Build Coastguard Worker  _user_input_variants['run'].add(parsed[1])
1028*795d594fSAndroid Build Coastguard Worker  _user_input_variants['prebuild'].add(parsed[2])
1029*795d594fSAndroid Build Coastguard Worker  _user_input_variants['compiler'].add(parsed[3])
1030*795d594fSAndroid Build Coastguard Worker  _user_input_variants['relocate'].add(parsed[4])
1031*795d594fSAndroid Build Coastguard Worker  _user_input_variants['trace'].add(parsed[5])
1032*795d594fSAndroid Build Coastguard Worker  _user_input_variants['gc'].add(parsed[6])
1033*795d594fSAndroid Build Coastguard Worker  _user_input_variants['jni'].add(parsed[7])
1034*795d594fSAndroid Build Coastguard Worker  _user_input_variants['image'].add(parsed[8])
1035*795d594fSAndroid Build Coastguard Worker  _user_input_variants['debuggable'].add(parsed[9])
1036*795d594fSAndroid Build Coastguard Worker  _user_input_variants['jvmti'].add(parsed[10])
1037*795d594fSAndroid Build Coastguard Worker  _user_input_variants['address_sizes'].add(parsed[12])
1038*795d594fSAndroid Build Coastguard Worker  return {parsed[11]}
1039*795d594fSAndroid Build Coastguard Worker
1040*795d594fSAndroid Build Coastguard Worker
1041*795d594fSAndroid Build Coastguard Workerdef get_target_cpu_count():
1042*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_ON_VM:
1043*795d594fSAndroid Build Coastguard Worker    command = f"{env.ART_SSH_CMD} cat /sys/devices/system/cpu/present"
1044*795d594fSAndroid Build Coastguard Worker  else:
1045*795d594fSAndroid Build Coastguard Worker    command = 'adb shell cat /sys/devices/system/cpu/present'
1046*795d594fSAndroid Build Coastguard Worker  cpu_info_proc = subprocess.Popen(command.split(), stdout=subprocess.PIPE)
1047*795d594fSAndroid Build Coastguard Worker  cpu_info = cpu_info_proc.stdout.read()
1048*795d594fSAndroid Build Coastguard Worker  if type(cpu_info) is bytes:
1049*795d594fSAndroid Build Coastguard Worker    cpu_info = cpu_info.decode('utf-8')
1050*795d594fSAndroid Build Coastguard Worker  cpu_info_regex = r'\d*-(\d*)'
1051*795d594fSAndroid Build Coastguard Worker  match = re.match(cpu_info_regex, cpu_info)
1052*795d594fSAndroid Build Coastguard Worker  if match:
1053*795d594fSAndroid Build Coastguard Worker    return int(match.group(1)) + 1  # Add one to convert from "last-index" to "count"
1054*795d594fSAndroid Build Coastguard Worker  else:
1055*795d594fSAndroid Build Coastguard Worker    raise ValueError('Unable to predict the concurrency for the target. '
1056*795d594fSAndroid Build Coastguard Worker                     'Is device connected?')
1057*795d594fSAndroid Build Coastguard Worker
1058*795d594fSAndroid Build Coastguard Worker
1059*795d594fSAndroid Build Coastguard Workerdef get_host_cpu_count():
1060*795d594fSAndroid Build Coastguard Worker  return multiprocessing.cpu_count()
1061*795d594fSAndroid Build Coastguard Worker
1062*795d594fSAndroid Build Coastguard Worker
1063*795d594fSAndroid Build Coastguard Workerdef parse_option():
1064*795d594fSAndroid Build Coastguard Worker  global verbose
1065*795d594fSAndroid Build Coastguard Worker  global dry_run
1066*795d594fSAndroid Build Coastguard Worker  global ignore_skips
1067*795d594fSAndroid Build Coastguard Worker  global n_thread
1068*795d594fSAndroid Build Coastguard Worker  global build
1069*795d594fSAndroid Build Coastguard Worker  global dist
1070*795d594fSAndroid Build Coastguard Worker  global gdb
1071*795d594fSAndroid Build Coastguard Worker  global gdb_arg
1072*795d594fSAndroid Build Coastguard Worker  global dump_cfg
1073*795d594fSAndroid Build Coastguard Worker  global gdb_dex2oat
1074*795d594fSAndroid Build Coastguard Worker  global gdb_dex2oat_args
1075*795d594fSAndroid Build Coastguard Worker  global runtime_option
1076*795d594fSAndroid Build Coastguard Worker  global run_test_option
1077*795d594fSAndroid Build Coastguard Worker  global timeout
1078*795d594fSAndroid Build Coastguard Worker  global dex2oat_jobs
1079*795d594fSAndroid Build Coastguard Worker  global run_all_configs
1080*795d594fSAndroid Build Coastguard Worker  global with_agent
1081*795d594fSAndroid Build Coastguard Worker  global csv_result
1082*795d594fSAndroid Build Coastguard Worker
1083*795d594fSAndroid Build Coastguard Worker  parser = argparse.ArgumentParser(description="Runs all or a subset of the ART test suite.")
1084*795d594fSAndroid Build Coastguard Worker  parser.add_argument('tests', action='extend', nargs="*", help='name(s) of the test(s)')
1085*795d594fSAndroid Build Coastguard Worker  parser.add_argument('-t', '--test', action='append', dest='tests', help='name(s) of the test(s)'
1086*795d594fSAndroid Build Coastguard Worker      ' (deprecated: use positional arguments at the end without any option instead)')
1087*795d594fSAndroid Build Coastguard Worker  global_group = parser.add_argument_group('Global options',
1088*795d594fSAndroid Build Coastguard Worker                                           'Options that affect all tests being run')
1089*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('-j', type=int, dest='n_thread', help="""Number of CPUs to use.
1090*795d594fSAndroid Build Coastguard Worker                            Defaults to half of CPUs on target and all CPUs on host.""")
1091*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--timeout', default=timeout, type=int, dest='timeout')
1092*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--verbose', '-v', action='store_true', dest='verbose')
1093*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--dry-run', action='store_true', dest='dry_run')
1094*795d594fSAndroid Build Coastguard Worker  global_group.add_argument("--skip", action='append', dest="skips", default=[],
1095*795d594fSAndroid Build Coastguard Worker                            help="Skip the given test in all circumstances.")
1096*795d594fSAndroid Build Coastguard Worker  global_group.add_argument("--no-skips", dest="ignore_skips", action='store_true', default=False,
1097*795d594fSAndroid Build Coastguard Worker                            help="""Don't skip any run-test configurations listed in
1098*795d594fSAndroid Build Coastguard Worker                            knownfailures.json.""")
1099*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--no-build-dependencies',
1100*795d594fSAndroid Build Coastguard Worker                            action='store_false', dest='build',
1101*795d594fSAndroid Build Coastguard Worker                            help="""Don't build dependencies under any circumstances. This is the
1102*795d594fSAndroid Build Coastguard Worker                            behavior if ART_TEST_RUN_TEST_ALWAYS_BUILD is not set to 'true'.""")
1103*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('-b', '--build-dependencies',
1104*795d594fSAndroid Build Coastguard Worker                            action='store_true', dest='build',
1105*795d594fSAndroid Build Coastguard Worker                            help="""Build dependencies under all circumstances. By default we will
1106*795d594fSAndroid Build Coastguard Worker                            not build dependencies unless ART_TEST_RUN_TEST_BUILD=true.""")
1107*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--dist',
1108*795d594fSAndroid Build Coastguard Worker                            action='store_true', dest='dist',
1109*795d594fSAndroid Build Coastguard Worker                            help="""If dependencies are to be built, pass `dist` to the build
1110*795d594fSAndroid Build Coastguard Worker                            command line. You may want to also set the DIST_DIR environment
1111*795d594fSAndroid Build Coastguard Worker                            variable when using this flag.""")
1112*795d594fSAndroid Build Coastguard Worker  global_group.set_defaults(build = env.ART_TEST_RUN_TEST_BUILD)
1113*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--gdb', action='store_true', dest='gdb')
1114*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--gdb-arg', dest='gdb_arg')
1115*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--dump-cfg', dest='dump_cfg',
1116*795d594fSAndroid Build Coastguard Worker                            help="""Dump the CFG to the specified host path.
1117*795d594fSAndroid Build Coastguard Worker                            Example \"--dump-cfg <full-path>/graph.cfg\".""")
1118*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--gdb-dex2oat', action='store_true', dest='gdb_dex2oat')
1119*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--gdb-dex2oat-args', dest='gdb_dex2oat_args')
1120*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--run-test-option', action='append', dest='run_test_option',
1121*795d594fSAndroid Build Coastguard Worker                            default=[],
1122*795d594fSAndroid Build Coastguard Worker                            help="""Pass an option, unaltered, to the run-test script.
1123*795d594fSAndroid Build Coastguard Worker                            This should be enclosed in single-quotes to allow for spaces. The option
1124*795d594fSAndroid Build Coastguard Worker                            will be split using shlex.split() prior to invoking run-test.
1125*795d594fSAndroid Build Coastguard Worker                            Example \"--run-test-option='--with-agent libtifast.so=MethodExit'\".""")
1126*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--with-agent', action='append', dest='with_agent',
1127*795d594fSAndroid Build Coastguard Worker                            help="""Pass an agent to be attached to the runtime""")
1128*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--runtime-option', action='append', dest='runtime_option',
1129*795d594fSAndroid Build Coastguard Worker                            help="""Pass an option to the runtime. Runtime options
1130*795d594fSAndroid Build Coastguard Worker                            starting with a '-' must be separated by a '=', for
1131*795d594fSAndroid Build Coastguard Worker                            example '--runtime-option=-Xjitthreshold:0'.""")
1132*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--dex2oat-jobs', type=int, dest='dex2oat_jobs',
1133*795d594fSAndroid Build Coastguard Worker                            help='Number of dex2oat jobs')
1134*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('-a', '--all', action='store_true', dest='run_all',
1135*795d594fSAndroid Build Coastguard Worker                            help="Run all the possible configurations for the input test set")
1136*795d594fSAndroid Build Coastguard Worker  global_group.add_argument('--csv-results', action='store', dest='csv_result', default=None,
1137*795d594fSAndroid Build Coastguard Worker                            type=argparse.FileType('w'), help='Store a CSV record of all results.')
1138*795d594fSAndroid Build Coastguard Worker  for variant_type, variant_set in VARIANT_TYPE_DICT.items():
1139*795d594fSAndroid Build Coastguard Worker    var_group = parser.add_argument_group(
1140*795d594fSAndroid Build Coastguard Worker        '{}-type Options'.format(variant_type),
1141*795d594fSAndroid Build Coastguard Worker        "Options that control the '{}' variants.".format(variant_type))
1142*795d594fSAndroid Build Coastguard Worker    var_group.add_argument('--all-' + variant_type,
1143*795d594fSAndroid Build Coastguard Worker                           action='store_true',
1144*795d594fSAndroid Build Coastguard Worker                           dest='all_' + variant_type,
1145*795d594fSAndroid Build Coastguard Worker                           help='Enable all variants of ' + variant_type)
1146*795d594fSAndroid Build Coastguard Worker    for variant in variant_set:
1147*795d594fSAndroid Build Coastguard Worker      flag = '--' + variant
1148*795d594fSAndroid Build Coastguard Worker      var_group.add_argument(flag, action='store_true', dest=variant)
1149*795d594fSAndroid Build Coastguard Worker
1150*795d594fSAndroid Build Coastguard Worker  options = vars(parser.parse_args())
1151*795d594fSAndroid Build Coastguard Worker  if options['csv_result'] is not None:
1152*795d594fSAndroid Build Coastguard Worker    csv_result = options['csv_result']
1153*795d594fSAndroid Build Coastguard Worker    setup_csv_result()
1154*795d594fSAndroid Build Coastguard Worker  # Handle the --all-<type> meta-options
1155*795d594fSAndroid Build Coastguard Worker  for variant_type, variant_set in VARIANT_TYPE_DICT.items():
1156*795d594fSAndroid Build Coastguard Worker    if options['all_' + variant_type]:
1157*795d594fSAndroid Build Coastguard Worker      for variant in variant_set:
1158*795d594fSAndroid Build Coastguard Worker        options[variant] = True
1159*795d594fSAndroid Build Coastguard Worker
1160*795d594fSAndroid Build Coastguard Worker  tests = None
1161*795d594fSAndroid Build Coastguard Worker  env.EXTRA_DISABLED_TESTS.update(set(options['skips']))
1162*795d594fSAndroid Build Coastguard Worker  if options['tests']:
1163*795d594fSAndroid Build Coastguard Worker    tests = set()
1164*795d594fSAndroid Build Coastguard Worker    for test_name in options['tests']:
1165*795d594fSAndroid Build Coastguard Worker      tests |= parse_test_name(test_name)
1166*795d594fSAndroid Build Coastguard Worker
1167*795d594fSAndroid Build Coastguard Worker  for variant_type in VARIANT_TYPE_DICT:
1168*795d594fSAndroid Build Coastguard Worker    for variant in VARIANT_TYPE_DICT[variant_type]:
1169*795d594fSAndroid Build Coastguard Worker      if options.get(variant):
1170*795d594fSAndroid Build Coastguard Worker        _user_input_variants[variant_type].add(variant)
1171*795d594fSAndroid Build Coastguard Worker
1172*795d594fSAndroid Build Coastguard Worker  if options['verbose']:
1173*795d594fSAndroid Build Coastguard Worker    verbose = True
1174*795d594fSAndroid Build Coastguard Worker  if options['n_thread']:
1175*795d594fSAndroid Build Coastguard Worker    n_thread = max(1, options['n_thread'])
1176*795d594fSAndroid Build Coastguard Worker  ignore_skips = options['ignore_skips']
1177*795d594fSAndroid Build Coastguard Worker  if options['dry_run']:
1178*795d594fSAndroid Build Coastguard Worker    dry_run = True
1179*795d594fSAndroid Build Coastguard Worker    verbose = True
1180*795d594fSAndroid Build Coastguard Worker  build = options['build']
1181*795d594fSAndroid Build Coastguard Worker  dist = options['dist']
1182*795d594fSAndroid Build Coastguard Worker  if options['gdb']:
1183*795d594fSAndroid Build Coastguard Worker    n_thread = 1
1184*795d594fSAndroid Build Coastguard Worker    gdb = True
1185*795d594fSAndroid Build Coastguard Worker    if options['gdb_arg']:
1186*795d594fSAndroid Build Coastguard Worker      gdb_arg = options['gdb_arg']
1187*795d594fSAndroid Build Coastguard Worker  if options['dump_cfg']:
1188*795d594fSAndroid Build Coastguard Worker    dump_cfg = options['dump_cfg']
1189*795d594fSAndroid Build Coastguard Worker  if options['gdb_dex2oat']:
1190*795d594fSAndroid Build Coastguard Worker    n_thread = 1
1191*795d594fSAndroid Build Coastguard Worker    gdb_dex2oat = True
1192*795d594fSAndroid Build Coastguard Worker    if options['gdb_dex2oat_args']:
1193*795d594fSAndroid Build Coastguard Worker      gdb_dex2oat_args = options['gdb_dex2oat_args']
1194*795d594fSAndroid Build Coastguard Worker  runtime_option = options['runtime_option'];
1195*795d594fSAndroid Build Coastguard Worker  with_agent = options['with_agent'];
1196*795d594fSAndroid Build Coastguard Worker  run_test_option = sum(map(shlex.split, options['run_test_option']), [])
1197*795d594fSAndroid Build Coastguard Worker
1198*795d594fSAndroid Build Coastguard Worker  timeout = options['timeout']
1199*795d594fSAndroid Build Coastguard Worker  if options['dex2oat_jobs']:
1200*795d594fSAndroid Build Coastguard Worker    dex2oat_jobs = options['dex2oat_jobs']
1201*795d594fSAndroid Build Coastguard Worker  if options['run_all']:
1202*795d594fSAndroid Build Coastguard Worker    run_all_configs = True
1203*795d594fSAndroid Build Coastguard Worker
1204*795d594fSAndroid Build Coastguard Worker  return tests or RUN_TEST_SET
1205*795d594fSAndroid Build Coastguard Worker
1206*795d594fSAndroid Build Coastguard Workerdef main():
1207*795d594fSAndroid Build Coastguard Worker  gather_test_info()
1208*795d594fSAndroid Build Coastguard Worker  tests = parse_option()
1209*795d594fSAndroid Build Coastguard Worker  setup_test_env()
1210*795d594fSAndroid Build Coastguard Worker  gather_disabled_test_info()
1211*795d594fSAndroid Build Coastguard Worker  if build:
1212*795d594fSAndroid Build Coastguard Worker    build_targets = []
1213*795d594fSAndroid Build Coastguard Worker    # Build only the needed shards (depending on the selected tests).
1214*795d594fSAndroid Build Coastguard Worker    shards = set(re.search("(\d\d)-", t).group(1) for t in tests)
1215*795d594fSAndroid Build Coastguard Worker    if any("hiddenapi" in t for t in tests):
1216*795d594fSAndroid Build Coastguard Worker      shards.add("HiddenApi")  # Include special HiddenApi shard.
1217*795d594fSAndroid Build Coastguard Worker    for mode in ['host', 'target', 'jvm']:
1218*795d594fSAndroid Build Coastguard Worker      if mode in _user_input_variants['target']:
1219*795d594fSAndroid Build Coastguard Worker        build_targets += ['test-art-{}-run-test-dependencies'.format(mode)]
1220*795d594fSAndroid Build Coastguard Worker        if len(shards) >= 100:
1221*795d594fSAndroid Build Coastguard Worker          build_targets += ["art-run-test-{}-data".format(mode)]  # Build all.
1222*795d594fSAndroid Build Coastguard Worker        else:
1223*795d594fSAndroid Build Coastguard Worker          build_targets += ["art-run-test-{}-data-shard{}".format(mode, s) for s in shards]
1224*795d594fSAndroid Build Coastguard Worker    build_command = env.ANDROID_BUILD_TOP + '/build/soong/soong_ui.bash --make-mode'
1225*795d594fSAndroid Build Coastguard Worker    build_command += ' D8='
1226*795d594fSAndroid Build Coastguard Worker    if dist:
1227*795d594fSAndroid Build Coastguard Worker      build_command += ' dist'
1228*795d594fSAndroid Build Coastguard Worker    build_command += ' ' + ' '.join(build_targets)
1229*795d594fSAndroid Build Coastguard Worker    print_text('Build command: %s\n' % build_command)
1230*795d594fSAndroid Build Coastguard Worker    if subprocess.call(build_command.split()):
1231*795d594fSAndroid Build Coastguard Worker      # Debugging for b/62653020
1232*795d594fSAndroid Build Coastguard Worker      if env.DIST_DIR:
1233*795d594fSAndroid Build Coastguard Worker        shutil.copyfile(env.SOONG_OUT_DIR + '/build.ninja', env.DIST_DIR + '/soong.ninja')
1234*795d594fSAndroid Build Coastguard Worker      sys.exit(1)
1235*795d594fSAndroid Build Coastguard Worker
1236*795d594fSAndroid Build Coastguard Worker  run_tests(tests)
1237*795d594fSAndroid Build Coastguard Worker
1238*795d594fSAndroid Build Coastguard Worker  print_analysis()
1239*795d594fSAndroid Build Coastguard Worker  close_csv_file()
1240*795d594fSAndroid Build Coastguard Worker
1241*795d594fSAndroid Build Coastguard Worker  exit_code = 0 if len(failed_tests) == 0 else 1
1242*795d594fSAndroid Build Coastguard Worker  sys.exit(exit_code)
1243*795d594fSAndroid Build Coastguard Worker
1244*795d594fSAndroid Build Coastguard Workerif __name__ == '__main__':
1245*795d594fSAndroid Build Coastguard Worker  main()
1246