blob: 27c8b6adf9283a44367e11b6970821b9a6584831 [file] [log] [blame]
Ian Zernydcb172e2022-02-22 15:36:45 +01001#!/usr/bin/env python3
Mads Ager418d1ca2017-05-22 09:35:49 +02002# Copyright (c) 2016, the R8 project authors. Please see the AUTHORS file
3# for details. All rights reserved. Use of this source code is governed by a
4# BSD-style license that can be found in the LICENSE file.
5
6# Convenience script for running tests. If no argument is given run all tests,
7# if an argument is given, run only tests with that pattern. This script will
8# force the tests to run, even if no input changed.
9
Mads Ager418d1ca2017-05-22 09:35:49 +020010import optparse
Ian Zerny5fffb0a2019-02-11 13:54:22 +010011import os
Ian Zerny24398bc2019-02-22 11:59:18 +010012import shutil
Rico Windf65a1d62017-06-30 09:41:56 +020013import subprocess
Mads Ager418d1ca2017-05-22 09:35:49 +020014import sys
Rico Windda6836e2018-12-07 12:32:03 +010015import time
Rico Wind06487ac2018-12-10 09:09:19 +010016import uuid
Ian Zerny5fffb0a2019-02-11 13:54:22 +010017
Ian Zerny3ced9262022-03-29 11:06:02 +020018import archive_desugar_jdk_libs
19import download_kotlin_dev
Ian Zerny5fffb0a2019-02-11 13:54:22 +010020import gradle
Ian Zerny3ced9262022-03-29 11:06:02 +020021import notify
Ian Zerny5fffb0a2019-02-11 13:54:22 +010022import utils
Jean-Marie Henaffce162f32017-10-04 10:39:27 +020023
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +010024if utils.is_python3():
25 import threading
26else:
27 import thread
28
Søren Gjessefe7c0112018-12-03 12:33:12 +010029ALL_ART_VMS = [
30 "default",
Søren Gjesse12a45f62022-02-04 12:05:27 +010031 "13.0.0",
Søren Gjesse953f7c42021-08-18 16:42:06 +020032 "12.0.0",
clementbera97d5cce2019-11-22 15:09:27 +010033 "10.0.0",
Søren Gjessefe7c0112018-12-03 12:33:12 +010034 "9.0.0",
35 "8.1.0",
36 "7.0.0",
37 "6.0.1",
38 "5.1.1",
39 "4.4.4",
40 "4.0.4"]
Mads Ager418d1ca2017-05-22 09:35:49 +020041
Rico Windda6836e2018-12-07 12:32:03 +010042# How often do we check for progress on the bots:
43# Should be long enough that a normal run would always have med progress
44# Should be short enough that we ensure that two calls are close enough
45# to happen before bot times out.
46# A false positiv, i.e., printing the stacks of non hanging processes
Rico Wind46cdf982021-09-27 19:53:45 +020047# is not a problem, no harm done except some logging in stdout.
Rico Windda6836e2018-12-07 12:32:03 +010048TIMEOUT_HANDLER_PERIOD = 60 * 18
49
Rico Wind06487ac2018-12-10 09:09:19 +010050BUCKET = 'r8-test-results'
51
Ian Zerny24398bc2019-02-22 11:59:18 +010052NUMBER_OF_TEST_REPORTS = 5
53REPORTS_PATH = os.path.join(utils.BUILD, 'reports')
54REPORT_INDEX = ['tests', 'test', 'index.html']
Ian Zernybcbd6c52019-10-29 15:27:04 +010055VALID_RUNTIMES = [
56 'none',
57 'jdk8',
58 'jdk9',
59 'jdk11',
Ian Zernyf0ce2c32022-03-28 15:39:32 +020060 'jdk17',
Ian Zernybcbd6c52019-10-29 15:27:04 +010061] + [ 'dex-%s' % dexvm for dexvm in ALL_ART_VMS ]
Ian Zerny24398bc2019-02-22 11:59:18 +010062
Mads Ager418d1ca2017-05-22 09:35:49 +020063def ParseOptions():
64 result = optparse.OptionParser()
Søren Gjesse77527982018-10-05 12:58:49 +020065 result.add_option('--no-internal', '--no_internal',
Mads Ager418d1ca2017-05-22 09:35:49 +020066 help='Do not run Google internal tests.',
67 default=False, action='store_true')
Søren Gjesse77527982018-10-05 12:58:49 +020068 result.add_option('--archive-failures', '--archive_failures',
Rico Winda94f01c2017-06-27 10:32:34 +020069 help='Upload test results to cloud storage on failure.',
70 default=False, action='store_true')
Morten Krogh-Jespersenef978ff2021-10-11 12:44:00 +020071 result.add_option('--archive-failures-file-name',
72 '--archive_failures_file_name',
73 help='Set file name for the archived failures file name',
74 default=uuid.uuid4())
Søren Gjesse77527982018-10-05 12:58:49 +020075 result.add_option('--only-internal', '--only_internal',
Mads Ager418d1ca2017-05-22 09:35:49 +020076 help='Only run Google internal tests.',
77 default=False, action='store_true')
Søren Gjesse77527982018-10-05 12:58:49 +020078 result.add_option('--all-tests', '--all_tests',
Mads Ager418d1ca2017-05-22 09:35:49 +020079 help='Run tests in all configurations.',
80 default=False, action='store_true')
Christoffer Quist Adamsen748e4662019-08-23 14:53:49 +020081 result.add_option('--slow-tests', '--slow_tests',
82 help='Also run slow tests.',
83 default=False, action='store_true')
Mads Ager418d1ca2017-05-22 09:35:49 +020084 result.add_option('-v', '--verbose',
85 help='Print test stdout to, well, stdout.',
86 default=False, action='store_true')
Søren Gjesse77527982018-10-05 12:58:49 +020087 result.add_option('--dex-vm', '--dex_vm',
Mads Ager418d1ca2017-05-22 09:35:49 +020088 help='The android version of the vm to use. "all" will run the tests on '
89 'all art vm versions (stopping after first failed execution)',
90 default="default",
91 choices=ALL_ART_VMS + ["all"])
Søren Gjesse77527982018-10-05 12:58:49 +020092 result.add_option('--dex-vm-kind', '--dex_vm_kind',
Jean-Marie Henaffce162f32017-10-04 10:39:27 +020093 help='Whether to use host or target version of runtime',
94 default="host",
95 nargs=1,
96 choices=["host", "target"])
Søren Gjesse77527982018-10-05 12:58:49 +020097 result.add_option('--one-line-per-test', '--one_line_per_test',
Mads Ager418d1ca2017-05-22 09:35:49 +020098 help='Print a line before a tests starts and after it ends to stdout.',
99 default=False, action='store_true')
100 result.add_option('--tool',
Tamas Kenezcfb2c052018-10-12 11:03:57 +0200101 help='Tool to run ART tests with: "r8" (default) or "d8" or "r8cf"'
102 ' (r8 w/CF-backend). Ignored if "--all_tests" enabled.',
103 default=None, choices=["r8", "d8", "r8cf"])
Søren Gjesse77527982018-10-05 12:58:49 +0200104 result.add_option('--disable-assertions', '--disable_assertions',
Tamas Kenezb77b7d82017-08-17 14:05:16 +0200105 help='Disable assertions when running tests.',
Søren Gjesseaf1c5e22017-06-15 12:24:03 +0200106 default=False, action='store_true')
Søren Gjesse77527982018-10-05 12:58:49 +0200107 result.add_option('--with-code-coverage', '--with_code_coverage',
Tamas Kenezb77b7d82017-08-17 14:05:16 +0200108 help='Enable code coverage with Jacoco.',
Sebastien Hertze2687b62017-07-25 11:16:04 +0200109 default=False, action='store_true')
Søren Gjesse77527982018-10-05 12:58:49 +0200110 result.add_option('--test-dir', '--test_dir',
Tamas Kenezb77b7d82017-08-17 14:05:16 +0200111 help='Use a custom directory for the test artifacts instead of a'
112 ' temporary (which is automatically removed after the test).'
113 ' Note that the directory will not be cleared before the test.')
Søren Gjesse77527982018-10-05 12:58:49 +0200114 result.add_option('--java-home', '--java_home',
Mikaël Peltier5c0a3232017-10-18 09:14:40 +0200115 help='Use a custom java version to run tests.')
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100116 result.add_option('--java-max-memory-size', '--java_max_memory_size',
Rico Wind97b0a992019-08-30 11:09:15 +0200117 help='Set memory for running tests, default 4G',
Christoffer Quist Adamsen0a5f2ef2022-01-24 14:02:13 +0100118 default=os.environ.get('R8_JAVA_MAX_MEMORY_SIZE', '4G'))
Rico Windba151112020-10-01 08:16:33 +0200119 result.add_option('--test-namespace', '--test_namespace',
120 help='Only run tests in this namespace. The namespace is relative to '
121 'com/android/tools/r8, e.g., desugar/desugaredlibrary',
122 default=None)
Rico Wind8e2f7e42019-02-21 10:13:21 +0100123 result.add_option('--shard-count', '--shard_count',
124 help='We are running this many shards.')
125 result.add_option('--shard-number', '--shard_number',
126 help='We are running this shard.')
Søren Gjesse77527982018-10-05 12:58:49 +0200127 result.add_option('--generate-golden-files-to', '--generate_golden_files_to',
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +0200128 help='Store dex files produced by tests in the specified directory.'
129 ' It is aimed to be read on platforms with no host runtime available'
130 ' for comparison.')
Søren Gjesse77527982018-10-05 12:58:49 +0200131 result.add_option('--use-golden-files-in', '--use_golden_files_in',
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +0200132 help='Download golden files hierarchy for this commit in the specified'
133 ' location and use them instead of executing on host runtime.')
Søren Gjesse1956bdb2019-02-19 08:37:52 +0100134 result.add_option('--no-r8lib', '--no_r8lib',
135 default=False, action='store_true',
Morten Krogh-Jespersen2243b162019-01-14 08:40:53 +0100136 help='Run the tests on R8 full with relocated dependencies.')
Rico Windbc820812022-05-31 09:19:56 +0200137 result.add_option('--no-arttests', '--no_arttests',
138 default=False, action='store_true',
139 help='Do not run the art tests.')
Søren Gjesse1956bdb2019-02-19 08:37:52 +0100140 result.add_option('--r8lib-no-deps', '--r8lib_no_deps',
141 default=False, action='store_true',
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100142 help='Run the tests on r8lib without relocated dependencies.')
Ian Zerny24398bc2019-02-22 11:59:18 +0100143 result.add_option('--failed',
144 default=False, action='store_true',
145 help='Run the tests that failed last execution.')
146 result.add_option('--fail-fast', '--fail_fast',
147 default=False, action='store_true',
148 help='Stop on first failure. Passes --fail-fast to gradle test runner.')
Morten Krogh-Jespersen89d005b2019-10-15 13:32:23 +0200149 result.add_option('--worktree',
150 default=False, action='store_true',
151 help='Tests are run in worktree and should not use gradle user home.')
Ian Zernybcbd6c52019-10-29 15:27:04 +0100152 result.add_option('--runtimes',
153 default=None,
154 help='Test parameter runtimes to use, separated by : (eg, none:jdk9).'
155 ' Special values include: all (for all runtimes)'
156 ' and empty (for no runtimes).')
Morten Krogh-Jespersendcb8d452020-07-09 15:07:50 +0200157 result.add_option('--print-hanging-stacks', '--print_hanging_stacks',
158 default=-1, type="int", help='Print hanging stacks after timeout in seconds')
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +0100159 result.add_option('--print-full-stacktraces', '--print_full_stacktraces',
160 default=False, action='store_true',
161 help='Print the full stacktraces without any filtering applied')
162 result.add_option(
163 '--print-obfuscated-stacktraces', '--print_obfuscated_stacktraces',
164 default=False, action='store_true',
165 help='Print the obfuscated stacktraces')
Morten Krogh-Jespersen2d3aca62020-11-30 12:48:11 +0100166 result.add_option(
167 '--debug-agent', '--debug_agent',
168 help='Enable Java debug agent and suspend compilation (default disabled)',
169 default=False,
170 action='store_true')
Rico Winde1393092021-03-21 12:57:01 +0100171 result.add_option('--desugared-library-configuration',
172 '--desugared_library-configuration',
Søren Gjesseef195772021-03-11 16:04:42 +0100173 help='Use alternative desugared library configuration.')
Søren Gjesse4a45f9b2021-02-11 14:05:29 +0100174 result.add_option('--desugared-library', '--desugared_library',
175 help='Build and use desugared library from GitHub.')
Rico Windf2f4c292021-04-23 07:06:13 +0200176 result.add_option('--print-times', '--print_times',
177 help='Print the execution time of the slowest tests..',
178 default=False, action='store_true')
Ian Zerny9a0e96a2021-04-28 12:35:49 +0200179 result.add_option(
Ian Zernycae764d2021-08-16 08:25:15 +0200180 '--testing-state-name',
181 help='Set an explict name for the testing state '
182 '(used in conjunction with --with/reset-testing-state).')
183 result.add_option(
Ian Zerny27ea4c72021-04-29 22:35:49 +0200184 '--with-testing-state',
185 help='Run/resume tests using testing state.',
186 default=False, action='store_true')
187 result.add_option(
188 '--reset-testing-state',
189 help='Clean the testing state and rerun tests (implies --with-testing-state).',
Ian Zerny9a0e96a2021-04-28 12:35:49 +0200190 default=False, action='store_true')
191 result.add_option(
192 '--stacktrace',
193 help='Pass --stacktrace to the gradle run',
194 default=False, action='store_true')
Morten Krogh-Jespersenc616fcd2021-09-23 08:25:09 +0200195 result.add_option('--kotlin-compiler-dev',
Morten Krogh-Jespersenc69a5542021-09-23 08:10:23 +0200196 help='Specify to download a kotlin dev compiler and run '
197 'tests with that',
198 default=False, action='store_true')
Morten Krogh-Jespersen69ed1d82021-11-26 13:30:11 +0100199 result.add_option('--kotlin-compiler-old',
200 help='Specify to run tests on older kotlin compilers',
201 default=False, action='store_true')
Mads Ager418d1ca2017-05-22 09:35:49 +0200202 return result.parse_args()
203
Rico Wind4cd3cbc2022-04-26 11:25:15 +0200204def has_failures(classes_file):
205 with open(classes_file) as f:
206 contents = f.read()
207 # The report has a div tag with the percentage of tests that succeeded.
208 assert '<div class="percent">' in contents
209 return '<div class="percent">100%</div>' not in contents
210
211def should_upload(filename, absolute_filename):
212 # filename is relative to REPO_ROOT/build/reports/tests
213 if filename.startswith('test/packages'):
214 # We don't upload the package overview
215 return False
216 if filename.startswith('test/classes'):
217 return has_failures(absolute_filename)
218 # Always upload index, css and js
219 return True
220
Morten Krogh-Jespersenef978ff2021-10-11 12:44:00 +0200221def archive_failures(options):
Rico Wind06487ac2018-12-10 09:09:19 +0100222 upload_dir = os.path.join(utils.REPO_ROOT, 'build', 'reports', 'tests')
Morten Krogh-Jespersenef978ff2021-10-11 12:44:00 +0200223 file_name = options.archive_failures_file_name
Rico Wind4cd3cbc2022-04-26 11:25:15 +0200224 destination_dir = 'gs://%s/%s/' % (BUCKET, file_name)
225 for (dir_path, dir_names, file_names) in os.walk(upload_dir):
226 for f in file_names:
227 absolute_file = os.path.join(dir_path, f)
228 relative_file = absolute_file[len(upload_dir)+1:]
229 if (should_upload(relative_file, absolute_file)):
230 utils.upload_file_to_cloud_storage(absolute_file,
Rico Wind03424282022-04-26 15:09:51 +0200231 destination_dir + relative_file)
Morten Krogh-Jespersenef978ff2021-10-11 12:44:00 +0200232 url = 'https://storage.googleapis.com/%s/%s/test/index.html' % (BUCKET, file_name)
233 print('Test results available at: %s' % url)
Rico Wind06487ac2018-12-10 09:09:19 +0100234
Mads Ager418d1ca2017-05-22 09:35:49 +0200235def Main():
236 (options, args) = ParseOptions()
Rico Windda6836e2018-12-07 12:32:03 +0100237 if utils.is_bot():
Rico Wind22707fc2019-03-15 13:19:57 +0100238 gradle.RunGradle(['--no-daemon', 'clean'])
Rico Wind8753a852022-02-22 09:36:58 +0100239 print('Running with python ' + str(sys.version_info))
Sebastien Hertze2687b62017-07-25 11:16:04 +0200240
Søren Gjesseef195772021-03-11 16:04:42 +0100241 desugar_jdk_json_dir = None
242 if options.desugared_library_configuration:
243 if options.desugared_library_configuration != 'jdk11':
244 print("Only value supported for --desugared-library is 'jdk11'")
245 exit(1)
246 desugar_jdk_json_dir = 'src/library_desugar/jdk11'
247
Søren Gjesse4a45f9b2021-02-11 14:05:29 +0100248 desugar_jdk_libs = None
249 if options.desugared_library:
250 if options.desugared_library != 'HEAD':
251 print("Only value supported for --desugared-library is 'HEAD'")
252 exit(1)
253 desugar_jdk_libs_dir = 'build/desugar_jdk_libs'
254 shutil.rmtree(desugar_jdk_libs_dir, ignore_errors=True)
255 os.makedirs(desugar_jdk_libs_dir)
256 print('Building desugared library.')
257 with utils.TempDir() as checkout_dir:
258 archive_desugar_jdk_libs.CloneDesugaredLibrary('google', checkout_dir)
Rico Winde4b43a32021-03-02 09:29:52 +0100259 # Make sure bazel is extracted in third_party.
260 utils.DownloadFromGoogleCloudStorage(utils.BAZEL_SHA_FILE)
261 utils.DownloadFromGoogleCloudStorage(utils.JAVA8_SHA_FILE)
Søren Gjesseef195772021-03-11 16:04:42 +0100262 utils.DownloadFromGoogleCloudStorage(utils.JAVA11_SHA_FILE)
263 (library_jar, maven_zip) = archive_desugar_jdk_libs.BuildDesugaredLibrary(checkout_dir, 'jdk11' if options.desugared_library_configuration == 'jdk11' else 'jdk8')
Søren Gjesse4a45f9b2021-02-11 14:05:29 +0100264 desugar_jdk_libs = os.path.join(desugar_jdk_libs_dir, os.path.basename(library_jar))
265 shutil.copyfile(library_jar, desugar_jdk_libs)
266 print('Desugared library for test in ' + desugar_jdk_libs)
267
Ian Zerny9a0e96a2021-04-28 12:35:49 +0200268 gradle_args = []
269
270 if options.stacktrace or utils.is_bot():
271 gradle_args.append('--stacktrace')
272
Rico Wind22707fc2019-03-15 13:19:57 +0100273 if utils.is_bot():
Rico Wind24777b92020-06-19 22:44:14 +0200274 # Bots don't like dangling processes.
Rico Wind22707fc2019-03-15 13:19:57 +0100275 gradle_args.append('--no-daemon')
276
Sebastien Hertze2687b62017-07-25 11:16:04 +0200277 # Set all necessary Gradle properties and options first.
Rico Wind8e2f7e42019-02-21 10:13:21 +0100278 if options.shard_count:
279 assert options.shard_number
280 gradle_args.append('-Pshard_count=%s' % options.shard_count)
281 gradle_args.append('-Pshard_number=%s' % options.shard_number)
Mads Ager418d1ca2017-05-22 09:35:49 +0200282 if options.verbose:
283 gradle_args.append('-Pprint_test_stdout')
284 if options.no_internal:
285 gradle_args.append('-Pno_internal')
286 if options.only_internal:
287 gradle_args.append('-Ponly_internal')
288 if options.all_tests:
289 gradle_args.append('-Pall_tests')
Christoffer Quist Adamsen748e4662019-08-23 14:53:49 +0200290 if options.slow_tests:
291 gradle_args.append('-Pslow_tests=1')
Mads Ager418d1ca2017-05-22 09:35:49 +0200292 if options.tool:
293 gradle_args.append('-Ptool=%s' % options.tool)
294 if options.one_line_per_test:
295 gradle_args.append('-Pone_line_per_test')
Rico Windba151112020-10-01 08:16:33 +0200296 if options.test_namespace:
297 gradle_args.append('-Ptest_namespace=%s' % options.test_namespace)
Søren Gjesseaf1c5e22017-06-15 12:24:03 +0200298 if options.disable_assertions:
299 gradle_args.append('-Pdisable_assertions')
Sebastien Hertze2687b62017-07-25 11:16:04 +0200300 if options.with_code_coverage:
301 gradle_args.append('-Pwith_code_coverage')
Christoffer Quist Adamsen7bf60342020-11-09 14:00:27 +0100302 if options.print_full_stacktraces:
303 gradle_args.append('-Pprint_full_stacktraces')
304 if options.print_obfuscated_stacktraces:
305 gradle_args.append('-Pprint_obfuscated_stacktraces')
Morten Krogh-Jespersen69ed1d82021-11-26 13:30:11 +0100306 if options.kotlin_compiler_old:
Morten Krogh-Jespersendcb967e2021-12-02 11:18:39 +0100307 gradle_args.append('-Pkotlin_compiler_old')
Morten Krogh-Jespersen3e0054b2021-09-23 08:32:33 +0200308 if options.kotlin_compiler_dev:
Morten Krogh-Jespersendcb967e2021-12-02 11:18:39 +0100309 gradle_args.append('-Pkotlin_compiler_dev')
Morten Krogh-Jespersenc69a5542021-09-23 08:10:23 +0200310 download_kotlin_dev.download_newest()
Jean-Marie Henaff7b424e92017-06-15 11:02:56 +0200311 if os.name == 'nt':
Jean-Marie Henaff7b424e92017-06-15 11:02:56 +0200312 gradle_args.append('-Pno_internal')
Tamas Kenezb77b7d82017-08-17 14:05:16 +0200313 if options.test_dir:
314 gradle_args.append('-Ptest_dir=' + options.test_dir)
315 if not os.path.exists(options.test_dir):
316 os.makedirs(options.test_dir)
Mikaël Peltier5c0a3232017-10-18 09:14:40 +0200317 if options.java_home:
318 gradle_args.append('-Dorg.gradle.java.home=' + options.java_home)
Ian Zerny5fffb0a2019-02-11 13:54:22 +0100319 if options.java_max_memory_size:
Rico Wind97b0a992019-08-30 11:09:15 +0200320 gradle_args.append('-Ptest_xmx=' + options.java_max_memory_size)
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +0200321 if options.generate_golden_files_to:
322 gradle_args.append('-Pgenerate_golden_files_to=' + options.generate_golden_files_to)
323 if not os.path.exists(options.generate_golden_files_to):
324 os.makedirs(options.generate_golden_files_to)
325 gradle_args.append('-PHEAD_sha1=' + utils.get_HEAD_sha1())
326 if options.use_golden_files_in:
327 gradle_args.append('-Puse_golden_files_in=' + options.use_golden_files_in)
328 if not os.path.exists(options.use_golden_files_in):
329 os.makedirs(options.use_golden_files_in)
330 gradle_args.append('-PHEAD_sha1=' + utils.get_HEAD_sha1())
Morten Krogh-Jespersen432dd912019-01-14 13:26:35 +0100331 if (not options.no_r8lib) and options.r8lib_no_deps:
Morten Krogh-Jespersen2243b162019-01-14 08:40:53 +0100332 print('Cannot run tests on r8lib with and without deps. R8lib is now default target.')
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100333 exit(1)
Morten Krogh-Jespersen2243b162019-01-14 08:40:53 +0100334 if not options.no_r8lib:
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100335 gradle_args.append('-Pr8lib')
Morten Krogh-Jespersen54f196e2019-01-14 16:10:08 +0100336 # Force gradle to build a version of r8lib without dependencies for
337 # BootstrapCurrentEqualityTest.
338 gradle_args.append('R8LibNoDeps')
Morten Krogh-Jespersen98ee89a2021-10-25 20:59:02 +0200339 gradle_args.append('R8Retrace')
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100340 if options.r8lib_no_deps:
341 gradle_args.append('-Pr8lib_no_deps')
Morten Krogh-Jespersen89d005b2019-10-15 13:32:23 +0200342 if options.worktree:
343 gradle_args.append('-g=' + os.path.join(utils.REPO_ROOT, ".gradle_user_home"))
Ian Zernya97ccc42020-02-10 14:18:07 +0100344 gradle_args.append('--no-daemon')
Morten Krogh-Jespersen2d3aca62020-11-30 12:48:11 +0100345 if options.debug_agent:
346 gradle_args.append('--no-daemon')
Søren Gjesseef195772021-03-11 16:04:42 +0100347 if desugar_jdk_json_dir:
348 gradle_args.append('-Pdesugar_jdk_json_dir=' + desugar_jdk_json_dir)
Søren Gjesse4a45f9b2021-02-11 14:05:29 +0100349 if desugar_jdk_libs:
350 gradle_args.append('-Pdesugar_jdk_libs=' + desugar_jdk_libs)
Rico Windbc820812022-05-31 09:19:56 +0200351 if options.no_arttests:
352 gradle_args.append('-Pno_arttests=true')
Ian Zerny27ea4c72021-04-29 22:35:49 +0200353 if options.reset_testing_state:
354 gradle_args.append('-Ptesting-state')
355 gradle_args.append('-Preset-testing-state')
356 elif options.with_testing_state:
357 gradle_args.append('-Ptesting-state')
Ian Zernycae764d2021-08-16 08:25:15 +0200358 if options.testing_state_name:
359 gradle_args.append('-Ptesting-state-name=' + options.testing_state_name)
Morten Krogh-Jespersen807b15f2018-12-17 14:24:22 +0100360
Morten Krogh-Jespersen54f196e2019-01-14 16:10:08 +0100361 # Build an R8 with dependencies for bootstrapping tests before adding test sources.
362 gradle_args.append('r8WithRelocatedDeps')
Clément Béraffc2d6a2022-08-02 13:03:04 +0200363 gradle_args.append('r8WithRelocatedDeps17')
Ian Zerny9cd6f522022-08-04 13:13:18 +0200364 # TODO(b/227160052): Remove 11 once the bootstrap test runs on 17.
365 gradle_args.append('r8WithRelocatedDeps11')
Morten Krogh-Jespersen54f196e2019-01-14 16:10:08 +0100366
Sebastien Hertze2687b62017-07-25 11:16:04 +0200367 # Add Gradle tasks
368 gradle_args.append('cleanTest')
369 gradle_args.append('test')
Morten Krogh-Jespersen2d3aca62020-11-30 12:48:11 +0100370 if options.debug_agent:
371 gradle_args.append('--debug-jvm')
Ian Zerny24398bc2019-02-22 11:59:18 +0100372 if options.fail_fast:
373 gradle_args.append('--fail-fast')
374 if options.failed:
375 args = compute_failed_tests(args)
376 if args is None:
377 return 1
378 if len(args) == 0:
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100379 print("No failing tests")
Ian Zerny24398bc2019-02-22 11:59:18 +0100380 return 0
Sebastien Hertz0f4e7fb2017-10-02 11:33:45 +0200381 # Test filtering. Must always follow the 'test' task.
382 for testFilter in args:
Sebastien Hertze2687b62017-07-25 11:16:04 +0200383 gradle_args.append('--tests')
Sebastien Hertz0f4e7fb2017-10-02 11:33:45 +0200384 gradle_args.append(testFilter)
Sebastien Hertze2687b62017-07-25 11:16:04 +0200385 if options.with_code_coverage:
386 # Create Jacoco report after tests.
387 gradle_args.append('jacocoTestReport')
388
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +0200389 if options.use_golden_files_in:
390 sha1 = '%s' % utils.get_HEAD_sha1()
391 with utils.ChangedWorkingDirectory(options.use_golden_files_in):
392 utils.download_file_from_cloud_storage(
393 'gs://r8-test-results/golden-files/%s.tar.gz' % sha1,
394 '%s.tar.gz' % sha1)
395 utils.unpack_archive('%s.tar.gz' % sha1)
396
Morten Krogh-Jespersendcb8d452020-07-09 15:07:50 +0200397 print_stacks_timeout = options.print_hanging_stacks
398 if (utils.is_bot() and not utils.IsWindows()) or print_stacks_timeout > -1:
Rico Windda6836e2018-12-07 12:32:03 +0100399 timestamp_file = os.path.join(utils.BUILD, 'last_test_time')
400 if os.path.exists(timestamp_file):
401 os.remove(timestamp_file)
402 gradle_args.append('-Pupdate_test_timestamp=' + timestamp_file)
Morten Krogh-Jespersendcb8d452020-07-09 15:07:50 +0200403 print_stacks_timeout = (print_stacks_timeout
404 if print_stacks_timeout != -1
405 else TIMEOUT_HANDLER_PERIOD)
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100406 if utils.is_python3():
407 threading.Thread(
408 target=timeout_handler,
Christoffer Quist Adamsendb5b6aa2022-02-16 13:07:47 +0100409 args=(timestamp_file, print_stacks_timeout),
410 daemon=True).start()
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100411 else:
412 thread.start_new_thread(
413 timeout_handler, (timestamp_file, print_stacks_timeout,))
Ian Zerny24398bc2019-02-22 11:59:18 +0100414 rotate_test_reports()
415
Sebastien Hertze2687b62017-07-25 11:16:04 +0200416 # Now run tests on selected runtime(s).
Ian Zernybcbd6c52019-10-29 15:27:04 +0100417 if options.runtimes:
418 if options.dex_vm != 'default':
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100419 print('Unexpected runtimes and dex_vm argument: ' + options.dex_vm)
Ian Zernybcbd6c52019-10-29 15:27:04 +0100420 sys.exit(1)
421 if options.runtimes == 'empty':
422 # Set runtimes with no content will configure no runtimes.
423 gradle_args.append('-Pruntimes=')
424 elif options.runtimes == 'all':
425 # An unset runtimes will configure all runtimes
426 pass
427 else:
428 prefixes = [prefix.strip() for prefix in options.runtimes.split(':')]
429 runtimes = []
430 for prefix in prefixes:
431 matches = [ rt for rt in VALID_RUNTIMES if rt.startswith(prefix) ]
432 if len(matches) == 0:
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100433 print("Invalid runtime prefix '%s'." % prefix)
434 print("Must be just 'all', 'empty'," \
435 " or a prefix of %s" % ', '.join(VALID_RUNTIMES))
Ian Zernybcbd6c52019-10-29 15:27:04 +0100436 sys.exit(1)
437 runtimes.extend(matches)
438 gradle_args.append('-Pruntimes=%s' % ':'.join(runtimes))
439
440 return_code = gradle.RunGradle(gradle_args, throw_on_failure=False)
441 return archive_and_return(return_code, options)
442
443 # Legacy testing populates the runtimes based on dex_vm.
Mads Ager418d1ca2017-05-22 09:35:49 +0200444 vms_to_test = [options.dex_vm] if options.dex_vm != "all" else ALL_ART_VMS
Rico Wind124b2712019-02-28 13:49:25 +0100445
Rico Windf2f4c292021-04-23 07:06:13 +0200446 if options.print_times:
447 gradle_args.append('-Pprint_times=true')
Mads Ager418d1ca2017-05-22 09:35:49 +0200448 for art_vm in vms_to_test:
Ian Zerny4dfd5a52019-03-12 07:56:11 +0100449 vm_suffix = "_" + options.dex_vm_kind if art_vm != "default" else ""
Ian Zerny324d7612019-03-20 10:52:28 +0100450 runtimes = ['dex-' + art_vm]
Ian Zerny019e7782021-04-20 15:34:01 +0200451 # Append the "none" runtime and default JVM if running the "default" DEX VM.
Ian Zerny324d7612019-03-20 10:52:28 +0100452 if art_vm == "default":
Morten Krogh-Jespersen69358942020-10-09 11:07:09 +0200453 runtimes.extend(['jdk11', 'none'])
Ian Zerny4dfd5a52019-03-12 07:56:11 +0100454 return_code = gradle.RunGradle(
455 gradle_args + [
456 '-Pdex_vm=%s' % art_vm + vm_suffix,
Ian Zerny324d7612019-03-20 10:52:28 +0100457 '-Pruntimes=%s' % ':'.join(runtimes),
458 ],
Ian Zerny4dfd5a52019-03-12 07:56:11 +0100459 throw_on_failure=False)
Jean-Marie Henaff7a64eec2018-05-31 15:30:35 +0200460 if options.generate_golden_files_to:
461 sha1 = '%s' % utils.get_HEAD_sha1()
462 with utils.ChangedWorkingDirectory(options.generate_golden_files_to):
463 archive = utils.create_archive(sha1)
464 utils.upload_file_to_cloud_storage(archive,
465 'gs://r8-test-results/golden-files/' + archive)
466
Rico Winda94f01c2017-06-27 10:32:34 +0200467 if return_code != 0:
Ian Zerny17561362019-05-27 15:16:26 +0200468 return archive_and_return(return_code, options)
Mads Ager418d1ca2017-05-22 09:35:49 +0200469
Jinseong Jeon9749d172017-09-19 00:25:01 -0700470 return 0
471
Rico Windda6836e2018-12-07 12:32:03 +0100472
Ian Zerny17561362019-05-27 15:16:26 +0200473def archive_and_return(return_code, options):
Rico Windc58a20e2019-05-23 09:43:19 +0200474 if return_code != 0:
Rico Windef7420c2021-10-14 13:16:01 +0200475 if options.archive_failures:
Morten Krogh-Jespersenef978ff2021-10-11 12:44:00 +0200476 archive_failures(options)
Rico Windc58a20e2019-05-23 09:43:19 +0200477 return return_code
478
Rico Windda6836e2018-12-07 12:32:03 +0100479def print_jstacks():
Rico Wind5a3dc122022-03-29 08:56:00 +0200480 processes = subprocess.check_output(['ps', 'aux']).decode('utf-8')
Rico Windda6836e2018-12-07 12:32:03 +0100481 for l in processes.splitlines():
Rico Wind274bb8a2021-11-03 12:39:27 +0100482 if 'art' in l or 'dalvik' in l:
483 print('Running art of dalvik process: \n%s' % l)
Rico Windda6836e2018-12-07 12:32:03 +0100484 if 'java' in l and 'openjdk' in l:
Rico Wind274bb8a2021-11-03 12:39:27 +0100485 print('Running jstack on process: \n%s' % l)
Rico Windda6836e2018-12-07 12:32:03 +0100486 # Example line:
487 # ricow 184313 2.6 0.0 36839068 31808 ? Sl 09:53 0:00 /us..
488 columns = l.split()
489 pid = columns[1]
490 return_value = subprocess.call(['jstack', pid])
491 if return_value:
492 print('Could not jstack %s' % l)
Rico Windda6836e2018-12-07 12:32:03 +0100493
494def get_time_from_file(timestamp_file):
495 if os.path.exists(timestamp_file):
496 timestamp = os.stat(timestamp_file).st_mtime
497 print('TIMEOUT HANDLER timestamp: %s' % (timestamp))
Rico Windda6836e2018-12-07 12:32:03 +0100498 sys.stdout.flush()
499 return timestamp
500 else:
501 print('TIMEOUT HANDLER no timestamp file yet')
Rico Windda6836e2018-12-07 12:32:03 +0100502 sys.stdout.flush()
503 return None
504
Morten Krogh-Jespersendcb8d452020-07-09 15:07:50 +0200505def timeout_handler(timestamp_file, timeout_handler_period):
Rico Windda6836e2018-12-07 12:32:03 +0100506 last_timestamp = None
507 while True:
Morten Krogh-Jespersendcb8d452020-07-09 15:07:50 +0200508 time.sleep(timeout_handler_period)
Rico Windda6836e2018-12-07 12:32:03 +0100509 new_timestamp = get_time_from_file(timestamp_file)
510 if last_timestamp and new_timestamp == last_timestamp:
511 print_jstacks()
512 last_timestamp = new_timestamp
513
Ian Zerny24398bc2019-02-22 11:59:18 +0100514def report_dir_path(index):
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100515 if index == 0:
Ian Zerny24398bc2019-02-22 11:59:18 +0100516 return REPORTS_PATH
517 return '%s%d' % (REPORTS_PATH, index)
518
519def report_index_path(index):
520 return os.path.join(report_dir_path(index), *REPORT_INDEX)
521
522# Rotate test results so previous results are still accessible.
523def rotate_test_reports():
524 if not os.path.exists(report_dir_path(0)):
525 return
526 i = 1
527 while i < NUMBER_OF_TEST_REPORTS and os.path.exists(report_dir_path(i)):
528 i += 1
529 if i == NUMBER_OF_TEST_REPORTS and os.path.exists(report_dir_path(i)):
530 shutil.rmtree(report_dir_path(i))
531 while i > 0:
532 shutil.move(report_dir_path(i - 1), report_dir_path(i))
533 i -= 1
534
535def compute_failed_tests(args):
536 if len(args) > 1:
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100537 print("Running with --failed can take an optional path to a report index (or report number).")
Ian Zerny24398bc2019-02-22 11:59:18 +0100538 return None
539 report = report_index_path(0)
540 # If the default report does not exist, fall back to the previous report as it may be a failed
541 # gradle run which has already moved the report to report1, but did not produce a new report.
542 if not os.path.exists(report):
543 report1 = report_index_path(1)
544 if os.path.exists(report1):
545 report = report1
546 if len(args) == 1:
547 try:
548 # try to parse the arg as a report index.
549 index = int(args[0])
550 report = report_index_path(index)
551 except ValueError:
552 # if integer parsing failed assume it is a report file path.
553 report = args[0]
554 if not os.path.exists(report):
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100555 print("Can't re-run failing, no report at:", report)
Ian Zerny24398bc2019-02-22 11:59:18 +0100556 return None
Christoffer Quist Adamsen6962b1f2022-02-16 12:01:07 +0100557 print("Reading failed tests in", report)
Ian Zerny24398bc2019-02-22 11:59:18 +0100558 failing = set()
559 inFailedSection = False
Rico Wind34e63c82022-04-21 14:40:38 +0200560 for line in open(report):
Ian Zerny24398bc2019-02-22 11:59:18 +0100561 l = line.strip()
562 if l == "<h2>Failed tests</h2>":
563 inFailedSection = True
564 elif l.startswith("<h2>"):
565 inFailedSection = False
566 prefix = '<a href="classes/'
567 if inFailedSection and l.startswith(prefix):
568 href = l[len(prefix):l.index('">')]
569 # Ignore enties ending with .html which are test classes, not test methods.
570 if not href.endswith('.html'):
571 # Remove the .html and anchor separateor, also, a classMethod test is the static
572 # setup failing so rerun the full class of tests.
573 test = href.replace('.html','').replace('#', '.').replace('.classMethod', '')
574 failing.add(test)
575 return list(failing)
Mads Ager418d1ca2017-05-22 09:35:49 +0200576if __name__ == '__main__':
Stephan Herhutd24b1b72017-08-24 15:09:36 +0200577 return_code = Main()
578 if return_code != 0:
579 notify.notify("Tests failed.")
580 else:
581 notify.notify("Tests passed.")
582 sys.exit(return_code)