blob: 3974ccb4f91fa05ed34305d7e6b6ac4f86f653ed [file] [log] [blame]
Shubham Ajmerafe793492017-03-16 13:31:35 -07001#!/usr/bin/env python3
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00002#
3# Copyright 2017, The Android Open Source Project
4#
5# Licensed under the Apache License, Version 2.0 (the "License");
6# you may not use this file except in compliance with the License.
7# You may obtain a copy of the License at
8#
9# http://www.apache.org/licenses/LICENSE-2.0
10#
11# Unless required by applicable law or agreed to in writing, software
12# distributed under the License is distributed on an "AS IS" BASIS,
13# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14# See the License for the specific language governing permissions and
15# limitations under the License.
16
17"""ART Run-Test TestRunner
18
19The testrunner runs the ART run-tests by simply invoking the script.
20It fetches the list of eligible tests from art/test directory, and list of
21disabled tests from art/test/knownfailures.json. It runs the tests by
22invoking art/test/run-test script and checks the exit value to decide if the
23test passed or failed.
24
25Before invoking the script, first build all the tests dependencies.
26There are two major build targets for building target and host tests
27dependencies:
281) test-art-host-run-test
292) test-art-target-run-test
30
31There are various options to invoke the script which are:
32-t: Either the test name as in art/test or the test name including the variant
33 information. Eg, "-t 001-HelloWorld",
34 "-t test-art-host-run-test-debug-prebuild-optimizing-relocate-ntrace-cms-checkjni-picimage-npictest-ndebuggable-001-HelloWorld32"
35-j: Number of thread workers to be used. Eg - "-j64"
36--dry-run: Instead of running the test name, just print its name.
37--verbose
38-b / --build-dependencies: to build the dependencies before running the test
39
40To specify any specific variants for the test, use --<<variant-name>>.
41For eg, for compiler type as optimizing, use --optimizing.
42
43
44In the end, the script will print the failed and skipped tests if any.
45
46"""
Alex Light7a1ccf82017-02-21 09:52:34 -080047import argparse
Shubham Ajmera85853952017-08-29 16:26:21 -070048import collections
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000049import fnmatch
50import itertools
51import json
Shubham Ajmera4a5a1622017-03-22 10:07:19 -070052import multiprocessing
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000053import os
54import re
55import subprocess
56import sys
Shubham Ajmera29f89682017-03-24 14:44:10 -070057import tempfile
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000058import threading
59import time
60
61import env
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -080062from target_config import target_config
Alex Light3412a002017-10-20 13:44:40 +000063from device_config import device_config
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000064
Shubham Ajmera186d3212017-07-21 01:20:57 +000065# timeout for individual tests.
66# TODO: make it adjustable per tests and for buildbots
67timeout = 3000 # 50 minutes
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000068
69# DISABLED_TEST_CONTAINER holds information about the disabled tests. It is a map
70# that has key as the test name (like 001-HelloWorld), and value as set of
71# variants that the test is disabled for.
72DISABLED_TEST_CONTAINER = {}
73
74# The Dict contains the list of all possible variants for a given type. For example,
75# for key TARGET, the value would be target and host. The list is used to parse
76# the test name given as the argument to run.
77VARIANT_TYPE_DICT = {}
78
79# The set contains all the variants of each time.
80TOTAL_VARIANTS_SET = set()
81
82# The colors are used in the output. When a test passes, COLOR_PASS is used,
83# and so on.
84COLOR_ERROR = '\033[91m'
85COLOR_PASS = '\033[92m'
86COLOR_SKIP = '\033[93m'
87COLOR_NORMAL = '\033[0m'
88
89# The mutex object is used by the threads for exclusive access of test_count
90# to make any changes in its value.
91test_count_mutex = threading.Lock()
Shubham Ajmera14d340c2017-02-15 18:49:10 +000092
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000093# The set contains the list of all the possible run tests that are in art/test
94# directory.
95RUN_TEST_SET = set()
Shubham Ajmera14d340c2017-02-15 18:49:10 +000096
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000097# The semaphore object is used by the testrunner to limit the number of
98# threads to the user requested concurrency value.
99semaphore = threading.Semaphore(1)
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000100
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000101# The mutex object is used to provide exclusive access to a thread to print
102# its output.
103print_mutex = threading.Lock()
104failed_tests = []
105skipped_tests = []
106
107# Flags
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700108n_thread = -1
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000109test_count = 0
110total_test_count = 0
111verbose = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000112dry_run = False
Alex Light42242dd2018-02-16 09:23:57 -0800113ignore_skips = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000114build = False
115gdb = False
116gdb_arg = ''
117stop_testrunner = False
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700118dex2oat_jobs = -1 # -1 corresponds to default threads for dex2oat
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700119run_all_configs = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000120
Alex Light3412a002017-10-20 13:44:40 +0000121# Dict containing extra arguments
122extra_arguments = { "host" : [], "target" : [] }
123
Shubham Ajmera85853952017-08-29 16:26:21 -0700124# Dict to store user requested test variants.
125# key: variant_type.
126# value: set of variants user wants to run of type <key>.
127_user_input_variants = collections.defaultdict(set)
128
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000129def gather_test_info():
130 """The method gathers test information about the test to be run which includes
131 generating the list of total tests from the art/test directory and the list
132 of disabled test. It also maps various variants to types.
133 """
134 global TOTAL_VARIANTS_SET
135 global DISABLED_TEST_CONTAINER
136 # TODO: Avoid duplication of the variant names in different lists.
137 VARIANT_TYPE_DICT['pictest'] = {'pictest', 'npictest'}
138 VARIANT_TYPE_DICT['run'] = {'ndebug', 'debug'}
Igor Murashkinbab15062018-02-23 14:53:24 -0800139 VARIANT_TYPE_DICT['target'] = {'target', 'host', 'jvm'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000140 VARIANT_TYPE_DICT['trace'] = {'trace', 'ntrace', 'stream'}
Richard Uhlerbb00f812017-02-16 14:21:10 +0000141 VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image', 'multipicimage'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000142 VARIANT_TYPE_DICT['debuggable'] = {'ndebuggable', 'debuggable'}
143 VARIANT_TYPE_DICT['gc'] = {'gcstress', 'gcverify', 'cms'}
144 VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'no-dex2oat', 'prebuild'}
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800145 VARIANT_TYPE_DICT['cdex_level'] = {'cdex-none', 'cdex-fast'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000146 VARIANT_TYPE_DICT['relocate'] = {'relocate-npatchoat', 'relocate', 'no-relocate'}
147 VARIANT_TYPE_DICT['jni'] = {'jni', 'forcecopy', 'checkjni'}
148 VARIANT_TYPE_DICT['address_sizes'] = {'64', '32'}
Alex Light43e935d2017-06-19 15:40:40 -0700149 VARIANT_TYPE_DICT['jvmti'] = {'no-jvmti', 'jvmti-stress', 'redefine-stress', 'trace-stress',
Alex Lightc38c3692017-06-27 15:45:14 -0700150 'field-stress', 'step-stress'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000151 VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'optimizing',
Shubham Ajmera85853952017-08-29 16:26:21 -0700152 'regalloc_gc', 'speed-profile'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000153
154 for v_type in VARIANT_TYPE_DICT:
155 TOTAL_VARIANTS_SET = TOTAL_VARIANTS_SET.union(VARIANT_TYPE_DICT.get(v_type))
156
157 test_dir = env.ANDROID_BUILD_TOP + '/art/test'
158 for f in os.listdir(test_dir):
159 if fnmatch.fnmatch(f, '[0-9]*'):
160 RUN_TEST_SET.add(f)
161 DISABLED_TEST_CONTAINER = get_disabled_test_info()
162
163
164def setup_test_env():
165 """The method sets default value for the various variants of the tests if they
166 are already not set.
167 """
168 if env.ART_TEST_BISECTION:
169 env.ART_TEST_RUN_TEST_NO_PREBUILD = True
170 env.ART_TEST_RUN_TEST_PREBUILD = False
171 # Bisection search writes to standard output.
172 env.ART_TEST_QUIET = False
173
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700174 global _user_input_variants
175 global run_all_configs
176 if run_all_configs:
177 target_types = _user_input_variants['target']
178 _user_input_variants = VARIANT_TYPE_DICT
179 _user_input_variants['target'] = target_types
180
Shubham Ajmera85853952017-08-29 16:26:21 -0700181 if not _user_input_variants['target']:
182 _user_input_variants['target'].add('host')
183 _user_input_variants['target'].add('target')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000184
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700185 if not _user_input_variants['prebuild']: # Default
Shubham Ajmera85853952017-08-29 16:26:21 -0700186 _user_input_variants['prebuild'].add('prebuild')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000187
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800188 if not _user_input_variants['cdex_level']: # Default
Mathieu Chartierdc757e52018-01-25 13:25:27 -0800189 _user_input_variants['cdex_level'].add('cdex-fast')
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800190
Alex Light8f2c6d42017-04-10 16:27:35 -0700191 # By default only run without jvmti
Shubham Ajmera85853952017-08-29 16:26:21 -0700192 if not _user_input_variants['jvmti']:
193 _user_input_variants['jvmti'].add('no-jvmti')
Alex Light8f2c6d42017-04-10 16:27:35 -0700194
Nicolas Geoffray70b21bd2017-03-15 10:18:50 +0000195 # By default we run all 'compiler' variants.
Igor Murashkinbab15062018-02-23 14:53:24 -0800196 if not _user_input_variants['compiler'] and _user_input_variants['target'] != 'jvm':
Shubham Ajmera85853952017-08-29 16:26:21 -0700197 _user_input_variants['compiler'].add('optimizing')
198 _user_input_variants['compiler'].add('jit')
199 _user_input_variants['compiler'].add('interpreter')
200 _user_input_variants['compiler'].add('interp-ac')
201 _user_input_variants['compiler'].add('speed-profile')
Nicolas Geoffray70b21bd2017-03-15 10:18:50 +0000202
Shubham Ajmera85853952017-08-29 16:26:21 -0700203 if not _user_input_variants['relocate']: # Default
204 _user_input_variants['relocate'].add('no-relocate')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000205
Shubham Ajmera85853952017-08-29 16:26:21 -0700206 if not _user_input_variants['trace']: # Default
207 _user_input_variants['trace'].add('ntrace')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000208
Shubham Ajmera85853952017-08-29 16:26:21 -0700209 if not _user_input_variants['gc']: # Default
210 _user_input_variants['gc'].add('cms')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000211
Shubham Ajmera85853952017-08-29 16:26:21 -0700212 if not _user_input_variants['jni']: # Default
213 _user_input_variants['jni'].add('checkjni')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000214
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700215 if not _user_input_variants['image']: # Default
Shubham Ajmera85853952017-08-29 16:26:21 -0700216 _user_input_variants['image'].add('picimage')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000217
Shubham Ajmera85853952017-08-29 16:26:21 -0700218 if not _user_input_variants['pictest']: # Default
219 _user_input_variants['pictest'].add('npictest')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000220
Shubham Ajmera85853952017-08-29 16:26:21 -0700221 if not _user_input_variants['debuggable']: # Default
222 _user_input_variants['debuggable'].add('ndebuggable')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000223
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700224 if not _user_input_variants['run']: # Default
225 _user_input_variants['run'].add('debug')
226
Shubham Ajmera85853952017-08-29 16:26:21 -0700227 _user_input_variants['address_sizes_target'] = collections.defaultdict(set)
228 if not _user_input_variants['address_sizes']:
229 _user_input_variants['address_sizes_target']['target'].add(
230 env.ART_PHONY_TEST_TARGET_SUFFIX)
231 _user_input_variants['address_sizes_target']['host'].add(
232 env.ART_PHONY_TEST_HOST_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000233 if env.ART_TEST_RUN_TEST_2ND_ARCH:
Shubham Ajmera85853952017-08-29 16:26:21 -0700234 _user_input_variants['address_sizes_target']['host'].add(
235 env.ART_2ND_PHONY_TEST_HOST_SUFFIX)
236 _user_input_variants['address_sizes_target']['target'].add(
237 env.ART_2ND_PHONY_TEST_TARGET_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000238 else:
Shubham Ajmera85853952017-08-29 16:26:21 -0700239 _user_input_variants['address_sizes_target']['host'] = _user_input_variants['address_sizes']
240 _user_input_variants['address_sizes_target']['target'] = _user_input_variants['address_sizes']
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000241
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700242 global n_thread
243 if n_thread is -1:
Shubham Ajmera85853952017-08-29 16:26:21 -0700244 if 'target' in _user_input_variants['target']:
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700245 n_thread = get_default_threads('target')
246 else:
247 n_thread = get_default_threads('host')
Shubham Ajmera93857f22017-10-09 13:47:35 -0700248 print_text("Concurrency: " + str(n_thread) + "\n")
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700249
Alex Light3412a002017-10-20 13:44:40 +0000250 global extra_arguments
251 for target in _user_input_variants['target']:
252 extra_arguments[target] = find_extra_device_arguments(target)
253
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000254 global semaphore
255 semaphore = threading.Semaphore(n_thread)
256
Shubham Ajmera22499e22017-03-22 18:33:37 -0700257 if not sys.stdout.isatty():
258 global COLOR_ERROR
259 global COLOR_PASS
260 global COLOR_SKIP
261 global COLOR_NORMAL
262 COLOR_ERROR = ''
263 COLOR_PASS = ''
264 COLOR_SKIP = ''
265 COLOR_NORMAL = ''
266
Alex Light3412a002017-10-20 13:44:40 +0000267def find_extra_device_arguments(target):
268 """
269 Gets any extra arguments from the device_config.
270 """
Igor Murashkinbab15062018-02-23 14:53:24 -0800271 device_name = target
272 if target == 'target':
273 device_name = get_device_name()
274 return device_config.get(device_name, { 'run-test-args' : [] })['run-test-args']
Alex Light3412a002017-10-20 13:44:40 +0000275
276def get_device_name():
277 """
278 Gets the value of ro.product.name from remote device.
279 """
280 proc = subprocess.Popen(['adb', 'shell', 'getprop', 'ro.product.name'],
281 stderr=subprocess.STDOUT,
282 stdout = subprocess.PIPE,
283 universal_newlines=True)
284 # only wait 2 seconds.
285 output = proc.communicate(timeout = 2)[0]
286 success = not proc.wait()
287 if success:
288 return output.strip()
289 else:
290 print_text("Unable to determine device type!\n")
291 print_text("Continuing anyway.\n")
292 return "UNKNOWN_TARGET"
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000293
294def run_tests(tests):
295 """Creates thread workers to run the tests.
296
297 The method generates command and thread worker to run the tests. Depending on
298 the user input for the number of threads to be used, the method uses a
299 semaphore object to keep a count in control for the thread workers. When a new
300 worker is created, it acquires the semaphore object, and when the number of
301 workers reaches the maximum allowed concurrency, the method wait for an
302 existing thread worker to release the semaphore object. Worker releases the
303 semaphore object when they finish printing the output.
304
305 Args:
306 tests: The set of tests to be run.
307 """
308 options_all = ''
Igor Murashkinbab15062018-02-23 14:53:24 -0800309
310 # jvm does not run with all these combinations,
311 # or at least it doesn't make sense for most of them.
312 # TODO: support some jvm variants like jvmti ?
313 target_input_variants = _user_input_variants['target']
314 uncombinated_target_input_variants = []
315 if 'jvm' in target_input_variants:
316 _user_input_variants['target'].remove('jvm')
317 uncombinated_target_input_variants.append('jvm')
318
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000319 global total_test_count
320 total_test_count = len(tests)
Igor Murashkinbab15062018-02-23 14:53:24 -0800321 if target_input_variants:
322 for variant_type in VARIANT_TYPE_DICT:
323 if not (variant_type == 'target' or 'address_sizes' in variant_type):
324 total_test_count *= len(_user_input_variants[variant_type])
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000325 target_address_combinations = 0
Igor Murashkinbab15062018-02-23 14:53:24 -0800326 for target in target_input_variants:
Shubham Ajmera85853952017-08-29 16:26:21 -0700327 for address_size in _user_input_variants['address_sizes_target'][target]:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000328 target_address_combinations += 1
Igor Murashkinbab15062018-02-23 14:53:24 -0800329 target_address_combinations += len(uncombinated_target_input_variants)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000330 total_test_count *= target_address_combinations
331
332 if env.ART_TEST_WITH_STRACE:
333 options_all += ' --strace'
334
335 if env.ART_TEST_RUN_TEST_ALWAYS_CLEAN:
336 options_all += ' --always-clean'
337
338 if env.ART_TEST_BISECTION:
339 options_all += ' --bisection-search'
340
341 if env.ART_TEST_ANDROID_ROOT:
342 options_all += ' --android-root ' + env.ART_TEST_ANDROID_ROOT
343
344 if gdb:
345 options_all += ' --gdb'
346 if gdb_arg:
347 options_all += ' --gdb-arg ' + gdb_arg
348
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700349 if dex2oat_jobs != -1:
350 options_all += ' --dex2oat-jobs ' + str(dex2oat_jobs)
351
Igor Murashkinbab15062018-02-23 14:53:24 -0800352 def iter_config(tests, input_variants, user_input_variants):
353 config = itertools.product(tests, input_variants, user_input_variants['run'],
354 user_input_variants['prebuild'], user_input_variants['compiler'],
355 user_input_variants['relocate'], user_input_variants['trace'],
356 user_input_variants['gc'], user_input_variants['jni'],
357 user_input_variants['image'], user_input_variants['pictest'],
358 user_input_variants['debuggable'], user_input_variants['jvmti'],
359 user_input_variants['cdex_level'])
360 return config
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000361
Igor Murashkinbab15062018-02-23 14:53:24 -0800362 # [--host, --target] combines with all the other user input variants.
363 config = iter_config(tests, target_input_variants, _user_input_variants)
364 # [--jvm] currently combines with nothing else. most of the extra flags we'd insert
365 # would be unrecognizable by the 'java' binary, so avoid inserting any extra flags for now.
366 uncombinated_config = iter_config(tests, uncombinated_target_input_variants, { 'run': [''],
367 'prebuild': [''], 'compiler': [''],
368 'relocate': [''], 'trace': [''],
369 'gc': [''], 'jni': [''],
370 'image': [''], 'pictest': [''],
371 'debuggable': [''], 'jvmti': [''],
372 'cdex_level': ['']})
373
374 def start_combination(config_tuple, address_size):
375 test, target, run, prebuild, compiler, relocate, trace, gc, \
376 jni, image, pictest, debuggable, jvmti, cdex_level = config_tuple
377
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000378 if stop_testrunner:
379 # When ART_TEST_KEEP_GOING is set to false, then as soon as a test
380 # fails, stop_testrunner is set to True. When this happens, the method
381 # stops creating any any thread and wait for all the exising threads
382 # to end.
383 while threading.active_count() > 2:
384 time.sleep(0.1)
385 return
Orion Hodson75a58dc2018-02-05 14:37:31 +0000386 # NB The order of components here should match the order of
387 # components in the regex parser in parse_test_name.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000388 test_name = 'test-art-'
389 test_name += target + '-run-test-'
390 test_name += run + '-'
391 test_name += prebuild + '-'
392 test_name += compiler + '-'
393 test_name += relocate + '-'
394 test_name += trace + '-'
395 test_name += gc + '-'
396 test_name += jni + '-'
397 test_name += image + '-'
398 test_name += pictest + '-'
399 test_name += debuggable + '-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700400 test_name += jvmti + '-'
Orion Hodson75a58dc2018-02-05 14:37:31 +0000401 test_name += cdex_level + '-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000402 test_name += test
403 test_name += address_size
404
405 variant_set = {target, run, prebuild, compiler, relocate, trace, gc, jni,
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800406 image, pictest, debuggable, jvmti, cdex_level, address_size}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000407
408 options_test = options_all
409
410 if target == 'host':
411 options_test += ' --host'
Igor Murashkinbab15062018-02-23 14:53:24 -0800412 elif target == 'jvm':
413 options_test += ' --jvm'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000414
415 if run == 'ndebug':
416 options_test += ' -O'
417
418 if prebuild == 'prebuild':
419 options_test += ' --prebuild'
420 elif prebuild == 'no-prebuild':
421 options_test += ' --no-prebuild'
422 elif prebuild == 'no-dex2oat':
423 options_test += ' --no-prebuild --no-dex2oat'
424
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800425 # Add option and remove the cdex- prefix.
426 options_test += ' --compact-dex-level ' + cdex_level.replace('cdex-','')
427
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000428 if compiler == 'optimizing':
429 options_test += ' --optimizing'
430 elif compiler == 'regalloc_gc':
431 options_test += ' --optimizing -Xcompiler-option --register-allocation-strategy=graph-color'
432 elif compiler == 'interpreter':
433 options_test += ' --interpreter'
434 elif compiler == 'interp-ac':
435 options_test += ' --interpreter --verify-soft-fail'
436 elif compiler == 'jit':
437 options_test += ' --jit'
Jeff Hao002b9312017-03-27 16:23:08 -0700438 elif compiler == 'speed-profile':
439 options_test += ' --random-profile'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000440
441 if relocate == 'relocate':
442 options_test += ' --relocate'
443 elif relocate == 'no-relocate':
444 options_test += ' --no-relocate'
445 elif relocate == 'relocate-npatchoat':
446 options_test += ' --relocate --no-patchoat'
447
448 if trace == 'trace':
449 options_test += ' --trace'
450 elif trace == 'stream':
451 options_test += ' --trace --stream'
452
453 if gc == 'gcverify':
454 options_test += ' --gcverify'
455 elif gc == 'gcstress':
456 options_test += ' --gcstress'
457
458 if jni == 'forcecopy':
459 options_test += ' --runtime-option -Xjniopts:forcecopy'
460 elif jni == 'checkjni':
461 options_test += ' --runtime-option -Xcheck:jni'
462
463 if image == 'no-image':
464 options_test += ' --no-image'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000465 elif image == 'multipicimage':
466 options_test += ' --multi-image'
467
468 if pictest == 'pictest':
469 options_test += ' --pic-test'
470
471 if debuggable == 'debuggable':
472 options_test += ' --debuggable'
473
Alex Light8f2c6d42017-04-10 16:27:35 -0700474 if jvmti == 'jvmti-stress':
Alex Light43e935d2017-06-19 15:40:40 -0700475 options_test += ' --jvmti-trace-stress --jvmti-redefine-stress --jvmti-field-stress'
476 elif jvmti == 'field-stress':
477 options_test += ' --jvmti-field-stress'
Alex Lightb7edcda2017-04-27 13:20:31 -0700478 elif jvmti == 'trace-stress':
479 options_test += ' --jvmti-trace-stress'
480 elif jvmti == 'redefine-stress':
481 options_test += ' --jvmti-redefine-stress'
Alex Lightc38c3692017-06-27 15:45:14 -0700482 elif jvmti == 'step-stress':
483 options_test += ' --jvmti-step-stress'
Alex Light8f2c6d42017-04-10 16:27:35 -0700484
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000485 if address_size == '64':
486 options_test += ' --64'
487
488 if env.DEX2OAT_HOST_INSTRUCTION_SET_FEATURES:
489 options_test += ' --instruction-set-features' + env.DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
490
491 elif address_size == '32':
492 if env.HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES:
493 options_test += ' --instruction-set-features ' + \
494 env.HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
495
Igor Murashkin8889a892017-04-24 16:09:15 -0700496 # Use the default run-test behavior unless ANDROID_COMPILE_WITH_JACK is explicitly set.
497 if env.ANDROID_COMPILE_WITH_JACK == True:
498 options_test += ' --build-with-jack'
499 elif env.ANDROID_COMPILE_WITH_JACK == False:
500 options_test += ' --build-with-javac-dx'
501
Nicolas Geoffray18085ac2017-11-08 09:20:01 +0000502 if env.USE_D8_BY_DEFAULT == True:
Alan Leung0afa07a2017-10-03 16:56:30 -0700503 options_test += ' --build-with-d8'
504
Shubham Ajmera29f89682017-03-24 14:44:10 -0700505 # TODO(http://36039166): This is a temporary solution to
506 # fix build breakages.
507 options_test = (' --output-path %s') % (
508 tempfile.mkdtemp(dir=env.ART_HOST_TEST_DIR)) + options_test
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000509
510 run_test_sh = env.ANDROID_BUILD_TOP + '/art/test/run-test'
Alex Light3412a002017-10-20 13:44:40 +0000511 command = ' '.join((run_test_sh, options_test, ' '.join(extra_arguments[target]), test))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000512
513 semaphore.acquire()
514 worker = threading.Thread(target=run_test, args=(command, test, variant_set, test_name))
515 worker.daemon = True
516 worker.start()
517
Igor Murashkinbab15062018-02-23 14:53:24 -0800518 for config_tuple in config:
519 target = config_tuple[1]
520 for address_size in _user_input_variants['address_sizes_target'][target]:
521 start_combination(config_tuple, address_size)
522
523 for config_tuple in uncombinated_config:
524 start_combination(config_tuple, "") # no address size
525
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000526 while threading.active_count() > 2:
527 time.sleep(0.1)
528
529
530def run_test(command, test, test_variant, test_name):
531 """Runs the test.
532
533 It invokes art/test/run-test script to run the test. The output of the script
534 is checked, and if it ends with "Succeeded!", it assumes that the tests
535 passed, otherwise, put it in the list of failed test. Before actually running
536 the test, it also checks if the test is placed in the list of disabled tests,
537 and if yes, it skips running it, and adds the test in the list of skipped
538 tests. The method uses print_text method to actually print the output. After
539 successfully running and capturing the output for the test, it releases the
540 semaphore object.
541
542 Args:
543 command: The command to be used to invoke the script
544 test: The name of the test without the variant information.
545 test_variant: The set of variant for the test.
546 test_name: The name of the test along with the variants.
547 """
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000548 global stop_testrunner
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000549 try:
550 if is_test_disabled(test, test_variant):
551 test_skipped = True
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000552 else:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000553 test_skipped = False
Shubham Ajmerab4949f52017-05-08 13:52:46 -0700554 if gdb:
555 proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, universal_newlines=True)
556 else:
557 proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, stdout = subprocess.PIPE,
558 universal_newlines=True)
Shubham Ajmera186d3212017-07-21 01:20:57 +0000559 script_output = proc.communicate(timeout=timeout)[0]
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000560 test_passed = not proc.wait()
561
562 if not test_skipped:
563 if test_passed:
564 print_test_info(test_name, 'PASS')
565 else:
Alex Light1ebe6142017-10-03 15:00:10 -0700566 failed_tests.append((test_name, str(command) + "\n" + script_output))
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000567 if not env.ART_TEST_KEEP_GOING:
568 stop_testrunner = True
569 print_test_info(test_name, 'FAIL', ('%s\n%s') % (
570 command, script_output))
571 elif not dry_run:
572 print_test_info(test_name, 'SKIP')
573 skipped_tests.append(test_name)
574 else:
575 print_test_info(test_name, '')
Shubham Ajmerafe793492017-03-16 13:31:35 -0700576 except subprocess.TimeoutExpired as e:
Shubham Ajmera186d3212017-07-21 01:20:57 +0000577 failed_tests.append((test_name, 'Timed out in %d seconds' % timeout))
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700578 print_test_info(test_name, 'TIMEOUT', 'Timed out in %d seconds\n%s' % (
Shubham Ajmera186d3212017-07-21 01:20:57 +0000579 timeout, command))
Shubham Ajmerafe793492017-03-16 13:31:35 -0700580 except Exception as e:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700581 failed_tests.append((test_name, str(e)))
582 print_test_info(test_name, 'FAIL',
583 ('%s\n%s\n\n') % (command, str(e)))
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000584 finally:
585 semaphore.release()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000586
587
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000588def print_test_info(test_name, result, failed_test_info=""):
589 """Print the continous test information
590
591 If verbose is set to True, it continuously prints test status information
592 on a new line.
593 If verbose is set to False, it keeps on erasing test
594 information by overriding it with the latest test information. Also,
595 in this case it stictly makes sure that the information length doesn't
596 exceed the console width. It does so by shortening the test_name.
597
598 When a test fails, it prints the output of the run-test script and
599 command used to invoke the script. It doesn't override the failing
600 test information in either of the cases.
601 """
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000602
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000603 global test_count
604 info = ''
605 if not verbose:
606 # Without --verbose, the testrunner erases passing test info. It
607 # does that by overriding the printed text with white spaces all across
608 # the console width.
609 console_width = int(os.popen('stty size', 'r').read().split()[1])
610 info = '\r' + ' ' * console_width + '\r'
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000611 try:
612 print_mutex.acquire()
613 test_count += 1
614 percent = (test_count * 100) / total_test_count
615 progress_info = ('[ %d%% %d/%d ]') % (
616 percent,
617 test_count,
618 total_test_count)
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000619
Shubham Ajmerafe793492017-03-16 13:31:35 -0700620 if result == 'FAIL' or result == 'TIMEOUT':
Alex Light1ebe6142017-10-03 15:00:10 -0700621 if not verbose:
622 info += ('%s %s %s\n') % (
623 progress_info,
624 test_name,
625 COLOR_ERROR + result + COLOR_NORMAL)
626 else:
627 info += ('%s %s %s\n%s\n') % (
628 progress_info,
629 test_name,
630 COLOR_ERROR + result + COLOR_NORMAL,
631 failed_test_info)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000632 else:
633 result_text = ''
634 if result == 'PASS':
635 result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL
636 elif result == 'SKIP':
637 result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL
638
639 if verbose:
640 info += ('%s %s %s\n') % (
641 progress_info,
642 test_name,
643 result_text)
644 else:
645 total_output_length = 2 # Two spaces
646 total_output_length += len(progress_info)
647 total_output_length += len(result)
648 allowed_test_length = console_width - total_output_length
649 test_name_len = len(test_name)
650 if allowed_test_length < test_name_len:
Shubham Ajmerafe793492017-03-16 13:31:35 -0700651 test_name = ('...%s') % (
652 test_name[-(allowed_test_length - 3):])
Alex Lightc14311c2017-02-23 17:02:46 -0800653 info += ('%s %s %s') % (
654 progress_info,
655 test_name,
656 result_text)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000657 print_text(info)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700658 except Exception as e:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000659 print_text(('%s\n%s\n') % (test_name, str(e)))
660 failed_tests.append(test_name)
661 finally:
662 print_mutex.release()
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000663
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700664def verify_knownfailure_entry(entry):
665 supported_field = {
Shubham Ajmerafe793492017-03-16 13:31:35 -0700666 'tests' : (list, str),
Alex Light6fdc1b62017-09-18 11:33:56 -0700667 'test_patterns' : (list,),
Shubham Ajmerafe793492017-03-16 13:31:35 -0700668 'description' : (list, str),
669 'bug' : (str,),
670 'variant' : (str,),
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700671 'env_vars' : (dict,),
672 }
673 for field in entry:
674 field_type = type(entry[field])
675 if field_type not in supported_field[field]:
676 raise ValueError('%s is not supported type for %s\n%s' % (
677 str(field_type),
678 field,
679 str(entry)))
680
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000681def get_disabled_test_info():
682 """Generate set of known failures.
683
684 It parses the art/test/knownfailures.json file to generate the list of
685 disabled tests.
686
687 Returns:
688 The method returns a dict of tests mapped to the variants list
689 for which the test should not be run.
690 """
691 known_failures_file = env.ANDROID_BUILD_TOP + '/art/test/knownfailures.json'
692 with open(known_failures_file) as known_failures_json:
693 known_failures_info = json.loads(known_failures_json.read())
694
695 disabled_test_info = {}
696 for failure in known_failures_info:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700697 verify_knownfailure_entry(failure)
698 tests = failure.get('tests', [])
Shubham Ajmerafe793492017-03-16 13:31:35 -0700699 if isinstance(tests, str):
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000700 tests = [tests]
Alex Light6fdc1b62017-09-18 11:33:56 -0700701 patterns = failure.get("test_patterns", [])
702 if (not isinstance(patterns, list)):
703 raise ValueError("test_patters is not a list in %s" % failure)
704
705 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 +0000706 variants = parse_variants(failure.get('variant'))
707 env_vars = failure.get('env_vars')
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700708
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000709 if check_env_vars(env_vars):
710 for test in tests:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700711 if test not in RUN_TEST_SET:
712 raise ValueError('%s is not a valid run-test' % (
713 test))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000714 if test in disabled_test_info:
715 disabled_test_info[test] = disabled_test_info[test].union(variants)
716 else:
717 disabled_test_info[test] = variants
718 return disabled_test_info
719
720
721def check_env_vars(env_vars):
722 """Checks if the env variables are set as required to run the test.
723
724 Returns:
725 True if all the env variables are set as required, otherwise False.
726 """
727
728 if not env_vars:
729 return True
730 for key in env_vars:
731 if env.get_env(key) != env_vars.get(key):
732 return False
733 return True
734
735
736def is_test_disabled(test, variant_set):
737 """Checks if the test along with the variant_set is disabled.
738
739 Args:
740 test: The name of the test as in art/test directory.
741 variant_set: Variants to be used for the test.
742 Returns:
743 True, if the test is disabled.
744 """
745 if dry_run:
746 return True
Alex Lightbc319b22017-02-17 14:21:33 -0800747 if test in env.EXTRA_DISABLED_TESTS:
748 return True
Alex Light42242dd2018-02-16 09:23:57 -0800749 if ignore_skips:
750 return False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000751 variants_list = DISABLED_TEST_CONTAINER.get(test, {})
752 for variants in variants_list:
753 variants_present = True
754 for variant in variants:
755 if variant not in variant_set:
756 variants_present = False
757 break
758 if variants_present:
759 return True
760 return False
761
762
763def parse_variants(variants):
764 """Parse variants fetched from art/test/knownfailures.json.
765 """
766 if not variants:
767 variants = ''
768 for variant in TOTAL_VARIANTS_SET:
769 variants += variant
770 variants += '|'
771 variants = variants[:-1]
772 variant_list = set()
773 or_variants = variants.split('|')
774 for or_variant in or_variants:
775 and_variants = or_variant.split('&')
776 variant = set()
777 for and_variant in and_variants:
778 and_variant = and_variant.strip()
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700779 if and_variant not in TOTAL_VARIANTS_SET:
780 raise ValueError('%s is not a valid variant' % (
781 and_variant))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000782 variant.add(and_variant)
783 variant_list.add(frozenset(variant))
784 return variant_list
785
786def print_text(output):
787 sys.stdout.write(output)
788 sys.stdout.flush()
789
790def print_analysis():
791 if not verbose:
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000792 # Without --verbose, the testrunner erases passing test info. It
793 # does that by overriding the printed text with white spaces all across
794 # the console width.
795 console_width = int(os.popen('stty size', 'r').read().split()[1])
796 eraser_text = '\r' + ' ' * console_width + '\r'
797 print_text(eraser_text)
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700798
799 # Prints information about the total tests run.
800 # E.g., "2/38 (5%) tests passed".
801 passed_test_count = total_test_count - len(skipped_tests) - len(failed_tests)
802 passed_test_information = ('%d/%d (%d%%) %s passed.\n') % (
803 passed_test_count,
804 total_test_count,
805 (passed_test_count*100)/total_test_count,
806 'tests' if passed_test_count > 1 else 'test')
807 print_text(passed_test_information)
808
809 # Prints the list of skipped tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000810 if skipped_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700811 print_text(COLOR_SKIP + 'SKIPPED TESTS: ' + COLOR_NORMAL + '\n')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000812 for test in skipped_tests:
813 print_text(test + '\n')
814 print_text('\n')
815
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700816 # Prints the list of failed tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000817 if failed_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700818 print_text(COLOR_ERROR + 'FAILED: ' + COLOR_NORMAL + '\n')
819 for test_info in failed_tests:
820 print_text(('%s\n%s\n' % (test_info[0], test_info[1])))
Andreas Gampe0dd7e852017-05-24 21:44:23 -0700821 print_text(COLOR_ERROR + '----------' + COLOR_NORMAL + '\n')
822 for failed_test in sorted([test_info[0] for test_info in failed_tests]):
823 print_text(('%s\n' % (failed_test)))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000824
825
826def parse_test_name(test_name):
827 """Parses the testname provided by the user.
828 It supports two types of test_name:
829 1) Like 001-HelloWorld. In this case, it will just verify if the test actually
830 exists and if it does, it returns the testname.
831 2) Like test-art-host-run-test-debug-prebuild-interpreter-no-relocate-ntrace-cms-checkjni-picimage-npictest-ndebuggable-001-HelloWorld32
832 In this case, it will parse all the variants and check if they are placed
833 correctly. If yes, it will set the various VARIANT_TYPES to use the
834 variants required to run the test. Again, it returns the test_name
835 without the variant information like 001-HelloWorld.
836 """
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000837 test_set = set()
838 for test in RUN_TEST_SET:
839 if test.startswith(test_name):
840 test_set.add(test)
841 if test_set:
842 return test_set
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000843
844 regex = '^test-art-'
845 regex += '(' + '|'.join(VARIANT_TYPE_DICT['target']) + ')-'
846 regex += 'run-test-'
847 regex += '(' + '|'.join(VARIANT_TYPE_DICT['run']) + ')-'
848 regex += '(' + '|'.join(VARIANT_TYPE_DICT['prebuild']) + ')-'
849 regex += '(' + '|'.join(VARIANT_TYPE_DICT['compiler']) + ')-'
850 regex += '(' + '|'.join(VARIANT_TYPE_DICT['relocate']) + ')-'
851 regex += '(' + '|'.join(VARIANT_TYPE_DICT['trace']) + ')-'
852 regex += '(' + '|'.join(VARIANT_TYPE_DICT['gc']) + ')-'
853 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jni']) + ')-'
854 regex += '(' + '|'.join(VARIANT_TYPE_DICT['image']) + ')-'
855 regex += '(' + '|'.join(VARIANT_TYPE_DICT['pictest']) + ')-'
856 regex += '(' + '|'.join(VARIANT_TYPE_DICT['debuggable']) + ')-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700857 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jvmti']) + ')-'
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800858 regex += '(' + '|'.join(VARIANT_TYPE_DICT['cdex_level']) + ')-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000859 regex += '(' + '|'.join(RUN_TEST_SET) + ')'
860 regex += '(' + '|'.join(VARIANT_TYPE_DICT['address_sizes']) + ')$'
861 match = re.match(regex, test_name)
862 if match:
Shubham Ajmera85853952017-08-29 16:26:21 -0700863 _user_input_variants['target'].add(match.group(1))
864 _user_input_variants['run'].add(match.group(2))
865 _user_input_variants['prebuild'].add(match.group(3))
866 _user_input_variants['compiler'].add(match.group(4))
867 _user_input_variants['relocate'].add(match.group(5))
868 _user_input_variants['trace'].add(match.group(6))
869 _user_input_variants['gc'].add(match.group(7))
870 _user_input_variants['jni'].add(match.group(8))
871 _user_input_variants['image'].add(match.group(9))
872 _user_input_variants['pictest'].add(match.group(10))
873 _user_input_variants['debuggable'].add(match.group(11))
874 _user_input_variants['jvmti'].add(match.group(12))
Mathieu Chartierdcd56c92017-11-20 20:30:24 -0800875 _user_input_variants['cdex_level'].add(match.group(13))
876 _user_input_variants['address_sizes'].add(match.group(15))
877 return {match.group(14)}
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000878 raise ValueError(test_name + " is not a valid test")
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000879
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800880
881def setup_env_for_build_target(build_target, parser, options):
882 """Setup environment for the build target
883
884 The method setup environment for the master-art-host targets.
885 """
886 os.environ.update(build_target['env'])
887 os.environ['SOONG_ALLOW_MISSING_DEPENDENCIES'] = 'true'
888 print_text('%s\n' % (str(os.environ)))
889
890 target_options = vars(parser.parse_args(build_target['flags']))
891 target_options['host'] = True
892 target_options['verbose'] = True
893 target_options['build'] = True
894 target_options['n_thread'] = options['n_thread']
895 target_options['dry_run'] = options['dry_run']
896
897 return target_options
898
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700899def get_default_threads(target):
900 if target is 'target':
901 adb_command = 'adb shell cat /sys/devices/system/cpu/present'
902 cpu_info_proc = subprocess.Popen(adb_command.split(), stdout=subprocess.PIPE)
903 cpu_info = cpu_info_proc.stdout.read()
Shubham Ajmera8fd26942017-05-09 11:30:47 -0700904 if type(cpu_info) is bytes:
905 cpu_info = cpu_info.decode('utf-8')
906 cpu_info_regex = '\d*-(\d*)'
907 match = re.match(cpu_info_regex, cpu_info)
908 if match:
909 return int(match.group(1))
910 else:
911 raise ValueError('Unable to predict the concurrency for the target. '
912 'Is device connected?')
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700913 else:
914 return multiprocessing.cpu_count()
915
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000916def parse_option():
917 global verbose
918 global dry_run
Alex Light42242dd2018-02-16 09:23:57 -0800919 global ignore_skips
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000920 global n_thread
921 global build
922 global gdb
923 global gdb_arg
Shubham Ajmerafe793492017-03-16 13:31:35 -0700924 global timeout
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700925 global dex2oat_jobs
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700926 global run_all_configs
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000927
Alex Light7a1ccf82017-02-21 09:52:34 -0800928 parser = argparse.ArgumentParser(description="Runs all or a subset of the ART test suite.")
Andreas Gampe09b2d502017-11-29 19:08:16 -0800929 parser.add_argument('-t', '--test', action='append', dest='tests', help='name(s) of the test(s)')
Alex Light7a1ccf82017-02-21 09:52:34 -0800930 parser.add_argument('-j', type=int, dest='n_thread')
Shubham Ajmera186d3212017-07-21 01:20:57 +0000931 parser.add_argument('--timeout', default=timeout, type=int, dest='timeout')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000932 for variant in TOTAL_VARIANTS_SET:
933 flag = '--' + variant
Shubham Ajmera85853952017-08-29 16:26:21 -0700934 parser.add_argument(flag, action='store_true', dest=variant)
Alex Light7a1ccf82017-02-21 09:52:34 -0800935 parser.add_argument('--verbose', '-v', action='store_true', dest='verbose')
936 parser.add_argument('--dry-run', action='store_true', dest='dry_run')
937 parser.add_argument("--skip", action="append", dest="skips", default=[],
938 help="Skip the given test in all circumstances.")
Alex Light42242dd2018-02-16 09:23:57 -0800939 parser.add_argument("--no-skips", dest="ignore_skips", action="store_true", default=False,
940 help="Don't skip any run-test configurations listed in knownfailures.json.")
Alex Light9b6b13e2017-02-22 11:46:50 -0800941 parser.add_argument('--no-build-dependencies',
942 action='store_false', dest='build',
943 help="Don't build dependencies under any circumstances. This is the " +
944 "behavior if ART_TEST_RUN_TEST_ALWAYS_BUILD is not set to 'true'.")
945 parser.add_argument('-b', '--build-dependencies',
946 action='store_true', dest='build',
947 help="Build dependencies under all circumstances. By default we will " +
948 "not build dependencies unless ART_TEST_RUN_TEST_BUILD=true.")
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800949 parser.add_argument('--build-target', dest='build_target', help='master-art-host targets')
Alex Light9b6b13e2017-02-22 11:46:50 -0800950 parser.set_defaults(build = env.ART_TEST_RUN_TEST_BUILD)
Alex Light7a1ccf82017-02-21 09:52:34 -0800951 parser.add_argument('--gdb', action='store_true', dest='gdb')
952 parser.add_argument('--gdb-arg', dest='gdb_arg')
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700953 parser.add_argument('--dex2oat-jobs', type=int, dest='dex2oat_jobs',
954 help='Number of dex2oat jobs')
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700955 parser.add_argument('-a', '--all', action='store_true', dest='run_all',
956 help="Run all the possible configurations for the input test set")
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000957
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800958 options = vars(parser.parse_args())
959 if options['build_target']:
960 options = setup_env_for_build_target(target_config[options['build_target']],
961 parser, options)
962
Andreas Gampe09b2d502017-11-29 19:08:16 -0800963 tests = None
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800964 env.EXTRA_DISABLED_TESTS.update(set(options['skips']))
Andreas Gampe09b2d502017-11-29 19:08:16 -0800965 if options['tests']:
966 tests = set()
967 for test_name in options['tests']:
968 tests |= parse_test_name(test_name)
Shubham Ajmera85853952017-08-29 16:26:21 -0700969
970 for variant_type in VARIANT_TYPE_DICT:
971 for variant in VARIANT_TYPE_DICT[variant_type]:
972 if options.get(variant):
973 _user_input_variants[variant_type].add(variant)
974
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800975 if options['verbose']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000976 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800977 if options['n_thread']:
978 n_thread = max(1, options['n_thread'])
Alex Light42242dd2018-02-16 09:23:57 -0800979 ignore_skips = options['ignore_skips']
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800980 if options['dry_run']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000981 dry_run = True
982 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800983 build = options['build']
984 if options['gdb']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000985 n_thread = 1
986 gdb = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800987 if options['gdb_arg']:
988 gdb_arg = options['gdb_arg']
Shubham Ajmerafe793492017-03-16 13:31:35 -0700989 timeout = options['timeout']
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700990 if options['dex2oat_jobs']:
991 dex2oat_jobs = options['dex2oat_jobs']
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700992 if options['run_all']:
993 run_all_configs = True
Shubham Ajmera22499e22017-03-22 18:33:37 -0700994
Andreas Gampe09b2d502017-11-29 19:08:16 -0800995 return tests
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000996
997def main():
998 gather_test_info()
Andreas Gampe09b2d502017-11-29 19:08:16 -0800999 user_requested_tests = parse_option()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001000 setup_test_env()
1001 if build:
1002 build_targets = ''
Shubham Ajmera85853952017-08-29 16:26:21 -07001003 if 'host' in _user_input_variants['target']:
Shubham Ajmera186d3212017-07-21 01:20:57 +00001004 build_targets += 'test-art-host-run-test-dependencies'
Shubham Ajmera85853952017-08-29 16:26:21 -07001005 if 'target' in _user_input_variants['target']:
Shubham Ajmera186d3212017-07-21 01:20:57 +00001006 build_targets += 'test-art-target-run-test-dependencies'
Igor Murashkinbab15062018-02-23 14:53:24 -08001007 if 'jvm' in _user_input_variants['target']:
1008 build_targets += 'test-art-host-run-test-dependencies'
Shubham Ajmera06cde292017-02-10 23:15:05 +00001009 build_command = 'make'
Colin Cross91f55e62017-10-21 12:45:26 -07001010 build_command += ' DX='
Shubham Ajmera4a5a1622017-03-22 10:07:19 -07001011 build_command += ' -j'
Shubham Ajmera06cde292017-02-10 23:15:05 +00001012 build_command += ' -C ' + env.ANDROID_BUILD_TOP
1013 build_command += ' ' + build_targets
Nicolas Geoffray300c09b2017-03-22 12:26:32 +00001014 # Add 'dist' to avoid Jack issues b/36169180.
1015 build_command += ' dist'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001016 if subprocess.call(build_command.split()):
1017 sys.exit(1)
Andreas Gampe09b2d502017-11-29 19:08:16 -08001018 if user_requested_tests:
1019 test_runner_thread = threading.Thread(target=run_tests, args=(user_requested_tests,))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001020 else:
1021 test_runner_thread = threading.Thread(target=run_tests, args=(RUN_TEST_SET,))
1022 test_runner_thread.daemon = True
1023 try:
1024 test_runner_thread.start()
Shubham Ajmera535a15c2017-11-02 11:31:14 -07001025 # This loops waits for all the threads to finish, unless
1026 # stop_testrunner is set to True. When ART_TEST_KEEP_GOING
1027 # is set to false, stop_testrunner is set to True as soon as
1028 # a test fails to signal the parent thread to stop
1029 # the execution of the testrunner.
1030 while threading.active_count() > 1 and not stop_testrunner:
Shubham Ajmera186d3212017-07-21 01:20:57 +00001031 time.sleep(0.1)
1032 print_analysis()
Shubham Ajmerafe793492017-03-16 13:31:35 -07001033 except Exception as e:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001034 print_analysis()
Shubham Ajmerafaf12502017-02-15 17:19:44 +00001035 print_text(str(e))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001036 sys.exit(1)
Shubham Ajmerac5aae872017-02-16 19:58:59 +00001037 if failed_tests:
1038 sys.exit(1)
1039 sys.exit(0)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001040
Shubham Ajmera65adb8b2017-02-06 16:04:25 +00001041if __name__ == '__main__':
1042 main()