xref: /aosp_15_r20/art/test/run-test (revision 795d594fd825385562da6b089ea9b2033f3abf5a)
1*795d594fSAndroid Build Coastguard Worker#!/usr/bin/env python3
2*795d594fSAndroid Build Coastguard Worker#
3*795d594fSAndroid Build Coastguard Worker# Copyright (C) 2007 The Android Open Source Project
4*795d594fSAndroid Build Coastguard Worker#
5*795d594fSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License");
6*795d594fSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License.
7*795d594fSAndroid Build Coastguard Worker# You may obtain a copy of the License at
8*795d594fSAndroid Build Coastguard Worker#
9*795d594fSAndroid Build Coastguard Worker#     http://www.apache.org/licenses/LICENSE-2.0
10*795d594fSAndroid Build Coastguard Worker#
11*795d594fSAndroid Build Coastguard Worker# Unless required by applicable law or agreed to in writing, software
12*795d594fSAndroid Build Coastguard Worker# distributed under the License is distributed on an "AS IS" BASIS,
13*795d594fSAndroid Build Coastguard Worker# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*795d594fSAndroid Build Coastguard Worker# See the License for the specific language governing permissions and
15*795d594fSAndroid Build Coastguard Worker# limitations under the License.
16*795d594fSAndroid Build Coastguard Worker
17*795d594fSAndroid Build Coastguard Workerimport os, sys, glob, re, shutil, subprocess, shlex, resource, atexit
18*795d594fSAndroid Build Coastguard Workerimport urllib.parse
19*795d594fSAndroid Build Coastguard Worker
20*795d594fSAndroid Build Coastguard Workerimport default_run as default_run_module
21*795d594fSAndroid Build Coastguard Worker
22*795d594fSAndroid Build Coastguard Workerfrom argparse import ArgumentParser, BooleanOptionalAction
23*795d594fSAndroid Build Coastguard Workerfrom default_run import get_target_arch
24*795d594fSAndroid Build Coastguard Workerfrom fcntl import lockf, LOCK_EX, LOCK_NB
25*795d594fSAndroid Build Coastguard Workerfrom hashlib import sha1
26*795d594fSAndroid Build Coastguard Workerfrom importlib.machinery import SourceFileLoader
27*795d594fSAndroid Build Coastguard Workerfrom inspect import currentframe, getframeinfo, FrameInfo
28*795d594fSAndroid Build Coastguard Workerfrom pathlib import Path
29*795d594fSAndroid Build Coastguard Workerfrom pprint import pprint
30*795d594fSAndroid Build Coastguard Workerfrom shutil import copyfile, copytree
31*795d594fSAndroid Build Coastguard Workerfrom testrunner import env
32*795d594fSAndroid Build Coastguard Workerfrom typing import Optional, Dict, List
33*795d594fSAndroid Build Coastguard Workerfrom zipfile import ZipFile
34*795d594fSAndroid Build Coastguard Worker
35*795d594fSAndroid Build Coastguard WorkerCOLOR = (os.environ.get("LUCI_CONTEXT") == None)  # Disable colors on LUCI.
36*795d594fSAndroid Build Coastguard WorkerCOLOR_BLUE = '\033[94m' if COLOR else ''
37*795d594fSAndroid Build Coastguard WorkerCOLOR_GREEN = '\033[92m' if COLOR else ''
38*795d594fSAndroid Build Coastguard WorkerCOLOR_NORMAL = '\033[0m' if COLOR else ''
39*795d594fSAndroid Build Coastguard WorkerCOLOR_RED = '\033[91m' if COLOR else ''
40*795d594fSAndroid Build Coastguard Worker
41*795d594fSAndroid Build Coastguard Worker# Helper class which allows us to access the environment using syntax sugar.
42*795d594fSAndroid Build Coastguard Worker# E.g. `env.ANDROID_BUILD_TOP` instead of `os.environ["ANDROID_BUILD_TOP"]`.
43*795d594fSAndroid Build Coastguard Workerclass Environment:
44*795d594fSAndroid Build Coastguard Worker
45*795d594fSAndroid Build Coastguard Worker  def __getattr__(self, name):
46*795d594fSAndroid Build Coastguard Worker    return os.environ.get(name)
47*795d594fSAndroid Build Coastguard Worker
48*795d594fSAndroid Build Coastguard Worker  def __setattr__(self, name, value):
49*795d594fSAndroid Build Coastguard Worker    os.environ[name] = str(value)
50*795d594fSAndroid Build Coastguard Worker
51*795d594fSAndroid Build Coastguard Worker
52*795d594fSAndroid Build Coastguard Worker# Context passed to individual tests to let them customize the behaviour.
53*795d594fSAndroid Build Coastguard Workerclass RunTestContext:
54*795d594fSAndroid Build Coastguard Worker
55*795d594fSAndroid Build Coastguard Worker  def __init__(self, tmp_dir: Path, target: bool, chroot, dex_location, test_name) -> None:
56*795d594fSAndroid Build Coastguard Worker    self.env = Environment()
57*795d594fSAndroid Build Coastguard Worker    self.target = target
58*795d594fSAndroid Build Coastguard Worker    self.chroot = chroot
59*795d594fSAndroid Build Coastguard Worker    self.dex_location = dex_location
60*795d594fSAndroid Build Coastguard Worker    self.test_name = test_name
61*795d594fSAndroid Build Coastguard Worker
62*795d594fSAndroid Build Coastguard Worker    # Note: The expected path can be modified by the tests.
63*795d594fSAndroid Build Coastguard Worker    self.expected_stdout = tmp_dir / "expected-stdout.txt"
64*795d594fSAndroid Build Coastguard Worker    self.expected_stderr = tmp_dir / "expected-stderr.txt"
65*795d594fSAndroid Build Coastguard Worker
66*795d594fSAndroid Build Coastguard Worker    self.runner: List[str] = ["#!/bin/bash"]
67*795d594fSAndroid Build Coastguard Worker
68*795d594fSAndroid Build Coastguard Worker  def echo(self, text):
69*795d594fSAndroid Build Coastguard Worker    self.run(f"echo {text} > {test_stdout}")
70*795d594fSAndroid Build Coastguard Worker
71*795d594fSAndroid Build Coastguard Worker  def export(self, **env: str) -> None:
72*795d594fSAndroid Build Coastguard Worker    self.runner.append("")
73*795d594fSAndroid Build Coastguard Worker    for name, value in env.items():
74*795d594fSAndroid Build Coastguard Worker      self.runner.append(f"export {name}={value}")
75*795d594fSAndroid Build Coastguard Worker
76*795d594fSAndroid Build Coastguard Worker  # Add "runner" script command. It is not executed now.
77*795d594fSAndroid Build Coastguard Worker  # All "runner" commands are executed later via single bash call.
78*795d594fSAndroid Build Coastguard Worker  def run(self, cmd: str, check: bool=True, expected_exit_code: int=0, desc:str = None) -> None:
79*795d594fSAndroid Build Coastguard Worker    if cmd == "true":
80*795d594fSAndroid Build Coastguard Worker      return
81*795d594fSAndroid Build Coastguard Worker    cmd_esc = cmd.replace("'", r"'\''")
82*795d594fSAndroid Build Coastguard Worker    self.runner.append("")
83*795d594fSAndroid Build Coastguard Worker    self.runner.append(f"echo '{COLOR_BLUE}$$ {cmd_esc}{COLOR_NORMAL}'")
84*795d594fSAndroid Build Coastguard Worker    self.runner.append(cmd)
85*795d594fSAndroid Build Coastguard Worker
86*795d594fSAndroid Build Coastguard Worker    # Check the exit code.
87*795d594fSAndroid Build Coastguard Worker    if check:
88*795d594fSAndroid Build Coastguard Worker      caller = getframeinfo(currentframe().f_back)  # type: ignore
89*795d594fSAndroid Build Coastguard Worker      source = "{}:{}".format(Path(caller.filename).name, caller.lineno)
90*795d594fSAndroid Build Coastguard Worker      msg = f"{self.test_name} FAILED: [{source}] "
91*795d594fSAndroid Build Coastguard Worker      msg += "{} returned exit code ${{exit_code}}.".format(desc or "Command")
92*795d594fSAndroid Build Coastguard Worker      if expected_exit_code:
93*795d594fSAndroid Build Coastguard Worker        msg += f" Expected {expected_exit_code}."
94*795d594fSAndroid Build Coastguard Worker      self.runner.append(
95*795d594fSAndroid Build Coastguard Worker        f"exit_code=$?; if [ $exit_code -ne {expected_exit_code} ]; then "
96*795d594fSAndroid Build Coastguard Worker        f"echo {COLOR_RED}{msg}{COLOR_NORMAL}; exit 100; "
97*795d594fSAndroid Build Coastguard Worker        f"fi; ")
98*795d594fSAndroid Build Coastguard Worker    else:
99*795d594fSAndroid Build Coastguard Worker      self.runner.append("true; # Ignore previous exit code")
100*795d594fSAndroid Build Coastguard Worker
101*795d594fSAndroid Build Coastguard Worker  # Execute the default runner (possibly with modified arguments).
102*795d594fSAndroid Build Coastguard Worker  def default_run(self, args, **kwargs):
103*795d594fSAndroid Build Coastguard Worker    default_run_module.default_run(self, args, **kwargs)
104*795d594fSAndroid Build Coastguard Worker
105*795d594fSAndroid Build Coastguard Worker# Make unique temporary directory guarded by lock file.
106*795d594fSAndroid Build Coastguard Worker# The name is deterministic (appending suffix as needed).
107*795d594fSAndroid Build Coastguard Workerdef make_tmp_dir():
108*795d594fSAndroid Build Coastguard Worker  parent = Path(os.environ.get("TMPDIR", "/tmp")) / "art" / "test"
109*795d594fSAndroid Build Coastguard Worker  parent.mkdir(parents=True, exist_ok=True)
110*795d594fSAndroid Build Coastguard Worker  args = [a for a in sys.argv[1:] if not a.startswith("--create-runner")]
111*795d594fSAndroid Build Coastguard Worker  hash = sha1((" ".join(args)).encode()).hexdigest()
112*795d594fSAndroid Build Coastguard Worker  for i in range(100):
113*795d594fSAndroid Build Coastguard Worker    tmp_dir = parent / (f"{hash[:8]}" + (f"-{i}" if i > 0 else ""))
114*795d594fSAndroid Build Coastguard Worker    lock = tmp_dir.with_suffix(".lock")  # NB: Next to the directory, not inside.
115*795d594fSAndroid Build Coastguard Worker    lock_handle = open(lock, "w")
116*795d594fSAndroid Build Coastguard Worker    try:
117*795d594fSAndroid Build Coastguard Worker      lockf(lock_handle, LOCK_EX | LOCK_NB)
118*795d594fSAndroid Build Coastguard Worker      tmp_dir.mkdir(exist_ok=True)
119*795d594fSAndroid Build Coastguard Worker      return str(tmp_dir), lock, lock_handle
120*795d594fSAndroid Build Coastguard Worker    except BlockingIOError:
121*795d594fSAndroid Build Coastguard Worker      continue
122*795d594fSAndroid Build Coastguard Worker  assert False, "Failed to create test directory"
123*795d594fSAndroid Build Coastguard Worker
124*795d594fSAndroid Build Coastguard Worker# TODO: Replace with 'def main():' (which might change variables from globals to locals)
125*795d594fSAndroid Build Coastguard Workerif True:
126*795d594fSAndroid Build Coastguard Worker  progdir = os.path.dirname(__file__)
127*795d594fSAndroid Build Coastguard Worker  oldwd = os.getcwd()
128*795d594fSAndroid Build Coastguard Worker  os.chdir(progdir)
129*795d594fSAndroid Build Coastguard Worker  PYTHON3 = os.environ.get("PYTHON3")
130*795d594fSAndroid Build Coastguard Worker  tmp_dir, tmp_dir_lock, tmp_dir_lock_handle = make_tmp_dir()
131*795d594fSAndroid Build Coastguard Worker  test_dir = Path(tmp_dir).name
132*795d594fSAndroid Build Coastguard Worker  checker = f"{progdir}/../tools/checker/checker.py"
133*795d594fSAndroid Build Coastguard Worker
134*795d594fSAndroid Build Coastguard Worker  ON_VM = env.ART_TEST_ON_VM
135*795d594fSAndroid Build Coastguard Worker  SSH_USER = env.ART_TEST_SSH_USER
136*795d594fSAndroid Build Coastguard Worker  SSH_HOST = env.ART_TEST_SSH_HOST
137*795d594fSAndroid Build Coastguard Worker  SSH_PORT = env.ART_TEST_SSH_PORT
138*795d594fSAndroid Build Coastguard Worker  SSH_CMD = env.ART_SSH_CMD
139*795d594fSAndroid Build Coastguard Worker  SCP_CMD = env.ART_SCP_CMD
140*795d594fSAndroid Build Coastguard Worker  CHROOT = env.ART_TEST_CHROOT
141*795d594fSAndroid Build Coastguard Worker  CHROOT_CMD = env.ART_CHROOT_CMD
142*795d594fSAndroid Build Coastguard Worker
143*795d594fSAndroid Build Coastguard Worker  def fail(message: str, caller:Optional[FrameInfo]=None):
144*795d594fSAndroid Build Coastguard Worker    caller = caller or getframeinfo(currentframe().f_back)  # type: ignore
145*795d594fSAndroid Build Coastguard Worker    assert caller
146*795d594fSAndroid Build Coastguard Worker    source = "{}:{}".format(Path(caller.filename).name, caller.lineno)
147*795d594fSAndroid Build Coastguard Worker    print(f"{COLOR_RED}{TEST_NAME} FAILED: [{source}] {message}{COLOR_NORMAL}",
148*795d594fSAndroid Build Coastguard Worker          file=sys.stderr)
149*795d594fSAndroid Build Coastguard Worker    sys.exit(1)
150*795d594fSAndroid Build Coastguard Worker
151*795d594fSAndroid Build Coastguard Worker  def run(cmdline: str, check=True, fail_message=None) -> subprocess.CompletedProcess:
152*795d594fSAndroid Build Coastguard Worker    print(f"{COLOR_BLUE}$ {cmdline}{COLOR_NORMAL}", flush=True)
153*795d594fSAndroid Build Coastguard Worker    proc = subprocess.run([cmdline],
154*795d594fSAndroid Build Coastguard Worker                          shell=True,
155*795d594fSAndroid Build Coastguard Worker                          executable="/bin/bash",
156*795d594fSAndroid Build Coastguard Worker                          stderr=subprocess.STDOUT)
157*795d594fSAndroid Build Coastguard Worker    if (check and proc.returncode != 0):
158*795d594fSAndroid Build Coastguard Worker      if fail_message:
159*795d594fSAndroid Build Coastguard Worker        # If we have custom fail message, exit without printing the full backtrace.
160*795d594fSAndroid Build Coastguard Worker        fail(fail_message, getframeinfo(currentframe().f_back))  # type: ignore
161*795d594fSAndroid Build Coastguard Worker      raise Exception(f"Command failed (exit code {proc.returncode})")
162*795d594fSAndroid Build Coastguard Worker    return proc
163*795d594fSAndroid Build Coastguard Worker
164*795d594fSAndroid Build Coastguard Worker  def export(env: str, value: str) -> None:
165*795d594fSAndroid Build Coastguard Worker    os.environ[env] = value
166*795d594fSAndroid Build Coastguard Worker    globals()[env] = value
167*795d594fSAndroid Build Coastguard Worker
168*795d594fSAndroid Build Coastguard Worker  def error(msg) -> None:
169*795d594fSAndroid Build Coastguard Worker    print(msg, file=sys.stderr, flush=True)
170*795d594fSAndroid Build Coastguard Worker
171*795d594fSAndroid Build Coastguard Worker  # ANDROID_BUILD_TOP is not set in a build environment.
172*795d594fSAndroid Build Coastguard Worker  ANDROID_BUILD_TOP = os.environ.get("ANDROID_BUILD_TOP")
173*795d594fSAndroid Build Coastguard Worker  if not ANDROID_BUILD_TOP:
174*795d594fSAndroid Build Coastguard Worker    export("ANDROID_BUILD_TOP", oldwd)
175*795d594fSAndroid Build Coastguard Worker
176*795d594fSAndroid Build Coastguard Worker  export("JAVA", "java")
177*795d594fSAndroid Build Coastguard Worker  export("JAVAC", "javac -g -Xlint:-options -source 1.8 -target 1.8")
178*795d594fSAndroid Build Coastguard Worker  export("PYTHON3",
179*795d594fSAndroid Build Coastguard Worker         f"{ANDROID_BUILD_TOP}/prebuilts/build-tools/path/linux-x86/python3")
180*795d594fSAndroid Build Coastguard Worker  export("RUN", f"{PYTHON3} {progdir}/etc/run-test-jar")
181*795d594fSAndroid Build Coastguard Worker  if env.ART_TEST_RUN_FROM_SOONG:
182*795d594fSAndroid Build Coastguard Worker    export("DEX_LOCATION", f"/data/local/tmp/art/test/{test_dir}")
183*795d594fSAndroid Build Coastguard Worker  else:
184*795d594fSAndroid Build Coastguard Worker    export("DEX_LOCATION", f"/data/run-test/{test_dir}")
185*795d594fSAndroid Build Coastguard Worker
186*795d594fSAndroid Build Coastguard Worker  # OUT_DIR defaults to out, and may be relative to ANDROID_BUILD_TOP.
187*795d594fSAndroid Build Coastguard Worker  # Convert it to an absolute path, since we cd into the tmp_dir to run the tests.
188*795d594fSAndroid Build Coastguard Worker  OUT_DIR = os.environ.get("OUT_DIR", "")
189*795d594fSAndroid Build Coastguard Worker  export("OUT_DIR", OUT_DIR or "out")
190*795d594fSAndroid Build Coastguard Worker  if not OUT_DIR.startswith("/"):
191*795d594fSAndroid Build Coastguard Worker    export("OUT_DIR", f"{ANDROID_BUILD_TOP}/{OUT_DIR}")
192*795d594fSAndroid Build Coastguard Worker
193*795d594fSAndroid Build Coastguard Worker# ANDROID_HOST_OUT is not set in a build environment.
194*795d594fSAndroid Build Coastguard Worker  ANDROID_HOST_OUT = os.environ.get("ANDROID_HOST_OUT")
195*795d594fSAndroid Build Coastguard Worker  if not ANDROID_HOST_OUT:
196*795d594fSAndroid Build Coastguard Worker    export("ANDROID_HOST_OUT", f"{OUT_DIR}/host/linux-x86")
197*795d594fSAndroid Build Coastguard Worker
198*795d594fSAndroid Build Coastguard Worker  info = "info.txt"
199*795d594fSAndroid Build Coastguard Worker  run_cmd = "run"
200*795d594fSAndroid Build Coastguard Worker  test_stdout = "test-stdout.txt"
201*795d594fSAndroid Build Coastguard Worker  test_stderr = "test-stderr.txt"
202*795d594fSAndroid Build Coastguard Worker  cfg_output = "graph.cfg"
203*795d594fSAndroid Build Coastguard Worker  run_checker = False
204*795d594fSAndroid Build Coastguard Worker  debug_mode = False
205*795d594fSAndroid Build Coastguard Worker  # To cause tests to fail fast, limit the file sizes created by dx, dex2oat and
206*795d594fSAndroid Build Coastguard Worker  # ART output to approximately 128MB. This should be more than sufficient
207*795d594fSAndroid Build Coastguard Worker  # for any test while still catching cases of runaway output.
208*795d594fSAndroid Build Coastguard Worker  # Set a hard limit to encourage ART developers to increase the ulimit here if
209*795d594fSAndroid Build Coastguard Worker  # needed to support a test case rather than resetting the limit in the run
210*795d594fSAndroid Build Coastguard Worker  # script for the particular test in question. Adjust this if needed for
211*795d594fSAndroid Build Coastguard Worker  # particular configurations.
212*795d594fSAndroid Build Coastguard Worker  file_ulimit = 128000
213*795d594fSAndroid Build Coastguard Worker
214*795d594fSAndroid Build Coastguard Worker  argp, opt_bool = ArgumentParser(), BooleanOptionalAction
215*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--O", action='store_true',
216*795d594fSAndroid Build Coastguard Worker                    help="Run non-debug rather than debug build (off by default).")
217*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--Xcompiler-option", type=str, action='append', default=[],
218*795d594fSAndroid Build Coastguard Worker                    help="Pass an option to the compiler.")
219*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--runtime-option", type=str, action='append', default=[],
220*795d594fSAndroid Build Coastguard Worker                    help="Pass an option to the runtime.")
221*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--debug", action='store_true',
222*795d594fSAndroid Build Coastguard Worker                    help="Wait for the default debugger to attach.")
223*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--debug-agent", type=str,
224*795d594fSAndroid Build Coastguard Worker                    help="Wait for the given debugger agent to attach. Currently "
225*795d594fSAndroid Build Coastguard Worker                         "only supported on host.")
226*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--debug-wrap-agent", action='store_true',
227*795d594fSAndroid Build Coastguard Worker                    help="use libwrapagentproperties and tools/libjdwp-compat.props "
228*795d594fSAndroid Build Coastguard Worker                         "to load the debugger agent specified by --debug-agent.")
229*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--with-agent", type=str, action='append', default=[],
230*795d594fSAndroid Build Coastguard Worker                    help="Run the test with the given agent loaded with -agentpath:")
231*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--debuggable", action='store_true',
232*795d594fSAndroid Build Coastguard Worker                    help="Whether to compile Java code for a debugger.")
233*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gdb", action='store_true',
234*795d594fSAndroid Build Coastguard Worker                    help="Run under gdb; incompatible with some tests.")
235*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gdb-dex2oat", action='store_true',
236*795d594fSAndroid Build Coastguard Worker                    help="Run dex2oat under the prebuilt gdb.")
237*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gdbserver", action='store_true',
238*795d594fSAndroid Build Coastguard Worker                    help="Start gdbserver (defaults to port :5039).")
239*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gdbserver-port", type=str,
240*795d594fSAndroid Build Coastguard Worker                    help="Start gdbserver with the given COMM (see man gdbserver).")
241*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gdbserver-bin", type=str,
242*795d594fSAndroid Build Coastguard Worker                    help="Use the given binary as gdbserver.")
243*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gdb-arg", type=str, action='append', default=[],
244*795d594fSAndroid Build Coastguard Worker                    help="Pass an option to gdb or gdbserver.")
245*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gdb-dex2oat-args", type=str,
246*795d594fSAndroid Build Coastguard Worker                    help="Pass options separated by ';' to gdb for dex2oat.")
247*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--simpleperf", action='store_true',
248*795d594fSAndroid Build Coastguard Worker                    help="Wraps the dalvikvm invocation in 'simpleperf record "
249*795d594fSAndroid Build Coastguard Worker                         "and dumps stats to stdout.")
250*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--interpreter", action='store_true',
251*795d594fSAndroid Build Coastguard Worker                    help="Enable interpreter only mode (off by default).")
252*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--jit", action='store_true',
253*795d594fSAndroid Build Coastguard Worker                    help="Enable jit (off by default).")
254*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--optimizing", action='store_true',
255*795d594fSAndroid Build Coastguard Worker                    help="Enable optimizing compiler (default).")
256*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--baseline", action='store_true',
257*795d594fSAndroid Build Coastguard Worker                    help="Enable baseline compiler.")
258*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--no-verify", action='store_true',
259*795d594fSAndroid Build Coastguard Worker                    help="Turn off verification (on by default).")
260*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--verify-soft-fail", action='store_true',
261*795d594fSAndroid Build Coastguard Worker                    help="Force soft fail verification (off by default). "
262*795d594fSAndroid Build Coastguard Worker                         "Verification is enabled if neither --no-verify "
263*795d594fSAndroid Build Coastguard Worker                         "nor --verify-soft-fail is specified.")
264*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--no-optimize", action='store_true',
265*795d594fSAndroid Build Coastguard Worker                    help="Turn off optimization (on by default).")
266*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--no-precise", action='store_true',
267*795d594fSAndroid Build Coastguard Worker                    help="Turn off precise GC (on by default).")
268*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--zygote", action='store_true',
269*795d594fSAndroid Build Coastguard Worker                    help="Spawn the process from the Zygote. "
270*795d594fSAndroid Build Coastguard Worker                         "If used, then the other runtime options are ignored.")
271*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--prebuild", action='store_true',
272*795d594fSAndroid Build Coastguard Worker                    help="Run dex2oat on the files before starting test. (default)")
273*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--no-prebuild", action='store_true',
274*795d594fSAndroid Build Coastguard Worker                    help="Do not run dex2oat on the files before starting the test.")
275*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--strip-dex", action='store_true',
276*795d594fSAndroid Build Coastguard Worker                    help="Strip the dex files before starting test.")
277*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--relocate", action='store_true',
278*795d594fSAndroid Build Coastguard Worker                    help="Force the use of relocating in the test, making "
279*795d594fSAndroid Build Coastguard Worker                         "the image and oat files be relocated to a random address before running.")
280*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--no-relocate", action='store_true',
281*795d594fSAndroid Build Coastguard Worker                    help="Force the use of no relocating in the test. (default)")
282*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--image", type=str,
283*795d594fSAndroid Build Coastguard Worker                    help="Run the test using a precompiled boot image. (default)")
284*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--no-image", action='store_true',
285*795d594fSAndroid Build Coastguard Worker                    help="Run the test without a precompiled boot image.")
286*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--host", action='store_true',
287*795d594fSAndroid Build Coastguard Worker                    help="Use the host-mode virtual machine.")
288*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--invoke-with", type=str, action='append', default=[],
289*795d594fSAndroid Build Coastguard Worker                    help="Pass --invoke-with option to runtime.")
290*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--dalvik", action='store_true',
291*795d594fSAndroid Build Coastguard Worker                    help="Use Dalvik (off by default).")
292*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--jvm", action='store_true',
293*795d594fSAndroid Build Coastguard Worker                    help="Use a host-local RI virtual machine.")
294*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--use-java-home", action='store_true',
295*795d594fSAndroid Build Coastguard Worker                    help="Use the JAVA_HOME environment variable to find the java compiler "
296*795d594fSAndroid Build Coastguard Worker                         "and runtime (if applicable) to run the test with.")
297*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--64", dest="is64bit", action='store_true',
298*795d594fSAndroid Build Coastguard Worker                    help="Run the test in 64-bit mode")
299*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--bionic", action='store_true',
300*795d594fSAndroid Build Coastguard Worker                    help="Use the (host, 64-bit only) linux_bionic libc runtime")
301*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--timeout", type=str,
302*795d594fSAndroid Build Coastguard Worker                    help="Test timeout in seconds")
303*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--trace", action='store_true',
304*795d594fSAndroid Build Coastguard Worker                    help="Run with method tracing")
305*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--strace", action='store_true',
306*795d594fSAndroid Build Coastguard Worker                    help="Run with syscall tracing from strace.")
307*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--stream", action='store_true',
308*795d594fSAndroid Build Coastguard Worker                    help="Run method tracing in streaming mode (requires --trace)")
309*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gcstress", action='store_true',
310*795d594fSAndroid Build Coastguard Worker                    help="Run with gc stress testing")
311*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--gcverify", action='store_true',
312*795d594fSAndroid Build Coastguard Worker                    help="Run with gc verification")
313*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--jvmti-trace-stress", action='store_true',
314*795d594fSAndroid Build Coastguard Worker                    help="Run with jvmti method tracing stress testing")
315*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--jvmti-step-stress", action='store_true',
316*795d594fSAndroid Build Coastguard Worker                    help="Run with jvmti single step stress testing")
317*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--jvmti-redefine-stress", action='store_true',
318*795d594fSAndroid Build Coastguard Worker                    help="Run with jvmti method redefinition stress testing")
319*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--always-clean", action='store_true',
320*795d594fSAndroid Build Coastguard Worker                    help="Delete the test files even if the test fails.")
321*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--never-clean", action='store_true',
322*795d594fSAndroid Build Coastguard Worker                    help="Keep the test files even if the test succeeds.")
323*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--chroot", type=str,
324*795d594fSAndroid Build Coastguard Worker                    help="Run with root directory set to newroot.")
325*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--android-root", type=str,
326*795d594fSAndroid Build Coastguard Worker                    help="The path on target for the android root. (/system by default).")
327*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--android-art-root", type=str,
328*795d594fSAndroid Build Coastguard Worker                    help="The path on target for the ART module root. "
329*795d594fSAndroid Build Coastguard Worker                         "(/apex/com.android.art by default).")
330*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--android-tzdata-root", type=str,
331*795d594fSAndroid Build Coastguard Worker                    help="The path on target for the Android Time Zone Data root. "
332*795d594fSAndroid Build Coastguard Worker                         "(/apex/com.android.tzdata by default).")
333*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--android-i18n-root", type=str,
334*795d594fSAndroid Build Coastguard Worker                    help="The path on target for the i18n module root. "
335*795d594fSAndroid Build Coastguard Worker                         "(/apex/com.android.i18n by default)."),
336*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--dex2oat-swap", action='store_true',
337*795d594fSAndroid Build Coastguard Worker                    help="Use a dex2oat swap file.")
338*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--instruction-set-features", type=str,
339*795d594fSAndroid Build Coastguard Worker                    help="Set instruction-set-features for compilation.")
340*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--quiet", action='store_true',
341*795d594fSAndroid Build Coastguard Worker                    help="Don't print anything except failure messages")
342*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--external-log-tags", action='store_true',
343*795d594fSAndroid Build Coastguard Worker                    help="Deprecated. Use --android-log-tags instead.")
344*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--android-log-tags", type=str,
345*795d594fSAndroid Build Coastguard Worker                    help="Custom logging level for a test run.")
346*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--suspend-timeout", type=str,
347*795d594fSAndroid Build Coastguard Worker                    help="Change thread suspend timeout ms (default 500000).")
348*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--switch-interpreter", action='store_true')
349*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--jvmti-field-stress", action='store_true',
350*795d594fSAndroid Build Coastguard Worker                    help="Run with jvmti method field stress testing")
351*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--vdex", action='store_true',
352*795d594fSAndroid Build Coastguard Worker                    help="Test using vdex as in input to dex2oat. Only works with --prebuild.")
353*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--dm", action='store_true'),
354*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--vdex-filter", type=str)
355*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--random-profile", action='store_true')
356*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--dex2oat-jobs", type=int,
357*795d594fSAndroid Build Coastguard Worker                    help="Number of dex2oat jobs.")
358*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--create-runner", type=Path, metavar='output_dir',
359*795d594fSAndroid Build Coastguard Worker                    help="Creates a runner script for use with other tools.")
360*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--dev", action='store_true',
361*795d594fSAndroid Build Coastguard Worker                    help="Development mode (dumps to stdout).")
362*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--update", action='store_true',
363*795d594fSAndroid Build Coastguard Worker                    help="Update mode (replaces expected-stdout.txt and expected-stderr.txt).")
364*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--dump-cfg", type=str,
365*795d594fSAndroid Build Coastguard Worker                    help="Dump the CFG to the specified path.")
366*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--bisection-search", action='store_true',
367*795d594fSAndroid Build Coastguard Worker                    help="Perform bisection bug search.")
368*795d594fSAndroid Build Coastguard Worker  argp.add_argument("--temp-path", type=str,
369*795d594fSAndroid Build Coastguard Worker                    help="Location where to execute the tests.")
370*795d594fSAndroid Build Coastguard Worker  argp.add_argument("test_name", nargs="?", default='-', type=str,
371*795d594fSAndroid Build Coastguard Worker                    help="Name of the test to run.")
372*795d594fSAndroid Build Coastguard Worker  argp.add_argument("test_args", nargs="*", default=None,
373*795d594fSAndroid Build Coastguard Worker                    help="Arguments to be passed to the test directly.")
374*795d594fSAndroid Build Coastguard Worker
375*795d594fSAndroid Build Coastguard Worker  # Python parser requires the format --key=--value, since without the equals symbol
376*795d594fSAndroid Build Coastguard Worker  # it looks like the required value has been omitted and there is just another flag.
377*795d594fSAndroid Build Coastguard Worker  # For example, '--Xcompiler-option --debuggable' will become '--Xcompiler-option=--debuggable'
378*795d594fSAndroid Build Coastguard Worker  # because otherwise the --Xcompiler-option is missing value and --debuggable is unknown argument.
379*795d594fSAndroid Build Coastguard Worker  argv = list(sys.argv[1:])
380*795d594fSAndroid Build Coastguard Worker  for i, arg in reversed(list(enumerate(argv))):
381*795d594fSAndroid Build Coastguard Worker    if arg in ["--runtime-option", "-Xcompiler-option"]:
382*795d594fSAndroid Build Coastguard Worker      argv[i] += "=" + argv.pop(i + 1)
383*795d594fSAndroid Build Coastguard Worker
384*795d594fSAndroid Build Coastguard Worker  # Accept single-dash arguments as if they were double-dash arguments.
385*795d594fSAndroid Build Coastguard Worker  # For example, '-Xcompiler-option' becomes '--Xcompiler-option'
386*795d594fSAndroid Build Coastguard Worker  # because single-dash can be used only with single-letter arguments.
387*795d594fSAndroid Build Coastguard Worker  for i, arg in list(enumerate(argv)):
388*795d594fSAndroid Build Coastguard Worker    if arg.startswith("-") and not arg.startswith("--"):
389*795d594fSAndroid Build Coastguard Worker      argv[i] = "-" + arg
390*795d594fSAndroid Build Coastguard Worker    if arg == "--":
391*795d594fSAndroid Build Coastguard Worker      break
392*795d594fSAndroid Build Coastguard Worker
393*795d594fSAndroid Build Coastguard Worker  args = argp.parse_args(argv)
394*795d594fSAndroid Build Coastguard Worker
395*795d594fSAndroid Build Coastguard Worker  if True:
396*795d594fSAndroid Build Coastguard Worker    run_args = []
397*795d594fSAndroid Build Coastguard Worker    target_mode = not args.host
398*795d594fSAndroid Build Coastguard Worker    if not target_mode:
399*795d594fSAndroid Build Coastguard Worker      DEX_LOCATION = tmp_dir
400*795d594fSAndroid Build Coastguard Worker      run_args += ["--host"]
401*795d594fSAndroid Build Coastguard Worker      os.environ["RUN_MODE"] = "host"
402*795d594fSAndroid Build Coastguard Worker    quiet = args.quiet
403*795d594fSAndroid Build Coastguard Worker    usage = False
404*795d594fSAndroid Build Coastguard Worker    if args.use_java_home:
405*795d594fSAndroid Build Coastguard Worker      JAVA_HOME = os.environ.get("JAVA_HOME")
406*795d594fSAndroid Build Coastguard Worker      if JAVA_HOME:
407*795d594fSAndroid Build Coastguard Worker        export("JAVA", f"{JAVA_HOME}/bin/java")
408*795d594fSAndroid Build Coastguard Worker        export("JAVAC", f"{JAVA_HOME}/bin/javac -g")
409*795d594fSAndroid Build Coastguard Worker      else:
410*795d594fSAndroid Build Coastguard Worker        error("Passed --use-java-home without JAVA_HOME variable set!")
411*795d594fSAndroid Build Coastguard Worker        usage = True
412*795d594fSAndroid Build Coastguard Worker    prebuild_mode = True
413*795d594fSAndroid Build Coastguard Worker    runtime = "art"
414*795d594fSAndroid Build Coastguard Worker    if args.jvm:
415*795d594fSAndroid Build Coastguard Worker      target_mode = False
416*795d594fSAndroid Build Coastguard Worker      DEX_LOCATION = tmp_dir
417*795d594fSAndroid Build Coastguard Worker      runtime = "jvm"
418*795d594fSAndroid Build Coastguard Worker      prebuild_mode = False
419*795d594fSAndroid Build Coastguard Worker      run_args += ["--jvm"]
420*795d594fSAndroid Build Coastguard Worker    lib = "libartd.so"
421*795d594fSAndroid Build Coastguard Worker    testlib = "arttestd"
422*795d594fSAndroid Build Coastguard Worker    if args.O:
423*795d594fSAndroid Build Coastguard Worker      lib = "libart.so"
424*795d594fSAndroid Build Coastguard Worker      testlib = "arttest"
425*795d594fSAndroid Build Coastguard Worker      run_args += ["-O"]
426*795d594fSAndroid Build Coastguard Worker    if args.dalvik:
427*795d594fSAndroid Build Coastguard Worker      lib = "libdvm.so"
428*795d594fSAndroid Build Coastguard Worker      runtime = "dalvik"
429*795d594fSAndroid Build Coastguard Worker    have_image = not args.no_image
430*795d594fSAndroid Build Coastguard Worker    relocate = args.relocate and not args.no_relocate
431*795d594fSAndroid Build Coastguard Worker    if args.prebuild:
432*795d594fSAndroid Build Coastguard Worker      run_args += ["--prebuild"]
433*795d594fSAndroid Build Coastguard Worker      prebuild_mode = True
434*795d594fSAndroid Build Coastguard Worker    if args.strip_dex:
435*795d594fSAndroid Build Coastguard Worker      run_args += ["--strip-dex"]
436*795d594fSAndroid Build Coastguard Worker    debuggable = args.debuggable
437*795d594fSAndroid Build Coastguard Worker    if debuggable:
438*795d594fSAndroid Build Coastguard Worker      run_args += ["-Xcompiler-option --debuggable"]
439*795d594fSAndroid Build Coastguard Worker    if args.no_prebuild:
440*795d594fSAndroid Build Coastguard Worker      run_args += ["--no-prebuild"]
441*795d594fSAndroid Build Coastguard Worker      prebuild_mode = False
442*795d594fSAndroid Build Coastguard Worker    basic_verify = gc_verify = args.gcverify
443*795d594fSAndroid Build Coastguard Worker    gc_stress = args.gcstress
444*795d594fSAndroid Build Coastguard Worker    if gc_stress:
445*795d594fSAndroid Build Coastguard Worker        basic_verify = True
446*795d594fSAndroid Build Coastguard Worker
447*795d594fSAndroid Build Coastguard Worker    jvmti_step_stress = args.jvmti_step_stress
448*795d594fSAndroid Build Coastguard Worker    jvmti_redefine_stress = args.jvmti_redefine_stress
449*795d594fSAndroid Build Coastguard Worker    jvmti_field_stress = args.jvmti_field_stress
450*795d594fSAndroid Build Coastguard Worker    jvmti_trace_stress = args.jvmti_trace_stress
451*795d594fSAndroid Build Coastguard Worker
452*795d594fSAndroid Build Coastguard Worker    if jvmti_step_stress:
453*795d594fSAndroid Build Coastguard Worker      os.environ["JVMTI_STEP_STRESS"] = "true"
454*795d594fSAndroid Build Coastguard Worker    if jvmti_redefine_stress:
455*795d594fSAndroid Build Coastguard Worker      os.environ["JVMTI_REDEFINE_STRESS"] = "true"
456*795d594fSAndroid Build Coastguard Worker    if jvmti_field_stress:
457*795d594fSAndroid Build Coastguard Worker      os.environ["JVMTI_FIELD_STRESS"] = "true"
458*795d594fSAndroid Build Coastguard Worker    if jvmti_trace_stress:
459*795d594fSAndroid Build Coastguard Worker      os.environ["JVMTI_TRACE_STRESS"] = "true"
460*795d594fSAndroid Build Coastguard Worker    suspend_timeout = args.suspend_timeout or "500000"
461*795d594fSAndroid Build Coastguard Worker    if args.image:
462*795d594fSAndroid Build Coastguard Worker      run_args += [f'--image "{args.image}"']
463*795d594fSAndroid Build Coastguard Worker    run_args.extend([f'-Xcompiler-option "{option}"' for option in args.Xcompiler_option])
464*795d594fSAndroid Build Coastguard Worker    run_args.extend([f'--runtime-option "{option}"' for option in args.runtime_option])
465*795d594fSAndroid Build Coastguard Worker    run_args.extend([f'--gdb-arg "{gdb_arg}"' for gdb_arg in args.gdb_arg])
466*795d594fSAndroid Build Coastguard Worker
467*795d594fSAndroid Build Coastguard Worker    if args.gdb_dex2oat_args:
468*795d594fSAndroid Build Coastguard Worker      run_args.append(f'--gdb-dex2oat-args="{args.gdb_dex2oat_args}"')
469*795d594fSAndroid Build Coastguard Worker    if args.debug:
470*795d594fSAndroid Build Coastguard Worker      run_args.append("--debug")
471*795d594fSAndroid Build Coastguard Worker    if args.debug_wrap_agent:
472*795d594fSAndroid Build Coastguard Worker      run_args.append("--debug-wrap-agent")
473*795d594fSAndroid Build Coastguard Worker    run_args.extend([f'--with-agent "{arg}"' for arg in args.with_agent])
474*795d594fSAndroid Build Coastguard Worker
475*795d594fSAndroid Build Coastguard Worker    if args.debug_agent:
476*795d594fSAndroid Build Coastguard Worker      run_args.append(f'--debug-agent "{args.debug_agent}"')
477*795d594fSAndroid Build Coastguard Worker
478*795d594fSAndroid Build Coastguard Worker    dump_cfg = bool(args.dump_cfg)
479*795d594fSAndroid Build Coastguard Worker    dump_cfg_path = args.dump_cfg or ""
480*795d594fSAndroid Build Coastguard Worker
481*795d594fSAndroid Build Coastguard Worker    dev_mode = args.gdb or args.gdb_dex2oat
482*795d594fSAndroid Build Coastguard Worker    if args.gdb:
483*795d594fSAndroid Build Coastguard Worker      run_args.append("--gdb")
484*795d594fSAndroid Build Coastguard Worker    if args.gdb_dex2oat:
485*795d594fSAndroid Build Coastguard Worker      run_args.append("--gdb-dex2oat")
486*795d594fSAndroid Build Coastguard Worker    if args.gdbserver_bin:
487*795d594fSAndroid Build Coastguard Worker      run_args.append(f'--gdbserver-bin "{args.gdbserver_bin}"')
488*795d594fSAndroid Build Coastguard Worker    if args.gdbserver_port:
489*795d594fSAndroid Build Coastguard Worker      run_args.append(f'--gdbserver-port "{args.gdbserver_port}"')
490*795d594fSAndroid Build Coastguard Worker    if args.gdbserver:
491*795d594fSAndroid Build Coastguard Worker      run_args.append("--gdbserver")
492*795d594fSAndroid Build Coastguard Worker      dev_mode = True
493*795d594fSAndroid Build Coastguard Worker    strace = args.strace
494*795d594fSAndroid Build Coastguard Worker    strace_output = "strace-output.txt"
495*795d594fSAndroid Build Coastguard Worker    timeout = ""
496*795d594fSAndroid Build Coastguard Worker    if strace:
497*795d594fSAndroid Build Coastguard Worker      run_args += [
498*795d594fSAndroid Build Coastguard Worker          f'--invoke-with=strace --invoke-with=-o --invoke-with="{tmp_dir}/{strace_output}"'
499*795d594fSAndroid Build Coastguard Worker      ]
500*795d594fSAndroid Build Coastguard Worker      timeout = timeout or "1800"
501*795d594fSAndroid Build Coastguard Worker    if args.zygote:
502*795d594fSAndroid Build Coastguard Worker      run_args += ["--zygote"]
503*795d594fSAndroid Build Coastguard Worker    if args.interpreter:
504*795d594fSAndroid Build Coastguard Worker      run_args += ["--interpreter"]
505*795d594fSAndroid Build Coastguard Worker    if args.switch_interpreter:
506*795d594fSAndroid Build Coastguard Worker      run_args += ["--switch-interpreter"]
507*795d594fSAndroid Build Coastguard Worker    if args.jit:
508*795d594fSAndroid Build Coastguard Worker      run_args += ["--jit"]
509*795d594fSAndroid Build Coastguard Worker    if args.baseline:
510*795d594fSAndroid Build Coastguard Worker      run_args += ["--baseline"]
511*795d594fSAndroid Build Coastguard Worker    run_optimizing = args.optimizing
512*795d594fSAndroid Build Coastguard Worker    if args.no_verify:
513*795d594fSAndroid Build Coastguard Worker      run_args += ["--no-verify"]
514*795d594fSAndroid Build Coastguard Worker    if args.verify_soft_fail:
515*795d594fSAndroid Build Coastguard Worker      run_args += ["--verify-soft-fail"]
516*795d594fSAndroid Build Coastguard Worker      os.environ["VERIFY_SOFT_FAIL"] = "true"
517*795d594fSAndroid Build Coastguard Worker    if args.no_optimize:
518*795d594fSAndroid Build Coastguard Worker      run_args += ["--no-optimize"]
519*795d594fSAndroid Build Coastguard Worker    if args.no_precise:
520*795d594fSAndroid Build Coastguard Worker      run_args += ["--no-precise"]
521*795d594fSAndroid Build Coastguard Worker    if args.android_log_tags:
522*795d594fSAndroid Build Coastguard Worker      run_args += [f"--android-log-tags {args.android_log_tags}"]
523*795d594fSAndroid Build Coastguard Worker    if args.external_log_tags:
524*795d594fSAndroid Build Coastguard Worker      run_args += ["--external-log-tags"]
525*795d594fSAndroid Build Coastguard Worker    if args.invoke_with:
526*795d594fSAndroid Build Coastguard Worker      run_args += [f'--invoke-with "{what}"' for what in args.invoke_with]
527*795d594fSAndroid Build Coastguard Worker    create_runner = args.create_runner
528*795d594fSAndroid Build Coastguard Worker    if create_runner:
529*795d594fSAndroid Build Coastguard Worker      run_args += ["--create-runner --dry-run"]
530*795d594fSAndroid Build Coastguard Worker      dev_mode = True
531*795d594fSAndroid Build Coastguard Worker    dev_mode = dev_mode or args.dev
532*795d594fSAndroid Build Coastguard Worker    chroot = args.chroot or ""
533*795d594fSAndroid Build Coastguard Worker    if chroot:
534*795d594fSAndroid Build Coastguard Worker      run_args += [f'--chroot "{chroot}"']
535*795d594fSAndroid Build Coastguard Worker    if args.simpleperf:
536*795d594fSAndroid Build Coastguard Worker      run_args += ["--simpleperf"]
537*795d594fSAndroid Build Coastguard Worker    android_root = args.android_root or "/system"
538*795d594fSAndroid Build Coastguard Worker    if args.android_root:
539*795d594fSAndroid Build Coastguard Worker      run_args += [f'--android-root "{android_root}"']
540*795d594fSAndroid Build Coastguard Worker    if args.android_art_root:
541*795d594fSAndroid Build Coastguard Worker      run_args += [f'--android-art-root "{args.android_art_root}"']
542*795d594fSAndroid Build Coastguard Worker    if args.android_tzdata_root:
543*795d594fSAndroid Build Coastguard Worker      run_args += [f'--android-tzdata-root "{args.android_tzdata_root}"']
544*795d594fSAndroid Build Coastguard Worker    update_mode = args.update
545*795d594fSAndroid Build Coastguard Worker    suffix64 = "64" if args.is64bit else ""
546*795d594fSAndroid Build Coastguard Worker    if args.is64bit:
547*795d594fSAndroid Build Coastguard Worker      run_args += ["--64"]
548*795d594fSAndroid Build Coastguard Worker    host_lib_root = ANDROID_HOST_OUT
549*795d594fSAndroid Build Coastguard Worker    if args.bionic:
550*795d594fSAndroid Build Coastguard Worker      # soong linux_bionic builds are 64bit only.
551*795d594fSAndroid Build Coastguard Worker      run_args += ["--bionic --host --64"]
552*795d594fSAndroid Build Coastguard Worker      suffix64 = "64"
553*795d594fSAndroid Build Coastguard Worker      target_mode = False
554*795d594fSAndroid Build Coastguard Worker      DEX_LOCATION = tmp_dir
555*795d594fSAndroid Build Coastguard Worker      host_lib_root = f"{OUT_DIR}/soong/host/linux_bionic-x86"
556*795d594fSAndroid Build Coastguard Worker
557*795d594fSAndroid Build Coastguard Worker    timeout = args.timeout or timeout
558*795d594fSAndroid Build Coastguard Worker    trace = args.trace
559*795d594fSAndroid Build Coastguard Worker    trace_stream = args.stream
560*795d594fSAndroid Build Coastguard Worker    always_clean = args.always_clean
561*795d594fSAndroid Build Coastguard Worker    never_clean = create_runner or args.never_clean
562*795d594fSAndroid Build Coastguard Worker    if args.dex2oat_swap:
563*795d594fSAndroid Build Coastguard Worker      run_args += ["--dex2oat-swap"]
564*795d594fSAndroid Build Coastguard Worker    if args.instruction_set_features:
565*795d594fSAndroid Build Coastguard Worker      run_args += [f'--instruction-set-features "{args.instruction_set_features}"']
566*795d594fSAndroid Build Coastguard Worker
567*795d594fSAndroid Build Coastguard Worker    bisection_search = args.bisection_search
568*795d594fSAndroid Build Coastguard Worker    if args.vdex:
569*795d594fSAndroid Build Coastguard Worker      run_args += ["--vdex"]
570*795d594fSAndroid Build Coastguard Worker    if args.dm:
571*795d594fSAndroid Build Coastguard Worker      run_args += ["--dm"]
572*795d594fSAndroid Build Coastguard Worker    if args.vdex_filter:
573*795d594fSAndroid Build Coastguard Worker      run_args += [f'--vdex-filter "{args.vdex_filter}"']
574*795d594fSAndroid Build Coastguard Worker    if args.random_profile:
575*795d594fSAndroid Build Coastguard Worker      run_args += ["--random-profile"]
576*795d594fSAndroid Build Coastguard Worker    if args.dex2oat_jobs:
577*795d594fSAndroid Build Coastguard Worker      run_args += [f'-Xcompiler-option "-j{str(args.dex2oat_jobs)}"']
578*795d594fSAndroid Build Coastguard Worker
579*795d594fSAndroid Build Coastguard Worker  export("DEX_LOCATION", DEX_LOCATION)
580*795d594fSAndroid Build Coastguard Worker
581*795d594fSAndroid Build Coastguard Worker# The DEX_LOCATION with the chroot prefix, if any.
582*795d594fSAndroid Build Coastguard Worker  chroot_dex_location = f"{chroot}{DEX_LOCATION}"
583*795d594fSAndroid Build Coastguard Worker
584*795d594fSAndroid Build Coastguard Worker  # tmp_dir may be relative, resolve.
585*795d594fSAndroid Build Coastguard Worker  os.chdir(oldwd)
586*795d594fSAndroid Build Coastguard Worker  tmp_dir = os.path.realpath(tmp_dir)
587*795d594fSAndroid Build Coastguard Worker  os.chdir(progdir)
588*795d594fSAndroid Build Coastguard Worker  if not tmp_dir:
589*795d594fSAndroid Build Coastguard Worker    error(f"Failed to resolve {tmp_dir}")
590*795d594fSAndroid Build Coastguard Worker    sys.exit(1)
591*795d594fSAndroid Build Coastguard Worker  os.makedirs(tmp_dir, exist_ok=True)
592*795d594fSAndroid Build Coastguard Worker
593*795d594fSAndroid Build Coastguard Worker  # Add thread suspend timeout flag
594*795d594fSAndroid Build Coastguard Worker  if runtime != "jvm":
595*795d594fSAndroid Build Coastguard Worker    run_args += [
596*795d594fSAndroid Build Coastguard Worker        f'--runtime-option "-XX:ThreadSuspendTimeout={suspend_timeout}"'
597*795d594fSAndroid Build Coastguard Worker    ]
598*795d594fSAndroid Build Coastguard Worker
599*795d594fSAndroid Build Coastguard Worker  if basic_verify:
600*795d594fSAndroid Build Coastguard Worker    # Set HspaceCompactForOOMMinIntervalMs to zero to run hspace compaction for OOM more frequently in tests.
601*795d594fSAndroid Build Coastguard Worker    run_args += [
602*795d594fSAndroid Build Coastguard Worker        "--runtime-option -Xgc:preverify --runtime-option -Xgc:postverify "
603*795d594fSAndroid Build Coastguard Worker        "--runtime-option -XX:HspaceCompactForOOMMinIntervalMs=0"
604*795d594fSAndroid Build Coastguard Worker    ]
605*795d594fSAndroid Build Coastguard Worker  if gc_verify:
606*795d594fSAndroid Build Coastguard Worker    run_args += [
607*795d594fSAndroid Build Coastguard Worker        "--runtime-option -Xgc:preverify_rosalloc --runtime-option "
608*795d594fSAndroid Build Coastguard Worker        "-Xgc:postverify_rosalloc"
609*795d594fSAndroid Build Coastguard Worker    ]
610*795d594fSAndroid Build Coastguard Worker  if gc_stress:
611*795d594fSAndroid Build Coastguard Worker    run_args += [
612*795d594fSAndroid Build Coastguard Worker        "--gc-stress --runtime-option -Xgc:gcstress --runtime-option -Xms2m "
613*795d594fSAndroid Build Coastguard Worker        "--runtime-option -Xmx16m"
614*795d594fSAndroid Build Coastguard Worker    ]
615*795d594fSAndroid Build Coastguard Worker  if jvmti_redefine_stress:
616*795d594fSAndroid Build Coastguard Worker    run_args += ["--no-app-image --jvmti-redefine-stress"]
617*795d594fSAndroid Build Coastguard Worker  if jvmti_step_stress:
618*795d594fSAndroid Build Coastguard Worker    run_args += ["--no-app-image --jvmti-step-stress"]
619*795d594fSAndroid Build Coastguard Worker  if jvmti_field_stress:
620*795d594fSAndroid Build Coastguard Worker    run_args += ["--no-app-image --jvmti-field-stress"]
621*795d594fSAndroid Build Coastguard Worker  if jvmti_trace_stress:
622*795d594fSAndroid Build Coastguard Worker    run_args += ["--no-app-image --jvmti-trace-stress"]
623*795d594fSAndroid Build Coastguard Worker  if trace:
624*795d594fSAndroid Build Coastguard Worker    run_args += [
625*795d594fSAndroid Build Coastguard Worker        "--runtime-option -Xmethod-trace --runtime-option "
626*795d594fSAndroid Build Coastguard Worker        "-Xmethod-trace-file-size:2000000"
627*795d594fSAndroid Build Coastguard Worker    ]
628*795d594fSAndroid Build Coastguard Worker    if trace_stream:
629*795d594fSAndroid Build Coastguard Worker      # Streaming mode uses the file size as the buffer size. So output gets really large. Drop
630*795d594fSAndroid Build Coastguard Worker      # the ability to analyze the file and just write to /dev/null.
631*795d594fSAndroid Build Coastguard Worker      run_args += ["--runtime-option -Xmethod-trace-file:/dev/null"]
632*795d594fSAndroid Build Coastguard Worker      # Enable streaming mode.
633*795d594fSAndroid Build Coastguard Worker      run_args += ["--runtime-option -Xmethod-trace-stream"]
634*795d594fSAndroid Build Coastguard Worker    else:
635*795d594fSAndroid Build Coastguard Worker      run_args += [
636*795d594fSAndroid Build Coastguard Worker          f'--runtime-option "-Xmethod-trace-file:{DEX_LOCATION}/trace.bin"'
637*795d594fSAndroid Build Coastguard Worker      ]
638*795d594fSAndroid Build Coastguard Worker  elif trace_stream:
639*795d594fSAndroid Build Coastguard Worker    error("Cannot use --stream without --trace.")
640*795d594fSAndroid Build Coastguard Worker    sys.exit(1)
641*795d594fSAndroid Build Coastguard Worker  if timeout:
642*795d594fSAndroid Build Coastguard Worker    run_args += [f'--timeout "{timeout}"']
643*795d594fSAndroid Build Coastguard Worker
644*795d594fSAndroid Build Coastguard Worker# Most interesting target architecture variables are Makefile variables, not environment variables.
645*795d594fSAndroid Build Coastguard Worker# Try to map the suffix64 flag and what we find in {ANDROID_PRODUCT_OUT}/data/art-test to an architecture name.
646*795d594fSAndroid Build Coastguard Worker
647*795d594fSAndroid Build Coastguard Worker  def guess_target_arch_name():
648*795d594fSAndroid Build Coastguard Worker    return get_target_arch(suffix64 == "64")
649*795d594fSAndroid Build Coastguard Worker
650*795d594fSAndroid Build Coastguard Worker  def guess_host_arch_name():
651*795d594fSAndroid Build Coastguard Worker    if suffix64 == "64":
652*795d594fSAndroid Build Coastguard Worker      return "x86_64"
653*795d594fSAndroid Build Coastguard Worker    else:
654*795d594fSAndroid Build Coastguard Worker      return "x86"
655*795d594fSAndroid Build Coastguard Worker
656*795d594fSAndroid Build Coastguard Worker  if not target_mode:
657*795d594fSAndroid Build Coastguard Worker    if runtime == "jvm":
658*795d594fSAndroid Build Coastguard Worker      if prebuild_mode:
659*795d594fSAndroid Build Coastguard Worker        error("--prebuild with --jvm is unsupported")
660*795d594fSAndroid Build Coastguard Worker        sys.exit(1)
661*795d594fSAndroid Build Coastguard Worker    else:
662*795d594fSAndroid Build Coastguard Worker      # ART/Dalvik host mode.
663*795d594fSAndroid Build Coastguard Worker      if chroot:
664*795d594fSAndroid Build Coastguard Worker        error("--chroot with --host is unsupported")
665*795d594fSAndroid Build Coastguard Worker        sys.exit(1)
666*795d594fSAndroid Build Coastguard Worker
667*795d594fSAndroid Build Coastguard Worker  if runtime != "jvm":
668*795d594fSAndroid Build Coastguard Worker    run_args += [f'--lib "{lib}"']
669*795d594fSAndroid Build Coastguard Worker
670*795d594fSAndroid Build Coastguard Worker  ANDROID_PRODUCT_OUT = os.environ.get("ANDROID_PRODUCT_OUT")
671*795d594fSAndroid Build Coastguard Worker  if runtime == "dalvik":
672*795d594fSAndroid Build Coastguard Worker    if not target_mode:
673*795d594fSAndroid Build Coastguard Worker      framework = f"{ANDROID_PRODUCT_OUT}/system/framework"
674*795d594fSAndroid Build Coastguard Worker      bpath = f"{framework}/core-icu4j.jar:{framework}/core-libart.jar:{framework}/core-oj.jar:{framework}/conscrypt.jar:{framework}/okhttp.jar:{framework}/bouncycastle.jar:{framework}/ext.jar"
675*795d594fSAndroid Build Coastguard Worker      run_args += [f'--boot --runtime-option "-Xbootclasspath:{bpath}"']
676*795d594fSAndroid Build Coastguard Worker    else:
677*795d594fSAndroid Build Coastguard Worker      pass  # defaults to using target BOOTCLASSPATH
678*795d594fSAndroid Build Coastguard Worker  elif runtime == "art":
679*795d594fSAndroid Build Coastguard Worker    if not target_mode:
680*795d594fSAndroid Build Coastguard Worker      host_arch_name = guess_host_arch_name()
681*795d594fSAndroid Build Coastguard Worker      run_args += [
682*795d594fSAndroid Build Coastguard Worker          f'--boot "{ANDROID_HOST_OUT}/apex/art_boot_images/javalib/boot.art"'
683*795d594fSAndroid Build Coastguard Worker      ]
684*795d594fSAndroid Build Coastguard Worker      run_args += [
685*795d594fSAndroid Build Coastguard Worker          f'--runtime-option "-Djava.library.path={host_lib_root}/lib{suffix64}:{host_lib_root}/nativetest{suffix64}"'
686*795d594fSAndroid Build Coastguard Worker      ]
687*795d594fSAndroid Build Coastguard Worker    else:
688*795d594fSAndroid Build Coastguard Worker      target_arch_name = guess_target_arch_name()
689*795d594fSAndroid Build Coastguard Worker      # Note that libarttest(d).so and other test libraries that depend on ART
690*795d594fSAndroid Build Coastguard Worker      # internal libraries must not be in this path for JNI libraries - they
691*795d594fSAndroid Build Coastguard Worker      # need to be loaded through LD_LIBRARY_PATH and
692*795d594fSAndroid Build Coastguard Worker      # NATIVELOADER_DEFAULT_NAMESPACE_LIBS instead.
693*795d594fSAndroid Build Coastguard Worker      run_args += [
694*795d594fSAndroid Build Coastguard Worker          f'--runtime-option "-Djava.library.path=/data/nativetest{suffix64}/art/{target_arch_name}"'
695*795d594fSAndroid Build Coastguard Worker      ]
696*795d594fSAndroid Build Coastguard Worker      if env.ART_TEST_RUN_FROM_SOONG:
697*795d594fSAndroid Build Coastguard Worker        run_args += ['--boot "/data/local/tmp/art/apex/art_boot_images/boot.art"']
698*795d594fSAndroid Build Coastguard Worker      else:
699*795d594fSAndroid Build Coastguard Worker        run_args += ['--boot "/system/framework/art_boot_images/boot.art"']
700*795d594fSAndroid Build Coastguard Worker    if relocate:
701*795d594fSAndroid Build Coastguard Worker      run_args += ["--relocate"]
702*795d594fSAndroid Build Coastguard Worker    else:
703*795d594fSAndroid Build Coastguard Worker      run_args += ["--no-relocate"]
704*795d594fSAndroid Build Coastguard Worker  elif runtime == "jvm":
705*795d594fSAndroid Build Coastguard Worker    # TODO: Detect whether the host is 32-bit or 64-bit.
706*795d594fSAndroid Build Coastguard Worker    run_args += [
707*795d594fSAndroid Build Coastguard Worker        f'--runtime-option "-Djava.library.path={ANDROID_HOST_OUT}/lib64:{ANDROID_HOST_OUT}/nativetest64"'
708*795d594fSAndroid Build Coastguard Worker    ]
709*795d594fSAndroid Build Coastguard Worker
710*795d594fSAndroid Build Coastguard Worker  if not have_image:
711*795d594fSAndroid Build Coastguard Worker    if runtime != "art":
712*795d594fSAndroid Build Coastguard Worker      error("--no-image is only supported on the art runtime")
713*795d594fSAndroid Build Coastguard Worker      sys.exit(1)
714*795d594fSAndroid Build Coastguard Worker    run_args += ["--no-image"]
715*795d594fSAndroid Build Coastguard Worker
716*795d594fSAndroid Build Coastguard Worker  if dev_mode and update_mode:
717*795d594fSAndroid Build Coastguard Worker    error("--dev and --update are mutually exclusive")
718*795d594fSAndroid Build Coastguard Worker    usage = True
719*795d594fSAndroid Build Coastguard Worker
720*795d594fSAndroid Build Coastguard Worker  if dev_mode and quiet:
721*795d594fSAndroid Build Coastguard Worker    error("--dev and --quiet are mutually exclusive")
722*795d594fSAndroid Build Coastguard Worker    usage = True
723*795d594fSAndroid Build Coastguard Worker
724*795d594fSAndroid Build Coastguard Worker  if bisection_search and prebuild_mode:
725*795d594fSAndroid Build Coastguard Worker    error("--bisection-search and --prebuild are mutually exclusive")
726*795d594fSAndroid Build Coastguard Worker    usage = True
727*795d594fSAndroid Build Coastguard Worker
728*795d594fSAndroid Build Coastguard Worker# TODO: Chroot-based bisection search is not supported yet (see below); implement it.
729*795d594fSAndroid Build Coastguard Worker  if bisection_search and chroot:
730*795d594fSAndroid Build Coastguard Worker    error("--chroot with --bisection-search is unsupported")
731*795d594fSAndroid Build Coastguard Worker    sys.exit(1)
732*795d594fSAndroid Build Coastguard Worker
733*795d594fSAndroid Build Coastguard Worker  if args.test_name == "-":
734*795d594fSAndroid Build Coastguard Worker    test_dir = os.path.basename(oldwd)
735*795d594fSAndroid Build Coastguard Worker  else:
736*795d594fSAndroid Build Coastguard Worker    test_dir = args.test_name
737*795d594fSAndroid Build Coastguard Worker
738*795d594fSAndroid Build Coastguard Worker  if not os.path.isdir(test_dir):
739*795d594fSAndroid Build Coastguard Worker    td2 = glob.glob(f"{test_dir}-*")
740*795d594fSAndroid Build Coastguard Worker    if len(td2) == 1 and os.path.isdir(td2[0]):
741*795d594fSAndroid Build Coastguard Worker      test_dir = td2[0]
742*795d594fSAndroid Build Coastguard Worker    else:
743*795d594fSAndroid Build Coastguard Worker      error(f"{test_dir}: no such test directory")
744*795d594fSAndroid Build Coastguard Worker      usage = True
745*795d594fSAndroid Build Coastguard Worker
746*795d594fSAndroid Build Coastguard Worker  os.chdir(test_dir)
747*795d594fSAndroid Build Coastguard Worker  test_dir = os.getcwd()
748*795d594fSAndroid Build Coastguard Worker
749*795d594fSAndroid Build Coastguard Worker  TEST_NAME = os.path.basename(test_dir)
750*795d594fSAndroid Build Coastguard Worker  export("TEST_NAME", TEST_NAME)
751*795d594fSAndroid Build Coastguard Worker
752*795d594fSAndroid Build Coastguard Worker  # Tests named '<number>-checker-*' will also have their CFGs verified with
753*795d594fSAndroid Build Coastguard Worker  # Checker when compiled with Optimizing on host.
754*795d594fSAndroid Build Coastguard Worker  # Additionally, if the user specifies that the CFG must be dumped, it will
755*795d594fSAndroid Build Coastguard Worker  # run the checker for any type of test to generate the CFG.
756*795d594fSAndroid Build Coastguard Worker  if re.match("[0-9]+-checker-", TEST_NAME) or dump_cfg:
757*795d594fSAndroid Build Coastguard Worker    if runtime == "art" and run_optimizing:
758*795d594fSAndroid Build Coastguard Worker      # In no-prebuild or no-image mode, the compiler only quickens so disable the checker.
759*795d594fSAndroid Build Coastguard Worker      if prebuild_mode:
760*795d594fSAndroid Build Coastguard Worker        run_checker = True
761*795d594fSAndroid Build Coastguard Worker
762*795d594fSAndroid Build Coastguard Worker        if not target_mode:
763*795d594fSAndroid Build Coastguard Worker          cfg_output_dir = tmp_dir
764*795d594fSAndroid Build Coastguard Worker          checker_args = f"--arch={host_arch_name.upper()}"
765*795d594fSAndroid Build Coastguard Worker        else:
766*795d594fSAndroid Build Coastguard Worker          cfg_output_dir = DEX_LOCATION
767*795d594fSAndroid Build Coastguard Worker          checker_args = f"--arch={target_arch_name.upper()}"
768*795d594fSAndroid Build Coastguard Worker
769*795d594fSAndroid Build Coastguard Worker        if debuggable:
770*795d594fSAndroid Build Coastguard Worker          checker_args += " --debuggable"
771*795d594fSAndroid Build Coastguard Worker
772*795d594fSAndroid Build Coastguard Worker        run_args += [
773*795d594fSAndroid Build Coastguard Worker            f'-Xcompiler-option "--dump-cfg={cfg_output_dir}/{cfg_output}" -Xcompiler-option -j1'
774*795d594fSAndroid Build Coastguard Worker        ]
775*795d594fSAndroid Build Coastguard Worker        checker_args = f"{checker_args} --print-cfg"
776*795d594fSAndroid Build Coastguard Worker
777*795d594fSAndroid Build Coastguard Worker  run_args += [f'--testlib "{testlib}"']
778*795d594fSAndroid Build Coastguard Worker
779*795d594fSAndroid Build Coastguard Worker  resource.setrlimit(resource.RLIMIT_FSIZE, (file_ulimit * 1024, resource.RLIM_INFINITY))
780*795d594fSAndroid Build Coastguard Worker
781*795d594fSAndroid Build Coastguard Worker  # Extract run-test data from the zip file.
782*795d594fSAndroid Build Coastguard Worker  def unzip():
783*795d594fSAndroid Build Coastguard Worker    if env.ART_TEST_RUN_FROM_SOONG:
784*795d594fSAndroid Build Coastguard Worker      # We already have the unzipped copy of the data.
785*795d594fSAndroid Build Coastguard Worker      assert target_mode
786*795d594fSAndroid Build Coastguard Worker      src = Path(ANDROID_BUILD_TOP) / "out" / "zip" / "target" / TEST_NAME
787*795d594fSAndroid Build Coastguard Worker      assert src.exists(), src
788*795d594fSAndroid Build Coastguard Worker      shutil.rmtree(tmp_dir)
789*795d594fSAndroid Build Coastguard Worker      copytree(src, tmp_dir)
790*795d594fSAndroid Build Coastguard Worker      os.chdir(tmp_dir)
791*795d594fSAndroid Build Coastguard Worker      return
792*795d594fSAndroid Build Coastguard Worker
793*795d594fSAndroid Build Coastguard Worker    # Clear the contents, but keep the directory just in case it is open in terminal.
794*795d594fSAndroid Build Coastguard Worker    for file in Path(tmp_dir).iterdir():
795*795d594fSAndroid Build Coastguard Worker      if file.is_file() or file.is_symlink():
796*795d594fSAndroid Build Coastguard Worker        file.unlink()
797*795d594fSAndroid Build Coastguard Worker      else:
798*795d594fSAndroid Build Coastguard Worker        shutil.rmtree(file)
799*795d594fSAndroid Build Coastguard Worker    os.makedirs(f"{tmp_dir}/.unzipped")
800*795d594fSAndroid Build Coastguard Worker    os.chdir(tmp_dir)
801*795d594fSAndroid Build Coastguard Worker    m = re.match("[0-9]*([0-9][0-9])-.*", TEST_NAME)
802*795d594fSAndroid Build Coastguard Worker    assert m, "Can not find test number in " + TEST_NAME
803*795d594fSAndroid Build Coastguard Worker    SHARD = "HiddenApi" if "hiddenapi" in TEST_NAME else m.group(1)
804*795d594fSAndroid Build Coastguard Worker    zip_dir = f"{ANDROID_HOST_OUT}/etc/art"
805*795d594fSAndroid Build Coastguard Worker    if target_mode:
806*795d594fSAndroid Build Coastguard Worker      zip_file = f"{zip_dir}/art-run-test-target-data-shard{SHARD}.zip"
807*795d594fSAndroid Build Coastguard Worker      zip_entry = f"target/{TEST_NAME}/"
808*795d594fSAndroid Build Coastguard Worker    elif runtime == "jvm":
809*795d594fSAndroid Build Coastguard Worker      zip_file = f"{zip_dir}/art-run-test-jvm-data-shard{SHARD}.zip"
810*795d594fSAndroid Build Coastguard Worker      zip_entry = f"jvm/{TEST_NAME}/"
811*795d594fSAndroid Build Coastguard Worker    else:
812*795d594fSAndroid Build Coastguard Worker      zip_file = f"{zip_dir}/art-run-test-host-data-shard{SHARD}.zip"
813*795d594fSAndroid Build Coastguard Worker      zip_entry = f"host/{TEST_NAME}/"
814*795d594fSAndroid Build Coastguard Worker    zip = ZipFile(zip_file, "r")
815*795d594fSAndroid Build Coastguard Worker    zip_entries = [e for e in zip.namelist() if e.startswith(zip_entry)]
816*795d594fSAndroid Build Coastguard Worker    zip.extractall(Path(tmp_dir) / ".unzipped", members=zip_entries)
817*795d594fSAndroid Build Coastguard Worker    for entry in (Path(tmp_dir) / ".unzipped" / zip_entry).iterdir():
818*795d594fSAndroid Build Coastguard Worker      entry.rename(Path(tmp_dir) / entry.name)
819*795d594fSAndroid Build Coastguard Worker
820*795d594fSAndroid Build Coastguard Worker  unzip()
821*795d594fSAndroid Build Coastguard Worker
822*795d594fSAndroid Build Coastguard Worker  def clean_up(passed: bool):
823*795d594fSAndroid Build Coastguard Worker    if always_clean or (passed and not never_clean):
824*795d594fSAndroid Build Coastguard Worker      os.chdir(oldwd)
825*795d594fSAndroid Build Coastguard Worker      shutil.rmtree(tmp_dir)
826*795d594fSAndroid Build Coastguard Worker      if target_mode:
827*795d594fSAndroid Build Coastguard Worker        if ON_VM:
828*795d594fSAndroid Build Coastguard Worker          run(f"{SSH_CMD} \"rm -rf {chroot_dex_location}\"")
829*795d594fSAndroid Build Coastguard Worker        else:
830*795d594fSAndroid Build Coastguard Worker          run(f"adb shell rm -rf {chroot_dex_location}")
831*795d594fSAndroid Build Coastguard Worker      os.remove(tmp_dir_lock)
832*795d594fSAndroid Build Coastguard Worker      print(f"{TEST_NAME} files deleted from host" +
833*795d594fSAndroid Build Coastguard Worker            (" and from target" if target_mode else ""))
834*795d594fSAndroid Build Coastguard Worker    else:
835*795d594fSAndroid Build Coastguard Worker      print(f"{TEST_NAME} files left in {tmp_dir} on host" +
836*795d594fSAndroid Build Coastguard Worker            (f" and in {chroot_dex_location} on target" if target_mode else ""))
837*795d594fSAndroid Build Coastguard Worker    atexit.unregister(clean_up)
838*795d594fSAndroid Build Coastguard Worker
839*795d594fSAndroid Build Coastguard Worker  ctx = RunTestContext(Path(tmp_dir), target_mode, chroot, DEX_LOCATION, TEST_NAME)
840*795d594fSAndroid Build Coastguard Worker  td_info = f"{test_dir}/{info}"
841*795d594fSAndroid Build Coastguard Worker  for td_file in [td_info, ctx.expected_stdout, ctx.expected_stderr]:
842*795d594fSAndroid Build Coastguard Worker    assert os.access(td_file, os.R_OK)
843*795d594fSAndroid Build Coastguard Worker
844*795d594fSAndroid Build Coastguard Worker  # Create runner (bash script that executes the whole test)
845*795d594fSAndroid Build Coastguard Worker  def create_runner_script() -> Path:
846*795d594fSAndroid Build Coastguard Worker    parsed_args = default_run_module.parse_args(shlex.split(" ".join(run_args + args.test_args)))
847*795d594fSAndroid Build Coastguard Worker    parsed_args.stdout_file = os.path.join(DEX_LOCATION, test_stdout)
848*795d594fSAndroid Build Coastguard Worker    parsed_args.stderr_file = os.path.join(DEX_LOCATION, test_stderr)
849*795d594fSAndroid Build Coastguard Worker
850*795d594fSAndroid Build Coastguard Worker    ctx.run(f"cd {DEX_LOCATION}")
851*795d594fSAndroid Build Coastguard Worker    if not target_mode:
852*795d594fSAndroid Build Coastguard Worker      # Make "out" directory accessible from test directory.
853*795d594fSAndroid Build Coastguard Worker      ctx.run(f"ln -s -f -t {DEX_LOCATION} {ANDROID_BUILD_TOP}/out")
854*795d594fSAndroid Build Coastguard Worker    # Clear the stdout/stderr files (create empty files).
855*795d594fSAndroid Build Coastguard Worker    ctx.run(f"echo -n > {test_stdout} && echo -n > {test_stderr}")
856*795d594fSAndroid Build Coastguard Worker
857*795d594fSAndroid Build Coastguard Worker    script = Path(tmp_dir) / "run.py"
858*795d594fSAndroid Build Coastguard Worker    if script.exists():
859*795d594fSAndroid Build Coastguard Worker      module = SourceFileLoader("run_" + TEST_NAME, str(script)).load_module()
860*795d594fSAndroid Build Coastguard Worker      module.run(ctx, parsed_args)
861*795d594fSAndroid Build Coastguard Worker    else:
862*795d594fSAndroid Build Coastguard Worker      default_run_module.default_run(ctx, parsed_args)
863*795d594fSAndroid Build Coastguard Worker
864*795d594fSAndroid Build Coastguard Worker    runner = Path(tmp_dir) / "run.sh"
865*795d594fSAndroid Build Coastguard Worker    runner.write_text("\n".join(ctx.runner))
866*795d594fSAndroid Build Coastguard Worker    runner.chmod(0o777)
867*795d594fSAndroid Build Coastguard Worker    return runner
868*795d594fSAndroid Build Coastguard Worker
869*795d594fSAndroid Build Coastguard Worker  def do_dump_cfg():
870*795d594fSAndroid Build Coastguard Worker    assert run_optimizing, "The CFG can be dumped only in optimizing mode"
871*795d594fSAndroid Build Coastguard Worker    if target_mode:
872*795d594fSAndroid Build Coastguard Worker      if ON_VM:
873*795d594fSAndroid Build Coastguard Worker        run(f'{SCP_CMD} "{SSH_USER}@${SSH_HOST}:{CHROOT}/{cfg_output_dir}/'
874*795d594fSAndroid Build Coastguard Worker            f'{cfg_output} {dump_cfg_path}"')
875*795d594fSAndroid Build Coastguard Worker      else:
876*795d594fSAndroid Build Coastguard Worker        run(f"adb pull {chroot}/{cfg_output_dir}/{cfg_output} {dump_cfg_path}")
877*795d594fSAndroid Build Coastguard Worker    else:
878*795d594fSAndroid Build Coastguard Worker      run(f"cp {cfg_output_dir}/{cfg_output} {dump_cfg_path}")
879*795d594fSAndroid Build Coastguard Worker
880*795d594fSAndroid Build Coastguard Worker  # Test might not execute anything but we still expect the output files to exist.
881*795d594fSAndroid Build Coastguard Worker  Path(test_stdout).touch()
882*795d594fSAndroid Build Coastguard Worker  Path(test_stderr).touch()
883*795d594fSAndroid Build Coastguard Worker
884*795d594fSAndroid Build Coastguard Worker  export("TEST_RUNTIME", runtime)
885*795d594fSAndroid Build Coastguard Worker
886*795d594fSAndroid Build Coastguard Worker  print(f"{test_dir}: Create runner script...")
887*795d594fSAndroid Build Coastguard Worker  runner = create_runner_script()
888*795d594fSAndroid Build Coastguard Worker
889*795d594fSAndroid Build Coastguard Worker  if args.create_runner:
890*795d594fSAndroid Build Coastguard Worker    # TODO: Generate better unique names.
891*795d594fSAndroid Build Coastguard Worker    dst = args.create_runner / TEST_NAME / f"{Path(tmp_dir).name}.sh"
892*795d594fSAndroid Build Coastguard Worker    assert not dst.exists(), dst
893*795d594fSAndroid Build Coastguard Worker    dst.parent.mkdir(parents=True, exist_ok=True)
894*795d594fSAndroid Build Coastguard Worker    copyfile(runner, dst)
895*795d594fSAndroid Build Coastguard Worker
896*795d594fSAndroid Build Coastguard Worker  # Script debugging feature - just export the runner script into a directory,
897*795d594fSAndroid Build Coastguard Worker  # so that it can be compared before/after runner script refactoring.
898*795d594fSAndroid Build Coastguard Worker  save_runner_dir = os.environ.get("RUN_TEST_DEBUG__SAVE_RUNNER_DIR")
899*795d594fSAndroid Build Coastguard Worker  if save_runner_dir:
900*795d594fSAndroid Build Coastguard Worker    name = [a for a in sys.argv[1:] if not a.startswith("--create-runner")]
901*795d594fSAndroid Build Coastguard Worker    name = urllib.parse.quote(" ".join(name), safe=' ')
902*795d594fSAndroid Build Coastguard Worker    dst = Path(save_runner_dir) / TEST_NAME / name
903*795d594fSAndroid Build Coastguard Worker    os.makedirs(dst.parent, exist_ok=True)
904*795d594fSAndroid Build Coastguard Worker    txt = runner.read_text()
905*795d594fSAndroid Build Coastguard Worker    txt = txt.replace(Path(tmp_dir).name, "${TMP_DIR}")  # Make it deterministic.
906*795d594fSAndroid Build Coastguard Worker    txt = re.sub('\[run-test:\d+\]', '[run-test:(line-number)]', txt)
907*795d594fSAndroid Build Coastguard Worker    dst.write_text(txt)
908*795d594fSAndroid Build Coastguard Worker
909*795d594fSAndroid Build Coastguard Worker  if args.create_runner or save_runner_dir:
910*795d594fSAndroid Build Coastguard Worker    sys.exit(0)
911*795d594fSAndroid Build Coastguard Worker
912*795d594fSAndroid Build Coastguard Worker  # TODO: Run this in global try-finally once the script is more refactored.
913*795d594fSAndroid Build Coastguard Worker  atexit.register(clean_up, passed=False)
914*795d594fSAndroid Build Coastguard Worker
915*795d594fSAndroid Build Coastguard Worker  print(f"{test_dir}: Run...")
916*795d594fSAndroid Build Coastguard Worker  if target_mode:
917*795d594fSAndroid Build Coastguard Worker    # Prepare the on-device test directory
918*795d594fSAndroid Build Coastguard Worker    if ON_VM:
919*795d594fSAndroid Build Coastguard Worker      run(f"{SSH_CMD} 'rm -rf {chroot_dex_location} && mkdir -p {chroot_dex_location}'")
920*795d594fSAndroid Build Coastguard Worker    else:
921*795d594fSAndroid Build Coastguard Worker      run("adb root")
922*795d594fSAndroid Build Coastguard Worker      run("adb wait-for-device")
923*795d594fSAndroid Build Coastguard Worker      run(f"adb shell 'rm -rf {chroot_dex_location} && mkdir -p {chroot_dex_location}'")
924*795d594fSAndroid Build Coastguard Worker    push_files = [Path(runner.name)]
925*795d594fSAndroid Build Coastguard Worker    push_files += list(Path(".").glob(f"{TEST_NAME}*.jar"))
926*795d594fSAndroid Build Coastguard Worker    push_files += list(Path(".").glob(f"expected-*.txt"))
927*795d594fSAndroid Build Coastguard Worker    push_files += [p for p in [Path("profile"), Path("res")] if p.exists()]
928*795d594fSAndroid Build Coastguard Worker    push_files = " ".join(map(str, push_files))
929*795d594fSAndroid Build Coastguard Worker    if ON_VM:
930*795d594fSAndroid Build Coastguard Worker      run(f"{SCP_CMD} {push_files} {SSH_USER}@{SSH_HOST}:{chroot_dex_location}")
931*795d594fSAndroid Build Coastguard Worker    else:
932*795d594fSAndroid Build Coastguard Worker      run("adb push {} {}".format(push_files, chroot_dex_location))
933*795d594fSAndroid Build Coastguard Worker
934*795d594fSAndroid Build Coastguard Worker    try:
935*795d594fSAndroid Build Coastguard Worker      if ON_VM:
936*795d594fSAndroid Build Coastguard Worker        run(f"{SSH_CMD} {CHROOT_CMD} bash {DEX_LOCATION}/run.sh",
937*795d594fSAndroid Build Coastguard Worker            fail_message=f"Runner {chroot_dex_location}/run.sh failed")
938*795d594fSAndroid Build Coastguard Worker      else:
939*795d594fSAndroid Build Coastguard Worker        chroot_prefix = f"chroot {chroot}" if chroot else ""
940*795d594fSAndroid Build Coastguard Worker        run(f"adb shell {chroot_prefix} sh {DEX_LOCATION}/run.sh",
941*795d594fSAndroid Build Coastguard Worker            fail_message=f"Runner {chroot_dex_location}/run.sh failed")
942*795d594fSAndroid Build Coastguard Worker    finally:
943*795d594fSAndroid Build Coastguard Worker      # Copy the generated CFG to the specified path.
944*795d594fSAndroid Build Coastguard Worker      if dump_cfg:
945*795d594fSAndroid Build Coastguard Worker        do_dump_cfg()
946*795d594fSAndroid Build Coastguard Worker
947*795d594fSAndroid Build Coastguard Worker    # Copy the on-device stdout/stderr to host.
948*795d594fSAndroid Build Coastguard Worker    pull_files = [test_stdout, test_stderr, "expected-stdout.txt", "expected-stderr.txt"]
949*795d594fSAndroid Build Coastguard Worker    if ON_VM:
950*795d594fSAndroid Build Coastguard Worker      srcs = " ".join(f"{SSH_USER}@{SSH_HOST}:{chroot_dex_location}/{f}" for f in pull_files)
951*795d594fSAndroid Build Coastguard Worker      run(f"{SCP_CMD} {srcs} .")
952*795d594fSAndroid Build Coastguard Worker    else:
953*795d594fSAndroid Build Coastguard Worker      run("adb pull {} .".format(" ".join(f"{chroot_dex_location}/{f}" for f in pull_files)))
954*795d594fSAndroid Build Coastguard Worker  else:
955*795d594fSAndroid Build Coastguard Worker    run(str(runner), fail_message=f"Runner {str(runner)} failed")
956*795d594fSAndroid Build Coastguard Worker
957*795d594fSAndroid Build Coastguard Worker  # NB: There is no exit code or return value.
958*795d594fSAndroid Build Coastguard Worker  # Failing tests just raise python exception.
959*795d594fSAndroid Build Coastguard Worker  os.chdir(tmp_dir)
960*795d594fSAndroid Build Coastguard Worker  if update_mode:
961*795d594fSAndroid Build Coastguard Worker    for src, dst in [(test_stdout, os.path.join(test_dir, ctx.expected_stdout.name)),
962*795d594fSAndroid Build Coastguard Worker                     (test_stderr, os.path.join(test_dir, ctx.expected_stderr.name))]:
963*795d594fSAndroid Build Coastguard Worker      if "[DO_NOT_UPDATE]" not in open(dst).readline():
964*795d594fSAndroid Build Coastguard Worker        copyfile(src, dst)
965*795d594fSAndroid Build Coastguard Worker
966*795d594fSAndroid Build Coastguard Worker  print("#################### info")
967*795d594fSAndroid Build Coastguard Worker  run(f'cat "{td_info}" | sed "s/^/# /g"')
968*795d594fSAndroid Build Coastguard Worker  print("#################### stdout diff")
969*795d594fSAndroid Build Coastguard Worker  proc_out = run(f'diff --strip-trailing-cr -u '
970*795d594fSAndroid Build Coastguard Worker                 f'"{ctx.expected_stdout}" "{test_stdout}"', check=False)
971*795d594fSAndroid Build Coastguard Worker  print("#################### stderr diff")
972*795d594fSAndroid Build Coastguard Worker  proc_err = run(f'diff --strip-trailing-cr -u '
973*795d594fSAndroid Build Coastguard Worker                 f'"{ctx.expected_stderr}" "{test_stderr}"', check=False)
974*795d594fSAndroid Build Coastguard Worker  if strace:
975*795d594fSAndroid Build Coastguard Worker    print("#################### strace output (trimmed to 3000 lines)")
976*795d594fSAndroid Build Coastguard Worker    # Some tests do not run dalvikvm, in which case the trace does not exist.
977*795d594fSAndroid Build Coastguard Worker    run(f'tail -n 3000 "{tmp_dir}/{strace_output}"', check=False)
978*795d594fSAndroid Build Coastguard Worker  SANITIZE_HOST = os.environ.get("SANITIZE_HOST")
979*795d594fSAndroid Build Coastguard Worker  if not target_mode and SANITIZE_HOST == "address":
980*795d594fSAndroid Build Coastguard Worker    # Run the stack script to symbolize any ASAN aborts on the host for SANITIZE_HOST. The
981*795d594fSAndroid Build Coastguard Worker    # tools used by the given ABI work for both x86 and x86-64.
982*795d594fSAndroid Build Coastguard Worker    print("#################### symbolizer (trimmed to 3000 lines)")
983*795d594fSAndroid Build Coastguard Worker    run(f'''echo "ABI: 'x86_64'" | cat - "{test_stdout}" "{test_stderr}"'''
984*795d594fSAndroid Build Coastguard Worker        f"""| {ANDROID_BUILD_TOP}/development/scripts/stack | tail -n 3000""")
985*795d594fSAndroid Build Coastguard Worker  print("####################", flush=True)
986*795d594fSAndroid Build Coastguard Worker
987*795d594fSAndroid Build Coastguard Worker  try:
988*795d594fSAndroid Build Coastguard Worker    if proc_out.returncode != 0 or proc_err.returncode != 0:
989*795d594fSAndroid Build Coastguard Worker      kind = ((["stdout"] if proc_out.returncode != 0 else []) +
990*795d594fSAndroid Build Coastguard Worker              (["stderr"] if proc_err.returncode != 0 else []))
991*795d594fSAndroid Build Coastguard Worker      fail("{} did not match the expected file".format(" and ".join(kind)))
992*795d594fSAndroid Build Coastguard Worker
993*795d594fSAndroid Build Coastguard Worker    if run_checker:
994*795d594fSAndroid Build Coastguard Worker      if target_mode:
995*795d594fSAndroid Build Coastguard Worker        if ON_VM:
996*795d594fSAndroid Build Coastguard Worker          run(f'{SCP_CMD} "{SSH_USER}@{SSH_HOST}:{CHROOT}/{cfg_output_dir}/'
997*795d594fSAndroid Build Coastguard Worker              f'{cfg_output}" "{tmp_dir}"')
998*795d594fSAndroid Build Coastguard Worker        else:
999*795d594fSAndroid Build Coastguard Worker          run(f'adb pull "{chroot}/{cfg_output_dir}/{cfg_output}"')
1000*795d594fSAndroid Build Coastguard Worker      run(f'"{checker}" -q {checker_args} "{cfg_output}" "{tmp_dir}"',
1001*795d594fSAndroid Build Coastguard Worker          fail_message="CFG checker failed")
1002*795d594fSAndroid Build Coastguard Worker  finally:
1003*795d594fSAndroid Build Coastguard Worker    # Copy the generated CFG to the specified path.
1004*795d594fSAndroid Build Coastguard Worker    if dump_cfg:
1005*795d594fSAndroid Build Coastguard Worker      do_dump_cfg()
1006*795d594fSAndroid Build Coastguard Worker
1007*795d594fSAndroid Build Coastguard Worker  clean_up(passed=True)
1008*795d594fSAndroid Build Coastguard Worker  print(f"{COLOR_GREEN}{test_dir}: PASSED{COLOR_NORMAL}")
1009