Skip to content

ci: wait for emulator services to be ready post-snapshot#64

Open
gmaclennan wants to merge 4 commits intomainfrom
claude/ci-emulator-readiness
Open

ci: wait for emulator services to be ready post-snapshot#64
gmaclennan wants to merge 4 commits intomainfrom
claude/ci-emulator-readiness

Conversation

@gmaclennan
Copy link
Copy Markdown
Member

Summary

sys.boot_completed flips as soon as zygote is alive, which on a snapshot restore happens before system_server finishes binding the settings, package, and activity services. The previous wait-for-device + getprop loop returned almost instantly because the property was already set, and the next adb shell settings put then crashed with:

cmd: Failure calling service settings: Broken pipe (32)

Replace it with wait_for_emulator, which polls each service we're about to call until it actually responds, with a 120s ceiling. One retry on each settings put covers a residual race where list succeeds but a write transaction loses to first-time service initialisation.

disable-animations: false is unchanged — emulator-runner's own input keyevent 82 path crashes the emulator on this image, which is why the workflow drives the settings directly.

Test plan

  • Re-run the Android instrumented test workflow a few times and confirm no "Broken pipe" failures
  • Confirm the readiness probe completes in well under 120s on a typical run

Generated by Claude Code

claude added 4 commits May 7, 2026 22:57
`sys.boot_completed` flips as soon as zygote is alive, which on a
snapshot restore happens before `system_server` finishes binding the
`settings`, `package`, and `activity` services. The previous wait-for-device
loop returned almost instantly because the property was already set, and the
next `adb shell settings put` then crashed with `cmd: Failure calling service
settings: Broken pipe (32)`.

Replace it with a probe that polls each service we're about to call until
it actually responds, with a 120s ceiling. One retry on each `settings put`
covers a residual race where `list` succeeds but a write transaction loses
to first-time service initialisation.

`disable-animations: false` is unchanged — emulator-runner's own
`input keyevent 82` path crashes the emulator on this image, which is why
the workflow drives the settings directly.
reactivecircus/android-emulator-runner v2 invokes the script with
\`/usr/bin/sh\` (dash on Ubuntu), not bash. The previous version used
\`[[ ]]\`, \`local\`, and \`\$SECONDS\` which dash refuses to parse with:

  /usr/bin/sh: 1: Syntax error: end of file unexpected (expecting \"}\")

Replace with POSIX-only constructs: \`[ ]\` tests, \`\$(date +%s)\` for
elapsed-time tracking, an inline loop with a \`ready\` flag instead of a
function. Verified parses + runs under dash locally.
reactivecircus/android-emulator-runner v2 invokes the workflow's
`script:` line by line through `sh -c`, not as a single multi-line
script — so any function definition, while loop, or other multi-line
construct is split across separate shell invocations and fails to
parse (the previous attempts hit "expecting }" / "expecting done").

Move the entire body to scripts/run-android-instrumented-tests.sh and
have the workflow invoke it as a single line. The script can use
bash freely (proper shebang, set -euo pipefail).
Scope the script down to just the multi-line wait-for-emulator-services
loop (the only part that can't survive the action's per-line `sh -c`).
Animation settings and the gradle invocation move back inline as
single-line statements; the `||` retry uses a one-line brace group,
which dash parses fine.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants