Stop the install watcher from dying quietly mid-run
You called this one: the watcher was not running any more, and the reason was mine. It ran under set -euo pipefail, and two helpers ended in a pipeline to head -1; when head exits first sed takes a SIGPIPE, pipefail turns that into a failed assignment and -e turns that into an exit. So the script answered the first dialog or two and then vanished without a word, which is exactly what a run that stops after its first install looks like. It now runs without -e, the helper pipelines end in || true, and it prints a heartbeat every thirty seconds so is it still running can be answered from the log. Measured after the fix: two consecutive uninstall/install cycles both succeeded, the script stayed alive through a 75 s watch, and in a full benchmark run it was still alive at the end with two dialogs answered. That run lasted 1m29s instead of the previous 35s and one test got as far as driving the app, so the installs do sometimes get through now. One was still refused, and the run still failed overall.
This commit is contained in:
@@ -27,7 +27,11 @@
|
||||
# Measured on the Xiaomi phone (Android 12, MIUI 14): an adb-started install raises the dialog after
|
||||
# about 1.7 s with a ten second deny countdown, so there is time for one dump and one tap; the same
|
||||
# dialog is FLAG_SECURE, so a screencap of it shows whatever is behind it.
|
||||
set -euo pipefail
|
||||
# No `-e`: this is a watcher that has to survive for the whole run, and a single failed adb call must not
|
||||
# end it. It ended silently once before, in the middle of a benchmark run, which is why it looked like it
|
||||
# had "stopped running" — a helper ending in `| head -1` takes a SIGPIPE when `head` exits first, and
|
||||
# `pipefail` plus `-e` turned that into an exit.
|
||||
set -uo pipefail
|
||||
|
||||
seconds=600
|
||||
interval=2
|
||||
@@ -83,7 +87,7 @@ is_installer() {
|
||||
|
||||
# The window token, so the same dialog is not answered twice while it closes.
|
||||
window_token() {
|
||||
sed -n 's/.*mCurrentFocus=Window{\([0-9a-f]*\).*/\1/p' <<<"$1" | head -1
|
||||
sed -n 's/.*mCurrentFocus=Window{\([0-9a-f]*\).*/\1/p' <<<"$1" | head -1 || true
|
||||
}
|
||||
|
||||
# The activity that owns the focused window. Dialogs each get their own window token, so the token
|
||||
@@ -91,7 +95,7 @@ window_token() {
|
||||
# which is exactly what happens when a run installs twice in quick succession. The activity name is
|
||||
# stable across both, and it is still specific enough that a tap can only ever land on an installer.
|
||||
installer_activity() {
|
||||
sed -n 's/.*u0 \([^ }]*\).*/\1/p' <<<"$1" | head -1
|
||||
sed -n 's/.*u0 \([^ }]*\).*/\1/p' <<<"$1" | head -1 || true
|
||||
}
|
||||
|
||||
# Prints "<x> <y> <label>" for the dialog's Install button, or nothing at all.
|
||||
@@ -201,9 +205,16 @@ answer_dialog() {
|
||||
|
||||
deadline=$((SECONDS + seconds))
|
||||
burst_until=0
|
||||
last_beat=$SECONDS
|
||||
echo "benchmark-watch-install: watching for $seconds s (idle poll ${interval}s, burst after a dialog)"
|
||||
|
||||
while [ $SECONDS -lt $deadline ]; do
|
||||
# A heartbeat, so "is it still running?" can be answered by reading the log instead of guessing.
|
||||
if [ $((SECONDS - last_beat)) -ge 30 ]; then
|
||||
echo " $(date +%H:%M:%S) still watching: $taps answered, $opened_windows window(s) seen"
|
||||
last_beat=$SECONDS
|
||||
fi
|
||||
|
||||
focus=$(focused_window)
|
||||
if is_installer "$focus"; then
|
||||
answer_dialog "$focus"
|
||||
|
||||
Reference in New Issue
Block a user