blob: 2eaab88fa1125996e38630b31f8ff4156c90d559 [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
Andreas Gampe7409b9f2019-07-08 09:29:52 -070064import datetime
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000065import fnmatch
66import itertools
67import json
Shubham Ajmera4a5a1622017-03-22 10:07:19 -070068import multiprocessing
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000069import os
70import re
Alex Light26829182018-06-11 11:36:24 -070071import shlex
Colin Cross9cb13a62018-06-07 13:02:02 -070072import shutil
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000073import subprocess
74import sys
Shubham Ajmera29f89682017-03-24 14:44:10 -070075import tempfile
Orion Hodson3e29e192019-09-03 14:24:04 +010076import time
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000077
78import env
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -080079from target_config import target_config
Alex Light3412a002017-10-20 13:44:40 +000080from device_config import device_config
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000081
Shubham Ajmera186d3212017-07-21 01:20:57 +000082# timeout for individual tests.
83# TODO: make it adjustable per tests and for buildbots
84timeout = 3000 # 50 minutes
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000085
86# DISABLED_TEST_CONTAINER holds information about the disabled tests. It is a map
87# that has key as the test name (like 001-HelloWorld), and value as set of
88# variants that the test is disabled for.
89DISABLED_TEST_CONTAINER = {}
90
91# The Dict contains the list of all possible variants for a given type. For example,
92# for key TARGET, the value would be target and host. The list is used to parse
93# the test name given as the argument to run.
94VARIANT_TYPE_DICT = {}
95
Alex Lighta86a5d12019-08-30 11:03:05 -070096# The set of all variant sets that are incompatible and will always be skipped.
97NONFUNCTIONAL_VARIANT_SETS = set()
98
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000099# The set contains all the variants of each time.
100TOTAL_VARIANTS_SET = set()
101
102# The colors are used in the output. When a test passes, COLOR_PASS is used,
103# and so on.
104COLOR_ERROR = '\033[91m'
105COLOR_PASS = '\033[92m'
106COLOR_SKIP = '\033[93m'
107COLOR_NORMAL = '\033[0m'
108
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000109# The set contains the list of all the possible run tests that are in art/test
110# directory.
111RUN_TEST_SET = set()
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000112
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000113failed_tests = []
114skipped_tests = []
115
116# Flags
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700117n_thread = -1
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000118total_test_count = 0
119verbose = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000120dry_run = False
Alex Light42242dd2018-02-16 09:23:57 -0800121ignore_skips = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000122build = False
123gdb = False
124gdb_arg = ''
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000125runtime_option = ''
Alex Lighte9f61032018-09-24 16:04:51 -0700126with_agent = []
Alex Light6f342dd2019-03-27 17:15:42 +0000127zipapex_loc = None
Alex Light26829182018-06-11 11:36:24 -0700128run_test_option = []
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700129dex2oat_jobs = -1 # -1 corresponds to default threads for dex2oat
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700130run_all_configs = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000131
Alex Light3412a002017-10-20 13:44:40 +0000132# Dict containing extra arguments
133extra_arguments = { "host" : [], "target" : [] }
134
Shubham Ajmera85853952017-08-29 16:26:21 -0700135# Dict to store user requested test variants.
136# key: variant_type.
137# value: set of variants user wants to run of type <key>.
138_user_input_variants = collections.defaultdict(set)
139
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000140def gather_test_info():
141 """The method gathers test information about the test to be run which includes
142 generating the list of total tests from the art/test directory and the list
143 of disabled test. It also maps various variants to types.
144 """
145 global TOTAL_VARIANTS_SET
146 global DISABLED_TEST_CONTAINER
147 # TODO: Avoid duplication of the variant names in different lists.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000148 VARIANT_TYPE_DICT['run'] = {'ndebug', 'debug'}
Igor Murashkinbab15062018-02-23 14:53:24 -0800149 VARIANT_TYPE_DICT['target'] = {'target', 'host', 'jvm'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000150 VARIANT_TYPE_DICT['trace'] = {'trace', 'ntrace', 'stream'}
Vladimir Marko4519b9d2018-10-10 15:21:21 +0100151 VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000152 VARIANT_TYPE_DICT['debuggable'] = {'ndebuggable', 'debuggable'}
153 VARIANT_TYPE_DICT['gc'] = {'gcstress', 'gcverify', 'cms'}
Nicolas Geoffray3d8a78a2018-08-29 21:10:16 +0000154 VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'prebuild'}
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800155 VARIANT_TYPE_DICT['cdex_level'] = {'cdex-none', 'cdex-fast'}
Vladimir Markoa497a392018-09-26 10:52:50 +0100156 VARIANT_TYPE_DICT['relocate'] = {'relocate', 'no-relocate'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000157 VARIANT_TYPE_DICT['jni'] = {'jni', 'forcecopy', 'checkjni'}
158 VARIANT_TYPE_DICT['address_sizes'] = {'64', '32'}
Alex Light43e935d2017-06-19 15:40:40 -0700159 VARIANT_TYPE_DICT['jvmti'] = {'no-jvmti', 'jvmti-stress', 'redefine-stress', 'trace-stress',
Alex Lightc38c3692017-06-27 15:45:14 -0700160 'field-stress', 'step-stress'}
Roland Levillainad694bf2018-10-09 14:49:15 +0100161 VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'jit-on-first-use',
Alex Lighta86a5d12019-08-30 11:03:05 -0700162 'optimizing', 'regalloc_gc',
163 'speed-profile', 'baseline'}
164
165 # Regalloc_GC cannot work with prebuild.
166 NONFUNCTIONAL_VARIANT_SETS.add(frozenset({'regalloc_gc', 'prebuild'}))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000167
168 for v_type in VARIANT_TYPE_DICT:
169 TOTAL_VARIANTS_SET = TOTAL_VARIANTS_SET.union(VARIANT_TYPE_DICT.get(v_type))
170
171 test_dir = env.ANDROID_BUILD_TOP + '/art/test'
172 for f in os.listdir(test_dir):
173 if fnmatch.fnmatch(f, '[0-9]*'):
174 RUN_TEST_SET.add(f)
175 DISABLED_TEST_CONTAINER = get_disabled_test_info()
176
177
178def setup_test_env():
179 """The method sets default value for the various variants of the tests if they
180 are already not set.
181 """
182 if env.ART_TEST_BISECTION:
183 env.ART_TEST_RUN_TEST_NO_PREBUILD = True
184 env.ART_TEST_RUN_TEST_PREBUILD = False
185 # Bisection search writes to standard output.
186 env.ART_TEST_QUIET = False
187
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700188 global _user_input_variants
189 global run_all_configs
Alex Lighta90c68c2018-03-26 14:50:24 -0700190 # These are the default variant-options we will use if nothing in the group is specified.
191 default_variants = {
192 'target': {'host', 'target'},
Alex Lighta90c68c2018-03-26 14:50:24 -0700193 'prebuild': {'prebuild'},
194 'cdex_level': {'cdex-fast'},
195 'jvmti': { 'no-jvmti'},
196 'compiler': {'optimizing',
197 'jit',
198 'interpreter',
199 'interp-ac',
200 'speed-profile'},
201 'relocate': {'no-relocate'},
202 'trace': {'ntrace'},
203 'gc': {'cms'},
204 'jni': {'checkjni'},
205 'image': {'picimage'},
Alex Lighta90c68c2018-03-26 14:50:24 -0700206 'debuggable': {'ndebuggable'},
207 'run': {'debug'},
208 # address_sizes_target depends on the target so it is dealt with below.
209 }
210 # We want to pull these early since the full VARIANT_TYPE_DICT has a few additional ones we don't
211 # want to pick up if we pass --all.
212 default_variants_keys = default_variants.keys()
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700213 if run_all_configs:
Alex Lighta90c68c2018-03-26 14:50:24 -0700214 default_variants = VARIANT_TYPE_DICT
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700215
Alex Lighta90c68c2018-03-26 14:50:24 -0700216 for key in default_variants_keys:
217 if not _user_input_variants[key]:
218 _user_input_variants[key] = default_variants[key]
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700219
Shubham Ajmera85853952017-08-29 16:26:21 -0700220 _user_input_variants['address_sizes_target'] = collections.defaultdict(set)
221 if not _user_input_variants['address_sizes']:
222 _user_input_variants['address_sizes_target']['target'].add(
223 env.ART_PHONY_TEST_TARGET_SUFFIX)
224 _user_input_variants['address_sizes_target']['host'].add(
225 env.ART_PHONY_TEST_HOST_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000226 if env.ART_TEST_RUN_TEST_2ND_ARCH:
Shubham Ajmera85853952017-08-29 16:26:21 -0700227 _user_input_variants['address_sizes_target']['host'].add(
228 env.ART_2ND_PHONY_TEST_HOST_SUFFIX)
229 _user_input_variants['address_sizes_target']['target'].add(
230 env.ART_2ND_PHONY_TEST_TARGET_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000231 else:
Shubham Ajmera85853952017-08-29 16:26:21 -0700232 _user_input_variants['address_sizes_target']['host'] = _user_input_variants['address_sizes']
233 _user_input_variants['address_sizes_target']['target'] = _user_input_variants['address_sizes']
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000234
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700235 global n_thread
Orion Hodsonda144b62019-09-03 11:57:53 +0100236 if n_thread == -1:
Shubham Ajmera85853952017-08-29 16:26:21 -0700237 if 'target' in _user_input_variants['target']:
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700238 n_thread = get_default_threads('target')
239 else:
240 n_thread = get_default_threads('host')
Shubham Ajmera93857f22017-10-09 13:47:35 -0700241 print_text("Concurrency: " + str(n_thread) + "\n")
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700242
Alex Light3412a002017-10-20 13:44:40 +0000243 global extra_arguments
244 for target in _user_input_variants['target']:
245 extra_arguments[target] = find_extra_device_arguments(target)
246
Shubham Ajmera22499e22017-03-22 18:33:37 -0700247 if not sys.stdout.isatty():
248 global COLOR_ERROR
249 global COLOR_PASS
250 global COLOR_SKIP
251 global COLOR_NORMAL
252 COLOR_ERROR = ''
253 COLOR_PASS = ''
254 COLOR_SKIP = ''
255 COLOR_NORMAL = ''
256
Alex Light3412a002017-10-20 13:44:40 +0000257def find_extra_device_arguments(target):
258 """
259 Gets any extra arguments from the device_config.
260 """
Igor Murashkinbab15062018-02-23 14:53:24 -0800261 device_name = target
262 if target == 'target':
263 device_name = get_device_name()
264 return device_config.get(device_name, { 'run-test-args' : [] })['run-test-args']
Alex Light3412a002017-10-20 13:44:40 +0000265
266def get_device_name():
267 """
268 Gets the value of ro.product.name from remote device.
269 """
270 proc = subprocess.Popen(['adb', 'shell', 'getprop', 'ro.product.name'],
271 stderr=subprocess.STDOUT,
272 stdout = subprocess.PIPE,
273 universal_newlines=True)
274 # only wait 2 seconds.
275 output = proc.communicate(timeout = 2)[0]
276 success = not proc.wait()
277 if success:
278 return output.strip()
279 else:
280 print_text("Unable to determine device type!\n")
281 print_text("Continuing anyway.\n")
282 return "UNKNOWN_TARGET"
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000283
284def run_tests(tests):
Orion Hodson163c8ab2019-04-05 11:40:30 +0100285 """This method generates variants of the tests to be run and executes them.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000286
287 Args:
288 tests: The set of tests to be run.
289 """
290 options_all = ''
Igor Murashkinbab15062018-02-23 14:53:24 -0800291
292 # jvm does not run with all these combinations,
293 # or at least it doesn't make sense for most of them.
294 # TODO: support some jvm variants like jvmti ?
295 target_input_variants = _user_input_variants['target']
296 uncombinated_target_input_variants = []
297 if 'jvm' in target_input_variants:
298 _user_input_variants['target'].remove('jvm')
299 uncombinated_target_input_variants.append('jvm')
300
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000301 global total_test_count
302 total_test_count = len(tests)
Igor Murashkinbab15062018-02-23 14:53:24 -0800303 if target_input_variants:
304 for variant_type in VARIANT_TYPE_DICT:
305 if not (variant_type == 'target' or 'address_sizes' in variant_type):
306 total_test_count *= len(_user_input_variants[variant_type])
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000307 target_address_combinations = 0
Igor Murashkinbab15062018-02-23 14:53:24 -0800308 for target in target_input_variants:
Shubham Ajmera85853952017-08-29 16:26:21 -0700309 for address_size in _user_input_variants['address_sizes_target'][target]:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000310 target_address_combinations += 1
Igor Murashkinbab15062018-02-23 14:53:24 -0800311 target_address_combinations += len(uncombinated_target_input_variants)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000312 total_test_count *= target_address_combinations
313
314 if env.ART_TEST_WITH_STRACE:
315 options_all += ' --strace'
316
317 if env.ART_TEST_RUN_TEST_ALWAYS_CLEAN:
318 options_all += ' --always-clean'
319
320 if env.ART_TEST_BISECTION:
321 options_all += ' --bisection-search'
322
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000323 if gdb:
324 options_all += ' --gdb'
325 if gdb_arg:
326 options_all += ' --gdb-arg ' + gdb_arg
327
Alex Light0d20d582018-06-12 16:16:41 -0700328 options_all += ' ' + ' '.join(run_test_option)
Alex Light26829182018-06-11 11:36:24 -0700329
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000330 if runtime_option:
331 for opt in runtime_option:
332 options_all += ' --runtime-option ' + opt
Alex Lighte9f61032018-09-24 16:04:51 -0700333 if with_agent:
334 for opt in with_agent:
335 options_all += ' --with-agent ' + opt
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000336
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700337 if dex2oat_jobs != -1:
338 options_all += ' --dex2oat-jobs ' + str(dex2oat_jobs)
339
Igor Murashkinbab15062018-02-23 14:53:24 -0800340 def iter_config(tests, input_variants, user_input_variants):
341 config = itertools.product(tests, input_variants, user_input_variants['run'],
342 user_input_variants['prebuild'], user_input_variants['compiler'],
343 user_input_variants['relocate'], user_input_variants['trace'],
344 user_input_variants['gc'], user_input_variants['jni'],
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100345 user_input_variants['image'],
Igor Murashkinbab15062018-02-23 14:53:24 -0800346 user_input_variants['debuggable'], user_input_variants['jvmti'],
347 user_input_variants['cdex_level'])
348 return config
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000349
Igor Murashkinbab15062018-02-23 14:53:24 -0800350 # [--host, --target] combines with all the other user input variants.
351 config = iter_config(tests, target_input_variants, _user_input_variants)
352 # [--jvm] currently combines with nothing else. most of the extra flags we'd insert
353 # would be unrecognizable by the 'java' binary, so avoid inserting any extra flags for now.
354 uncombinated_config = iter_config(tests, uncombinated_target_input_variants, { 'run': [''],
355 'prebuild': [''], 'compiler': [''],
356 'relocate': [''], 'trace': [''],
357 'gc': [''], 'jni': [''],
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100358 'image': [''],
Igor Murashkinbab15062018-02-23 14:53:24 -0800359 'debuggable': [''], 'jvmti': [''],
360 'cdex_level': ['']})
361
Orion Hodson163c8ab2019-04-05 11:40:30 +0100362 def start_combination(executor, config_tuple, global_options, address_size):
Igor Murashkinbab15062018-02-23 14:53:24 -0800363 test, target, run, prebuild, compiler, relocate, trace, gc, \
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100364 jni, image, debuggable, jvmti, cdex_level = config_tuple
Igor Murashkinbab15062018-02-23 14:53:24 -0800365
Orion Hodson75a58dc2018-02-05 14:37:31 +0000366 # NB The order of components here should match the order of
367 # components in the regex parser in parse_test_name.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000368 test_name = 'test-art-'
369 test_name += target + '-run-test-'
370 test_name += run + '-'
371 test_name += prebuild + '-'
372 test_name += compiler + '-'
373 test_name += relocate + '-'
374 test_name += trace + '-'
375 test_name += gc + '-'
376 test_name += jni + '-'
377 test_name += image + '-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000378 test_name += debuggable + '-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700379 test_name += jvmti + '-'
Orion Hodson75a58dc2018-02-05 14:37:31 +0000380 test_name += cdex_level + '-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000381 test_name += test
382 test_name += address_size
383
384 variant_set = {target, run, prebuild, compiler, relocate, trace, gc, jni,
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100385 image, debuggable, jvmti, cdex_level, address_size}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000386
Alex Light6f342dd2019-03-27 17:15:42 +0000387 options_test = global_options
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000388
389 if target == 'host':
390 options_test += ' --host'
Igor Murashkinbab15062018-02-23 14:53:24 -0800391 elif target == 'jvm':
392 options_test += ' --jvm'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000393
Neil Fuller26a5dd62019-03-13 15:16:35 +0000394 # Honor ART_TEST_CHROOT, ART_TEST_ANDROID_ROOT, ART_TEST_ANDROID_RUNTIME_ROOT,
Victor Chang64611242019-07-05 16:32:41 +0100395 # ART_TEST_ANDROID_I18N_ROOT, and ART_TEST_ANDROID_TZDATA_ROOT but only for target tests.
Roland Levillainb0633b22018-05-24 15:59:18 +0100396 if target == 'target':
397 if env.ART_TEST_CHROOT:
398 options_test += ' --chroot ' + env.ART_TEST_CHROOT
399 if env.ART_TEST_ANDROID_ROOT:
400 options_test += ' --android-root ' + env.ART_TEST_ANDROID_ROOT
Victor Chang64611242019-07-05 16:32:41 +0100401 if env.ART_TEST_ANDROID_I18N_ROOT:
402 options_test += ' --android-i18n-root ' + env.ART_TEST_ANDROID_I18N_ROOT
Roland Levillain28076142019-01-10 16:39:25 +0000403 if env.ART_TEST_ANDROID_RUNTIME_ROOT:
404 options_test += ' --android-runtime-root ' + env.ART_TEST_ANDROID_RUNTIME_ROOT
Neil Fuller26a5dd62019-03-13 15:16:35 +0000405 if env.ART_TEST_ANDROID_TZDATA_ROOT:
406 options_test += ' --android-tzdata-root ' + env.ART_TEST_ANDROID_TZDATA_ROOT
Roland Levillainb0633b22018-05-24 15:59:18 +0100407
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000408 if run == 'ndebug':
409 options_test += ' -O'
410
411 if prebuild == 'prebuild':
412 options_test += ' --prebuild'
413 elif prebuild == 'no-prebuild':
414 options_test += ' --no-prebuild'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000415
Orion Hodson6aa4e0d2018-05-25 09:39:16 +0100416 if cdex_level:
417 # Add option and remove the cdex- prefix.
418 options_test += ' --compact-dex-level ' + cdex_level.replace('cdex-','')
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800419
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000420 if compiler == 'optimizing':
421 options_test += ' --optimizing'
422 elif compiler == 'regalloc_gc':
423 options_test += ' --optimizing -Xcompiler-option --register-allocation-strategy=graph-color'
424 elif compiler == 'interpreter':
425 options_test += ' --interpreter'
426 elif compiler == 'interp-ac':
427 options_test += ' --interpreter --verify-soft-fail'
428 elif compiler == 'jit':
429 options_test += ' --jit'
Roland Levillainad694bf2018-10-09 14:49:15 +0100430 elif compiler == 'jit-on-first-use':
431 options_test += ' --jit --runtime-option -Xjitthreshold:0'
Jeff Hao002b9312017-03-27 16:23:08 -0700432 elif compiler == 'speed-profile':
433 options_test += ' --random-profile'
Nicolas Geoffrayacc56ac2018-10-09 08:45:24 +0100434 elif compiler == 'baseline':
435 options_test += ' --baseline'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000436
437 if relocate == 'relocate':
438 options_test += ' --relocate'
439 elif relocate == 'no-relocate':
440 options_test += ' --no-relocate'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000441
442 if trace == 'trace':
443 options_test += ' --trace'
444 elif trace == 'stream':
445 options_test += ' --trace --stream'
446
447 if gc == 'gcverify':
448 options_test += ' --gcverify'
449 elif gc == 'gcstress':
450 options_test += ' --gcstress'
451
452 if jni == 'forcecopy':
453 options_test += ' --runtime-option -Xjniopts:forcecopy'
454 elif jni == 'checkjni':
455 options_test += ' --runtime-option -Xcheck:jni'
456
457 if image == 'no-image':
458 options_test += ' --no-image'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000459
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000460 if debuggable == 'debuggable':
Alex Lightbb5b4f32019-07-09 02:31:48 -0700461 options_test += ' --debuggable --runtime-option -Xopaque-jni-ids:true'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000462
Alex Light8f2c6d42017-04-10 16:27:35 -0700463 if jvmti == 'jvmti-stress':
Alex Light43e935d2017-06-19 15:40:40 -0700464 options_test += ' --jvmti-trace-stress --jvmti-redefine-stress --jvmti-field-stress'
465 elif jvmti == 'field-stress':
466 options_test += ' --jvmti-field-stress'
Alex Lightb7edcda2017-04-27 13:20:31 -0700467 elif jvmti == 'trace-stress':
468 options_test += ' --jvmti-trace-stress'
469 elif jvmti == 'redefine-stress':
470 options_test += ' --jvmti-redefine-stress'
Alex Lightc38c3692017-06-27 15:45:14 -0700471 elif jvmti == 'step-stress':
472 options_test += ' --jvmti-step-stress'
Alex Light8f2c6d42017-04-10 16:27:35 -0700473
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000474 if address_size == '64':
475 options_test += ' --64'
476
477 if env.DEX2OAT_HOST_INSTRUCTION_SET_FEATURES:
478 options_test += ' --instruction-set-features' + env.DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
479
480 elif address_size == '32':
481 if env.HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES:
482 options_test += ' --instruction-set-features ' + \
483 env.HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
484
Shubham Ajmera29f89682017-03-24 14:44:10 -0700485 # TODO(http://36039166): This is a temporary solution to
486 # fix build breakages.
487 options_test = (' --output-path %s') % (
488 tempfile.mkdtemp(dir=env.ART_HOST_TEST_DIR)) + options_test
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000489
490 run_test_sh = env.ANDROID_BUILD_TOP + '/art/test/run-test'
Alex Light3412a002017-10-20 13:44:40 +0000491 command = ' '.join((run_test_sh, options_test, ' '.join(extra_arguments[target]), test))
Orion Hodson163c8ab2019-04-05 11:40:30 +0100492 return executor.submit(run_test, command, test, variant_set, test_name)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000493
Alex Light6f342dd2019-03-27 17:15:42 +0000494 # Use a context-manager to handle cleaning up the extracted zipapex if needed.
495 with handle_zipapex(zipapex_loc) as zipapex_opt:
496 options_all += zipapex_opt
Orion Hodson163c8ab2019-04-05 11:40:30 +0100497 global n_thread
498 with concurrent.futures.ThreadPoolExecutor(max_workers=n_thread) as executor:
499 test_futures = []
500 for config_tuple in config:
501 target = config_tuple[1]
502 for address_size in _user_input_variants['address_sizes_target'][target]:
503 test_futures.append(start_combination(executor, config_tuple, options_all, address_size))
Igor Murashkinbab15062018-02-23 14:53:24 -0800504
Orion Hodson163c8ab2019-04-05 11:40:30 +0100505 for config_tuple in uncombinated_config:
506 test_futures.append(start_combination(executor, config_tuple, options_all, "")) # no address size
Igor Murashkinbab15062018-02-23 14:53:24 -0800507
Orion Hodson163c8ab2019-04-05 11:40:30 +0100508 tests_done = 0
509 for test_future in concurrent.futures.as_completed(test_futures):
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700510 (test, status, failure_info, test_time) = test_future.result()
Orion Hodson163c8ab2019-04-05 11:40:30 +0100511 tests_done += 1
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700512 print_test_info(tests_done, test, status, failure_info, test_time)
Orion Hodson163c8ab2019-04-05 11:40:30 +0100513 if failure_info and not env.ART_TEST_KEEP_GOING:
514 for f in test_futures:
515 f.cancel()
516 break
517 executor.shutdown(True)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000518
Alex Light6f342dd2019-03-27 17:15:42 +0000519@contextlib.contextmanager
520def handle_zipapex(ziploc):
521 """Extracts the zipapex (if present) and handles cleanup.
522
523 If we are running out of a zipapex we want to unzip it once and have all the tests use the same
524 extracted contents. This extracts the files and handles cleanup if needed. It returns the
525 required extra arguments to pass to the run-test.
526 """
527 if ziploc is not None:
528 with tempfile.TemporaryDirectory() as tmpdir:
529 subprocess.check_call(["unzip", "-qq", ziploc, "apex_payload.zip", "-d", tmpdir])
530 subprocess.check_call(
531 ["unzip", "-qq", os.path.join(tmpdir, "apex_payload.zip"), "-d", tmpdir])
532 yield " --runtime-extracted-zipapex " + tmpdir
533 else:
534 yield ""
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000535
536def run_test(command, test, test_variant, test_name):
537 """Runs the test.
538
539 It invokes art/test/run-test script to run the test. The output of the script
540 is checked, and if it ends with "Succeeded!", it assumes that the tests
541 passed, otherwise, put it in the list of failed test. Before actually running
542 the test, it also checks if the test is placed in the list of disabled tests,
543 and if yes, it skips running it, and adds the test in the list of skipped
Orion Hodson163c8ab2019-04-05 11:40:30 +0100544 tests.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000545
546 Args:
547 command: The command to be used to invoke the script
548 test: The name of the test without the variant information.
549 test_variant: The set of variant for the test.
550 test_name: The name of the test along with the variants.
Orion Hodson163c8ab2019-04-05 11:40:30 +0100551
Andreas Gampe52699512019-08-02 17:27:47 -0700552 Returns: a tuple of testname, status, optional failure info, and test time.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000553 """
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000554 try:
555 if is_test_disabled(test, test_variant):
556 test_skipped = True
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700557 test_time = datetime.timedelta()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000558 else:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000559 test_skipped = False
Orion Hodson3e29e192019-09-03 14:24:04 +0100560 test_start_time = time.monotonic()
Shubham Ajmerab4949f52017-05-08 13:52:46 -0700561 if gdb:
562 proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, universal_newlines=True)
563 else:
564 proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, stdout = subprocess.PIPE,
565 universal_newlines=True)
Shubham Ajmera186d3212017-07-21 01:20:57 +0000566 script_output = proc.communicate(timeout=timeout)[0]
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000567 test_passed = not proc.wait()
Orion Hodson3e29e192019-09-03 14:24:04 +0100568 test_time_seconds = time.monotonic() - test_start_time
569 test_time = datetime.timedelta(seconds=test_time_seconds)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000570
571 if not test_skipped:
572 if test_passed:
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700573 return (test_name, 'PASS', None, test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000574 else:
Alex Light1ebe6142017-10-03 15:00:10 -0700575 failed_tests.append((test_name, str(command) + "\n" + script_output))
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700576 return (test_name, 'FAIL', ('%s\n%s') % (command, script_output), test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000577 elif not dry_run:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000578 skipped_tests.append(test_name)
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700579 return (test_name, 'SKIP', None, test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000580 else:
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700581 return (test_name, 'PASS', None, test_time)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700582 except subprocess.TimeoutExpired as e:
Orion Hodson3e29e192019-09-03 14:24:04 +0100583 test_time_seconds = time.monotonic() - test_start_time
584 test_time = datetime.timedelta(seconds=test_time_seconds)
Shubham Ajmera186d3212017-07-21 01:20:57 +0000585 failed_tests.append((test_name, 'Timed out in %d seconds' % timeout))
Andreas Gampe52699512019-08-02 17:27:47 -0700586
Andreas Gampe1ec82e52019-08-02 17:41:04 -0700587 # The python documentation states that it is necessary to actually kill the process.
588 # Note: This is not the correct solution, really, as it will not kill descendants. We would need
589 # something more complex, e.g., killing by session ID (e.g., in a trap in run-test).
590 proc.kill()
591 script_output = proc.communicate()
592
Orion Hodson3e29e192019-09-03 14:24:04 +0100593 return (test_name, 'TIMEOUT', 'Timed out in %d seconds\n%s' % (timeout, command), test_time)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700594 except Exception as e:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700595 failed_tests.append((test_name, str(e)))
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700596 return (test_name, 'FAIL', ('%s\n%s\n\n') % (command, str(e)), datetime.timedelta())
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000597
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700598def print_test_info(test_count, test_name, result, failed_test_info="",
599 test_time=datetime.timedelta()):
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000600 """Print the continous test information
601
602 If verbose is set to True, it continuously prints test status information
603 on a new line.
604 If verbose is set to False, it keeps on erasing test
605 information by overriding it with the latest test information. Also,
606 in this case it stictly makes sure that the information length doesn't
607 exceed the console width. It does so by shortening the test_name.
608
609 When a test fails, it prints the output of the run-test script and
610 command used to invoke the script. It doesn't override the failing
611 test information in either of the cases.
612 """
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000613
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000614 info = ''
615 if not verbose:
616 # Without --verbose, the testrunner erases passing test info. It
617 # does that by overriding the printed text with white spaces all across
618 # the console width.
619 console_width = int(os.popen('stty size', 'r').read().split()[1])
620 info = '\r' + ' ' * console_width + '\r'
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000621 try:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000622 percent = (test_count * 100) / total_test_count
623 progress_info = ('[ %d%% %d/%d ]') % (
624 percent,
625 test_count,
626 total_test_count)
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700627 if test_time.total_seconds() != 0 and verbose:
628 info += '(%s)' % str(test_time)
629
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000630
Shubham Ajmerafe793492017-03-16 13:31:35 -0700631 if result == 'FAIL' or result == 'TIMEOUT':
Alex Light1ebe6142017-10-03 15:00:10 -0700632 if not verbose:
633 info += ('%s %s %s\n') % (
634 progress_info,
635 test_name,
636 COLOR_ERROR + result + COLOR_NORMAL)
637 else:
638 info += ('%s %s %s\n%s\n') % (
639 progress_info,
640 test_name,
641 COLOR_ERROR + result + COLOR_NORMAL,
642 failed_test_info)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000643 else:
644 result_text = ''
645 if result == 'PASS':
646 result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL
647 elif result == 'SKIP':
648 result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL
649
650 if verbose:
651 info += ('%s %s %s\n') % (
652 progress_info,
653 test_name,
654 result_text)
655 else:
656 total_output_length = 2 # Two spaces
657 total_output_length += len(progress_info)
658 total_output_length += len(result)
659 allowed_test_length = console_width - total_output_length
660 test_name_len = len(test_name)
661 if allowed_test_length < test_name_len:
Shubham Ajmerafe793492017-03-16 13:31:35 -0700662 test_name = ('...%s') % (
663 test_name[-(allowed_test_length - 3):])
Alex Lightc14311c2017-02-23 17:02:46 -0800664 info += ('%s %s %s') % (
665 progress_info,
666 test_name,
667 result_text)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000668 print_text(info)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700669 except Exception as e:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000670 print_text(('%s\n%s\n') % (test_name, str(e)))
671 failed_tests.append(test_name)
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000672
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700673def verify_knownfailure_entry(entry):
674 supported_field = {
Shubham Ajmerafe793492017-03-16 13:31:35 -0700675 'tests' : (list, str),
Alex Light6fdc1b62017-09-18 11:33:56 -0700676 'test_patterns' : (list,),
Shubham Ajmerafe793492017-03-16 13:31:35 -0700677 'description' : (list, str),
678 'bug' : (str,),
679 'variant' : (str,),
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700680 'env_vars' : (dict,),
681 }
682 for field in entry:
683 field_type = type(entry[field])
684 if field_type not in supported_field[field]:
685 raise ValueError('%s is not supported type for %s\n%s' % (
686 str(field_type),
687 field,
688 str(entry)))
689
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000690def get_disabled_test_info():
691 """Generate set of known failures.
692
693 It parses the art/test/knownfailures.json file to generate the list of
694 disabled tests.
695
696 Returns:
697 The method returns a dict of tests mapped to the variants list
698 for which the test should not be run.
699 """
700 known_failures_file = env.ANDROID_BUILD_TOP + '/art/test/knownfailures.json'
701 with open(known_failures_file) as known_failures_json:
702 known_failures_info = json.loads(known_failures_json.read())
703
704 disabled_test_info = {}
705 for failure in known_failures_info:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700706 verify_knownfailure_entry(failure)
707 tests = failure.get('tests', [])
Shubham Ajmerafe793492017-03-16 13:31:35 -0700708 if isinstance(tests, str):
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000709 tests = [tests]
Alex Light6fdc1b62017-09-18 11:33:56 -0700710 patterns = failure.get("test_patterns", [])
711 if (not isinstance(patterns, list)):
712 raise ValueError("test_patters is not a list in %s" % failure)
713
714 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 +0000715 variants = parse_variants(failure.get('variant'))
716 env_vars = failure.get('env_vars')
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700717
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000718 if check_env_vars(env_vars):
719 for test in tests:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700720 if test not in RUN_TEST_SET:
721 raise ValueError('%s is not a valid run-test' % (
722 test))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000723 if test in disabled_test_info:
724 disabled_test_info[test] = disabled_test_info[test].union(variants)
725 else:
726 disabled_test_info[test] = variants
727 return disabled_test_info
728
729
730def check_env_vars(env_vars):
731 """Checks if the env variables are set as required to run the test.
732
733 Returns:
734 True if all the env variables are set as required, otherwise False.
735 """
736
737 if not env_vars:
738 return True
739 for key in env_vars:
740 if env.get_env(key) != env_vars.get(key):
741 return False
742 return True
743
744
745def is_test_disabled(test, variant_set):
746 """Checks if the test along with the variant_set is disabled.
747
748 Args:
749 test: The name of the test as in art/test directory.
750 variant_set: Variants to be used for the test.
751 Returns:
752 True, if the test is disabled.
753 """
754 if dry_run:
755 return True
Alex Lightbc319b22017-02-17 14:21:33 -0800756 if test in env.EXTRA_DISABLED_TESTS:
757 return True
Alex Light42242dd2018-02-16 09:23:57 -0800758 if ignore_skips:
759 return False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000760 variants_list = DISABLED_TEST_CONTAINER.get(test, {})
761 for variants in variants_list:
762 variants_present = True
763 for variant in variants:
764 if variant not in variant_set:
765 variants_present = False
766 break
767 if variants_present:
768 return True
Alex Lighta86a5d12019-08-30 11:03:05 -0700769 for bad_combo in NONFUNCTIONAL_VARIANT_SETS:
770 if bad_combo.issubset(variant_set):
771 return True
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000772 return False
773
774
775def parse_variants(variants):
776 """Parse variants fetched from art/test/knownfailures.json.
777 """
778 if not variants:
779 variants = ''
780 for variant in TOTAL_VARIANTS_SET:
781 variants += variant
782 variants += '|'
783 variants = variants[:-1]
784 variant_list = set()
785 or_variants = variants.split('|')
786 for or_variant in or_variants:
787 and_variants = or_variant.split('&')
788 variant = set()
789 for and_variant in and_variants:
790 and_variant = and_variant.strip()
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700791 if and_variant not in TOTAL_VARIANTS_SET:
792 raise ValueError('%s is not a valid variant' % (
793 and_variant))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000794 variant.add(and_variant)
795 variant_list.add(frozenset(variant))
796 return variant_list
797
798def print_text(output):
799 sys.stdout.write(output)
800 sys.stdout.flush()
801
802def print_analysis():
803 if not verbose:
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000804 # Without --verbose, the testrunner erases passing test info. It
805 # does that by overriding the printed text with white spaces all across
806 # the console width.
807 console_width = int(os.popen('stty size', 'r').read().split()[1])
808 eraser_text = '\r' + ' ' * console_width + '\r'
809 print_text(eraser_text)
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700810
811 # Prints information about the total tests run.
812 # E.g., "2/38 (5%) tests passed".
813 passed_test_count = total_test_count - len(skipped_tests) - len(failed_tests)
814 passed_test_information = ('%d/%d (%d%%) %s passed.\n') % (
815 passed_test_count,
816 total_test_count,
817 (passed_test_count*100)/total_test_count,
818 'tests' if passed_test_count > 1 else 'test')
819 print_text(passed_test_information)
820
821 # Prints the list of skipped tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000822 if skipped_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700823 print_text(COLOR_SKIP + 'SKIPPED TESTS: ' + COLOR_NORMAL + '\n')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000824 for test in skipped_tests:
825 print_text(test + '\n')
826 print_text('\n')
827
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700828 # Prints the list of failed tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000829 if failed_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700830 print_text(COLOR_ERROR + 'FAILED: ' + COLOR_NORMAL + '\n')
831 for test_info in failed_tests:
832 print_text(('%s\n%s\n' % (test_info[0], test_info[1])))
Andreas Gampe0dd7e852017-05-24 21:44:23 -0700833 print_text(COLOR_ERROR + '----------' + COLOR_NORMAL + '\n')
834 for failed_test in sorted([test_info[0] for test_info in failed_tests]):
835 print_text(('%s\n' % (failed_test)))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000836
837
838def parse_test_name(test_name):
839 """Parses the testname provided by the user.
840 It supports two types of test_name:
841 1) Like 001-HelloWorld. In this case, it will just verify if the test actually
842 exists and if it does, it returns the testname.
Alex Light79d6c802019-06-27 15:50:11 +0000843 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 +0000844 In this case, it will parse all the variants and check if they are placed
845 correctly. If yes, it will set the various VARIANT_TYPES to use the
846 variants required to run the test. Again, it returns the test_name
847 without the variant information like 001-HelloWorld.
848 """
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000849 test_set = set()
850 for test in RUN_TEST_SET:
851 if test.startswith(test_name):
852 test_set.add(test)
853 if test_set:
854 return test_set
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000855
856 regex = '^test-art-'
857 regex += '(' + '|'.join(VARIANT_TYPE_DICT['target']) + ')-'
858 regex += 'run-test-'
859 regex += '(' + '|'.join(VARIANT_TYPE_DICT['run']) + ')-'
860 regex += '(' + '|'.join(VARIANT_TYPE_DICT['prebuild']) + ')-'
861 regex += '(' + '|'.join(VARIANT_TYPE_DICT['compiler']) + ')-'
862 regex += '(' + '|'.join(VARIANT_TYPE_DICT['relocate']) + ')-'
863 regex += '(' + '|'.join(VARIANT_TYPE_DICT['trace']) + ')-'
864 regex += '(' + '|'.join(VARIANT_TYPE_DICT['gc']) + ')-'
865 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jni']) + ')-'
866 regex += '(' + '|'.join(VARIANT_TYPE_DICT['image']) + ')-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000867 regex += '(' + '|'.join(VARIANT_TYPE_DICT['debuggable']) + ')-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700868 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jvmti']) + ')-'
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800869 regex += '(' + '|'.join(VARIANT_TYPE_DICT['cdex_level']) + ')-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000870 regex += '(' + '|'.join(RUN_TEST_SET) + ')'
871 regex += '(' + '|'.join(VARIANT_TYPE_DICT['address_sizes']) + ')$'
872 match = re.match(regex, test_name)
873 if match:
Shubham Ajmera85853952017-08-29 16:26:21 -0700874 _user_input_variants['target'].add(match.group(1))
875 _user_input_variants['run'].add(match.group(2))
876 _user_input_variants['prebuild'].add(match.group(3))
877 _user_input_variants['compiler'].add(match.group(4))
878 _user_input_variants['relocate'].add(match.group(5))
879 _user_input_variants['trace'].add(match.group(6))
880 _user_input_variants['gc'].add(match.group(7))
881 _user_input_variants['jni'].add(match.group(8))
882 _user_input_variants['image'].add(match.group(9))
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100883 _user_input_variants['debuggable'].add(match.group(10))
884 _user_input_variants['jvmti'].add(match.group(11))
885 _user_input_variants['cdex_level'].add(match.group(12))
886 _user_input_variants['address_sizes'].add(match.group(14))
887 return {match.group(13)}
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000888 raise ValueError(test_name + " is not a valid test")
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000889
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800890
891def setup_env_for_build_target(build_target, parser, options):
892 """Setup environment for the build target
893
894 The method setup environment for the master-art-host targets.
895 """
896 os.environ.update(build_target['env'])
897 os.environ['SOONG_ALLOW_MISSING_DEPENDENCIES'] = 'true'
898 print_text('%s\n' % (str(os.environ)))
899
900 target_options = vars(parser.parse_args(build_target['flags']))
901 target_options['host'] = True
902 target_options['verbose'] = True
903 target_options['build'] = True
904 target_options['n_thread'] = options['n_thread']
905 target_options['dry_run'] = options['dry_run']
906
907 return target_options
908
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700909def get_default_threads(target):
Orion Hodsonda144b62019-09-03 11:57:53 +0100910 if target == 'target':
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700911 adb_command = 'adb shell cat /sys/devices/system/cpu/present'
912 cpu_info_proc = subprocess.Popen(adb_command.split(), stdout=subprocess.PIPE)
913 cpu_info = cpu_info_proc.stdout.read()
Shubham Ajmera8fd26942017-05-09 11:30:47 -0700914 if type(cpu_info) is bytes:
915 cpu_info = cpu_info.decode('utf-8')
Orion Hodsonda144b62019-09-03 11:57:53 +0100916 cpu_info_regex = r'\d*-(\d*)'
Shubham Ajmera8fd26942017-05-09 11:30:47 -0700917 match = re.match(cpu_info_regex, cpu_info)
918 if match:
919 return int(match.group(1))
920 else:
921 raise ValueError('Unable to predict the concurrency for the target. '
922 'Is device connected?')
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700923 else:
924 return multiprocessing.cpu_count()
925
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000926def parse_option():
927 global verbose
928 global dry_run
Alex Light42242dd2018-02-16 09:23:57 -0800929 global ignore_skips
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000930 global n_thread
931 global build
932 global gdb
933 global gdb_arg
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000934 global runtime_option
Alex Light26829182018-06-11 11:36:24 -0700935 global run_test_option
Shubham Ajmerafe793492017-03-16 13:31:35 -0700936 global timeout
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700937 global dex2oat_jobs
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700938 global run_all_configs
Alex Lighte9f61032018-09-24 16:04:51 -0700939 global with_agent
Alex Light6f342dd2019-03-27 17:15:42 +0000940 global zipapex_loc
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000941
Alex Light7a1ccf82017-02-21 09:52:34 -0800942 parser = argparse.ArgumentParser(description="Runs all or a subset of the ART test suite.")
Andreas Gampe09b2d502017-11-29 19:08:16 -0800943 parser.add_argument('-t', '--test', action='append', dest='tests', help='name(s) of the test(s)')
Alex Lightc0322512018-03-13 10:33:52 -0700944 global_group = parser.add_argument_group('Global options',
945 'Options that affect all tests being run')
946 global_group.add_argument('-j', type=int, dest='n_thread')
947 global_group.add_argument('--timeout', default=timeout, type=int, dest='timeout')
948 global_group.add_argument('--verbose', '-v', action='store_true', dest='verbose')
949 global_group.add_argument('--dry-run', action='store_true', dest='dry_run')
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000950 global_group.add_argument("--skip", action='append', dest="skips", default=[],
Alex Lightc0322512018-03-13 10:33:52 -0700951 help="Skip the given test in all circumstances.")
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000952 global_group.add_argument("--no-skips", dest="ignore_skips", action='store_true', default=False,
Alex Lightc0322512018-03-13 10:33:52 -0700953 help="""Don't skip any run-test configurations listed in
954 knownfailures.json.""")
955 global_group.add_argument('--no-build-dependencies',
956 action='store_false', dest='build',
957 help="""Don't build dependencies under any circumstances. This is the
958 behavior if ART_TEST_RUN_TEST_ALWAYS_BUILD is not set to 'true'.""")
959 global_group.add_argument('-b', '--build-dependencies',
960 action='store_true', dest='build',
961 help="""Build dependencies under all circumstances. By default we will
962 not build dependencies unless ART_TEST_RUN_TEST_BUILD=true.""")
963 global_group.add_argument('--build-target', dest='build_target', help='master-art-host targets')
964 global_group.set_defaults(build = env.ART_TEST_RUN_TEST_BUILD)
965 global_group.add_argument('--gdb', action='store_true', dest='gdb')
966 global_group.add_argument('--gdb-arg', dest='gdb_arg')
Alex Light26829182018-06-11 11:36:24 -0700967 global_group.add_argument('--run-test-option', action='append', dest='run_test_option',
968 default=[],
969 help="""Pass an option, unaltered, to the run-test script.
970 This should be enclosed in single-quotes to allow for spaces. The option
971 will be split using shlex.split() prior to invoking run-test.
972 Example \"--run-test-option='--with-agent libtifast.so=MethodExit'\"""")
Alex Lighte9f61032018-09-24 16:04:51 -0700973 global_group.add_argument('--with-agent', action='append', dest='with_agent',
974 help="""Pass an agent to be attached to the runtime""")
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000975 global_group.add_argument('--runtime-option', action='append', dest='runtime_option',
976 help="""Pass an option to the runtime. Runtime options
977 starting with a '-' must be separated by a '=', for
978 example '--runtime-option=-Xjitthreshold:0'.""")
Alex Lightc0322512018-03-13 10:33:52 -0700979 global_group.add_argument('--dex2oat-jobs', type=int, dest='dex2oat_jobs',
980 help='Number of dex2oat jobs')
Alex Light6f342dd2019-03-27 17:15:42 +0000981 global_group.add_argument('--runtime-zipapex', dest='runtime_zipapex', default=None,
982 help='Location for runtime zipapex.')
Alex Lightc0322512018-03-13 10:33:52 -0700983 global_group.add_argument('-a', '--all', action='store_true', dest='run_all',
984 help="Run all the possible configurations for the input test set")
985 for variant_type, variant_set in VARIANT_TYPE_DICT.items():
986 var_group = parser.add_argument_group(
987 '{}-type Options'.format(variant_type),
988 "Options that control the '{}' variants.".format(variant_type))
Alex Lightbf8a5d82019-08-30 10:17:22 -0700989 var_group.add_argument('--all-' + variant_type,
990 action='store_true',
991 dest='all_' + variant_type,
992 help='Enable all variants of ' + variant_type)
Alex Lightc0322512018-03-13 10:33:52 -0700993 for variant in variant_set:
994 flag = '--' + variant
995 var_group.add_argument(flag, action='store_true', dest=variant)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000996
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800997 options = vars(parser.parse_args())
Alex Lightbf8a5d82019-08-30 10:17:22 -0700998 # Handle the --all-<type> meta-options
999 for variant_type, variant_set in VARIANT_TYPE_DICT.items():
1000 if options['all_' + variant_type]:
1001 for variant in variant_set:
1002 options[variant] = True
1003
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001004 if options['build_target']:
1005 options = setup_env_for_build_target(target_config[options['build_target']],
1006 parser, options)
1007
Andreas Gampe09b2d502017-11-29 19:08:16 -08001008 tests = None
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001009 env.EXTRA_DISABLED_TESTS.update(set(options['skips']))
Andreas Gampe09b2d502017-11-29 19:08:16 -08001010 if options['tests']:
1011 tests = set()
1012 for test_name in options['tests']:
1013 tests |= parse_test_name(test_name)
Shubham Ajmera85853952017-08-29 16:26:21 -07001014
1015 for variant_type in VARIANT_TYPE_DICT:
1016 for variant in VARIANT_TYPE_DICT[variant_type]:
1017 if options.get(variant):
1018 _user_input_variants[variant_type].add(variant)
1019
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001020 if options['verbose']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001021 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001022 if options['n_thread']:
1023 n_thread = max(1, options['n_thread'])
Alex Light42242dd2018-02-16 09:23:57 -08001024 ignore_skips = options['ignore_skips']
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001025 if options['dry_run']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001026 dry_run = True
1027 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001028 build = options['build']
1029 if options['gdb']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001030 n_thread = 1
1031 gdb = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001032 if options['gdb_arg']:
1033 gdb_arg = options['gdb_arg']
Vladimir Marko41b1f0e2018-03-21 11:17:12 +00001034 runtime_option = options['runtime_option'];
Alex Lighte9f61032018-09-24 16:04:51 -07001035 with_agent = options['with_agent'];
Alex Light26829182018-06-11 11:36:24 -07001036 run_test_option = sum(map(shlex.split, options['run_test_option']), [])
Alex Light6f342dd2019-03-27 17:15:42 +00001037 zipapex_loc = options['runtime_zipapex']
Alex Light26829182018-06-11 11:36:24 -07001038
Shubham Ajmerafe793492017-03-16 13:31:35 -07001039 timeout = options['timeout']
Shubham Ajmera981d99c2017-08-17 14:11:08 -07001040 if options['dex2oat_jobs']:
1041 dex2oat_jobs = options['dex2oat_jobs']
Shubham Ajmera42ea83b2017-09-25 21:05:57 -07001042 if options['run_all']:
1043 run_all_configs = True
Shubham Ajmera22499e22017-03-22 18:33:37 -07001044
Andreas Gampe09b2d502017-11-29 19:08:16 -08001045 return tests
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001046
1047def main():
1048 gather_test_info()
Andreas Gampe09b2d502017-11-29 19:08:16 -08001049 user_requested_tests = parse_option()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001050 setup_test_env()
1051 if build:
1052 build_targets = ''
Shubham Ajmera85853952017-08-29 16:26:21 -07001053 if 'host' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001054 build_targets += 'test-art-host-run-test-dependencies '
Shubham Ajmera85853952017-08-29 16:26:21 -07001055 if 'target' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001056 build_targets += 'test-art-target-run-test-dependencies '
Igor Murashkinbab15062018-02-23 14:53:24 -08001057 if 'jvm' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001058 build_targets += 'test-art-host-run-test-dependencies '
Alex Lightd51af9e2018-10-11 16:07:55 -07001059 build_command = env.ANDROID_BUILD_TOP + '/build/soong/soong_ui.bash --make-mode'
Colin Cross91f55e62017-10-21 12:45:26 -07001060 build_command += ' DX='
Shubham Ajmera06cde292017-02-10 23:15:05 +00001061 build_command += ' ' + build_targets
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001062 if subprocess.call(build_command.split()):
Colin Cross9cb13a62018-06-07 13:02:02 -07001063 # Debugging for b/62653020
1064 if env.DIST_DIR:
1065 shutil.copyfile(env.SOONG_OUT_DIR + '/build.ninja', env.DIST_DIR + '/soong.ninja')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001066 sys.exit(1)
Orion Hodson163c8ab2019-04-05 11:40:30 +01001067
Andreas Gampe09b2d502017-11-29 19:08:16 -08001068 if user_requested_tests:
Orion Hodson163c8ab2019-04-05 11:40:30 +01001069 run_tests(user_requested_tests)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001070 else:
Orion Hodson163c8ab2019-04-05 11:40:30 +01001071 run_tests(RUN_TEST_SET)
1072
1073 print_analysis()
1074
1075 exit_code = 0 if len(failed_tests) == 0 else 1
1076 sys.exit(exit_code)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001077
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001078if __name__ == '__main__':
1079 main()