blob: 9ab4ba754ba2b23e730edbff6fd5c30e3399b7f4 [file] [log] [blame]
Shubham Ajmerafe793492017-03-16 13:31:35 -07001#!/usr/bin/env python3
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00002#
Roland Levillain4e8e0a52019-08-29 16:28:26 +01003# [VPYTHON:BEGIN]
David Srbecky8feeef62019-08-29 10:11:21 +01004# python_version: "3.8"
Roland Levillain4e8e0a52019-08-29 16:28:26 +01005# [VPYTHON:END]
David Srbecky8feeef62019-08-29 10:11:21 +01006#
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00007# Copyright 2017, The Android Open Source Project
8#
9# Licensed under the Apache License, Version 2.0 (the "License");
10# you may not use this file except in compliance with the License.
11# You may obtain a copy of the License at
12#
13# http://www.apache.org/licenses/LICENSE-2.0
14#
15# Unless required by applicable law or agreed to in writing, software
16# distributed under the License is distributed on an "AS IS" BASIS,
17# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18# See the License for the specific language governing permissions and
19# limitations under the License.
20
21"""ART Run-Test TestRunner
22
23The testrunner runs the ART run-tests by simply invoking the script.
24It fetches the list of eligible tests from art/test directory, and list of
25disabled tests from art/test/knownfailures.json. It runs the tests by
26invoking art/test/run-test script and checks the exit value to decide if the
27test passed or failed.
28
29Before invoking the script, first build all the tests dependencies.
30There are two major build targets for building target and host tests
31dependencies:
321) test-art-host-run-test
332) test-art-target-run-test
34
35There are various options to invoke the script which are:
36-t: Either the test name as in art/test or the test name including the variant
37 information. Eg, "-t 001-HelloWorld",
Vladimir Markoa2da9b92018-10-10 14:21:55 +010038 "-t test-art-host-run-test-debug-prebuild-optimizing-relocate-ntrace-cms-checkjni-picimage-ndebuggable-001-HelloWorld32"
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000039-j: Number of thread workers to be used. Eg - "-j64"
40--dry-run: Instead of running the test name, just print its name.
41--verbose
42-b / --build-dependencies: to build the dependencies before running the test
43
44To specify any specific variants for the test, use --<<variant-name>>.
45For eg, for compiler type as optimizing, use --optimizing.
46
47
48In the end, the script will print the failed and skipped tests if any.
49
50"""
Alex Light7a1ccf82017-02-21 09:52:34 -080051import argparse
Shubham Ajmera85853952017-08-29 16:26:21 -070052import collections
Andreas Gampe49484072019-08-28 11:03:37 -070053
54# b/140161314 diagnostics.
55try:
56 import concurrent.futures
57except Exception:
58 import sys
59 sys.stdout.write("\n\n" + sys.executable + " " + sys.version + "\n\n")
60 sys.stdout.flush()
61 raise
62
Alex Light6f342dd2019-03-27 17:15:42 +000063import contextlib
Alex Lightaba509f2020-05-12 15:19:52 -070064import csv
Andreas Gampe7409b9f2019-07-08 09:29:52 -070065import datetime
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000066import fnmatch
67import itertools
68import json
Shubham Ajmera4a5a1622017-03-22 10:07:19 -070069import multiprocessing
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000070import os
71import re
Alex Light26829182018-06-11 11:36:24 -070072import shlex
Colin Cross9cb13a62018-06-07 13:02:02 -070073import shutil
David Srbeckye456b6f2019-10-04 11:27:51 +010074import signal
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000075import subprocess
76import sys
Shubham Ajmera29f89682017-03-24 14:44:10 -070077import tempfile
Martin Stjernholmfd7044d2021-04-27 16:01:17 +010078import threading
Orion Hodson3e29e192019-09-03 14:24:04 +010079import time
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000080
81import env
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -080082from target_config import target_config
Alex Light3412a002017-10-20 13:44:40 +000083from device_config import device_config
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000084
Shubham Ajmera186d3212017-07-21 01:20:57 +000085# TODO: make it adjustable per tests and for buildbots
Andreas Gampe60931d92019-09-12 10:12:11 -070086#
87# Note: this needs to be larger than run-test timeouts, as long as this script
88# does not push the value to run-test. run-test is somewhat complicated:
89# base: 25m (large for ASAN)
90# + timeout handling: 2m
David Srbecky7021c132019-10-04 12:56:22 +010091# + gcstress extra: 20m
Andreas Gampe60931d92019-09-12 10:12:11 -070092# -----------------------
David Srbecky7021c132019-10-04 12:56:22 +010093# 47m
94timeout = 3600 # 60 minutes
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000095
Artem Serov381d35c2021-02-10 21:27:00 +000096if env.ART_TEST_RUN_ON_ARM_FVP:
97 # Increase timeout to 600 minutes due to the emulation overhead on FVP.
98 timeout = 36000
99
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000100# DISABLED_TEST_CONTAINER holds information about the disabled tests. It is a map
101# that has key as the test name (like 001-HelloWorld), and value as set of
102# variants that the test is disabled for.
103DISABLED_TEST_CONTAINER = {}
104
105# The Dict contains the list of all possible variants for a given type. For example,
106# for key TARGET, the value would be target and host. The list is used to parse
107# the test name given as the argument to run.
108VARIANT_TYPE_DICT = {}
109
Alex Lighta86a5d12019-08-30 11:03:05 -0700110# The set of all variant sets that are incompatible and will always be skipped.
111NONFUNCTIONAL_VARIANT_SETS = set()
112
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000113# The set contains all the variants of each time.
114TOTAL_VARIANTS_SET = set()
115
116# The colors are used in the output. When a test passes, COLOR_PASS is used,
117# and so on.
118COLOR_ERROR = '\033[91m'
119COLOR_PASS = '\033[92m'
120COLOR_SKIP = '\033[93m'
121COLOR_NORMAL = '\033[0m'
122
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000123# The set contains the list of all the possible run tests that are in art/test
124# directory.
125RUN_TEST_SET = set()
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000126
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000127failed_tests = []
128skipped_tests = []
129
130# Flags
David Srbeckye1d17062021-04-20 16:41:29 +0000131n_thread = 0
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000132total_test_count = 0
133verbose = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000134dry_run = False
Alex Light42242dd2018-02-16 09:23:57 -0800135ignore_skips = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000136build = False
Roland Levillain93e4df72020-06-29 13:33:56 +0100137dist = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000138gdb = False
139gdb_arg = ''
Stelios Ioannou1b621222021-06-17 14:15:45 +0100140dump_cfg = ''
Stelios Ioannou816b0da2021-06-03 13:25:50 +0100141gdb_dex2oat = False
142gdb_dex2oat_args = ''
Alex Lightaba509f2020-05-12 15:19:52 -0700143csv_result = None
144csv_writer = None
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000145runtime_option = ''
Alex Lighte9f61032018-09-24 16:04:51 -0700146with_agent = []
Alex Light6f342dd2019-03-27 17:15:42 +0000147zipapex_loc = None
Alex Light26829182018-06-11 11:36:24 -0700148run_test_option = []
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700149dex2oat_jobs = -1 # -1 corresponds to default threads for dex2oat
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700150run_all_configs = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000151
Alex Light3412a002017-10-20 13:44:40 +0000152# Dict containing extra arguments
153extra_arguments = { "host" : [], "target" : [] }
154
Shubham Ajmera85853952017-08-29 16:26:21 -0700155# Dict to store user requested test variants.
156# key: variant_type.
157# value: set of variants user wants to run of type <key>.
158_user_input_variants = collections.defaultdict(set)
159
Martin Stjernholmfd7044d2021-04-27 16:01:17 +0100160
161class ChildProcessTracker(object):
162 """Keeps track of forked child processes to be able to kill them."""
163
164 def __init__(self):
165 self.procs = {} # dict from pid to subprocess.Popen object
166 self.mutex = threading.Lock()
167
168 def wait(self, proc, timeout):
169 """Waits on the given subprocess and makes it available to kill_all meanwhile.
170
171 Args:
172 proc: The subprocess.Popen object to wait on.
173 timeout: Timeout passed on to proc.communicate.
174
175 Returns: A tuple of the process stdout output and its return value.
176 """
177 with self.mutex:
178 if self.procs is not None:
179 self.procs[proc.pid] = proc
180 else:
181 os.killpg(proc.pid, signal.SIGKILL) # kill_all has already been called.
182 try:
183 output = proc.communicate(timeout=timeout)[0]
184 return_value = proc.wait()
185 return output, return_value
186 finally:
187 with self.mutex:
188 if self.procs is not None:
189 del self.procs[proc.pid]
190
191 def kill_all(self):
192 """Kills all currently running processes and any future ones."""
193 with self.mutex:
194 for pid in self.procs:
195 os.killpg(pid, signal.SIGKILL)
196 self.procs = None # Make future wait() calls kill their processes immediately.
197
198child_process_tracker = ChildProcessTracker()
199
Alex Lightaba509f2020-05-12 15:19:52 -0700200def setup_csv_result():
201 """Set up the CSV output if required."""
202 global csv_writer
203 csv_writer = csv.writer(csv_result)
204 # Write the header.
205 csv_writer.writerow(['target', 'run', 'prebuild', 'compiler', 'relocate', 'trace', 'gc',
206 'jni', 'image', 'debuggable', 'jvmti', 'cdex_level', 'test', 'address_size', 'result'])
207
208
209def send_csv_result(test, result):
210 """
211 Write a line into the CSV results file if one is available.
212 """
213 if csv_writer is not None:
214 csv_writer.writerow(extract_test_name(test) + [result])
215
216def close_csv_file():
217 global csv_result
218 global csv_writer
219 if csv_result is not None:
220 csv_writer = None
221 csv_result.flush()
222 csv_result.close()
223 csv_result = None
224
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000225def gather_test_info():
226 """The method gathers test information about the test to be run which includes
227 generating the list of total tests from the art/test directory and the list
228 of disabled test. It also maps various variants to types.
229 """
230 global TOTAL_VARIANTS_SET
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000231 # TODO: Avoid duplication of the variant names in different lists.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000232 VARIANT_TYPE_DICT['run'] = {'ndebug', 'debug'}
Ulya Trafimovich5439f052020-07-29 10:03:46 +0100233 VARIANT_TYPE_DICT['target'] = {'target', 'host', 'jvm'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000234 VARIANT_TYPE_DICT['trace'] = {'trace', 'ntrace', 'stream'}
Vladimir Marko4519b9d2018-10-10 15:21:21 +0100235 VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000236 VARIANT_TYPE_DICT['debuggable'] = {'ndebuggable', 'debuggable'}
237 VARIANT_TYPE_DICT['gc'] = {'gcstress', 'gcverify', 'cms'}
Nicolas Geoffray3d8a78a2018-08-29 21:10:16 +0000238 VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'prebuild'}
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800239 VARIANT_TYPE_DICT['cdex_level'] = {'cdex-none', 'cdex-fast'}
Vladimir Markoa497a392018-09-26 10:52:50 +0100240 VARIANT_TYPE_DICT['relocate'] = {'relocate', 'no-relocate'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000241 VARIANT_TYPE_DICT['jni'] = {'jni', 'forcecopy', 'checkjni'}
242 VARIANT_TYPE_DICT['address_sizes'] = {'64', '32'}
Alex Light43e935d2017-06-19 15:40:40 -0700243 VARIANT_TYPE_DICT['jvmti'] = {'no-jvmti', 'jvmti-stress', 'redefine-stress', 'trace-stress',
Alex Lightc38c3692017-06-27 15:45:14 -0700244 'field-stress', 'step-stress'}
Roland Levillainad694bf2018-10-09 14:49:15 +0100245 VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'jit-on-first-use',
Alex Lighta86a5d12019-08-30 11:03:05 -0700246 'optimizing', 'regalloc_gc',
247 'speed-profile', 'baseline'}
248
249 # Regalloc_GC cannot work with prebuild.
250 NONFUNCTIONAL_VARIANT_SETS.add(frozenset({'regalloc_gc', 'prebuild'}))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000251
252 for v_type in VARIANT_TYPE_DICT:
253 TOTAL_VARIANTS_SET = TOTAL_VARIANTS_SET.union(VARIANT_TYPE_DICT.get(v_type))
254
255 test_dir = env.ANDROID_BUILD_TOP + '/art/test'
256 for f in os.listdir(test_dir):
257 if fnmatch.fnmatch(f, '[0-9]*'):
258 RUN_TEST_SET.add(f)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000259
260
261def setup_test_env():
262 """The method sets default value for the various variants of the tests if they
263 are already not set.
264 """
265 if env.ART_TEST_BISECTION:
266 env.ART_TEST_RUN_TEST_NO_PREBUILD = True
267 env.ART_TEST_RUN_TEST_PREBUILD = False
268 # Bisection search writes to standard output.
269 env.ART_TEST_QUIET = False
270
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700271 global _user_input_variants
272 global run_all_configs
Alex Lighta90c68c2018-03-26 14:50:24 -0700273 # These are the default variant-options we will use if nothing in the group is specified.
274 default_variants = {
275 'target': {'host', 'target'},
Alex Lighta90c68c2018-03-26 14:50:24 -0700276 'prebuild': {'prebuild'},
277 'cdex_level': {'cdex-fast'},
278 'jvmti': { 'no-jvmti'},
279 'compiler': {'optimizing',
280 'jit',
281 'interpreter',
282 'interp-ac',
283 'speed-profile'},
284 'relocate': {'no-relocate'},
285 'trace': {'ntrace'},
286 'gc': {'cms'},
287 'jni': {'checkjni'},
288 'image': {'picimage'},
Alex Lighta90c68c2018-03-26 14:50:24 -0700289 'debuggable': {'ndebuggable'},
290 'run': {'debug'},
291 # address_sizes_target depends on the target so it is dealt with below.
292 }
293 # We want to pull these early since the full VARIANT_TYPE_DICT has a few additional ones we don't
294 # want to pick up if we pass --all.
295 default_variants_keys = default_variants.keys()
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700296 if run_all_configs:
Alex Lighta90c68c2018-03-26 14:50:24 -0700297 default_variants = VARIANT_TYPE_DICT
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700298
Alex Lighta90c68c2018-03-26 14:50:24 -0700299 for key in default_variants_keys:
300 if not _user_input_variants[key]:
301 _user_input_variants[key] = default_variants[key]
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700302
Shubham Ajmera85853952017-08-29 16:26:21 -0700303 _user_input_variants['address_sizes_target'] = collections.defaultdict(set)
304 if not _user_input_variants['address_sizes']:
305 _user_input_variants['address_sizes_target']['target'].add(
306 env.ART_PHONY_TEST_TARGET_SUFFIX)
307 _user_input_variants['address_sizes_target']['host'].add(
308 env.ART_PHONY_TEST_HOST_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000309 if env.ART_TEST_RUN_TEST_2ND_ARCH:
Shubham Ajmera85853952017-08-29 16:26:21 -0700310 _user_input_variants['address_sizes_target']['host'].add(
311 env.ART_2ND_PHONY_TEST_HOST_SUFFIX)
312 _user_input_variants['address_sizes_target']['target'].add(
313 env.ART_2ND_PHONY_TEST_TARGET_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000314 else:
Shubham Ajmera85853952017-08-29 16:26:21 -0700315 _user_input_variants['address_sizes_target']['host'] = _user_input_variants['address_sizes']
316 _user_input_variants['address_sizes_target']['target'] = _user_input_variants['address_sizes']
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000317
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700318 global n_thread
David Srbecky0108f0d2021-05-09 21:56:04 +0100319 if 'target' in _user_input_variants['target']:
320 device_name = get_device_name()
321 if n_thread == 0:
David Srbecky50535212021-11-30 18:30:46 +0000322 # Use only part of the cores since fully loading the device tends to lead to timeouts.
323 n_thread = max(1, int(get_target_cpu_count() * 0.75))
David Srbecky0108f0d2021-05-09 21:56:04 +0100324 if device_name == 'fugu':
325 n_thread = 1
326 else:
327 device_name = "host"
328 if n_thread == 0:
David Srbeckye1d17062021-04-20 16:41:29 +0000329 n_thread = get_host_cpu_count()
David Srbecky0108f0d2021-05-09 21:56:04 +0100330 print_text("Concurrency: {} ({})\n".format(n_thread, device_name))
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700331
Alex Light3412a002017-10-20 13:44:40 +0000332 global extra_arguments
333 for target in _user_input_variants['target']:
334 extra_arguments[target] = find_extra_device_arguments(target)
335
Shubham Ajmera22499e22017-03-22 18:33:37 -0700336 if not sys.stdout.isatty():
337 global COLOR_ERROR
338 global COLOR_PASS
339 global COLOR_SKIP
340 global COLOR_NORMAL
341 COLOR_ERROR = ''
342 COLOR_PASS = ''
343 COLOR_SKIP = ''
344 COLOR_NORMAL = ''
345
Alex Light3412a002017-10-20 13:44:40 +0000346def find_extra_device_arguments(target):
347 """
348 Gets any extra arguments from the device_config.
349 """
Igor Murashkinbab15062018-02-23 14:53:24 -0800350 device_name = target
351 if target == 'target':
352 device_name = get_device_name()
353 return device_config.get(device_name, { 'run-test-args' : [] })['run-test-args']
Alex Light3412a002017-10-20 13:44:40 +0000354
355def get_device_name():
356 """
357 Gets the value of ro.product.name from remote device.
358 """
359 proc = subprocess.Popen(['adb', 'shell', 'getprop', 'ro.product.name'],
360 stderr=subprocess.STDOUT,
361 stdout = subprocess.PIPE,
362 universal_newlines=True)
363 # only wait 2 seconds.
Artem Serov381d35c2021-02-10 21:27:00 +0000364 timeout_val = 2
365
366 if env.ART_TEST_RUN_ON_ARM_FVP:
367 # Increase timeout to 200 seconds due to the emulation overhead on FVP.
368 timeout_val = 200
369
370 output = proc.communicate(timeout = timeout_val)[0]
Alex Light3412a002017-10-20 13:44:40 +0000371 success = not proc.wait()
372 if success:
373 return output.strip()
374 else:
375 print_text("Unable to determine device type!\n")
376 print_text("Continuing anyway.\n")
377 return "UNKNOWN_TARGET"
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000378
379def run_tests(tests):
Orion Hodson163c8ab2019-04-05 11:40:30 +0100380 """This method generates variants of the tests to be run and executes them.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000381
382 Args:
383 tests: The set of tests to be run.
384 """
385 options_all = ''
Igor Murashkinbab15062018-02-23 14:53:24 -0800386
387 # jvm does not run with all these combinations,
388 # or at least it doesn't make sense for most of them.
389 # TODO: support some jvm variants like jvmti ?
390 target_input_variants = _user_input_variants['target']
391 uncombinated_target_input_variants = []
392 if 'jvm' in target_input_variants:
393 _user_input_variants['target'].remove('jvm')
394 uncombinated_target_input_variants.append('jvm')
395
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000396 global total_test_count
397 total_test_count = len(tests)
Igor Murashkinbab15062018-02-23 14:53:24 -0800398 if target_input_variants:
399 for variant_type in VARIANT_TYPE_DICT:
400 if not (variant_type == 'target' or 'address_sizes' in variant_type):
401 total_test_count *= len(_user_input_variants[variant_type])
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000402 target_address_combinations = 0
Igor Murashkinbab15062018-02-23 14:53:24 -0800403 for target in target_input_variants:
Shubham Ajmera85853952017-08-29 16:26:21 -0700404 for address_size in _user_input_variants['address_sizes_target'][target]:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000405 target_address_combinations += 1
Igor Murashkinbab15062018-02-23 14:53:24 -0800406 target_address_combinations += len(uncombinated_target_input_variants)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000407 total_test_count *= target_address_combinations
408
409 if env.ART_TEST_WITH_STRACE:
410 options_all += ' --strace'
411
412 if env.ART_TEST_RUN_TEST_ALWAYS_CLEAN:
413 options_all += ' --always-clean'
414
415 if env.ART_TEST_BISECTION:
416 options_all += ' --bisection-search'
417
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000418 if gdb:
419 options_all += ' --gdb'
420 if gdb_arg:
421 options_all += ' --gdb-arg ' + gdb_arg
422
Stelios Ioannou1b621222021-06-17 14:15:45 +0100423 if dump_cfg:
424 options_all += ' --dump-cfg ' + dump_cfg
Stelios Ioannou816b0da2021-06-03 13:25:50 +0100425 if gdb_dex2oat:
426 options_all += ' --gdb-dex2oat'
427 if gdb_dex2oat_args:
428 options_all += ' --gdb-dex2oat-args ' + gdb_dex2oat_args
Stelios Ioannou1b621222021-06-17 14:15:45 +0100429
Alex Light0d20d582018-06-12 16:16:41 -0700430 options_all += ' ' + ' '.join(run_test_option)
Alex Light26829182018-06-11 11:36:24 -0700431
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000432 if runtime_option:
433 for opt in runtime_option:
434 options_all += ' --runtime-option ' + opt
Alex Lighte9f61032018-09-24 16:04:51 -0700435 if with_agent:
436 for opt in with_agent:
437 options_all += ' --with-agent ' + opt
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000438
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700439 if dex2oat_jobs != -1:
440 options_all += ' --dex2oat-jobs ' + str(dex2oat_jobs)
441
Igor Murashkinbab15062018-02-23 14:53:24 -0800442 def iter_config(tests, input_variants, user_input_variants):
443 config = itertools.product(tests, input_variants, user_input_variants['run'],
444 user_input_variants['prebuild'], user_input_variants['compiler'],
445 user_input_variants['relocate'], user_input_variants['trace'],
446 user_input_variants['gc'], user_input_variants['jni'],
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100447 user_input_variants['image'],
Igor Murashkinbab15062018-02-23 14:53:24 -0800448 user_input_variants['debuggable'], user_input_variants['jvmti'],
449 user_input_variants['cdex_level'])
450 return config
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000451
Igor Murashkinbab15062018-02-23 14:53:24 -0800452 # [--host, --target] combines with all the other user input variants.
453 config = iter_config(tests, target_input_variants, _user_input_variants)
454 # [--jvm] currently combines with nothing else. most of the extra flags we'd insert
455 # would be unrecognizable by the 'java' binary, so avoid inserting any extra flags for now.
456 uncombinated_config = iter_config(tests, uncombinated_target_input_variants, { 'run': [''],
457 'prebuild': [''], 'compiler': [''],
458 'relocate': [''], 'trace': [''],
459 'gc': [''], 'jni': [''],
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100460 'image': [''],
Igor Murashkinbab15062018-02-23 14:53:24 -0800461 'debuggable': [''], 'jvmti': [''],
462 'cdex_level': ['']})
463
Orion Hodson163c8ab2019-04-05 11:40:30 +0100464 def start_combination(executor, config_tuple, global_options, address_size):
Igor Murashkinbab15062018-02-23 14:53:24 -0800465 test, target, run, prebuild, compiler, relocate, trace, gc, \
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100466 jni, image, debuggable, jvmti, cdex_level = config_tuple
Igor Murashkinbab15062018-02-23 14:53:24 -0800467
Orion Hodson75a58dc2018-02-05 14:37:31 +0000468 # NB The order of components here should match the order of
469 # components in the regex parser in parse_test_name.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000470 test_name = 'test-art-'
471 test_name += target + '-run-test-'
472 test_name += run + '-'
473 test_name += prebuild + '-'
474 test_name += compiler + '-'
475 test_name += relocate + '-'
476 test_name += trace + '-'
477 test_name += gc + '-'
478 test_name += jni + '-'
479 test_name += image + '-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000480 test_name += debuggable + '-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700481 test_name += jvmti + '-'
Orion Hodson75a58dc2018-02-05 14:37:31 +0000482 test_name += cdex_level + '-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000483 test_name += test
484 test_name += address_size
485
486 variant_set = {target, run, prebuild, compiler, relocate, trace, gc, jni,
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100487 image, debuggable, jvmti, cdex_level, address_size}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000488
Alex Light6f342dd2019-03-27 17:15:42 +0000489 options_test = global_options
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000490
491 if target == 'host':
492 options_test += ' --host'
Igor Murashkinbab15062018-02-23 14:53:24 -0800493 elif target == 'jvm':
494 options_test += ' --jvm'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000495
Martin Stjernholme58624f2019-09-20 15:53:40 +0100496 # Honor ART_TEST_CHROOT, ART_TEST_ANDROID_ROOT, ART_TEST_ANDROID_ART_ROOT,
497 # ART_TEST_ANDROID_I18N_ROOT, and ART_TEST_ANDROID_TZDATA_ROOT but only
498 # for target tests.
Roland Levillainb0633b22018-05-24 15:59:18 +0100499 if target == 'target':
500 if env.ART_TEST_CHROOT:
501 options_test += ' --chroot ' + env.ART_TEST_CHROOT
502 if env.ART_TEST_ANDROID_ROOT:
503 options_test += ' --android-root ' + env.ART_TEST_ANDROID_ROOT
Victor Chang64611242019-07-05 16:32:41 +0100504 if env.ART_TEST_ANDROID_I18N_ROOT:
505 options_test += ' --android-i18n-root ' + env.ART_TEST_ANDROID_I18N_ROOT
Martin Stjernholme58624f2019-09-20 15:53:40 +0100506 if env.ART_TEST_ANDROID_ART_ROOT:
507 options_test += ' --android-art-root ' + env.ART_TEST_ANDROID_ART_ROOT
Neil Fuller26a5dd62019-03-13 15:16:35 +0000508 if env.ART_TEST_ANDROID_TZDATA_ROOT:
509 options_test += ' --android-tzdata-root ' + env.ART_TEST_ANDROID_TZDATA_ROOT
Roland Levillainb0633b22018-05-24 15:59:18 +0100510
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000511 if run == 'ndebug':
512 options_test += ' -O'
513
514 if prebuild == 'prebuild':
515 options_test += ' --prebuild'
516 elif prebuild == 'no-prebuild':
517 options_test += ' --no-prebuild'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000518
Orion Hodson6aa4e0d2018-05-25 09:39:16 +0100519 if cdex_level:
520 # Add option and remove the cdex- prefix.
521 options_test += ' --compact-dex-level ' + cdex_level.replace('cdex-','')
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800522
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000523 if compiler == 'optimizing':
524 options_test += ' --optimizing'
525 elif compiler == 'regalloc_gc':
526 options_test += ' --optimizing -Xcompiler-option --register-allocation-strategy=graph-color'
527 elif compiler == 'interpreter':
528 options_test += ' --interpreter'
529 elif compiler == 'interp-ac':
530 options_test += ' --interpreter --verify-soft-fail'
531 elif compiler == 'jit':
532 options_test += ' --jit'
Roland Levillainad694bf2018-10-09 14:49:15 +0100533 elif compiler == 'jit-on-first-use':
534 options_test += ' --jit --runtime-option -Xjitthreshold:0'
Jeff Hao002b9312017-03-27 16:23:08 -0700535 elif compiler == 'speed-profile':
536 options_test += ' --random-profile'
Nicolas Geoffrayacc56ac2018-10-09 08:45:24 +0100537 elif compiler == 'baseline':
538 options_test += ' --baseline'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000539
540 if relocate == 'relocate':
541 options_test += ' --relocate'
542 elif relocate == 'no-relocate':
543 options_test += ' --no-relocate'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000544
545 if trace == 'trace':
546 options_test += ' --trace'
547 elif trace == 'stream':
548 options_test += ' --trace --stream'
549
550 if gc == 'gcverify':
551 options_test += ' --gcverify'
552 elif gc == 'gcstress':
553 options_test += ' --gcstress'
554
555 if jni == 'forcecopy':
556 options_test += ' --runtime-option -Xjniopts:forcecopy'
557 elif jni == 'checkjni':
558 options_test += ' --runtime-option -Xcheck:jni'
559
560 if image == 'no-image':
561 options_test += ' --no-image'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000562
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000563 if debuggable == 'debuggable':
Alex Lightbb5b4f32019-07-09 02:31:48 -0700564 options_test += ' --debuggable --runtime-option -Xopaque-jni-ids:true'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000565
Alex Light8f2c6d42017-04-10 16:27:35 -0700566 if jvmti == 'jvmti-stress':
Alex Light43e935d2017-06-19 15:40:40 -0700567 options_test += ' --jvmti-trace-stress --jvmti-redefine-stress --jvmti-field-stress'
568 elif jvmti == 'field-stress':
569 options_test += ' --jvmti-field-stress'
Alex Lightb7edcda2017-04-27 13:20:31 -0700570 elif jvmti == 'trace-stress':
571 options_test += ' --jvmti-trace-stress'
572 elif jvmti == 'redefine-stress':
573 options_test += ' --jvmti-redefine-stress'
Alex Lightc38c3692017-06-27 15:45:14 -0700574 elif jvmti == 'step-stress':
575 options_test += ' --jvmti-step-stress'
Alex Light8f2c6d42017-04-10 16:27:35 -0700576
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000577 if address_size == '64':
578 options_test += ' --64'
579
David Srbeckyca15b8d2021-04-23 12:25:08 +0100580 # b/36039166: Note that the path lengths must kept reasonably short.
581 temp_path = tempfile.mkdtemp(dir=env.ART_HOST_TEST_DIR)
David Srbecky7cf6c582021-07-20 16:56:06 +0100582 options_test = '--temp-path {} '.format(temp_path) + options_test
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000583
584 run_test_sh = env.ANDROID_BUILD_TOP + '/art/test/run-test'
Alex Light3412a002017-10-20 13:44:40 +0000585 command = ' '.join((run_test_sh, options_test, ' '.join(extra_arguments[target]), test))
Orion Hodson163c8ab2019-04-05 11:40:30 +0100586 return executor.submit(run_test, command, test, variant_set, test_name)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000587
Alex Light6f342dd2019-03-27 17:15:42 +0000588 # Use a context-manager to handle cleaning up the extracted zipapex if needed.
589 with handle_zipapex(zipapex_loc) as zipapex_opt:
590 options_all += zipapex_opt
Orion Hodson163c8ab2019-04-05 11:40:30 +0100591 global n_thread
592 with concurrent.futures.ThreadPoolExecutor(max_workers=n_thread) as executor:
593 test_futures = []
594 for config_tuple in config:
595 target = config_tuple[1]
596 for address_size in _user_input_variants['address_sizes_target'][target]:
597 test_futures.append(start_combination(executor, config_tuple, options_all, address_size))
Igor Murashkinbab15062018-02-23 14:53:24 -0800598
Roland Levillain9b789242020-04-21 19:06:51 +0100599 for config_tuple in uncombinated_config:
600 test_futures.append(
601 start_combination(executor, config_tuple, options_all, "")) # no address size
Igor Murashkinbab15062018-02-23 14:53:24 -0800602
Martin Stjernholmfd7044d2021-04-27 16:01:17 +0100603 try:
604 tests_done = 0
David Srbeckyca15b8d2021-04-23 12:25:08 +0100605 for test_future in concurrent.futures.as_completed(f for f in test_futures if f):
Martin Stjernholmfd7044d2021-04-27 16:01:17 +0100606 (test, status, failure_info, test_time) = test_future.result()
607 tests_done += 1
608 print_test_info(tests_done, test, status, failure_info, test_time)
609 if failure_info and not env.ART_TEST_KEEP_GOING:
610 for f in test_futures:
611 f.cancel()
612 break
613 except KeyboardInterrupt:
614 for f in test_futures:
615 f.cancel()
616 child_process_tracker.kill_all()
Orion Hodson163c8ab2019-04-05 11:40:30 +0100617 executor.shutdown(True)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000618
Alex Light6f342dd2019-03-27 17:15:42 +0000619@contextlib.contextmanager
620def handle_zipapex(ziploc):
621 """Extracts the zipapex (if present) and handles cleanup.
622
623 If we are running out of a zipapex we want to unzip it once and have all the tests use the same
624 extracted contents. This extracts the files and handles cleanup if needed. It returns the
625 required extra arguments to pass to the run-test.
626 """
627 if ziploc is not None:
628 with tempfile.TemporaryDirectory() as tmpdir:
629 subprocess.check_call(["unzip", "-qq", ziploc, "apex_payload.zip", "-d", tmpdir])
630 subprocess.check_call(
631 ["unzip", "-qq", os.path.join(tmpdir, "apex_payload.zip"), "-d", tmpdir])
632 yield " --runtime-extracted-zipapex " + tmpdir
633 else:
634 yield ""
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000635
Andreas Gamped6b07c52020-03-03 20:02:26 +0000636def _popen(**kwargs):
637 if sys.version_info.major == 3 and sys.version_info.minor >= 6:
638 return subprocess.Popen(encoding=sys.stdout.encoding, **kwargs)
639 return subprocess.Popen(**kwargs)
640
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000641def run_test(command, test, test_variant, test_name):
642 """Runs the test.
643
644 It invokes art/test/run-test script to run the test. The output of the script
645 is checked, and if it ends with "Succeeded!", it assumes that the tests
646 passed, otherwise, put it in the list of failed test. Before actually running
647 the test, it also checks if the test is placed in the list of disabled tests,
648 and if yes, it skips running it, and adds the test in the list of skipped
Orion Hodson163c8ab2019-04-05 11:40:30 +0100649 tests.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000650
651 Args:
652 command: The command to be used to invoke the script
653 test: The name of the test without the variant information.
654 test_variant: The set of variant for the test.
655 test_name: The name of the test along with the variants.
Orion Hodson163c8ab2019-04-05 11:40:30 +0100656
Andreas Gampe52699512019-08-02 17:27:47 -0700657 Returns: a tuple of testname, status, optional failure info, and test time.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000658 """
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000659 try:
660 if is_test_disabled(test, test_variant):
661 test_skipped = True
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700662 test_time = datetime.timedelta()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000663 else:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000664 test_skipped = False
Orion Hodson3e29e192019-09-03 14:24:04 +0100665 test_start_time = time.monotonic()
David Srbecky97421fd2019-10-07 11:41:02 +0100666 if verbose:
667 print_text("Starting %s at %s\n" % (test_name, test_start_time))
David Srbeckybfa76b32022-06-20 21:30:56 +0100668 env = dict(os.environ)
669 env["FULL_TEST_NAME"] = test_name
Stelios Ioannou816b0da2021-06-03 13:25:50 +0100670 if gdb or gdb_dex2oat:
Andreas Gamped6b07c52020-03-03 20:02:26 +0000671 proc = _popen(
672 args=command.split(),
David Srbeckybfa76b32022-06-20 21:30:56 +0100673 env=env,
Andreas Gamped6b07c52020-03-03 20:02:26 +0000674 stderr=subprocess.STDOUT,
675 universal_newlines=True,
676 start_new_session=True
677 )
Shubham Ajmerab4949f52017-05-08 13:52:46 -0700678 else:
Andreas Gamped6b07c52020-03-03 20:02:26 +0000679 proc = _popen(
680 args=command.split(),
David Srbeckybfa76b32022-06-20 21:30:56 +0100681 env=env,
Andreas Gamped6b07c52020-03-03 20:02:26 +0000682 stderr=subprocess.STDOUT,
683 stdout = subprocess.PIPE,
684 universal_newlines=True,
685 start_new_session=True,
686 )
Martin Stjernholmfd7044d2021-04-27 16:01:17 +0100687 script_output, return_value = child_process_tracker.wait(proc, timeout)
688 test_passed = not return_value
Orion Hodson3e29e192019-09-03 14:24:04 +0100689 test_time_seconds = time.monotonic() - test_start_time
690 test_time = datetime.timedelta(seconds=test_time_seconds)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000691
692 if not test_skipped:
693 if test_passed:
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700694 return (test_name, 'PASS', None, test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000695 else:
Alex Light1ebe6142017-10-03 15:00:10 -0700696 failed_tests.append((test_name, str(command) + "\n" + script_output))
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700697 return (test_name, 'FAIL', ('%s\n%s') % (command, script_output), test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000698 elif not dry_run:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000699 skipped_tests.append(test_name)
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700700 return (test_name, 'SKIP', None, test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000701 else:
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700702 return (test_name, 'PASS', None, test_time)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700703 except subprocess.TimeoutExpired as e:
David Srbecky97421fd2019-10-07 11:41:02 +0100704 if verbose:
705 print_text("Timeout of %s at %s\n" % (test_name, time.monotonic()))
Orion Hodson3e29e192019-09-03 14:24:04 +0100706 test_time_seconds = time.monotonic() - test_start_time
707 test_time = datetime.timedelta(seconds=test_time_seconds)
Shubham Ajmera186d3212017-07-21 01:20:57 +0000708 failed_tests.append((test_name, 'Timed out in %d seconds' % timeout))
Andreas Gampe52699512019-08-02 17:27:47 -0700709
Orion Hodson9965fef2019-11-19 09:23:16 +0000710 # HACK(b/142039427): Print extra backtraces on timeout.
711 if "-target-" in test_name:
712 for i in range(8):
713 proc_name = "dalvikvm" + test_name[-2:]
714 pidof = subprocess.run(["adb", "shell", "pidof", proc_name], stdout=subprocess.PIPE)
715 for pid in pidof.stdout.decode("ascii").split():
716 if i >= 4:
717 print_text("Backtrace of %s at %s\n" % (pid, time.monotonic()))
David Srbecky47c4ccd2019-10-20 19:48:47 +0100718 subprocess.run(["adb", "shell", "debuggerd", pid])
Orion Hodson9965fef2019-11-19 09:23:16 +0000719 time.sleep(10)
720 task_dir = "/proc/%s/task" % pid
721 tids = subprocess.run(["adb", "shell", "ls", task_dir], stdout=subprocess.PIPE)
722 for tid in tids.stdout.decode("ascii").split():
723 for status in ["stat", "status"]:
724 filename = "%s/%s/%s" % (task_dir, tid, status)
725 print_text("Content of %s\n" % (filename))
726 subprocess.run(["adb", "shell", "cat", filename])
727 time.sleep(60)
David Srbecky2bd8bfd2019-10-17 15:49:03 +0100728
Andreas Gampe1ec82e52019-08-02 17:41:04 -0700729 # The python documentation states that it is necessary to actually kill the process.
David Srbeckyf9ba5212019-10-02 15:56:08 +0100730 os.killpg(proc.pid, signal.SIGKILL)
Andreas Gampe1ec82e52019-08-02 17:41:04 -0700731 script_output = proc.communicate()
732
Orion Hodson3e29e192019-09-03 14:24:04 +0100733 return (test_name, 'TIMEOUT', 'Timed out in %d seconds\n%s' % (timeout, command), test_time)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700734 except Exception as e:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700735 failed_tests.append((test_name, str(e)))
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700736 return (test_name, 'FAIL', ('%s\n%s\n\n') % (command, str(e)), datetime.timedelta())
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000737
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700738def print_test_info(test_count, test_name, result, failed_test_info="",
739 test_time=datetime.timedelta()):
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000740 """Print the continous test information
741
742 If verbose is set to True, it continuously prints test status information
743 on a new line.
744 If verbose is set to False, it keeps on erasing test
745 information by overriding it with the latest test information. Also,
746 in this case it stictly makes sure that the information length doesn't
747 exceed the console width. It does so by shortening the test_name.
748
749 When a test fails, it prints the output of the run-test script and
750 command used to invoke the script. It doesn't override the failing
751 test information in either of the cases.
752 """
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000753
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000754 info = ''
755 if not verbose:
756 # Without --verbose, the testrunner erases passing test info. It
757 # does that by overriding the printed text with white spaces all across
758 # the console width.
759 console_width = int(os.popen('stty size', 'r').read().split()[1])
760 info = '\r' + ' ' * console_width + '\r'
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000761 try:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000762 percent = (test_count * 100) / total_test_count
763 progress_info = ('[ %d%% %d/%d ]') % (
764 percent,
765 test_count,
766 total_test_count)
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700767 if test_time.total_seconds() != 0 and verbose:
768 info += '(%s)' % str(test_time)
769
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000770
Shubham Ajmerafe793492017-03-16 13:31:35 -0700771 if result == 'FAIL' or result == 'TIMEOUT':
Alex Light1ebe6142017-10-03 15:00:10 -0700772 if not verbose:
773 info += ('%s %s %s\n') % (
774 progress_info,
775 test_name,
776 COLOR_ERROR + result + COLOR_NORMAL)
777 else:
778 info += ('%s %s %s\n%s\n') % (
779 progress_info,
780 test_name,
781 COLOR_ERROR + result + COLOR_NORMAL,
782 failed_test_info)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000783 else:
784 result_text = ''
785 if result == 'PASS':
786 result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL
787 elif result == 'SKIP':
788 result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL
789
790 if verbose:
791 info += ('%s %s %s\n') % (
792 progress_info,
793 test_name,
794 result_text)
795 else:
796 total_output_length = 2 # Two spaces
797 total_output_length += len(progress_info)
798 total_output_length += len(result)
799 allowed_test_length = console_width - total_output_length
800 test_name_len = len(test_name)
801 if allowed_test_length < test_name_len:
Shubham Ajmerafe793492017-03-16 13:31:35 -0700802 test_name = ('...%s') % (
803 test_name[-(allowed_test_length - 3):])
Alex Lightc14311c2017-02-23 17:02:46 -0800804 info += ('%s %s %s') % (
805 progress_info,
806 test_name,
807 result_text)
Alex Lightaba509f2020-05-12 15:19:52 -0700808 send_csv_result(test_name, result)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000809 print_text(info)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700810 except Exception as e:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000811 print_text(('%s\n%s\n') % (test_name, str(e)))
812 failed_tests.append(test_name)
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000813
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700814def verify_knownfailure_entry(entry):
815 supported_field = {
Shubham Ajmerafe793492017-03-16 13:31:35 -0700816 'tests' : (list, str),
Alex Light6fdc1b62017-09-18 11:33:56 -0700817 'test_patterns' : (list,),
Shubham Ajmerafe793492017-03-16 13:31:35 -0700818 'description' : (list, str),
819 'bug' : (str,),
820 'variant' : (str,),
Orion Hodsonaaac8d22019-10-10 13:04:36 +0100821 'devices': (list, str),
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700822 'env_vars' : (dict,),
Alex Lightf92f6f12019-11-26 12:37:14 -0800823 'zipapex' : (bool,),
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700824 }
825 for field in entry:
826 field_type = type(entry[field])
827 if field_type not in supported_field[field]:
828 raise ValueError('%s is not supported type for %s\n%s' % (
829 str(field_type),
830 field,
831 str(entry)))
832
Orion Hodsonaaac8d22019-10-10 13:04:36 +0100833def get_disabled_test_info(device_name):
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000834 """Generate set of known failures.
835
836 It parses the art/test/knownfailures.json file to generate the list of
837 disabled tests.
838
839 Returns:
840 The method returns a dict of tests mapped to the variants list
841 for which the test should not be run.
842 """
843 known_failures_file = env.ANDROID_BUILD_TOP + '/art/test/knownfailures.json'
844 with open(known_failures_file) as known_failures_json:
845 known_failures_info = json.loads(known_failures_json.read())
846
847 disabled_test_info = {}
848 for failure in known_failures_info:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700849 verify_knownfailure_entry(failure)
850 tests = failure.get('tests', [])
Shubham Ajmerafe793492017-03-16 13:31:35 -0700851 if isinstance(tests, str):
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000852 tests = [tests]
Alex Light6fdc1b62017-09-18 11:33:56 -0700853 patterns = failure.get("test_patterns", [])
854 if (not isinstance(patterns, list)):
Orion Hodsonaaac8d22019-10-10 13:04:36 +0100855 raise ValueError("test_patterns is not a list in %s" % failure)
Alex Light6fdc1b62017-09-18 11:33:56 -0700856
857 tests += [f for f in RUN_TEST_SET if any(re.match(pat, f) is not None for pat in patterns)]
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000858 variants = parse_variants(failure.get('variant'))
Orion Hodsonaaac8d22019-10-10 13:04:36 +0100859
860 # Treat a '"devices": "<foo>"' equivalent to 'target' variant if
861 # "foo" is present in "devices".
862 device_names = failure.get('devices', [])
863 if isinstance(device_names, str):
864 device_names = [device_names]
865 if len(device_names) != 0:
866 if device_name in device_names:
867 variants.add('target')
868 else:
869 # Skip adding test info as device_name is not present in "devices" entry.
870 continue
871
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000872 env_vars = failure.get('env_vars')
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700873
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000874 if check_env_vars(env_vars):
875 for test in tests:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700876 if test not in RUN_TEST_SET:
877 raise ValueError('%s is not a valid run-test' % (
878 test))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000879 if test in disabled_test_info:
880 disabled_test_info[test] = disabled_test_info[test].union(variants)
881 else:
882 disabled_test_info[test] = variants
Alex Lightf92f6f12019-11-26 12:37:14 -0800883
884 zipapex_disable = failure.get("zipapex", False)
885 if zipapex_disable and zipapex_loc is not None:
886 for test in tests:
887 if test not in RUN_TEST_SET:
888 raise ValueError('%s is not a valid run-test' % (test))
889 if test in disabled_test_info:
890 disabled_test_info[test] = disabled_test_info[test].union(variants)
891 else:
892 disabled_test_info[test] = variants
893
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000894 return disabled_test_info
895
Orion Hodsonaaac8d22019-10-10 13:04:36 +0100896def gather_disabled_test_info():
897 global DISABLED_TEST_CONTAINER
898 device_name = get_device_name() if 'target' in _user_input_variants['target'] else None
899 DISABLED_TEST_CONTAINER = get_disabled_test_info(device_name)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000900
901def check_env_vars(env_vars):
902 """Checks if the env variables are set as required to run the test.
903
904 Returns:
905 True if all the env variables are set as required, otherwise False.
906 """
907
908 if not env_vars:
909 return True
910 for key in env_vars:
911 if env.get_env(key) != env_vars.get(key):
912 return False
913 return True
914
915
916def is_test_disabled(test, variant_set):
917 """Checks if the test along with the variant_set is disabled.
918
919 Args:
920 test: The name of the test as in art/test directory.
921 variant_set: Variants to be used for the test.
922 Returns:
923 True, if the test is disabled.
924 """
925 if dry_run:
926 return True
Alex Lightbc319b22017-02-17 14:21:33 -0800927 if test in env.EXTRA_DISABLED_TESTS:
928 return True
Alex Light42242dd2018-02-16 09:23:57 -0800929 if ignore_skips:
930 return False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000931 variants_list = DISABLED_TEST_CONTAINER.get(test, {})
932 for variants in variants_list:
933 variants_present = True
934 for variant in variants:
935 if variant not in variant_set:
936 variants_present = False
937 break
938 if variants_present:
939 return True
Alex Lighta86a5d12019-08-30 11:03:05 -0700940 for bad_combo in NONFUNCTIONAL_VARIANT_SETS:
941 if bad_combo.issubset(variant_set):
942 return True
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000943 return False
944
945
946def parse_variants(variants):
947 """Parse variants fetched from art/test/knownfailures.json.
948 """
949 if not variants:
950 variants = ''
951 for variant in TOTAL_VARIANTS_SET:
952 variants += variant
953 variants += '|'
954 variants = variants[:-1]
955 variant_list = set()
956 or_variants = variants.split('|')
957 for or_variant in or_variants:
958 and_variants = or_variant.split('&')
959 variant = set()
960 for and_variant in and_variants:
961 and_variant = and_variant.strip()
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700962 if and_variant not in TOTAL_VARIANTS_SET:
963 raise ValueError('%s is not a valid variant' % (
964 and_variant))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000965 variant.add(and_variant)
966 variant_list.add(frozenset(variant))
967 return variant_list
968
969def print_text(output):
970 sys.stdout.write(output)
971 sys.stdout.flush()
972
973def print_analysis():
974 if not verbose:
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000975 # Without --verbose, the testrunner erases passing test info. It
976 # does that by overriding the printed text with white spaces all across
977 # the console width.
978 console_width = int(os.popen('stty size', 'r').read().split()[1])
979 eraser_text = '\r' + ' ' * console_width + '\r'
980 print_text(eraser_text)
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700981
982 # Prints information about the total tests run.
983 # E.g., "2/38 (5%) tests passed".
984 passed_test_count = total_test_count - len(skipped_tests) - len(failed_tests)
985 passed_test_information = ('%d/%d (%d%%) %s passed.\n') % (
986 passed_test_count,
987 total_test_count,
988 (passed_test_count*100)/total_test_count,
989 'tests' if passed_test_count > 1 else 'test')
990 print_text(passed_test_information)
991
992 # Prints the list of skipped tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000993 if skipped_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700994 print_text(COLOR_SKIP + 'SKIPPED TESTS: ' + COLOR_NORMAL + '\n')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000995 for test in skipped_tests:
996 print_text(test + '\n')
997 print_text('\n')
998
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700999 # Prints the list of failed tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001000 if failed_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -07001001 print_text(COLOR_ERROR + 'FAILED: ' + COLOR_NORMAL + '\n')
1002 for test_info in failed_tests:
1003 print_text(('%s\n%s\n' % (test_info[0], test_info[1])))
Andreas Gampe0dd7e852017-05-24 21:44:23 -07001004 print_text(COLOR_ERROR + '----------' + COLOR_NORMAL + '\n')
1005 for failed_test in sorted([test_info[0] for test_info in failed_tests]):
1006 print_text(('%s\n' % (failed_test)))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001007
Alex Lightaba509f2020-05-12 15:19:52 -07001008test_name_matcher = None
1009def extract_test_name(test_name):
1010 """Parses the test name and returns all the parts"""
1011 global test_name_matcher
1012 if test_name_matcher is None:
1013 regex = '^test-art-'
1014 regex += '(' + '|'.join(VARIANT_TYPE_DICT['target']) + ')-'
1015 regex += 'run-test-'
1016 regex += '(' + '|'.join(VARIANT_TYPE_DICT['run']) + ')-'
1017 regex += '(' + '|'.join(VARIANT_TYPE_DICT['prebuild']) + ')-'
1018 regex += '(' + '|'.join(VARIANT_TYPE_DICT['compiler']) + ')-'
1019 regex += '(' + '|'.join(VARIANT_TYPE_DICT['relocate']) + ')-'
1020 regex += '(' + '|'.join(VARIANT_TYPE_DICT['trace']) + ')-'
1021 regex += '(' + '|'.join(VARIANT_TYPE_DICT['gc']) + ')-'
1022 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jni']) + ')-'
1023 regex += '(' + '|'.join(VARIANT_TYPE_DICT['image']) + ')-'
1024 regex += '(' + '|'.join(VARIANT_TYPE_DICT['debuggable']) + ')-'
1025 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jvmti']) + ')-'
1026 regex += '(' + '|'.join(VARIANT_TYPE_DICT['cdex_level']) + ')-'
1027 regex += '(' + '|'.join(RUN_TEST_SET) + ')'
1028 regex += '(' + '|'.join(VARIANT_TYPE_DICT['address_sizes']) + ')$'
1029 test_name_matcher = re.compile(regex)
1030 match = test_name_matcher.match(test_name)
1031 if match:
1032 return list(match.group(i) for i in range(1,15))
1033 raise ValueError(test_name + " is not a valid test")
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001034
1035def parse_test_name(test_name):
1036 """Parses the testname provided by the user.
1037 It supports two types of test_name:
1038 1) Like 001-HelloWorld. In this case, it will just verify if the test actually
1039 exists and if it does, it returns the testname.
Alex Light79d6c802019-06-27 15:50:11 +00001040 2) Like test-art-host-run-test-debug-prebuild-interpreter-no-relocate-ntrace-cms-checkjni-pointer-ids-picimage-ndebuggable-001-HelloWorld32
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001041 In this case, it will parse all the variants and check if they are placed
1042 correctly. If yes, it will set the various VARIANT_TYPES to use the
1043 variants required to run the test. Again, it returns the test_name
1044 without the variant information like 001-HelloWorld.
1045 """
Shubham Ajmerafaf12502017-02-15 17:19:44 +00001046 test_set = set()
1047 for test in RUN_TEST_SET:
1048 if test.startswith(test_name):
1049 test_set.add(test)
1050 if test_set:
1051 return test_set
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001052
Evgeny Astigeevich8bcba222020-05-18 13:06:37 +01001053 parsed = extract_test_name(test_name)
Alex Lightaba509f2020-05-12 15:19:52 -07001054 _user_input_variants['target'].add(parsed[0])
1055 _user_input_variants['run'].add(parsed[1])
1056 _user_input_variants['prebuild'].add(parsed[2])
1057 _user_input_variants['compiler'].add(parsed[3])
1058 _user_input_variants['relocate'].add(parsed[4])
1059 _user_input_variants['trace'].add(parsed[5])
1060 _user_input_variants['gc'].add(parsed[6])
1061 _user_input_variants['jni'].add(parsed[7])
1062 _user_input_variants['image'].add(parsed[8])
1063 _user_input_variants['debuggable'].add(parsed[9])
1064 _user_input_variants['jvmti'].add(parsed[10])
1065 _user_input_variants['cdex_level'].add(parsed[11])
1066 _user_input_variants['address_sizes'].add(parsed[13])
1067 return {parsed[12]}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001068
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001069
David Srbeckye1d17062021-04-20 16:41:29 +00001070def get_target_cpu_count():
1071 adb_command = 'adb shell cat /sys/devices/system/cpu/present'
1072 cpu_info_proc = subprocess.Popen(adb_command.split(), stdout=subprocess.PIPE)
1073 cpu_info = cpu_info_proc.stdout.read()
1074 if type(cpu_info) is bytes:
1075 cpu_info = cpu_info.decode('utf-8')
1076 cpu_info_regex = r'\d*-(\d*)'
1077 match = re.match(cpu_info_regex, cpu_info)
1078 if match:
1079 return int(match.group(1)) + 1 # Add one to convert from "last-index" to "count"
David Srbeckyab474e32021-04-20 16:33:51 +00001080 else:
David Srbeckye1d17062021-04-20 16:41:29 +00001081 raise ValueError('Unable to predict the concurrency for the target. '
1082 'Is device connected?')
1083
1084
1085def get_host_cpu_count():
1086 return multiprocessing.cpu_count()
1087
Shubham Ajmera4a5a1622017-03-22 10:07:19 -07001088
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001089def parse_option():
1090 global verbose
1091 global dry_run
Alex Light42242dd2018-02-16 09:23:57 -08001092 global ignore_skips
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001093 global n_thread
1094 global build
Roland Levillain93e4df72020-06-29 13:33:56 +01001095 global dist
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001096 global gdb
1097 global gdb_arg
Stelios Ioannou1b621222021-06-17 14:15:45 +01001098 global dump_cfg
Stelios Ioannou816b0da2021-06-03 13:25:50 +01001099 global gdb_dex2oat
1100 global gdb_dex2oat_args
Vladimir Marko41b1f0e2018-03-21 11:17:12 +00001101 global runtime_option
Alex Light26829182018-06-11 11:36:24 -07001102 global run_test_option
Shubham Ajmerafe793492017-03-16 13:31:35 -07001103 global timeout
Shubham Ajmera981d99c2017-08-17 14:11:08 -07001104 global dex2oat_jobs
Shubham Ajmera42ea83b2017-09-25 21:05:57 -07001105 global run_all_configs
Alex Lighte9f61032018-09-24 16:04:51 -07001106 global with_agent
Alex Light6f342dd2019-03-27 17:15:42 +00001107 global zipapex_loc
Alex Lightaba509f2020-05-12 15:19:52 -07001108 global csv_result
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001109
Alex Light7a1ccf82017-02-21 09:52:34 -08001110 parser = argparse.ArgumentParser(description="Runs all or a subset of the ART test suite.")
Andreas Gampe09b2d502017-11-29 19:08:16 -08001111 parser.add_argument('-t', '--test', action='append', dest='tests', help='name(s) of the test(s)')
Alex Lightc0322512018-03-13 10:33:52 -07001112 global_group = parser.add_argument_group('Global options',
1113 'Options that affect all tests being run')
David Srbeckye1d17062021-04-20 16:41:29 +00001114 global_group.add_argument('-j', type=int, dest='n_thread', help="""Number of CPUs to use.
1115 Defaults to half of CPUs on target and all CPUs on host.""")
Alex Lightc0322512018-03-13 10:33:52 -07001116 global_group.add_argument('--timeout', default=timeout, type=int, dest='timeout')
1117 global_group.add_argument('--verbose', '-v', action='store_true', dest='verbose')
1118 global_group.add_argument('--dry-run', action='store_true', dest='dry_run')
Vladimir Marko41b1f0e2018-03-21 11:17:12 +00001119 global_group.add_argument("--skip", action='append', dest="skips", default=[],
Alex Lightc0322512018-03-13 10:33:52 -07001120 help="Skip the given test in all circumstances.")
Vladimir Marko41b1f0e2018-03-21 11:17:12 +00001121 global_group.add_argument("--no-skips", dest="ignore_skips", action='store_true', default=False,
Alex Lightc0322512018-03-13 10:33:52 -07001122 help="""Don't skip any run-test configurations listed in
1123 knownfailures.json.""")
1124 global_group.add_argument('--no-build-dependencies',
1125 action='store_false', dest='build',
1126 help="""Don't build dependencies under any circumstances. This is the
1127 behavior if ART_TEST_RUN_TEST_ALWAYS_BUILD is not set to 'true'.""")
1128 global_group.add_argument('-b', '--build-dependencies',
1129 action='store_true', dest='build',
1130 help="""Build dependencies under all circumstances. By default we will
1131 not build dependencies unless ART_TEST_RUN_TEST_BUILD=true.""")
Roland Levillain93e4df72020-06-29 13:33:56 +01001132 global_group.add_argument('--dist',
1133 action='store_true', dest='dist',
1134 help="""If dependencies are to be built, pass `dist` to the build
1135 command line. You may want to also set the DIST_DIR environment
1136 variable when using this flag.""")
Alex Lightc0322512018-03-13 10:33:52 -07001137 global_group.set_defaults(build = env.ART_TEST_RUN_TEST_BUILD)
1138 global_group.add_argument('--gdb', action='store_true', dest='gdb')
1139 global_group.add_argument('--gdb-arg', dest='gdb_arg')
Stelios Ioannou1b621222021-06-17 14:15:45 +01001140 global_group.add_argument('--dump-cfg', dest='dump_cfg',
1141 help="""Dump the CFG to the specified host path.
1142 Example \"--dump-cfg <full-path>/graph.cfg\".""")
Stelios Ioannou816b0da2021-06-03 13:25:50 +01001143 global_group.add_argument('--gdb-dex2oat', action='store_true', dest='gdb_dex2oat')
1144 global_group.add_argument('--gdb-dex2oat-args', dest='gdb_dex2oat_args')
Alex Light26829182018-06-11 11:36:24 -07001145 global_group.add_argument('--run-test-option', action='append', dest='run_test_option',
1146 default=[],
1147 help="""Pass an option, unaltered, to the run-test script.
1148 This should be enclosed in single-quotes to allow for spaces. The option
1149 will be split using shlex.split() prior to invoking run-test.
David Srbeckyca15b8d2021-04-23 12:25:08 +01001150 Example \"--run-test-option='--with-agent libtifast.so=MethodExit'\".""")
Alex Lighte9f61032018-09-24 16:04:51 -07001151 global_group.add_argument('--with-agent', action='append', dest='with_agent',
1152 help="""Pass an agent to be attached to the runtime""")
Vladimir Marko41b1f0e2018-03-21 11:17:12 +00001153 global_group.add_argument('--runtime-option', action='append', dest='runtime_option',
1154 help="""Pass an option to the runtime. Runtime options
1155 starting with a '-' must be separated by a '=', for
1156 example '--runtime-option=-Xjitthreshold:0'.""")
Alex Lightc0322512018-03-13 10:33:52 -07001157 global_group.add_argument('--dex2oat-jobs', type=int, dest='dex2oat_jobs',
1158 help='Number of dex2oat jobs')
Alex Light6f342dd2019-03-27 17:15:42 +00001159 global_group.add_argument('--runtime-zipapex', dest='runtime_zipapex', default=None,
1160 help='Location for runtime zipapex.')
Alex Lightc0322512018-03-13 10:33:52 -07001161 global_group.add_argument('-a', '--all', action='store_true', dest='run_all',
1162 help="Run all the possible configurations for the input test set")
Alex Lightaba509f2020-05-12 15:19:52 -07001163 global_group.add_argument('--csv-results', action='store', dest='csv_result', default=None,
1164 type=argparse.FileType('w'), help='Store a CSV record of all results.')
Alex Lightc0322512018-03-13 10:33:52 -07001165 for variant_type, variant_set in VARIANT_TYPE_DICT.items():
1166 var_group = parser.add_argument_group(
1167 '{}-type Options'.format(variant_type),
1168 "Options that control the '{}' variants.".format(variant_type))
Alex Lightbf8a5d82019-08-30 10:17:22 -07001169 var_group.add_argument('--all-' + variant_type,
1170 action='store_true',
1171 dest='all_' + variant_type,
1172 help='Enable all variants of ' + variant_type)
Alex Lightc0322512018-03-13 10:33:52 -07001173 for variant in variant_set:
1174 flag = '--' + variant
1175 var_group.add_argument(flag, action='store_true', dest=variant)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001176
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001177 options = vars(parser.parse_args())
Alex Lightaba509f2020-05-12 15:19:52 -07001178 if options['csv_result'] is not None:
1179 csv_result = options['csv_result']
1180 setup_csv_result()
Alex Lightbf8a5d82019-08-30 10:17:22 -07001181 # Handle the --all-<type> meta-options
1182 for variant_type, variant_set in VARIANT_TYPE_DICT.items():
1183 if options['all_' + variant_type]:
1184 for variant in variant_set:
1185 options[variant] = True
1186
Andreas Gampe09b2d502017-11-29 19:08:16 -08001187 tests = None
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001188 env.EXTRA_DISABLED_TESTS.update(set(options['skips']))
Andreas Gampe09b2d502017-11-29 19:08:16 -08001189 if options['tests']:
1190 tests = set()
1191 for test_name in options['tests']:
1192 tests |= parse_test_name(test_name)
Shubham Ajmera85853952017-08-29 16:26:21 -07001193
1194 for variant_type in VARIANT_TYPE_DICT:
1195 for variant in VARIANT_TYPE_DICT[variant_type]:
1196 if options.get(variant):
1197 _user_input_variants[variant_type].add(variant)
1198
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001199 if options['verbose']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001200 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001201 if options['n_thread']:
1202 n_thread = max(1, options['n_thread'])
Alex Light42242dd2018-02-16 09:23:57 -08001203 ignore_skips = options['ignore_skips']
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001204 if options['dry_run']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001205 dry_run = True
1206 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001207 build = options['build']
Roland Levillain93e4df72020-06-29 13:33:56 +01001208 dist = options['dist']
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001209 if options['gdb']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001210 n_thread = 1
1211 gdb = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001212 if options['gdb_arg']:
1213 gdb_arg = options['gdb_arg']
Stelios Ioannou1b621222021-06-17 14:15:45 +01001214 if options['dump_cfg']:
1215 dump_cfg = options['dump_cfg']
Stelios Ioannou816b0da2021-06-03 13:25:50 +01001216 if options['gdb_dex2oat']:
1217 n_thread = 1
1218 gdb_dex2oat = True
1219 if options['gdb_dex2oat_args']:
1220 gdb_dex2oat_args = options['gdb_dex2oat_args']
Vladimir Marko41b1f0e2018-03-21 11:17:12 +00001221 runtime_option = options['runtime_option'];
Alex Lighte9f61032018-09-24 16:04:51 -07001222 with_agent = options['with_agent'];
Alex Light26829182018-06-11 11:36:24 -07001223 run_test_option = sum(map(shlex.split, options['run_test_option']), [])
Alex Light6f342dd2019-03-27 17:15:42 +00001224 zipapex_loc = options['runtime_zipapex']
Alex Light26829182018-06-11 11:36:24 -07001225
Shubham Ajmerafe793492017-03-16 13:31:35 -07001226 timeout = options['timeout']
Shubham Ajmera981d99c2017-08-17 14:11:08 -07001227 if options['dex2oat_jobs']:
1228 dex2oat_jobs = options['dex2oat_jobs']
Shubham Ajmera42ea83b2017-09-25 21:05:57 -07001229 if options['run_all']:
1230 run_all_configs = True
Shubham Ajmera22499e22017-03-22 18:33:37 -07001231
Andreas Gampe09b2d502017-11-29 19:08:16 -08001232 return tests
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001233
1234def main():
1235 gather_test_info()
Andreas Gampe09b2d502017-11-29 19:08:16 -08001236 user_requested_tests = parse_option()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001237 setup_test_env()
Orion Hodsonaaac8d22019-10-10 13:04:36 +01001238 gather_disabled_test_info()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001239 if build:
1240 build_targets = ''
Shubham Ajmera85853952017-08-29 16:26:21 -07001241 if 'host' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001242 build_targets += 'test-art-host-run-test-dependencies '
Shubham Ajmera85853952017-08-29 16:26:21 -07001243 if 'target' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001244 build_targets += 'test-art-target-run-test-dependencies '
Igor Murashkinbab15062018-02-23 14:53:24 -08001245 if 'jvm' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001246 build_targets += 'test-art-host-run-test-dependencies '
Alex Lightd51af9e2018-10-11 16:07:55 -07001247 build_command = env.ANDROID_BUILD_TOP + '/build/soong/soong_ui.bash --make-mode'
Ian Zerny39439a62022-04-20 14:02:09 +02001248 build_command += ' D8='
Roland Levillain93e4df72020-06-29 13:33:56 +01001249 if dist:
1250 build_command += ' dist'
Shubham Ajmera06cde292017-02-10 23:15:05 +00001251 build_command += ' ' + build_targets
Roland Levillain22831a32020-06-29 13:31:28 +01001252 print_text('Build command: %s\n' % build_command)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001253 if subprocess.call(build_command.split()):
Colin Cross9cb13a62018-06-07 13:02:02 -07001254 # Debugging for b/62653020
1255 if env.DIST_DIR:
1256 shutil.copyfile(env.SOONG_OUT_DIR + '/build.ninja', env.DIST_DIR + '/soong.ninja')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001257 sys.exit(1)
Orion Hodson163c8ab2019-04-05 11:40:30 +01001258
Andreas Gampe09b2d502017-11-29 19:08:16 -08001259 if user_requested_tests:
Orion Hodson163c8ab2019-04-05 11:40:30 +01001260 run_tests(user_requested_tests)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001261 else:
Orion Hodson163c8ab2019-04-05 11:40:30 +01001262 run_tests(RUN_TEST_SET)
1263
1264 print_analysis()
Alex Lightaba509f2020-05-12 15:19:52 -07001265 close_csv_file()
Orion Hodson163c8ab2019-04-05 11:40:30 +01001266
1267 exit_code = 0 if len(failed_tests) == 0 else 1
1268 sys.exit(exit_code)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001269
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001270if __name__ == '__main__':
1271 main()