Run-tests: Run checker after stdout/stderr diff.
There does not seem to be a reason to mix the two.
Run CFG checker as its own separate step.
Test: test.py -r --all-target --optimizing --64
Change-Id: I4a2e055206217244c4676dc1c953fe6a0f945358
diff --git a/test/run-test b/test/run-test
index 28ccf28..0bd1173 100755
--- a/test/run-test
+++ b/test/run-test
@@ -20,7 +20,10 @@
from importlib.machinery import SourceFileLoader
from pathlib import Path
+from inspect import currentframe, getframeinfo
+COLOR_RED = '\033[91m'
+COLOR_NORMAL = '\033[0m'
# Helper class which allows us to access the environment using syntax sugar.
# E.g. `env.ANDROID_BUILD_TOP` instead of `os.environ["ANDROID_BUILD_TOP"]`.
@@ -69,6 +72,7 @@
def run(cmdline: str,
check=True,
+ fail_message=None,
capture_output=True) -> subprocess.CompletedProcess:
proc = subprocess.run([cmdline],
shell=True,
@@ -77,9 +81,15 @@
if (check and proc.returncode != 0) or (quiet == "no"):
print("$ " + cmdline)
print(proc.stdout or "", file=sys.stdout, end="", flush=True)
- print(proc.stderr or "", file=sys.stderr, end="", flush=True)
+ print(COLOR_RED + (proc.stderr or "") + COLOR_NORMAL, file=sys.stderr, end="", flush=True)
if (check and proc.returncode != 0):
- raise Exception("Command returned exit code {}".format(proc.returncode))
+ if fail_message:
+ # If we have custom fail message, exit without printing the full backtrace.
+ caller = getframeinfo(currentframe().f_back) # type: ignore
+ source = f"{caller.filename}:{caller.lineno}" # Last line of backtrace.
+ print(f"Command failed: {fail_message} ({source})", file=sys.stderr)
+ sys.exit(1)
+ raise Exception(f"Command failed (exit code {proc.returncode})")
return proc
def export(env: str, value: str) -> None:
@@ -949,10 +959,6 @@
# NB: There is no exit code or return value.
# Failing tests just raise python exception.
os.chdir(tmp_dir)
- if run_checker == "yes":
- if target_mode == "yes":
- run(f'adb pull "{chroot}/{cfg_output_dir}/{cfg_output}"')
- run(f'"{checker}" -q {checker_args} "{cfg_output}" "{tmp_dir}" >>"{test_stdout}" 2>>"{test_stderr}"', check=False)
if update_mode == "yes":
run(f'''sed -e 's/[[:cntrl:]]$//g' <"{test_stdout}" >"{td_expected_stdout}"''')
run(f'''sed -e 's/[[:cntrl:]]$//g' <"{test_stderr}" >"{td_expected_stderr}"''')
@@ -973,11 +979,7 @@
error("#################### info")
run(f'cat "{td_info}" | sed "s/^/# /g"')
error("#################### stdout diffs")
- if run_checker == "yes":
- # Checker failures dump the whole CFG, so we output the whole diff.
- run(f'diff --strip-trailing-cr -u "{expected_stdout}" "{test_stdout}"', check=False)
- else:
- run(f'diff --strip-trailing-cr -u "{expected_stdout}" "{test_stdout}" | tail -n 10000', check=False)
+ run(f'diff --strip-trailing-cr -u "{expected_stdout}" "{test_stdout}" | tail -n 10000', check=False)
error("####################")
error("#################### stderr diffs")
run(f'diff --strip-trailing-cr -u "{expected_stderr}" "{test_stderr}" | tail -n 10000', check=False)
@@ -994,17 +996,19 @@
f"""| {ANDROID_BUILD_TOP}/development/scripts/stack | tail -n 3000""")
error(" ")
-# Copy the generated CFG to the specified path.
+ if run_checker == "yes":
+ if target_mode == "yes":
+ run(f'adb pull "{chroot}/{cfg_output_dir}/{cfg_output}"')
+ run(f'"{checker}" -q {checker_args} "{cfg_output}" "{tmp_dir}"',
+ fail_message="CFG checker failed")
+
+ # Copy the generated CFG to the specified path.
if dump_cfg == "true":
- if run_optimizing != "true":
- error(
- "Can't dump the .cfg if the compiler type isn't set to \"optimizing\"."
- )
+ assert run_optimizing == "true", "The CFG can be dumped only in optimizing mode"
+ if target_mode == "yes":
+ run(f"adb pull {chroot}/{cfg_output_dir}/{cfg_output} {dump_cfg_path}")
else:
- if target_mode == "yes":
- run(f"adb pull {chroot}/{cfg_output_dir}/{cfg_output} {dump_cfg_path}")
- else:
- run(f"cp {cfg_output_dir}/{cfg_output} {dump_cfg_path}")
+ run(f"cp {cfg_output_dir}/{cfg_output} {dump_cfg_path}")
# Clean up test files.
if (always_clean == "yes" or good == "yes") and never_clean == "no":