blob: 8d92deb625cf465eec1dbffc6c2411ea361cd25d [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
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000063
Shubham Ajmera186d3212017-07-21 01:20:57 +000064# timeout for individual tests.
65# TODO: make it adjustable per tests and for buildbots
66timeout = 3000 # 50 minutes
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000067
68# DISABLED_TEST_CONTAINER holds information about the disabled tests. It is a map
69# that has key as the test name (like 001-HelloWorld), and value as set of
70# variants that the test is disabled for.
71DISABLED_TEST_CONTAINER = {}
72
73# The Dict contains the list of all possible variants for a given type. For example,
74# for key TARGET, the value would be target and host. The list is used to parse
75# the test name given as the argument to run.
76VARIANT_TYPE_DICT = {}
77
78# The set contains all the variants of each time.
79TOTAL_VARIANTS_SET = set()
80
81# The colors are used in the output. When a test passes, COLOR_PASS is used,
82# and so on.
83COLOR_ERROR = '\033[91m'
84COLOR_PASS = '\033[92m'
85COLOR_SKIP = '\033[93m'
86COLOR_NORMAL = '\033[0m'
87
88# The mutex object is used by the threads for exclusive access of test_count
89# to make any changes in its value.
90test_count_mutex = threading.Lock()
Shubham Ajmera14d340c2017-02-15 18:49:10 +000091
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000092# The set contains the list of all the possible run tests that are in art/test
93# directory.
94RUN_TEST_SET = set()
Shubham Ajmera14d340c2017-02-15 18:49:10 +000095
Shubham Ajmera65adb8b2017-02-06 16:04:25 +000096# The semaphore object is used by the testrunner to limit the number of
97# threads to the user requested concurrency value.
98semaphore = threading.Semaphore(1)
Shubham Ajmera14d340c2017-02-15 18:49:10 +000099
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000100# The mutex object is used to provide exclusive access to a thread to print
101# its output.
102print_mutex = threading.Lock()
103failed_tests = []
104skipped_tests = []
105
106# Flags
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700107n_thread = -1
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000108test_count = 0
109total_test_count = 0
110verbose = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000111dry_run = False
112build = False
113gdb = False
114gdb_arg = ''
115stop_testrunner = False
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700116dex2oat_jobs = -1 # -1 corresponds to default threads for dex2oat
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700117run_all_configs = False
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000118
Shubham Ajmera85853952017-08-29 16:26:21 -0700119# Dict to store user requested test variants.
120# key: variant_type.
121# value: set of variants user wants to run of type <key>.
122_user_input_variants = collections.defaultdict(set)
123
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000124def gather_test_info():
125 """The method gathers test information about the test to be run which includes
126 generating the list of total tests from the art/test directory and the list
127 of disabled test. It also maps various variants to types.
128 """
129 global TOTAL_VARIANTS_SET
130 global DISABLED_TEST_CONTAINER
131 # TODO: Avoid duplication of the variant names in different lists.
132 VARIANT_TYPE_DICT['pictest'] = {'pictest', 'npictest'}
133 VARIANT_TYPE_DICT['run'] = {'ndebug', 'debug'}
134 VARIANT_TYPE_DICT['target'] = {'target', 'host'}
135 VARIANT_TYPE_DICT['trace'] = {'trace', 'ntrace', 'stream'}
Richard Uhlerbb00f812017-02-16 14:21:10 +0000136 VARIANT_TYPE_DICT['image'] = {'picimage', 'no-image', 'multipicimage'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000137 VARIANT_TYPE_DICT['debuggable'] = {'ndebuggable', 'debuggable'}
138 VARIANT_TYPE_DICT['gc'] = {'gcstress', 'gcverify', 'cms'}
139 VARIANT_TYPE_DICT['prebuild'] = {'no-prebuild', 'no-dex2oat', 'prebuild'}
140 VARIANT_TYPE_DICT['relocate'] = {'relocate-npatchoat', 'relocate', 'no-relocate'}
141 VARIANT_TYPE_DICT['jni'] = {'jni', 'forcecopy', 'checkjni'}
142 VARIANT_TYPE_DICT['address_sizes'] = {'64', '32'}
Alex Light43e935d2017-06-19 15:40:40 -0700143 VARIANT_TYPE_DICT['jvmti'] = {'no-jvmti', 'jvmti-stress', 'redefine-stress', 'trace-stress',
Alex Lightc38c3692017-06-27 15:45:14 -0700144 'field-stress', 'step-stress'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000145 VARIANT_TYPE_DICT['compiler'] = {'interp-ac', 'interpreter', 'jit', 'optimizing',
Shubham Ajmera85853952017-08-29 16:26:21 -0700146 'regalloc_gc', 'speed-profile'}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000147
148 for v_type in VARIANT_TYPE_DICT:
149 TOTAL_VARIANTS_SET = TOTAL_VARIANTS_SET.union(VARIANT_TYPE_DICT.get(v_type))
150
151 test_dir = env.ANDROID_BUILD_TOP + '/art/test'
152 for f in os.listdir(test_dir):
153 if fnmatch.fnmatch(f, '[0-9]*'):
154 RUN_TEST_SET.add(f)
155 DISABLED_TEST_CONTAINER = get_disabled_test_info()
156
157
158def setup_test_env():
159 """The method sets default value for the various variants of the tests if they
160 are already not set.
161 """
162 if env.ART_TEST_BISECTION:
163 env.ART_TEST_RUN_TEST_NO_PREBUILD = True
164 env.ART_TEST_RUN_TEST_PREBUILD = False
165 # Bisection search writes to standard output.
166 env.ART_TEST_QUIET = False
167
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700168 global _user_input_variants
169 global run_all_configs
170 if run_all_configs:
171 target_types = _user_input_variants['target']
172 _user_input_variants = VARIANT_TYPE_DICT
173 _user_input_variants['target'] = target_types
174
Shubham Ajmera85853952017-08-29 16:26:21 -0700175 if not _user_input_variants['target']:
176 _user_input_variants['target'].add('host')
177 _user_input_variants['target'].add('target')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000178
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700179 if not _user_input_variants['prebuild']: # Default
Shubham Ajmera85853952017-08-29 16:26:21 -0700180 _user_input_variants['prebuild'].add('prebuild')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000181
Alex Light8f2c6d42017-04-10 16:27:35 -0700182 # By default only run without jvmti
Shubham Ajmera85853952017-08-29 16:26:21 -0700183 if not _user_input_variants['jvmti']:
184 _user_input_variants['jvmti'].add('no-jvmti')
Alex Light8f2c6d42017-04-10 16:27:35 -0700185
Nicolas Geoffray70b21bd2017-03-15 10:18:50 +0000186 # By default we run all 'compiler' variants.
Shubham Ajmera85853952017-08-29 16:26:21 -0700187 if not _user_input_variants['compiler']:
188 _user_input_variants['compiler'].add('optimizing')
189 _user_input_variants['compiler'].add('jit')
190 _user_input_variants['compiler'].add('interpreter')
191 _user_input_variants['compiler'].add('interp-ac')
192 _user_input_variants['compiler'].add('speed-profile')
Nicolas Geoffray70b21bd2017-03-15 10:18:50 +0000193
Shubham Ajmera85853952017-08-29 16:26:21 -0700194 if not _user_input_variants['relocate']: # Default
195 _user_input_variants['relocate'].add('no-relocate')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000196
Shubham Ajmera85853952017-08-29 16:26:21 -0700197 if not _user_input_variants['trace']: # Default
198 _user_input_variants['trace'].add('ntrace')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000199
Shubham Ajmera85853952017-08-29 16:26:21 -0700200 if not _user_input_variants['gc']: # Default
201 _user_input_variants['gc'].add('cms')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000202
Shubham Ajmera85853952017-08-29 16:26:21 -0700203 if not _user_input_variants['jni']: # Default
204 _user_input_variants['jni'].add('checkjni')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000205
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700206 if not _user_input_variants['image']: # Default
Shubham Ajmera85853952017-08-29 16:26:21 -0700207 _user_input_variants['image'].add('picimage')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000208
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700209
Shubham Ajmera85853952017-08-29 16:26:21 -0700210 if not _user_input_variants['pictest']: # Default
211 _user_input_variants['pictest'].add('npictest')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000212
Shubham Ajmera85853952017-08-29 16:26:21 -0700213 if not _user_input_variants['debuggable']: # Default
214 _user_input_variants['debuggable'].add('ndebuggable')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000215
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700216 if not _user_input_variants['run']: # Default
217 _user_input_variants['run'].add('debug')
218
Shubham Ajmera85853952017-08-29 16:26:21 -0700219 _user_input_variants['address_sizes_target'] = collections.defaultdict(set)
220 if not _user_input_variants['address_sizes']:
221 _user_input_variants['address_sizes_target']['target'].add(
222 env.ART_PHONY_TEST_TARGET_SUFFIX)
223 _user_input_variants['address_sizes_target']['host'].add(
224 env.ART_PHONY_TEST_HOST_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000225 if env.ART_TEST_RUN_TEST_2ND_ARCH:
Shubham Ajmera85853952017-08-29 16:26:21 -0700226 _user_input_variants['address_sizes_target']['host'].add(
227 env.ART_2ND_PHONY_TEST_HOST_SUFFIX)
228 _user_input_variants['address_sizes_target']['target'].add(
229 env.ART_2ND_PHONY_TEST_TARGET_SUFFIX)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000230 else:
Shubham Ajmera85853952017-08-29 16:26:21 -0700231 _user_input_variants['address_sizes_target']['host'] = _user_input_variants['address_sizes']
232 _user_input_variants['address_sizes_target']['target'] = _user_input_variants['address_sizes']
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000233
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700234 global n_thread
235 if n_thread is -1:
Shubham Ajmera85853952017-08-29 16:26:21 -0700236 if 'target' in _user_input_variants['target']:
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700237 n_thread = get_default_threads('target')
238 else:
239 n_thread = get_default_threads('host')
240
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000241 global semaphore
242 semaphore = threading.Semaphore(n_thread)
243
Shubham Ajmera22499e22017-03-22 18:33:37 -0700244 if not sys.stdout.isatty():
245 global COLOR_ERROR
246 global COLOR_PASS
247 global COLOR_SKIP
248 global COLOR_NORMAL
249 COLOR_ERROR = ''
250 COLOR_PASS = ''
251 COLOR_SKIP = ''
252 COLOR_NORMAL = ''
253
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000254
255def run_tests(tests):
256 """Creates thread workers to run the tests.
257
258 The method generates command and thread worker to run the tests. Depending on
259 the user input for the number of threads to be used, the method uses a
260 semaphore object to keep a count in control for the thread workers. When a new
261 worker is created, it acquires the semaphore object, and when the number of
262 workers reaches the maximum allowed concurrency, the method wait for an
263 existing thread worker to release the semaphore object. Worker releases the
264 semaphore object when they finish printing the output.
265
266 Args:
267 tests: The set of tests to be run.
268 """
269 options_all = ''
270 global total_test_count
271 total_test_count = len(tests)
Shubham Ajmerad0358f82017-09-25 20:57:32 -0700272 for variant_type in VARIANT_TYPE_DICT:
Shubham Ajmera85853952017-08-29 16:26:21 -0700273 if not (variant_type == 'target' or 'address_sizes' in variant_type):
274 total_test_count *= len(_user_input_variants[variant_type])
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000275 target_address_combinations = 0
Shubham Ajmera85853952017-08-29 16:26:21 -0700276 for target in _user_input_variants['target']:
277 for address_size in _user_input_variants['address_sizes_target'][target]:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000278 target_address_combinations += 1
279 total_test_count *= target_address_combinations
280
281 if env.ART_TEST_WITH_STRACE:
282 options_all += ' --strace'
283
284 if env.ART_TEST_RUN_TEST_ALWAYS_CLEAN:
285 options_all += ' --always-clean'
286
287 if env.ART_TEST_BISECTION:
288 options_all += ' --bisection-search'
289
290 if env.ART_TEST_ANDROID_ROOT:
291 options_all += ' --android-root ' + env.ART_TEST_ANDROID_ROOT
292
293 if gdb:
294 options_all += ' --gdb'
295 if gdb_arg:
296 options_all += ' --gdb-arg ' + gdb_arg
297
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700298 if dex2oat_jobs != -1:
299 options_all += ' --dex2oat-jobs ' + str(dex2oat_jobs)
300
Shubham Ajmera85853952017-08-29 16:26:21 -0700301 config = itertools.product(tests, _user_input_variants['target'], _user_input_variants['run'],
302 _user_input_variants['prebuild'], _user_input_variants['compiler'],
303 _user_input_variants['relocate'], _user_input_variants['trace'],
304 _user_input_variants['gc'], _user_input_variants['jni'],
305 _user_input_variants['image'], _user_input_variants['pictest'],
306 _user_input_variants['debuggable'], _user_input_variants['jvmti'])
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000307
308 for test, target, run, prebuild, compiler, relocate, trace, gc, \
Alex Light8f2c6d42017-04-10 16:27:35 -0700309 jni, image, pictest, debuggable, jvmti in config:
Shubham Ajmera85853952017-08-29 16:26:21 -0700310 for address_size in _user_input_variants['address_sizes_target'][target]:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000311 if stop_testrunner:
312 # When ART_TEST_KEEP_GOING is set to false, then as soon as a test
313 # fails, stop_testrunner is set to True. When this happens, the method
314 # stops creating any any thread and wait for all the exising threads
315 # to end.
316 while threading.active_count() > 2:
317 time.sleep(0.1)
318 return
319 test_name = 'test-art-'
320 test_name += target + '-run-test-'
321 test_name += run + '-'
322 test_name += prebuild + '-'
323 test_name += compiler + '-'
324 test_name += relocate + '-'
325 test_name += trace + '-'
326 test_name += gc + '-'
327 test_name += jni + '-'
328 test_name += image + '-'
329 test_name += pictest + '-'
330 test_name += debuggable + '-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700331 test_name += jvmti + '-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000332 test_name += test
333 test_name += address_size
334
335 variant_set = {target, run, prebuild, compiler, relocate, trace, gc, jni,
Alex Light8f2c6d42017-04-10 16:27:35 -0700336 image, pictest, debuggable, jvmti, address_size}
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000337
338 options_test = options_all
339
340 if target == 'host':
341 options_test += ' --host'
342
343 if run == 'ndebug':
344 options_test += ' -O'
345
346 if prebuild == 'prebuild':
347 options_test += ' --prebuild'
348 elif prebuild == 'no-prebuild':
349 options_test += ' --no-prebuild'
350 elif prebuild == 'no-dex2oat':
351 options_test += ' --no-prebuild --no-dex2oat'
352
353 if compiler == 'optimizing':
354 options_test += ' --optimizing'
355 elif compiler == 'regalloc_gc':
356 options_test += ' --optimizing -Xcompiler-option --register-allocation-strategy=graph-color'
357 elif compiler == 'interpreter':
358 options_test += ' --interpreter'
359 elif compiler == 'interp-ac':
360 options_test += ' --interpreter --verify-soft-fail'
361 elif compiler == 'jit':
362 options_test += ' --jit'
Jeff Hao002b9312017-03-27 16:23:08 -0700363 elif compiler == 'speed-profile':
364 options_test += ' --random-profile'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000365
366 if relocate == 'relocate':
367 options_test += ' --relocate'
368 elif relocate == 'no-relocate':
369 options_test += ' --no-relocate'
370 elif relocate == 'relocate-npatchoat':
371 options_test += ' --relocate --no-patchoat'
372
373 if trace == 'trace':
374 options_test += ' --trace'
375 elif trace == 'stream':
376 options_test += ' --trace --stream'
377
378 if gc == 'gcverify':
379 options_test += ' --gcverify'
380 elif gc == 'gcstress':
381 options_test += ' --gcstress'
382
383 if jni == 'forcecopy':
384 options_test += ' --runtime-option -Xjniopts:forcecopy'
385 elif jni == 'checkjni':
386 options_test += ' --runtime-option -Xcheck:jni'
387
388 if image == 'no-image':
389 options_test += ' --no-image'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000390 elif image == 'multipicimage':
391 options_test += ' --multi-image'
392
393 if pictest == 'pictest':
394 options_test += ' --pic-test'
395
396 if debuggable == 'debuggable':
397 options_test += ' --debuggable'
398
Alex Light8f2c6d42017-04-10 16:27:35 -0700399 if jvmti == 'jvmti-stress':
Alex Light43e935d2017-06-19 15:40:40 -0700400 options_test += ' --jvmti-trace-stress --jvmti-redefine-stress --jvmti-field-stress'
401 elif jvmti == 'field-stress':
402 options_test += ' --jvmti-field-stress'
Alex Lightb7edcda2017-04-27 13:20:31 -0700403 elif jvmti == 'trace-stress':
404 options_test += ' --jvmti-trace-stress'
405 elif jvmti == 'redefine-stress':
406 options_test += ' --jvmti-redefine-stress'
Alex Lightc38c3692017-06-27 15:45:14 -0700407 elif jvmti == 'step-stress':
408 options_test += ' --jvmti-step-stress'
Alex Light8f2c6d42017-04-10 16:27:35 -0700409
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000410 if address_size == '64':
411 options_test += ' --64'
412
413 if env.DEX2OAT_HOST_INSTRUCTION_SET_FEATURES:
414 options_test += ' --instruction-set-features' + env.DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
415
416 elif address_size == '32':
417 if env.HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES:
418 options_test += ' --instruction-set-features ' + \
419 env.HOST_2ND_ARCH_PREFIX_DEX2OAT_HOST_INSTRUCTION_SET_FEATURES
420
Igor Murashkin8889a892017-04-24 16:09:15 -0700421 # Use the default run-test behavior unless ANDROID_COMPILE_WITH_JACK is explicitly set.
422 if env.ANDROID_COMPILE_WITH_JACK == True:
423 options_test += ' --build-with-jack'
424 elif env.ANDROID_COMPILE_WITH_JACK == False:
425 options_test += ' --build-with-javac-dx'
426
Shubham Ajmera29f89682017-03-24 14:44:10 -0700427 # TODO(http://36039166): This is a temporary solution to
428 # fix build breakages.
429 options_test = (' --output-path %s') % (
430 tempfile.mkdtemp(dir=env.ART_HOST_TEST_DIR)) + options_test
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000431
432 run_test_sh = env.ANDROID_BUILD_TOP + '/art/test/run-test'
433 command = run_test_sh + ' ' + options_test + ' ' + test
434
435 semaphore.acquire()
436 worker = threading.Thread(target=run_test, args=(command, test, variant_set, test_name))
437 worker.daemon = True
438 worker.start()
439
440 while threading.active_count() > 2:
441 time.sleep(0.1)
442
443
444def run_test(command, test, test_variant, test_name):
445 """Runs the test.
446
447 It invokes art/test/run-test script to run the test. The output of the script
448 is checked, and if it ends with "Succeeded!", it assumes that the tests
449 passed, otherwise, put it in the list of failed test. Before actually running
450 the test, it also checks if the test is placed in the list of disabled tests,
451 and if yes, it skips running it, and adds the test in the list of skipped
452 tests. The method uses print_text method to actually print the output. After
453 successfully running and capturing the output for the test, it releases the
454 semaphore object.
455
456 Args:
457 command: The command to be used to invoke the script
458 test: The name of the test without the variant information.
459 test_variant: The set of variant for the test.
460 test_name: The name of the test along with the variants.
461 """
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000462 global stop_testrunner
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000463 try:
464 if is_test_disabled(test, test_variant):
465 test_skipped = True
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000466 else:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000467 test_skipped = False
Shubham Ajmerab4949f52017-05-08 13:52:46 -0700468 if gdb:
469 proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, universal_newlines=True)
470 else:
471 proc = subprocess.Popen(command.split(), stderr=subprocess.STDOUT, stdout = subprocess.PIPE,
472 universal_newlines=True)
Shubham Ajmera186d3212017-07-21 01:20:57 +0000473 script_output = proc.communicate(timeout=timeout)[0]
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000474 test_passed = not proc.wait()
475
476 if not test_skipped:
477 if test_passed:
478 print_test_info(test_name, 'PASS')
479 else:
Alex Light1ebe6142017-10-03 15:00:10 -0700480 failed_tests.append((test_name, str(command) + "\n" + script_output))
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000481 if not env.ART_TEST_KEEP_GOING:
482 stop_testrunner = True
483 print_test_info(test_name, 'FAIL', ('%s\n%s') % (
484 command, script_output))
485 elif not dry_run:
486 print_test_info(test_name, 'SKIP')
487 skipped_tests.append(test_name)
488 else:
489 print_test_info(test_name, '')
Shubham Ajmerafe793492017-03-16 13:31:35 -0700490 except subprocess.TimeoutExpired as e:
Shubham Ajmera186d3212017-07-21 01:20:57 +0000491 failed_tests.append((test_name, 'Timed out in %d seconds' % timeout))
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700492 print_test_info(test_name, 'TIMEOUT', 'Timed out in %d seconds\n%s' % (
Shubham Ajmera186d3212017-07-21 01:20:57 +0000493 timeout, command))
Shubham Ajmerafe793492017-03-16 13:31:35 -0700494 except Exception as e:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700495 failed_tests.append((test_name, str(e)))
496 print_test_info(test_name, 'FAIL',
497 ('%s\n%s\n\n') % (command, str(e)))
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000498 finally:
499 semaphore.release()
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000500
501
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000502def print_test_info(test_name, result, failed_test_info=""):
503 """Print the continous test information
504
505 If verbose is set to True, it continuously prints test status information
506 on a new line.
507 If verbose is set to False, it keeps on erasing test
508 information by overriding it with the latest test information. Also,
509 in this case it stictly makes sure that the information length doesn't
510 exceed the console width. It does so by shortening the test_name.
511
512 When a test fails, it prints the output of the run-test script and
513 command used to invoke the script. It doesn't override the failing
514 test information in either of the cases.
515 """
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000516
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000517 global test_count
518 info = ''
519 if not verbose:
520 # Without --verbose, the testrunner erases passing test info. It
521 # does that by overriding the printed text with white spaces all across
522 # the console width.
523 console_width = int(os.popen('stty size', 'r').read().split()[1])
524 info = '\r' + ' ' * console_width + '\r'
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000525 try:
526 print_mutex.acquire()
527 test_count += 1
528 percent = (test_count * 100) / total_test_count
529 progress_info = ('[ %d%% %d/%d ]') % (
530 percent,
531 test_count,
532 total_test_count)
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000533
Shubham Ajmerafe793492017-03-16 13:31:35 -0700534 if result == 'FAIL' or result == 'TIMEOUT':
Alex Light1ebe6142017-10-03 15:00:10 -0700535 if not verbose:
536 info += ('%s %s %s\n') % (
537 progress_info,
538 test_name,
539 COLOR_ERROR + result + COLOR_NORMAL)
540 else:
541 info += ('%s %s %s\n%s\n') % (
542 progress_info,
543 test_name,
544 COLOR_ERROR + result + COLOR_NORMAL,
545 failed_test_info)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000546 else:
547 result_text = ''
548 if result == 'PASS':
549 result_text += COLOR_PASS + 'PASS' + COLOR_NORMAL
550 elif result == 'SKIP':
551 result_text += COLOR_SKIP + 'SKIP' + COLOR_NORMAL
552
553 if verbose:
554 info += ('%s %s %s\n') % (
555 progress_info,
556 test_name,
557 result_text)
558 else:
559 total_output_length = 2 # Two spaces
560 total_output_length += len(progress_info)
561 total_output_length += len(result)
562 allowed_test_length = console_width - total_output_length
563 test_name_len = len(test_name)
564 if allowed_test_length < test_name_len:
Shubham Ajmerafe793492017-03-16 13:31:35 -0700565 test_name = ('...%s') % (
566 test_name[-(allowed_test_length - 3):])
Alex Lightc14311c2017-02-23 17:02:46 -0800567 info += ('%s %s %s') % (
568 progress_info,
569 test_name,
570 result_text)
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000571 print_text(info)
Shubham Ajmerafe793492017-03-16 13:31:35 -0700572 except Exception as e:
Shubham Ajmerabbd84332017-02-17 00:41:10 +0000573 print_text(('%s\n%s\n') % (test_name, str(e)))
574 failed_tests.append(test_name)
575 finally:
576 print_mutex.release()
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000577
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700578def verify_knownfailure_entry(entry):
579 supported_field = {
Shubham Ajmerafe793492017-03-16 13:31:35 -0700580 'tests' : (list, str),
Alex Light6fdc1b62017-09-18 11:33:56 -0700581 'test_patterns' : (list,),
Shubham Ajmerafe793492017-03-16 13:31:35 -0700582 'description' : (list, str),
583 'bug' : (str,),
584 'variant' : (str,),
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700585 'env_vars' : (dict,),
586 }
587 for field in entry:
588 field_type = type(entry[field])
589 if field_type not in supported_field[field]:
590 raise ValueError('%s is not supported type for %s\n%s' % (
591 str(field_type),
592 field,
593 str(entry)))
594
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000595def get_disabled_test_info():
596 """Generate set of known failures.
597
598 It parses the art/test/knownfailures.json file to generate the list of
599 disabled tests.
600
601 Returns:
602 The method returns a dict of tests mapped to the variants list
603 for which the test should not be run.
604 """
605 known_failures_file = env.ANDROID_BUILD_TOP + '/art/test/knownfailures.json'
606 with open(known_failures_file) as known_failures_json:
607 known_failures_info = json.loads(known_failures_json.read())
608
609 disabled_test_info = {}
610 for failure in known_failures_info:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700611 verify_knownfailure_entry(failure)
612 tests = failure.get('tests', [])
Shubham Ajmerafe793492017-03-16 13:31:35 -0700613 if isinstance(tests, str):
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000614 tests = [tests]
Alex Light6fdc1b62017-09-18 11:33:56 -0700615 patterns = failure.get("test_patterns", [])
616 if (not isinstance(patterns, list)):
617 raise ValueError("test_patters is not a list in %s" % failure)
618
619 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 +0000620 variants = parse_variants(failure.get('variant'))
621 env_vars = failure.get('env_vars')
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700622
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000623 if check_env_vars(env_vars):
624 for test in tests:
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700625 if test not in RUN_TEST_SET:
626 raise ValueError('%s is not a valid run-test' % (
627 test))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000628 if test in disabled_test_info:
629 disabled_test_info[test] = disabled_test_info[test].union(variants)
630 else:
631 disabled_test_info[test] = variants
632 return disabled_test_info
633
634
635def check_env_vars(env_vars):
636 """Checks if the env variables are set as required to run the test.
637
638 Returns:
639 True if all the env variables are set as required, otherwise False.
640 """
641
642 if not env_vars:
643 return True
644 for key in env_vars:
645 if env.get_env(key) != env_vars.get(key):
646 return False
647 return True
648
649
650def is_test_disabled(test, variant_set):
651 """Checks if the test along with the variant_set is disabled.
652
653 Args:
654 test: The name of the test as in art/test directory.
655 variant_set: Variants to be used for the test.
656 Returns:
657 True, if the test is disabled.
658 """
659 if dry_run:
660 return True
Alex Lightbc319b22017-02-17 14:21:33 -0800661 if test in env.EXTRA_DISABLED_TESTS:
662 return True
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000663 variants_list = DISABLED_TEST_CONTAINER.get(test, {})
664 for variants in variants_list:
665 variants_present = True
666 for variant in variants:
667 if variant not in variant_set:
668 variants_present = False
669 break
670 if variants_present:
671 return True
672 return False
673
674
675def parse_variants(variants):
676 """Parse variants fetched from art/test/knownfailures.json.
677 """
678 if not variants:
679 variants = ''
680 for variant in TOTAL_VARIANTS_SET:
681 variants += variant
682 variants += '|'
683 variants = variants[:-1]
684 variant_list = set()
685 or_variants = variants.split('|')
686 for or_variant in or_variants:
687 and_variants = or_variant.split('&')
688 variant = set()
689 for and_variant in and_variants:
690 and_variant = and_variant.strip()
Shubham Ajmera14de5c42017-03-13 10:51:14 -0700691 if and_variant not in TOTAL_VARIANTS_SET:
692 raise ValueError('%s is not a valid variant' % (
693 and_variant))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000694 variant.add(and_variant)
695 variant_list.add(frozenset(variant))
696 return variant_list
697
698def print_text(output):
699 sys.stdout.write(output)
700 sys.stdout.flush()
701
702def print_analysis():
703 if not verbose:
Shubham Ajmera14d340c2017-02-15 18:49:10 +0000704 # Without --verbose, the testrunner erases passing test info. It
705 # does that by overriding the printed text with white spaces all across
706 # the console width.
707 console_width = int(os.popen('stty size', 'r').read().split()[1])
708 eraser_text = '\r' + ' ' * console_width + '\r'
709 print_text(eraser_text)
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700710
711 # Prints information about the total tests run.
712 # E.g., "2/38 (5%) tests passed".
713 passed_test_count = total_test_count - len(skipped_tests) - len(failed_tests)
714 passed_test_information = ('%d/%d (%d%%) %s passed.\n') % (
715 passed_test_count,
716 total_test_count,
717 (passed_test_count*100)/total_test_count,
718 'tests' if passed_test_count > 1 else 'test')
719 print_text(passed_test_information)
720
721 # Prints the list of skipped tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000722 if skipped_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700723 print_text(COLOR_SKIP + 'SKIPPED TESTS: ' + COLOR_NORMAL + '\n')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000724 for test in skipped_tests:
725 print_text(test + '\n')
726 print_text('\n')
727
Shubham Ajmeracbf56282017-03-13 09:54:23 -0700728 # Prints the list of failed tests, if any.
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000729 if failed_tests:
Shubham Ajmera3092c6e2017-03-24 16:19:48 -0700730 print_text(COLOR_ERROR + 'FAILED: ' + COLOR_NORMAL + '\n')
731 for test_info in failed_tests:
732 print_text(('%s\n%s\n' % (test_info[0], test_info[1])))
Andreas Gampe0dd7e852017-05-24 21:44:23 -0700733 print_text(COLOR_ERROR + '----------' + COLOR_NORMAL + '\n')
734 for failed_test in sorted([test_info[0] for test_info in failed_tests]):
735 print_text(('%s\n' % (failed_test)))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000736
737
738def parse_test_name(test_name):
739 """Parses the testname provided by the user.
740 It supports two types of test_name:
741 1) Like 001-HelloWorld. In this case, it will just verify if the test actually
742 exists and if it does, it returns the testname.
743 2) Like test-art-host-run-test-debug-prebuild-interpreter-no-relocate-ntrace-cms-checkjni-picimage-npictest-ndebuggable-001-HelloWorld32
744 In this case, it will parse all the variants and check if they are placed
745 correctly. If yes, it will set the various VARIANT_TYPES to use the
746 variants required to run the test. Again, it returns the test_name
747 without the variant information like 001-HelloWorld.
748 """
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000749 test_set = set()
750 for test in RUN_TEST_SET:
751 if test.startswith(test_name):
752 test_set.add(test)
753 if test_set:
754 return test_set
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000755
756 regex = '^test-art-'
757 regex += '(' + '|'.join(VARIANT_TYPE_DICT['target']) + ')-'
758 regex += 'run-test-'
759 regex += '(' + '|'.join(VARIANT_TYPE_DICT['run']) + ')-'
760 regex += '(' + '|'.join(VARIANT_TYPE_DICT['prebuild']) + ')-'
761 regex += '(' + '|'.join(VARIANT_TYPE_DICT['compiler']) + ')-'
762 regex += '(' + '|'.join(VARIANT_TYPE_DICT['relocate']) + ')-'
763 regex += '(' + '|'.join(VARIANT_TYPE_DICT['trace']) + ')-'
764 regex += '(' + '|'.join(VARIANT_TYPE_DICT['gc']) + ')-'
765 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jni']) + ')-'
766 regex += '(' + '|'.join(VARIANT_TYPE_DICT['image']) + ')-'
767 regex += '(' + '|'.join(VARIANT_TYPE_DICT['pictest']) + ')-'
768 regex += '(' + '|'.join(VARIANT_TYPE_DICT['debuggable']) + ')-'
Alex Light8f2c6d42017-04-10 16:27:35 -0700769 regex += '(' + '|'.join(VARIANT_TYPE_DICT['jvmti']) + ')-'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000770 regex += '(' + '|'.join(RUN_TEST_SET) + ')'
771 regex += '(' + '|'.join(VARIANT_TYPE_DICT['address_sizes']) + ')$'
772 match = re.match(regex, test_name)
773 if match:
Shubham Ajmera85853952017-08-29 16:26:21 -0700774 _user_input_variants['target'].add(match.group(1))
775 _user_input_variants['run'].add(match.group(2))
776 _user_input_variants['prebuild'].add(match.group(3))
777 _user_input_variants['compiler'].add(match.group(4))
778 _user_input_variants['relocate'].add(match.group(5))
779 _user_input_variants['trace'].add(match.group(6))
780 _user_input_variants['gc'].add(match.group(7))
781 _user_input_variants['jni'].add(match.group(8))
782 _user_input_variants['image'].add(match.group(9))
783 _user_input_variants['pictest'].add(match.group(10))
784 _user_input_variants['debuggable'].add(match.group(11))
785 _user_input_variants['jvmti'].add(match.group(12))
786 _user_input_variants['address_sizes'].add(match.group(14))
Alex Light8f2c6d42017-04-10 16:27:35 -0700787 return {match.group(13)}
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000788 raise ValueError(test_name + " is not a valid test")
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000789
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800790
791def setup_env_for_build_target(build_target, parser, options):
792 """Setup environment for the build target
793
794 The method setup environment for the master-art-host targets.
795 """
796 os.environ.update(build_target['env'])
797 os.environ['SOONG_ALLOW_MISSING_DEPENDENCIES'] = 'true'
798 print_text('%s\n' % (str(os.environ)))
799
800 target_options = vars(parser.parse_args(build_target['flags']))
801 target_options['host'] = True
802 target_options['verbose'] = True
803 target_options['build'] = True
804 target_options['n_thread'] = options['n_thread']
805 target_options['dry_run'] = options['dry_run']
806
807 return target_options
808
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700809def get_default_threads(target):
810 if target is 'target':
811 adb_command = 'adb shell cat /sys/devices/system/cpu/present'
812 cpu_info_proc = subprocess.Popen(adb_command.split(), stdout=subprocess.PIPE)
813 cpu_info = cpu_info_proc.stdout.read()
Shubham Ajmera8fd26942017-05-09 11:30:47 -0700814 if type(cpu_info) is bytes:
815 cpu_info = cpu_info.decode('utf-8')
816 cpu_info_regex = '\d*-(\d*)'
817 match = re.match(cpu_info_regex, cpu_info)
818 if match:
819 return int(match.group(1))
820 else:
821 raise ValueError('Unable to predict the concurrency for the target. '
822 'Is device connected?')
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700823 else:
824 return multiprocessing.cpu_count()
825
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000826def parse_option():
827 global verbose
828 global dry_run
829 global n_thread
830 global build
831 global gdb
832 global gdb_arg
Shubham Ajmerafe793492017-03-16 13:31:35 -0700833 global timeout
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700834 global dex2oat_jobs
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700835 global run_all_configs
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000836
Alex Light7a1ccf82017-02-21 09:52:34 -0800837 parser = argparse.ArgumentParser(description="Runs all or a subset of the ART test suite.")
838 parser.add_argument('-t', '--test', dest='test', help='name of the test')
839 parser.add_argument('-j', type=int, dest='n_thread')
Shubham Ajmera186d3212017-07-21 01:20:57 +0000840 parser.add_argument('--timeout', default=timeout, type=int, dest='timeout')
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000841 for variant in TOTAL_VARIANTS_SET:
842 flag = '--' + variant
Shubham Ajmera85853952017-08-29 16:26:21 -0700843 parser.add_argument(flag, action='store_true', dest=variant)
Alex Light7a1ccf82017-02-21 09:52:34 -0800844 parser.add_argument('--verbose', '-v', action='store_true', dest='verbose')
845 parser.add_argument('--dry-run', action='store_true', dest='dry_run')
846 parser.add_argument("--skip", action="append", dest="skips", default=[],
847 help="Skip the given test in all circumstances.")
Alex Light9b6b13e2017-02-22 11:46:50 -0800848 parser.add_argument('--no-build-dependencies',
849 action='store_false', dest='build',
850 help="Don't build dependencies under any circumstances. This is the " +
851 "behavior if ART_TEST_RUN_TEST_ALWAYS_BUILD is not set to 'true'.")
852 parser.add_argument('-b', '--build-dependencies',
853 action='store_true', dest='build',
854 help="Build dependencies under all circumstances. By default we will " +
855 "not build dependencies unless ART_TEST_RUN_TEST_BUILD=true.")
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800856 parser.add_argument('--build-target', dest='build_target', help='master-art-host targets')
Alex Light9b6b13e2017-02-22 11:46:50 -0800857 parser.set_defaults(build = env.ART_TEST_RUN_TEST_BUILD)
Alex Light7a1ccf82017-02-21 09:52:34 -0800858 parser.add_argument('--gdb', action='store_true', dest='gdb')
859 parser.add_argument('--gdb-arg', dest='gdb_arg')
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700860 parser.add_argument('--dex2oat-jobs', type=int, dest='dex2oat_jobs',
861 help='Number of dex2oat jobs')
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700862 parser.add_argument('-a', '--all', action='store_true', dest='run_all',
863 help="Run all the possible configurations for the input test set")
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000864
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800865 options = vars(parser.parse_args())
866 if options['build_target']:
867 options = setup_env_for_build_target(target_config[options['build_target']],
868 parser, options)
869
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000870 test = ''
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800871 env.EXTRA_DISABLED_TESTS.update(set(options['skips']))
872 if options['test']:
873 test = parse_test_name(options['test'])
Shubham Ajmera85853952017-08-29 16:26:21 -0700874
875 for variant_type in VARIANT_TYPE_DICT:
876 for variant in VARIANT_TYPE_DICT[variant_type]:
877 if options.get(variant):
878 _user_input_variants[variant_type].add(variant)
879
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800880 if options['verbose']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000881 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800882 if options['n_thread']:
883 n_thread = max(1, options['n_thread'])
884 if options['dry_run']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000885 dry_run = True
886 verbose = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800887 build = options['build']
888 if options['gdb']:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000889 n_thread = 1
890 gdb = True
Shubham Ajmerab9d09ca2017-03-07 10:45:05 -0800891 if options['gdb_arg']:
892 gdb_arg = options['gdb_arg']
Shubham Ajmerafe793492017-03-16 13:31:35 -0700893 timeout = options['timeout']
Shubham Ajmera981d99c2017-08-17 14:11:08 -0700894 if options['dex2oat_jobs']:
895 dex2oat_jobs = options['dex2oat_jobs']
Shubham Ajmera42ea83b2017-09-25 21:05:57 -0700896 if options['run_all']:
897 run_all_configs = True
Shubham Ajmera22499e22017-03-22 18:33:37 -0700898
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000899 return test
900
901def main():
902 gather_test_info()
903 user_requested_test = parse_option()
904 setup_test_env()
905 if build:
906 build_targets = ''
Shubham Ajmera85853952017-08-29 16:26:21 -0700907 if 'host' in _user_input_variants['target']:
Shubham Ajmera186d3212017-07-21 01:20:57 +0000908 build_targets += 'test-art-host-run-test-dependencies'
Shubham Ajmera85853952017-08-29 16:26:21 -0700909 if 'target' in _user_input_variants['target']:
Shubham Ajmera186d3212017-07-21 01:20:57 +0000910 build_targets += 'test-art-target-run-test-dependencies'
Shubham Ajmera06cde292017-02-10 23:15:05 +0000911 build_command = 'make'
Shubham Ajmera4a5a1622017-03-22 10:07:19 -0700912 build_command += ' -j'
Shubham Ajmera06cde292017-02-10 23:15:05 +0000913 build_command += ' -C ' + env.ANDROID_BUILD_TOP
914 build_command += ' ' + build_targets
Nicolas Geoffray300c09b2017-03-22 12:26:32 +0000915 # Add 'dist' to avoid Jack issues b/36169180.
916 build_command += ' dist'
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000917 if subprocess.call(build_command.split()):
918 sys.exit(1)
919 if user_requested_test:
920 test_runner_thread = threading.Thread(target=run_tests, args=(user_requested_test,))
921 else:
922 test_runner_thread = threading.Thread(target=run_tests, args=(RUN_TEST_SET,))
923 test_runner_thread.daemon = True
924 try:
925 test_runner_thread.start()
926 while threading.active_count() > 1:
Shubham Ajmera186d3212017-07-21 01:20:57 +0000927 time.sleep(0.1)
928 print_analysis()
Shubham Ajmerafe793492017-03-16 13:31:35 -0700929 except Exception as e:
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000930 print_analysis()
Shubham Ajmerafaf12502017-02-15 17:19:44 +0000931 print_text(str(e))
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000932 sys.exit(1)
Shubham Ajmerac5aae872017-02-16 19:58:59 +0000933 if failed_tests:
934 sys.exit(1)
935 sys.exit(0)
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000936
Shubham Ajmera65adb8b2017-02-06 16:04:25 +0000937if __name__ == '__main__':
938 main()