blob: 578e8854aad0dbf45114919cc53090c53cfea9e5 [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
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000076
77import env
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -080078from target_config import target_config
Alex Light3412a002017-10-20 13:44:40 +000079from device_config import device_config
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000080
Shubham Ajmera186d3212017-07-21 01:20:57 +000081# timeout for individual tests.
82# TODO: make it adjustable per tests and for buildbots
83timeout = 3000 # 50 minutes
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000084
85# DISABLED_TEST_CONTAINER holds information about the disabled tests. It is a map
86# that has key as the test name (like 001-HelloWorld), and value as set of
87# variants that the test is disabled for.
88DISABLED_TEST_CONTAINER = {}
89
90# The Dict contains the list of all possible variants for a given type. For example,
91# for key TARGET, the value would be target and host. The list is used to parse
92# the test name given as the argument to run.
93VARIANT_TYPE_DICT = {}
94
95# The set contains all the variants of each time.
96TOTAL_VARIANTS_SET = set()
97
98# The colors are used in the output. When a test passes, COLOR_PASS is used,
99# and so on.
100COLOR_ERROR = '\033[91m'
101COLOR_PASS = '\033[92m'
102COLOR_SKIP = '\033[93m'
103COLOR_NORMAL = '\033[0m'
104
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000105# The set contains the list of all the possible run tests that are in art/test
106# directory.
107RUN_TEST_SET = set()
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000108
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000109failed_tests = []
110skipped_tests = []
111
112# Flags
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700113n_thread = -1
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000114total_test_count = 0
115verbose = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000116dry_run = False
Alex Light42242dd2018-02-16 09:23:57 -0800117ignore_skips = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000118build = False
119gdb = False
120gdb_arg = ''
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000121runtime_option = ''
Alex Lighte9f61032018-09-24 16:04:51 -0700122with_agent = []
Alex Light6f342dd2019-03-27 17:15:42 +0000123zipapex_loc = None
Alex Light26829182018-06-11 11:36:24 -0700124run_test_option = []
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700125dex2oat_jobs = -1 # -1 corresponds to default threads for dex2oat
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700126run_all_configs = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000127
Alex Light3412a002017-10-20 13:44:40 +0000128# Dict containing extra arguments
129extra_arguments = { "host" : [], "target" : [] }
130
Shubham Ajmera85853952017-08-29 16:26:21 -0700131# Dict to store user requested test variants.
132# key: variant_type.
133# value: set of variants user wants to run of type <key>.
134_user_input_variants = collections.defaultdict(set)
135
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000136def gather_test_info():
137 """The method gathers test information about the test to be run which includes
138 generating the list of total tests from the art/test directory and the list
139 of disabled test. It also maps various variants to types.
140 """
141 global TOTAL_VARIANTS_SET
142 global DISABLED_TEST_CONTAINER
143 # TODO: Avoid duplication of the variant names in different lists.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000144 VARIANT_TYPE_DICT['run'] = {'ndebug', 'debug'}
Igor Murashkinbab15062018-02-23 14:53:24 -0800145 VARIANT_TYPE_DICT['target'] = {'target', 'host', 'jvm'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000146 VARIANT_TYPE_DICT['trace'] = {'trace', 'ntrace', 'stream'}
Vladimir Marko4519b9d2018-10-10 15:21:21 +0100147 VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000148 VARIANT_TYPE_DICT['debuggable'] = {'ndebuggable', 'debuggable'}
149 VARIANT_TYPE_DICT['gc'] = {'gcstress', 'gcverify', 'cms'}
Nicolas Geoffray3d8a78a2018-08-29 21:10:16 +0000150 VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'prebuild'}
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800151 VARIANT_TYPE_DICT['cdex_level'] = {'cdex-none', 'cdex-fast'}
Vladimir Markoa497a392018-09-26 10:52:50 +0100152 VARIANT_TYPE_DICT['relocate'] = {'relocate', 'no-relocate'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000153 VARIANT_TYPE_DICT['jni'] = {'jni', 'forcecopy', 'checkjni'}
154 VARIANT_TYPE_DICT['address_sizes'] = {'64', '32'}
Alex Light43e935d2017-06-19 15:40:40 -0700155 VARIANT_TYPE_DICT['jvmti'] = {'no-jvmti', 'jvmti-stress', 'redefine-stress', 'trace-stress',
Alex Lightc38c3692017-06-27 15:45:14 -0700156 'field-stress', 'step-stress'}
Roland Levillainad694bf2018-10-09 14:49:15 +0100157 VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'jit-on-first-use',
Nicolas Geoffrayacc56ac2018-10-09 08:45:24 +0100158 'optimizing', 'regalloc_gc', 'speed-profile', 'baseline'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000159
160 for v_type in VARIANT_TYPE_DICT:
161 TOTAL_VARIANTS_SET = TOTAL_VARIANTS_SET.union(VARIANT_TYPE_DICT.get(v_type))
162
163 test_dir = env.ANDROID_BUILD_TOP + '/art/test'
164 for f in os.listdir(test_dir):
165 if fnmatch.fnmatch(f, '[0-9]*'):
166 RUN_TEST_SET.add(f)
167 DISABLED_TEST_CONTAINER = get_disabled_test_info()
168
169
170def setup_test_env():
171 """The method sets default value for the various variants of the tests if they
172 are already not set.
173 """
174 if env.ART_TEST_BISECTION:
175 env.ART_TEST_RUN_TEST_NO_PREBUILD = True
176 env.ART_TEST_RUN_TEST_PREBUILD = False
177 # Bisection search writes to standard output.
178 env.ART_TEST_QUIET = False
179
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700180 global _user_input_variants
181 global run_all_configs
Alex Lighta90c68c2018-03-26 14:50:24 -0700182 # These are the default variant-options we will use if nothing in the group is specified.
183 default_variants = {
184 'target': {'host', 'target'},
Alex Lighta90c68c2018-03-26 14:50:24 -0700185 'prebuild': {'prebuild'},
186 'cdex_level': {'cdex-fast'},
187 'jvmti': { 'no-jvmti'},
188 'compiler': {'optimizing',
189 'jit',
190 'interpreter',
191 'interp-ac',
192 'speed-profile'},
193 'relocate': {'no-relocate'},
194 'trace': {'ntrace'},
195 'gc': {'cms'},
196 'jni': {'checkjni'},
197 'image': {'picimage'},
Alex Lighta90c68c2018-03-26 14:50:24 -0700198 'debuggable': {'ndebuggable'},
199 'run': {'debug'},
200 # address_sizes_target depends on the target so it is dealt with below.
201 }
202 # We want to pull these early since the full VARIANT_TYPE_DICT has a few additional ones we don't
203 # want to pick up if we pass --all.
204 default_variants_keys = default_variants.keys()
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700205 if run_all_configs:
Alex Lighta90c68c2018-03-26 14:50:24 -0700206 default_variants = VARIANT_TYPE_DICT
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700207
Alex Lighta90c68c2018-03-26 14:50:24 -0700208 for key in default_variants_keys:
209 if not _user_input_variants[key]:
210 _user_input_variants[key] = default_variants[key]
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700211
Shubham Ajmera85853952017-08-29 16:26:21 -0700212 _user_input_variants['address_sizes_target'] = collections.defaultdict(set)
213 if not _user_input_variants['address_sizes']:
214 _user_input_variants['address_sizes_target']['target'].add(
215 env.ART_PHONY_TEST_TARGET_SUFFIX)
216 _user_input_variants['address_sizes_target']['host'].add(
217 env.ART_PHONY_TEST_HOST_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000218 if env.ART_TEST_RUN_TEST_2ND_ARCH:
Shubham Ajmera85853952017-08-29 16:26:21 -0700219 _user_input_variants['address_sizes_target']['host'].add(
220 env.ART_2ND_PHONY_TEST_HOST_SUFFIX)
221 _user_input_variants['address_sizes_target']['target'].add(
222 env.ART_2ND_PHONY_TEST_TARGET_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000223 else:
Shubham Ajmera85853952017-08-29 16:26:21 -0700224 _user_input_variants['address_sizes_target']['host'] = _user_input_variants['address_sizes']
225 _user_input_variants['address_sizes_target']['target'] = _user_input_variants['address_sizes']
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000226
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700227 global n_thread
228 if n_thread is -1:
Shubham Ajmera85853952017-08-29 16:26:21 -0700229 if 'target' in _user_input_variants['target']:
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700230 n_thread = get_default_threads('target')
231 else:
232 n_thread = get_default_threads('host')
Shubham Ajmera93857f22017-10-09 13:47:35 -0700233 print_text("Concurrency: " + str(n_thread) + "\n")
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700234
Alex Light3412a002017-10-20 13:44:40 +0000235 global extra_arguments
236 for target in _user_input_variants['target']:
237 extra_arguments[target] = find_extra_device_arguments(target)
238
Shubham Ajmera22499e22017-03-22 18:33:37 -0700239 if not sys.stdout.isatty():
240 global COLOR_ERROR
241 global COLOR_PASS
242 global COLOR_SKIP
243 global COLOR_NORMAL
244 COLOR_ERROR = ''
245 COLOR_PASS = ''
246 COLOR_SKIP = ''
247 COLOR_NORMAL = ''
248
Alex Light3412a002017-10-20 13:44:40 +0000249def find_extra_device_arguments(target):
250 """
251 Gets any extra arguments from the device_config.
252 """
Igor Murashkinbab15062018-02-23 14:53:24 -0800253 device_name = target
254 if target == 'target':
255 device_name = get_device_name()
256 return device_config.get(device_name, { 'run-test-args' : [] })['run-test-args']
Alex Light3412a002017-10-20 13:44:40 +0000257
258def get_device_name():
259 """
260 Gets the value of ro.product.name from remote device.
261 """
262 proc = subprocess.Popen(['adb', 'shell', 'getprop', 'ro.product.name'],
263 stderr=subprocess.STDOUT,
264 stdout = subprocess.PIPE,
265 universal_newlines=True)
266 # only wait 2 seconds.
267 output = proc.communicate(timeout = 2)[0]
268 success = not proc.wait()
269 if success:
270 return output.strip()
271 else:
272 print_text("Unable to determine device type!\n")
273 print_text("Continuing anyway.\n")
274 return "UNKNOWN_TARGET"
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000275
276def run_tests(tests):
Orion Hodson163c8ab2019-04-05 11:40:30 +0100277 """This method generates variants of the tests to be run and executes them.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000278
279 Args:
280 tests: The set of tests to be run.
281 """
282 options_all = ''
Igor Murashkinbab15062018-02-23 14:53:24 -0800283
284 # jvm does not run with all these combinations,
285 # or at least it doesn't make sense for most of them.
286 # TODO: support some jvm variants like jvmti ?
287 target_input_variants = _user_input_variants['target']
288 uncombinated_target_input_variants = []
289 if 'jvm' in target_input_variants:
290 _user_input_variants['target'].remove('jvm')
291 uncombinated_target_input_variants.append('jvm')
292
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000293 global total_test_count
294 total_test_count = len(tests)
Igor Murashkinbab15062018-02-23 14:53:24 -0800295 if target_input_variants:
296 for variant_type in VARIANT_TYPE_DICT:
297 if not (variant_type == 'target' or 'address_sizes' in variant_type):
298 total_test_count *= len(_user_input_variants[variant_type])
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000299 target_address_combinations = 0
Igor Murashkinbab15062018-02-23 14:53:24 -0800300 for target in target_input_variants:
Shubham Ajmera85853952017-08-29 16:26:21 -0700301 for address_size in _user_input_variants['address_sizes_target'][target]:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000302 target_address_combinations += 1
Igor Murashkinbab15062018-02-23 14:53:24 -0800303 target_address_combinations += len(uncombinated_target_input_variants)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000304 total_test_count *= target_address_combinations
305
306 if env.ART_TEST_WITH_STRACE:
307 options_all += ' --strace'
308
309 if env.ART_TEST_RUN_TEST_ALWAYS_CLEAN:
310 options_all += ' --always-clean'
311
312 if env.ART_TEST_BISECTION:
313 options_all += ' --bisection-search'
314
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000315 if gdb:
316 options_all += ' --gdb'
317 if gdb_arg:
318 options_all += ' --gdb-arg ' + gdb_arg
319
Alex Light0d20d582018-06-12 16:16:41 -0700320 options_all += ' ' + ' '.join(run_test_option)
Alex Light26829182018-06-11 11:36:24 -0700321
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000322 if runtime_option:
323 for opt in runtime_option:
324 options_all += ' --runtime-option ' + opt
Alex Lighte9f61032018-09-24 16:04:51 -0700325 if with_agent:
326 for opt in with_agent:
327 options_all += ' --with-agent ' + opt
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000328
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700329 if dex2oat_jobs != -1:
330 options_all += ' --dex2oat-jobs ' + str(dex2oat_jobs)
331
Igor Murashkinbab15062018-02-23 14:53:24 -0800332 def iter_config(tests, input_variants, user_input_variants):
333 config = itertools.product(tests, input_variants, user_input_variants['run'],
334 user_input_variants['prebuild'], user_input_variants['compiler'],
335 user_input_variants['relocate'], user_input_variants['trace'],
336 user_input_variants['gc'], user_input_variants['jni'],
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100337 user_input_variants['image'],
Igor Murashkinbab15062018-02-23 14:53:24 -0800338 user_input_variants['debuggable'], user_input_variants['jvmti'],
339 user_input_variants['cdex_level'])
340 return config
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000341
Igor Murashkinbab15062018-02-23 14:53:24 -0800342 # [--host, --target] combines with all the other user input variants.
343 config = iter_config(tests, target_input_variants, _user_input_variants)
344 # [--jvm] currently combines with nothing else. most of the extra flags we'd insert
345 # would be unrecognizable by the 'java' binary, so avoid inserting any extra flags for now.
346 uncombinated_config = iter_config(tests, uncombinated_target_input_variants, { 'run': [''],
347 'prebuild': [''], 'compiler': [''],
348 'relocate': [''], 'trace': [''],
349 'gc': [''], 'jni': [''],
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100350 'image': [''],
Igor Murashkinbab15062018-02-23 14:53:24 -0800351 'debuggable': [''], 'jvmti': [''],
352 'cdex_level': ['']})
353
Orion Hodson163c8ab2019-04-05 11:40:30 +0100354 def start_combination(executor, config_tuple, global_options, address_size):
Igor Murashkinbab15062018-02-23 14:53:24 -0800355 test, target, run, prebuild, compiler, relocate, trace, gc, \
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100356 jni, image, debuggable, jvmti, cdex_level = config_tuple
Igor Murashkinbab15062018-02-23 14:53:24 -0800357
Orion Hodson75a58dc2018-02-05 14:37:31 +0000358 # NB The order of components here should match the order of
359 # components in the regex parser in parse_test_name.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000360 test_name = 'test-art-'
361 test_name += target + '-run-test-'
362 test_name += run + '-'
363 test_name += prebuild + '-'
364 test_name += compiler + '-'
365 test_name += relocate + '-'
366 test_name += trace + '-'
367 test_name += gc + '-'
368 test_name += jni + '-'
369 test_name += image + '-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000370 test_name += debuggable + '-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700371 test_name += jvmti + '-'
Orion Hodson75a58dc2018-02-05 14:37:31 +0000372 test_name += cdex_level + '-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000373 test_name += test
374 test_name += address_size
375
376 variant_set = {target, run, prebuild, compiler, relocate, trace, gc, jni,
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100377 image, debuggable, jvmti, cdex_level, address_size}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000378
Alex Light6f342dd2019-03-27 17:15:42 +0000379 options_test = global_options
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000380
381 if target == 'host':
382 options_test += ' --host'
Igor Murashkinbab15062018-02-23 14:53:24 -0800383 elif target == 'jvm':
384 options_test += ' --jvm'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000385
Neil Fuller26a5dd62019-03-13 15:16:35 +0000386 # Honor ART_TEST_CHROOT, ART_TEST_ANDROID_ROOT, ART_TEST_ANDROID_RUNTIME_ROOT,
Victor Chang64611242019-07-05 16:32:41 +0100387 # ART_TEST_ANDROID_I18N_ROOT, and ART_TEST_ANDROID_TZDATA_ROOT but only for target tests.
Roland Levillainb0633b22018-05-24 15:59:18 +0100388 if target == 'target':
389 if env.ART_TEST_CHROOT:
390 options_test += ' --chroot ' + env.ART_TEST_CHROOT
391 if env.ART_TEST_ANDROID_ROOT:
392 options_test += ' --android-root ' + env.ART_TEST_ANDROID_ROOT
Victor Chang64611242019-07-05 16:32:41 +0100393 if env.ART_TEST_ANDROID_I18N_ROOT:
394 options_test += ' --android-i18n-root ' + env.ART_TEST_ANDROID_I18N_ROOT
Roland Levillain28076142019-01-10 16:39:25 +0000395 if env.ART_TEST_ANDROID_RUNTIME_ROOT:
396 options_test += ' --android-runtime-root ' + env.ART_TEST_ANDROID_RUNTIME_ROOT
Neil Fuller26a5dd62019-03-13 15:16:35 +0000397 if env.ART_TEST_ANDROID_TZDATA_ROOT:
398 options_test += ' --android-tzdata-root ' + env.ART_TEST_ANDROID_TZDATA_ROOT
Roland Levillainb0633b22018-05-24 15:59:18 +0100399
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000400 if run == 'ndebug':
401 options_test += ' -O'
402
403 if prebuild == 'prebuild':
404 options_test += ' --prebuild'
405 elif prebuild == 'no-prebuild':
406 options_test += ' --no-prebuild'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000407
Orion Hodson6aa4e0d2018-05-25 09:39:16 +0100408 if cdex_level:
409 # Add option and remove the cdex- prefix.
410 options_test += ' --compact-dex-level ' + cdex_level.replace('cdex-','')
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800411
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000412 if compiler == 'optimizing':
413 options_test += ' --optimizing'
414 elif compiler == 'regalloc_gc':
415 options_test += ' --optimizing -Xcompiler-option --register-allocation-strategy=graph-color'
416 elif compiler == 'interpreter':
417 options_test += ' --interpreter'
418 elif compiler == 'interp-ac':
419 options_test += ' --interpreter --verify-soft-fail'
420 elif compiler == 'jit':
421 options_test += ' --jit'
Roland Levillainad694bf2018-10-09 14:49:15 +0100422 elif compiler == 'jit-on-first-use':
423 options_test += ' --jit --runtime-option -Xjitthreshold:0'
Jeff Hao002b9312017-03-27 16:23:08 -0700424 elif compiler == 'speed-profile':
425 options_test += ' --random-profile'
Nicolas Geoffrayacc56ac2018-10-09 08:45:24 +0100426 elif compiler == 'baseline':
427 options_test += ' --baseline'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000428
429 if relocate == 'relocate':
430 options_test += ' --relocate'
431 elif relocate == 'no-relocate':
432 options_test += ' --no-relocate'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000433
434 if trace == 'trace':
435 options_test += ' --trace'
436 elif trace == 'stream':
437 options_test += ' --trace --stream'
438
439 if gc == 'gcverify':
440 options_test += ' --gcverify'
441 elif gc == 'gcstress':
442 options_test += ' --gcstress'
443
444 if jni == 'forcecopy':
445 options_test += ' --runtime-option -Xjniopts:forcecopy'
446 elif jni == 'checkjni':
447 options_test += ' --runtime-option -Xcheck:jni'
448
449 if image == 'no-image':
450 options_test += ' --no-image'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000451
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000452 if debuggable == 'debuggable':
Alex Lightbb5b4f32019-07-09 02:31:48 -0700453 options_test += ' --debuggable --runtime-option -Xopaque-jni-ids:true'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000454
Alex Light8f2c6d42017-04-10 16:27:35 -0700455 if jvmti == 'jvmti-stress':
Alex Light43e935d2017-06-19 15:40:40 -0700456 options_test += ' --jvmti-trace-stress --jvmti-redefine-stress --jvmti-field-stress'
457 elif jvmti == 'field-stress':
458 options_test += ' --jvmti-field-stress'
Alex Lightb7edcda2017-04-27 13:20:31 -0700459 elif jvmti == 'trace-stress':
460 options_test += ' --jvmti-trace-stress'
461 elif jvmti == 'redefine-stress':
462 options_test += ' --jvmti-redefine-stress'
Alex Lightc38c3692017-06-27 15:45:14 -0700463 elif jvmti == 'step-stress':
464 options_test += ' --jvmti-step-stress'
Alex Light8f2c6d42017-04-10 16:27:35 -0700465
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000466 if address_size == '64':
467 options_test += ' --64'
468
469 if env.DEX2OAT_HOST_INSTRUCTION_SET_FEATURES:
470 options_test += ' --instruction-set-features' + env.DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
471
472 elif address_size == '32':
473 if env.HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES:
474 options_test += ' --instruction-set-features ' + \
475 env.HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
476
Shubham Ajmera29f89682017-03-24 14:44:10 -0700477 # TODO(http://36039166): This is a temporary solution to
478 # fix build breakages.
479 options_test = (' --output-path %s') % (
480 tempfile.mkdtemp(dir=env.ART_HOST_TEST_DIR)) + options_test
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000481
482 run_test_sh = env.ANDROID_BUILD_TOP + '/art/test/run-test'
Alex Light3412a002017-10-20 13:44:40 +0000483 command = ' '.join((run_test_sh, options_test, ' '.join(extra_arguments[target]), test))
Orion Hodson163c8ab2019-04-05 11:40:30 +0100484 return executor.submit(run_test, command, test, variant_set, test_name)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000485
Alex Light6f342dd2019-03-27 17:15:42 +0000486 # Use a context-manager to handle cleaning up the extracted zipapex if needed.
487 with handle_zipapex(zipapex_loc) as zipapex_opt:
488 options_all += zipapex_opt
Orion Hodson163c8ab2019-04-05 11:40:30 +0100489 global n_thread
490 with concurrent.futures.ThreadPoolExecutor(max_workers=n_thread) as executor:
491 test_futures = []
492 for config_tuple in config:
493 target = config_tuple[1]
494 for address_size in _user_input_variants['address_sizes_target'][target]:
495 test_futures.append(start_combination(executor, config_tuple, options_all, address_size))
Igor Murashkinbab15062018-02-23 14:53:24 -0800496
Orion Hodson163c8ab2019-04-05 11:40:30 +0100497 for config_tuple in uncombinated_config:
498 test_futures.append(start_combination(executor, config_tuple, options_all, "")) # no address size
Igor Murashkinbab15062018-02-23 14:53:24 -0800499
Orion Hodson163c8ab2019-04-05 11:40:30 +0100500 tests_done = 0
501 for test_future in concurrent.futures.as_completed(test_futures):
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700502 (test, status, failure_info, test_time) = test_future.result()
Orion Hodson163c8ab2019-04-05 11:40:30 +0100503 tests_done += 1
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700504 print_test_info(tests_done, test, status, failure_info, test_time)
Orion Hodson163c8ab2019-04-05 11:40:30 +0100505 if failure_info and not env.ART_TEST_KEEP_GOING:
506 for f in test_futures:
507 f.cancel()
508 break
509 executor.shutdown(True)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000510
Alex Light6f342dd2019-03-27 17:15:42 +0000511@contextlib.contextmanager
512def handle_zipapex(ziploc):
513 """Extracts the zipapex (if present) and handles cleanup.
514
515 If we are running out of a zipapex we want to unzip it once and have all the tests use the same
516 extracted contents. This extracts the files and handles cleanup if needed. It returns the
517 required extra arguments to pass to the run-test.
518 """
519 if ziploc is not None:
520 with tempfile.TemporaryDirectory() as tmpdir:
521 subprocess.check_call(["unzip", "-qq", ziploc, "apex_payload.zip", "-d", tmpdir])
522 subprocess.check_call(
523 ["unzip", "-qq", os.path.join(tmpdir, "apex_payload.zip"), "-d", tmpdir])
524 yield " --runtime-extracted-zipapex " + tmpdir
525 else:
526 yield ""
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000527
528def run_test(command, test, test_variant, test_name):
529 """Runs the test.
530
531 It invokes art/test/run-test script to run the test. The output of the script
532 is checked, and if it ends with "Succeeded!", it assumes that the tests
533 passed, otherwise, put it in the list of failed test. Before actually running
534 the test, it also checks if the test is placed in the list of disabled tests,
535 and if yes, it skips running it, and adds the test in the list of skipped
Orion Hodson163c8ab2019-04-05 11:40:30 +0100536 tests.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000537
538 Args:
539 command: The command to be used to invoke the script
540 test: The name of the test without the variant information.
541 test_variant: The set of variant for the test.
542 test_name: The name of the test along with the variants.
Orion Hodson163c8ab2019-04-05 11:40:30 +0100543
Andreas Gampe52699512019-08-02 17:27:47 -0700544 Returns: a tuple of testname, status, optional failure info, and test time.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000545 """
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000546 try:
547 if is_test_disabled(test, test_variant):
548 test_skipped = True
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700549 test_time = datetime.timedelta()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000550 else:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000551 test_skipped = False
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700552 test_start_time = datetime.datetime.now()
Shubham Ajmerab4949f52017-05-08 13:52:46 -0700553 if gdb:
554 proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, universal_newlines=True)
555 else:
556 proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, stdout = subprocess.PIPE,
557 universal_newlines=True)
Shubham Ajmera186d3212017-07-21 01:20:57 +0000558 script_output = proc.communicate(timeout=timeout)[0]
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000559 test_passed = not proc.wait()
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700560 test_end_time = datetime.datetime.now()
561 test_time = test_end_time - test_start_time
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000562
563 if not test_skipped:
564 if test_passed:
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700565 return (test_name, 'PASS', None, test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000566 else:
Alex Light1ebe6142017-10-03 15:00:10 -0700567 failed_tests.append((test_name, str(command) + "\n" + script_output))
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700568 return (test_name, 'FAIL', ('%s\n%s') % (command, script_output), test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000569 elif not dry_run:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000570 skipped_tests.append(test_name)
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700571 return (test_name, 'SKIP', None, test_time)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000572 else:
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700573 return (test_name, 'PASS', None, test_time)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700574 except subprocess.TimeoutExpired as e:
Andreas Gampe52699512019-08-02 17:27:47 -0700575 test_end_time = datetime.datetime.now()
Shubham Ajmera186d3212017-07-21 01:20:57 +0000576 failed_tests.append((test_name, 'Timed out in %d seconds' % timeout))
Andreas Gampe52699512019-08-02 17:27:47 -0700577
Andreas Gampe1ec82e52019-08-02 17:41:04 -0700578 # The python documentation states that it is necessary to actually kill the process.
579 # Note: This is not the correct solution, really, as it will not kill descendants. We would need
580 # something more complex, e.g., killing by session ID (e.g., in a trap in run-test).
581 proc.kill()
582 script_output = proc.communicate()
583
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700584 return (test_name,
585 'TIMEOUT',
586 'Timed out in %d seconds\n%s' % (timeout, command),
Andreas Gampe52699512019-08-02 17:27:47 -0700587 test_end_time - test_start_time)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700588 except Exception as e:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700589 failed_tests.append((test_name, str(e)))
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700590 return (test_name, 'FAIL', ('%s\n%s\n\n') % (command, str(e)), datetime.timedelta())
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000591
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700592def print_test_info(test_count, test_name, result, failed_test_info="",
593 test_time=datetime.timedelta()):
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000594 """Print the continous test information
595
596 If verbose is set to True, it continuously prints test status information
597 on a new line.
598 If verbose is set to False, it keeps on erasing test
599 information by overriding it with the latest test information. Also,
600 in this case it stictly makes sure that the information length doesn't
601 exceed the console width. It does so by shortening the test_name.
602
603 When a test fails, it prints the output of the run-test script and
604 command used to invoke the script. It doesn't override the failing
605 test information in either of the cases.
606 """
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000607
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000608 info = ''
609 if not verbose:
610 # Without --verbose, the testrunner erases passing test info. It
611 # does that by overriding the printed text with white spaces all across
612 # the console width.
613 console_width = int(os.popen('stty size', 'r').read().split()[1])
614 info = '\r' + ' ' * console_width + '\r'
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000615 try:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000616 percent = (test_count * 100) / total_test_count
617 progress_info = ('[ %d%% %d/%d ]') % (
618 percent,
619 test_count,
620 total_test_count)
Andreas Gampe7409b9f2019-07-08 09:29:52 -0700621 if test_time.total_seconds() != 0 and verbose:
622 info += '(%s)' % str(test_time)
623
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000624
Shubham Ajmerafe793492017-03-16 13:31:35 -0700625 if result == 'FAIL' or result == 'TIMEOUT':
Alex Light1ebe6142017-10-03 15:00:10 -0700626 if not verbose:
627 info += ('%s %s %s\n') % (
628 progress_info,
629 test_name,
630 COLOR_ERROR + result + COLOR_NORMAL)
631 else:
632 info += ('%s %s %s\n%s\n') % (
633 progress_info,
634 test_name,
635 COLOR_ERROR + result + COLOR_NORMAL,
636 failed_test_info)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000637 else:
638 result_text = ''
639 if result == 'PASS':
640 result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL
641 elif result == 'SKIP':
642 result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL
643
644 if verbose:
645 info += ('%s %s %s\n') % (
646 progress_info,
647 test_name,
648 result_text)
649 else:
650 total_output_length = 2 # Two spaces
651 total_output_length += len(progress_info)
652 total_output_length += len(result)
653 allowed_test_length = console_width - total_output_length
654 test_name_len = len(test_name)
655 if allowed_test_length < test_name_len:
Shubham Ajmerafe793492017-03-16 13:31:35 -0700656 test_name = ('...%s') % (
657 test_name[-(allowed_test_length - 3):])
Alex Lightc14311c2017-02-23 17:02:46 -0800658 info += ('%s %s %s') % (
659 progress_info,
660 test_name,
661 result_text)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000662 print_text(info)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700663 except Exception as e:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000664 print_text(('%s\n%s\n') % (test_name, str(e)))
665 failed_tests.append(test_name)
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000666
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700667def verify_knownfailure_entry(entry):
668 supported_field = {
Shubham Ajmerafe793492017-03-16 13:31:35 -0700669 'tests' : (list, str),
Alex Light6fdc1b62017-09-18 11:33:56 -0700670 'test_patterns' : (list,),
Shubham Ajmerafe793492017-03-16 13:31:35 -0700671 'description' : (list, str),
672 'bug' : (str,),
673 'variant' : (str,),
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700674 'env_vars' : (dict,),
675 }
676 for field in entry:
677 field_type = type(entry[field])
678 if field_type not in supported_field[field]:
679 raise ValueError('%s is not supported type for %s\n%s' % (
680 str(field_type),
681 field,
682 str(entry)))
683
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000684def get_disabled_test_info():
685 """Generate set of known failures.
686
687 It parses the art/test/knownfailures.json file to generate the list of
688 disabled tests.
689
690 Returns:
691 The method returns a dict of tests mapped to the variants list
692 for which the test should not be run.
693 """
694 known_failures_file = env.ANDROID_BUILD_TOP + '/art/test/knownfailures.json'
695 with open(known_failures_file) as known_failures_json:
696 known_failures_info = json.loads(known_failures_json.read())
697
698 disabled_test_info = {}
699 for failure in known_failures_info:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700700 verify_knownfailure_entry(failure)
701 tests = failure.get('tests', [])
Shubham Ajmerafe793492017-03-16 13:31:35 -0700702 if isinstance(tests, str):
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000703 tests = [tests]
Alex Light6fdc1b62017-09-18 11:33:56 -0700704 patterns = failure.get("test_patterns", [])
705 if (not isinstance(patterns, list)):
706 raise ValueError("test_patters is not a list in %s" % failure)
707
708 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 +0000709 variants = parse_variants(failure.get('variant'))
710 env_vars = failure.get('env_vars')
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700711
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000712 if check_env_vars(env_vars):
713 for test in tests:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700714 if test not in RUN_TEST_SET:
715 raise ValueError('%s is not a valid run-test' % (
716 test))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000717 if test in disabled_test_info:
718 disabled_test_info[test] = disabled_test_info[test].union(variants)
719 else:
720 disabled_test_info[test] = variants
721 return disabled_test_info
722
723
724def check_env_vars(env_vars):
725 """Checks if the env variables are set as required to run the test.
726
727 Returns:
728 True if all the env variables are set as required, otherwise False.
729 """
730
731 if not env_vars:
732 return True
733 for key in env_vars:
734 if env.get_env(key) != env_vars.get(key):
735 return False
736 return True
737
738
739def is_test_disabled(test, variant_set):
740 """Checks if the test along with the variant_set is disabled.
741
742 Args:
743 test: The name of the test as in art/test directory.
744 variant_set: Variants to be used for the test.
745 Returns:
746 True, if the test is disabled.
747 """
748 if dry_run:
749 return True
Alex Lightbc319b22017-02-17 14:21:33 -0800750 if test in env.EXTRA_DISABLED_TESTS:
751 return True
Alex Light42242dd2018-02-16 09:23:57 -0800752 if ignore_skips:
753 return False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000754 variants_list = DISABLED_TEST_CONTAINER.get(test, {})
755 for variants in variants_list:
756 variants_present = True
757 for variant in variants:
758 if variant not in variant_set:
759 variants_present = False
760 break
761 if variants_present:
762 return True
763 return False
764
765
766def parse_variants(variants):
767 """Parse variants fetched from art/test/knownfailures.json.
768 """
769 if not variants:
770 variants = ''
771 for variant in TOTAL_VARIANTS_SET:
772 variants += variant
773 variants += '|'
774 variants = variants[:-1]
775 variant_list = set()
776 or_variants = variants.split('|')
777 for or_variant in or_variants:
778 and_variants = or_variant.split('&')
779 variant = set()
780 for and_variant in and_variants:
781 and_variant = and_variant.strip()
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700782 if and_variant not in TOTAL_VARIANTS_SET:
783 raise ValueError('%s is not a valid variant' % (
784 and_variant))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000785 variant.add(and_variant)
786 variant_list.add(frozenset(variant))
787 return variant_list
788
789def print_text(output):
790 sys.stdout.write(output)
791 sys.stdout.flush()
792
793def print_analysis():
794 if not verbose:
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000795 # Without --verbose, the testrunner erases passing test info. It
796 # does that by overriding the printed text with white spaces all across
797 # the console width.
798 console_width = int(os.popen('stty size', 'r').read().split()[1])
799 eraser_text = '\r' + ' ' * console_width + '\r'
800 print_text(eraser_text)
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700801
802 # Prints information about the total tests run.
803 # E.g., "2/38 (5%) tests passed".
804 passed_test_count = total_test_count - len(skipped_tests) - len(failed_tests)
805 passed_test_information = ('%d/%d (%d%%) %s passed.\n') % (
806 passed_test_count,
807 total_test_count,
808 (passed_test_count*100)/total_test_count,
809 'tests' if passed_test_count > 1 else 'test')
810 print_text(passed_test_information)
811
812 # Prints the list of skipped tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000813 if skipped_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700814 print_text(COLOR_SKIP + 'SKIPPED TESTS: ' + COLOR_NORMAL + '\n')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000815 for test in skipped_tests:
816 print_text(test + '\n')
817 print_text('\n')
818
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700819 # Prints the list of failed tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000820 if failed_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700821 print_text(COLOR_ERROR + 'FAILED: ' + COLOR_NORMAL + '\n')
822 for test_info in failed_tests:
823 print_text(('%s\n%s\n' % (test_info[0], test_info[1])))
Andreas Gampe0dd7e852017-05-24 21:44:23 -0700824 print_text(COLOR_ERROR + '----------' + COLOR_NORMAL + '\n')
825 for failed_test in sorted([test_info[0] for test_info in failed_tests]):
826 print_text(('%s\n' % (failed_test)))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000827
828
829def parse_test_name(test_name):
830 """Parses the testname provided by the user.
831 It supports two types of test_name:
832 1) Like 001-HelloWorld. In this case, it will just verify if the test actually
833 exists and if it does, it returns the testname.
Alex Light79d6c802019-06-27 15:50:11 +0000834 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 +0000835 In this case, it will parse all the variants and check if they are placed
836 correctly. If yes, it will set the various VARIANT_TYPES to use the
837 variants required to run the test. Again, it returns the test_name
838 without the variant information like 001-HelloWorld.
839 """
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000840 test_set = set()
841 for test in RUN_TEST_SET:
842 if test.startswith(test_name):
843 test_set.add(test)
844 if test_set:
845 return test_set
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000846
847 regex = '^test-art-'
848 regex += '(' + '|'.join(VARIANT_TYPE_DICT['target']) + ')-'
849 regex += 'run-test-'
850 regex += '(' + '|'.join(VARIANT_TYPE_DICT['run']) + ')-'
851 regex += '(' + '|'.join(VARIANT_TYPE_DICT['prebuild']) + ')-'
852 regex += '(' + '|'.join(VARIANT_TYPE_DICT['compiler']) + ')-'
853 regex += '(' + '|'.join(VARIANT_TYPE_DICT['relocate']) + ')-'
854 regex += '(' + '|'.join(VARIANT_TYPE_DICT['trace']) + ')-'
855 regex += '(' + '|'.join(VARIANT_TYPE_DICT['gc']) + ')-'
856 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jni']) + ')-'
857 regex += '(' + '|'.join(VARIANT_TYPE_DICT['image']) + ')-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000858 regex += '(' + '|'.join(VARIANT_TYPE_DICT['debuggable']) + ')-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700859 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jvmti']) + ')-'
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800860 regex += '(' + '|'.join(VARIANT_TYPE_DICT['cdex_level']) + ')-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000861 regex += '(' + '|'.join(RUN_TEST_SET) + ')'
862 regex += '(' + '|'.join(VARIANT_TYPE_DICT['address_sizes']) + ')$'
863 match = re.match(regex, test_name)
864 if match:
Shubham Ajmera85853952017-08-29 16:26:21 -0700865 _user_input_variants['target'].add(match.group(1))
866 _user_input_variants['run'].add(match.group(2))
867 _user_input_variants['prebuild'].add(match.group(3))
868 _user_input_variants['compiler'].add(match.group(4))
869 _user_input_variants['relocate'].add(match.group(5))
870 _user_input_variants['trace'].add(match.group(6))
871 _user_input_variants['gc'].add(match.group(7))
872 _user_input_variants['jni'].add(match.group(8))
873 _user_input_variants['image'].add(match.group(9))
Vladimir Markoa2da9b92018-10-10 14:21:55 +0100874 _user_input_variants['debuggable'].add(match.group(10))
875 _user_input_variants['jvmti'].add(match.group(11))
876 _user_input_variants['cdex_level'].add(match.group(12))
877 _user_input_variants['address_sizes'].add(match.group(14))
878 return {match.group(13)}
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000879 raise ValueError(test_name + " is not a valid test")
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000880
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800881
882def setup_env_for_build_target(build_target, parser, options):
883 """Setup environment for the build target
884
885 The method setup environment for the master-art-host targets.
886 """
887 os.environ.update(build_target['env'])
888 os.environ['SOONG_ALLOW_MISSING_DEPENDENCIES'] = 'true'
889 print_text('%s\n' % (str(os.environ)))
890
891 target_options = vars(parser.parse_args(build_target['flags']))
892 target_options['host'] = True
893 target_options['verbose'] = True
894 target_options['build'] = True
895 target_options['n_thread'] = options['n_thread']
896 target_options['dry_run'] = options['dry_run']
897
898 return target_options
899
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700900def get_default_threads(target):
901 if target is 'target':
902 adb_command = 'adb shell cat /sys/devices/system/cpu/present'
903 cpu_info_proc = subprocess.Popen(adb_command.split(), stdout=subprocess.PIPE)
904 cpu_info = cpu_info_proc.stdout.read()
Shubham Ajmera8fd26942017-05-09 11:30:47 -0700905 if type(cpu_info) is bytes:
906 cpu_info = cpu_info.decode('utf-8')
907 cpu_info_regex = '\d*-(\d*)'
908 match = re.match(cpu_info_regex, cpu_info)
909 if match:
910 return int(match.group(1))
911 else:
912 raise ValueError('Unable to predict the concurrency for the target. '
913 'Is device connected?')
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700914 else:
915 return multiprocessing.cpu_count()
916
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000917def parse_option():
918 global verbose
919 global dry_run
Alex Light42242dd2018-02-16 09:23:57 -0800920 global ignore_skips
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000921 global n_thread
922 global build
923 global gdb
924 global gdb_arg
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000925 global runtime_option
Alex Light26829182018-06-11 11:36:24 -0700926 global run_test_option
Shubham Ajmerafe793492017-03-16 13:31:35 -0700927 global timeout
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700928 global dex2oat_jobs
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700929 global run_all_configs
Alex Lighte9f61032018-09-24 16:04:51 -0700930 global with_agent
Alex Light6f342dd2019-03-27 17:15:42 +0000931 global zipapex_loc
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000932
Alex Light7a1ccf82017-02-21 09:52:34 -0800933 parser = argparse.ArgumentParser(description="Runs all or a subset of the ART test suite.")
Andreas Gampe09b2d502017-11-29 19:08:16 -0800934 parser.add_argument('-t', '--test', action='append', dest='tests', help='name(s) of the test(s)')
Alex Lightc0322512018-03-13 10:33:52 -0700935 global_group = parser.add_argument_group('Global options',
936 'Options that affect all tests being run')
937 global_group.add_argument('-j', type=int, dest='n_thread')
938 global_group.add_argument('--timeout', default=timeout, type=int, dest='timeout')
939 global_group.add_argument('--verbose', '-v', action='store_true', dest='verbose')
940 global_group.add_argument('--dry-run', action='store_true', dest='dry_run')
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000941 global_group.add_argument("--skip", action='append', dest="skips", default=[],
Alex Lightc0322512018-03-13 10:33:52 -0700942 help="Skip the given test in all circumstances.")
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000943 global_group.add_argument("--no-skips", dest="ignore_skips", action='store_true', default=False,
Alex Lightc0322512018-03-13 10:33:52 -0700944 help="""Don't skip any run-test configurations listed in
945 knownfailures.json.""")
946 global_group.add_argument('--no-build-dependencies',
947 action='store_false', dest='build',
948 help="""Don't build dependencies under any circumstances. This is the
949 behavior if ART_TEST_RUN_TEST_ALWAYS_BUILD is not set to 'true'.""")
950 global_group.add_argument('-b', '--build-dependencies',
951 action='store_true', dest='build',
952 help="""Build dependencies under all circumstances. By default we will
953 not build dependencies unless ART_TEST_RUN_TEST_BUILD=true.""")
954 global_group.add_argument('--build-target', dest='build_target', help='master-art-host targets')
955 global_group.set_defaults(build = env.ART_TEST_RUN_TEST_BUILD)
956 global_group.add_argument('--gdb', action='store_true', dest='gdb')
957 global_group.add_argument('--gdb-arg', dest='gdb_arg')
Alex Light26829182018-06-11 11:36:24 -0700958 global_group.add_argument('--run-test-option', action='append', dest='run_test_option',
959 default=[],
960 help="""Pass an option, unaltered, to the run-test script.
961 This should be enclosed in single-quotes to allow for spaces. The option
962 will be split using shlex.split() prior to invoking run-test.
963 Example \"--run-test-option='--with-agent libtifast.so=MethodExit'\"""")
Alex Lighte9f61032018-09-24 16:04:51 -0700964 global_group.add_argument('--with-agent', action='append', dest='with_agent',
965 help="""Pass an agent to be attached to the runtime""")
Vladimir Marko41b1f0e2018-03-21 11:17:12 +0000966 global_group.add_argument('--runtime-option', action='append', dest='runtime_option',
967 help="""Pass an option to the runtime. Runtime options
968 starting with a '-' must be separated by a '=', for
969 example '--runtime-option=-Xjitthreshold:0'.""")
Alex Lightc0322512018-03-13 10:33:52 -0700970 global_group.add_argument('--dex2oat-jobs', type=int, dest='dex2oat_jobs',
971 help='Number of dex2oat jobs')
Alex Light6f342dd2019-03-27 17:15:42 +0000972 global_group.add_argument('--runtime-zipapex', dest='runtime_zipapex', default=None,
973 help='Location for runtime zipapex.')
Alex Lightc0322512018-03-13 10:33:52 -0700974 global_group.add_argument('-a', '--all', action='store_true', dest='run_all',
975 help="Run all the possible configurations for the input test set")
976 for variant_type, variant_set in VARIANT_TYPE_DICT.items():
977 var_group = parser.add_argument_group(
978 '{}-type Options'.format(variant_type),
979 "Options that control the '{}' variants.".format(variant_type))
980 for variant in variant_set:
981 flag = '--' + variant
982 var_group.add_argument(flag, action='store_true', dest=variant)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000983
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800984 options = vars(parser.parse_args())
985 if options['build_target']:
986 options = setup_env_for_build_target(target_config[options['build_target']],
987 parser, options)
988
Andreas Gampe09b2d502017-11-29 19:08:16 -0800989 tests = None
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800990 env.EXTRA_DISABLED_TESTS.update(set(options['skips']))
Andreas Gampe09b2d502017-11-29 19:08:16 -0800991 if options['tests']:
992 tests = set()
993 for test_name in options['tests']:
994 tests |= parse_test_name(test_name)
Shubham Ajmera85853952017-08-29 16:26:21 -0700995
996 for variant_type in VARIANT_TYPE_DICT:
997 for variant in VARIANT_TYPE_DICT[variant_type]:
998 if options.get(variant):
999 _user_input_variants[variant_type].add(variant)
1000
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001001 if options['verbose']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001002 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001003 if options['n_thread']:
1004 n_thread = max(1, options['n_thread'])
Alex Light42242dd2018-02-16 09:23:57 -08001005 ignore_skips = options['ignore_skips']
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001006 if options['dry_run']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001007 dry_run = True
1008 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001009 build = options['build']
1010 if options['gdb']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001011 n_thread = 1
1012 gdb = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -08001013 if options['gdb_arg']:
1014 gdb_arg = options['gdb_arg']
Vladimir Marko41b1f0e2018-03-21 11:17:12 +00001015 runtime_option = options['runtime_option'];
Alex Lighte9f61032018-09-24 16:04:51 -07001016 with_agent = options['with_agent'];
Alex Light26829182018-06-11 11:36:24 -07001017 run_test_option = sum(map(shlex.split, options['run_test_option']), [])
Alex Light6f342dd2019-03-27 17:15:42 +00001018 zipapex_loc = options['runtime_zipapex']
Alex Light26829182018-06-11 11:36:24 -07001019
Shubham Ajmerafe793492017-03-16 13:31:35 -07001020 timeout = options['timeout']
Shubham Ajmera981d99c2017-08-17 14:11:08 -07001021 if options['dex2oat_jobs']:
1022 dex2oat_jobs = options['dex2oat_jobs']
Shubham Ajmera42ea83b2017-09-25 21:05:57 -07001023 if options['run_all']:
1024 run_all_configs = True
Shubham Ajmera22499e22017-03-22 18:33:37 -07001025
Andreas Gampe09b2d502017-11-29 19:08:16 -08001026 return tests
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001027
1028def main():
1029 gather_test_info()
Andreas Gampe09b2d502017-11-29 19:08:16 -08001030 user_requested_tests = parse_option()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001031 setup_test_env()
1032 if build:
1033 build_targets = ''
Shubham Ajmera85853952017-08-29 16:26:21 -07001034 if 'host' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001035 build_targets += 'test-art-host-run-test-dependencies '
Shubham Ajmera85853952017-08-29 16:26:21 -07001036 if 'target' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001037 build_targets += 'test-art-target-run-test-dependencies '
Igor Murashkinbab15062018-02-23 14:53:24 -08001038 if 'jvm' in _user_input_variants['target']:
Alex Light0d20d582018-06-12 16:16:41 -07001039 build_targets += 'test-art-host-run-test-dependencies '
Alex Lightd51af9e2018-10-11 16:07:55 -07001040 build_command = env.ANDROID_BUILD_TOP + '/build/soong/soong_ui.bash --make-mode'
Colin Cross91f55e62017-10-21 12:45:26 -07001041 build_command += ' DX='
Shubham Ajmera06cde292017-02-10 23:15:05 +00001042 build_command += ' ' + build_targets
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001043 if subprocess.call(build_command.split()):
Colin Cross9cb13a62018-06-07 13:02:02 -07001044 # Debugging for b/62653020
1045 if env.DIST_DIR:
1046 shutil.copyfile(env.SOONG_OUT_DIR + '/build.ninja', env.DIST_DIR + '/soong.ninja')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001047 sys.exit(1)
Orion Hodson163c8ab2019-04-05 11:40:30 +01001048
Andreas Gampe09b2d502017-11-29 19:08:16 -08001049 if user_requested_tests:
Orion Hodson163c8ab2019-04-05 11:40:30 +01001050 run_tests(user_requested_tests)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001051 else:
Orion Hodson163c8ab2019-04-05 11:40:30 +01001052 run_tests(RUN_TEST_SET)
1053
1054 print_analysis()
1055
1056 exit_code = 0 if len(failed_tests) == 0 else 1
1057 sys.exit(exit_code)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001058
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001059if __name__ == '__main__':
1060 main()