Skip to content

Commit efa984b

Browse files
[3.14] gh-131531: Android test fixes (GH-136845) (#136962)
Modifies the test runner script to no longer export the the HOST environment variable, and to allow for tests that produce no Python output (output from the Android console is still expected and required). These changes stem from knowledge gained during developing a PR for Android support in cibuildwheel. (cherry picked from commit 149bddc) Co-authored-by: Malcolm Smith <smith@chaquo.com>
1 parent 6e1b31b commit efa984b

File tree

1 file changed

+40
-33
lines changed

1 file changed

+40
-33
lines changed

Android/android.py

Lines changed: 40 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -50,7 +50,19 @@
5050
+ (".bat" if os.name == "nt" else "")
5151
)
5252

53-
logcat_started = False
53+
# Whether we've seen any output from Python yet.
54+
python_started = False
55+
56+
# Buffer for verbose output which will be displayed only if a test fails and
57+
# there has been no output from Python.
58+
hidden_output = []
59+
60+
61+
def log_verbose(context, line, stream=sys.stdout):
62+
if context.verbose:
63+
stream.write(line)
64+
else:
65+
hidden_output.append((stream, line))
5466

5567

5668
def delete_glob(pattern):
@@ -118,7 +130,7 @@ def android_env(host):
118130
env_script = ANDROID_DIR / "android-env.sh"
119131
env_output = subprocess.run(
120132
f"set -eu; "
121-
f"export HOST={host}; "
133+
f"HOST={host}; "
122134
f"PREFIX={prefix}; "
123135
f". {env_script}; "
124136
f"export",
@@ -453,17 +465,19 @@ async def logcat_task(context, initial_devices):
453465

454466
# `--pid` requires API level 24 or higher.
455467
args = [adb, "-s", serial, "logcat", "--pid", pid, "--format", "tag"]
456-
hidden_output = []
468+
logcat_started = False
457469
async with async_process(
458470
*args, stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
459471
) as process:
460472
while line := (await process.stdout.readline()).decode(*DECODE_ARGS):
461473
if match := re.fullmatch(r"([A-Z])/(.*)", line, re.DOTALL):
474+
logcat_started = True
462475
level, message = match.groups()
463476
else:
464-
# If the regex doesn't match, this is probably the second or
465-
# subsequent line of a multi-line message. Python won't produce
466-
# such messages, but other components might.
477+
# If the regex doesn't match, this is either a logcat startup
478+
# error, or the second or subsequent line of a multi-line
479+
# message. Python won't produce multi-line messages, but other
480+
# components might.
467481
level, message = None, line
468482

469483
# Exclude high-volume messages which are rarely useful.
@@ -483,25 +497,22 @@ async def logcat_task(context, initial_devices):
483497
# tag indicators from Python's stdout and stderr.
484498
for prefix in ["python.stdout: ", "python.stderr: "]:
485499
if message.startswith(prefix):
486-
global logcat_started
487-
logcat_started = True
500+
global python_started
501+
python_started = True
488502
stream.write(message.removeprefix(prefix))
489503
break
490504
else:
491-
if context.verbose:
492-
# Non-Python messages add a lot of noise, but they may
493-
# sometimes help explain a failure.
494-
stream.write(line)
495-
else:
496-
hidden_output.append(line)
505+
# Non-Python messages add a lot of noise, but they may
506+
# sometimes help explain a failure.
507+
log_verbose(context, line, stream)
497508

498509
# If the device disconnects while logcat is running, which always
499510
# happens in --managed mode, some versions of adb return non-zero.
500511
# Distinguish this from a logcat startup error by checking whether we've
501-
# received a message from Python yet.
512+
# received any logcat messages yet.
502513
status = await wait_for(process.wait(), timeout=1)
503514
if status != 0 and not logcat_started:
504-
raise CalledProcessError(status, args, "".join(hidden_output))
515+
raise CalledProcessError(status, args)
505516

506517

507518
def stop_app(serial):
@@ -516,16 +527,6 @@ async def gradle_task(context):
516527
task_prefix = "connected"
517528
env["ANDROID_SERIAL"] = context.connected
518529

519-
hidden_output = []
520-
521-
def log(line):
522-
# Gradle may take several minutes to install SDK packages, so it's worth
523-
# showing those messages even in non-verbose mode.
524-
if context.verbose or line.startswith('Preparing "Install'):
525-
sys.stdout.write(line)
526-
else:
527-
hidden_output.append(line)
528-
529530
if context.command:
530531
mode = "-c"
531532
module = context.command
@@ -550,27 +551,27 @@ def log(line):
550551
]
551552
if context.verbose >= 2:
552553
args.append("--info")
553-
log("> " + join_command(args))
554+
log_verbose(context, f"> {join_command(args)}\n")
554555

555556
try:
556557
async with async_process(
557558
*args, cwd=TESTBED_DIR, env=env,
558559
stdout=subprocess.PIPE, stderr=subprocess.STDOUT,
559560
) as process:
560561
while line := (await process.stdout.readline()).decode(*DECODE_ARGS):
561-
log(line)
562+
# Gradle may take several minutes to install SDK packages, so
563+
# it's worth showing those messages even in non-verbose mode.
564+
if line.startswith('Preparing "Install'):
565+
sys.stdout.write(line)
566+
else:
567+
log_verbose(context, line)
562568

563569
status = await wait_for(process.wait(), timeout=1)
564570
if status == 0:
565571
exit(0)
566572
else:
567573
raise CalledProcessError(status, args)
568574
finally:
569-
# If logcat never started, then something has gone badly wrong, so the
570-
# user probably wants to see the Gradle output even in non-verbose mode.
571-
if hidden_output and not logcat_started:
572-
sys.stdout.write("".join(hidden_output))
573-
574575
# Gradle does not stop the tests when interrupted.
575576
if context.connected:
576577
stop_app(context.connected)
@@ -600,6 +601,12 @@ async def run_testbed(context):
600601
except* MySystemExit as e:
601602
raise SystemExit(*e.exceptions[0].args) from None
602603
except* CalledProcessError as e:
604+
# If Python produced no output, then the user probably wants to see the
605+
# verbose output to explain why the test failed.
606+
if not python_started:
607+
for stream, line in hidden_output:
608+
stream.write(line)
609+
603610
# Extract it from the ExceptionGroup so it can be handled by `main`.
604611
raise e.exceptions[0]
605612

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy