Skip to content

Preview multi-run: never relaunch the app, and bound the adb polls - #28

Merged
jpcottin merged 2 commits into
mainfrom
ci/multirun-no-relaunch-and-failfast
Jul 27, 2026
Merged

Preview multi-run: never relaunch the app, and bound the adb polls#28
jpcottin merged 2 commits into
mainfrom
ci/multirun-no-relaunch-and-failfast

Conversation

@jpcottin

Copy link
Copy Markdown
Owner

1. The app is never relaunched after a restore

The job issued am start unconditionally on every cycle, including after a snapshot restore. Whether the app comes back by itself is the question this job exists to answer — launching it there answers it for the emulator.

It was invisible because the preview emulator does restore the app, so the launch was a no-op:

RUN 4 app pid after boot/restore (pre am-start): 2388
Starting: Intent { cmp=com.jpcottin.vulkanspaceinvaders/android.app.NativeActivity }
Warning: Activity not started, intent has been delivered to currently running top-most instance.

But had a restore ever dropped the app, that same line would have relaunched it and produced a healthy-looking exit screenshot, hiding the failure entirely.

Now only cycle 1 launches. Later cycles report app survived restore: YES/NO and are left alone — matching the Android CLI multi-run job, so the two are directly comparable: same measurement, different emulator. Input is only driven while the app is actually running, so a dead app cannot leave taps landing on the home screen.

2. The adb polls are bounded

The polling loops called adb without a timeout. adb blocks indefinitely against a wedged device, so the loops never iterated — the nominal 180s and 480s budgets never applied and the boot timeout branch never ran.

That is why the previous run sat silent for 23 minutes after Snapshot 'default_boot' loaded in 2488 ms and was killed by the 25-minute step timeout with no diagnostics at all.

Every adb call in the loops is now wrapped in timeout, and the failure paths dump the tail of the emulator log. A hang now reports within its budget and says something useful.

On the hang itself

Not addressed here, and it does not appear to be caused by any recent change: the emulator-preview-multirun job passed 12 consecutive runs before this failure, the job and the composite action were byte-identical to the previous passing commit, and the main run immediately after passed as well. It looks intermittent. This PR makes it diagnosable rather than silent, which is the prerequisite for chasing it if it recurs.

jpcottin added 2 commits July 26, 2026 17:37
Two problems, both in the preview multi-run job.

The job issued `am start` unconditionally on every cycle, including after a
snapshot restore. Whether the app comes back by itself is the question this
job exists to answer, so launching it there answers it for the emulator. It
happened to be invisible because the preview emulator does restore the app,
so the launch was a no-op ("Activity not started, intent has been delivered
to currently running top-most instance") -- but had a restore ever dropped
the app, the relaunch would have produced a healthy-looking screenshot and
hidden it. Now only cycle 1 launches; later cycles report
"app survived restore: YES/NO" and are left alone, matching the Android CLI
multi-run job so the two are directly comparable. Input is only driven while
the app is actually running, so a dead app cannot leave taps landing on the
home screen.

The polling loops also called adb without a timeout. adb blocks indefinitely
against a wedged device, so the loops never iterated, the nominal 180s and
480s budgets never applied, and the "boot timeout" branch never ran. One run
sat silent for 23 minutes after "Snapshot 'default_boot' loaded" and was then
killed by the step timeout with no diagnostics. Each adb call is now bounded
and the failure paths dump the tail of the emulator log, so a hang reports
within its budget and says something useful.

The hang itself looks intermittent -- twelve runs of this job passed before
it and the run straight after it passed too -- and is not addressed here.
The new tap guard reads the app pid to decide whether to drive input, but a
single pidof query races the launch and can come back empty while the
process is still starting. That suppressed the taps in cycle 1, so the game
stayed on the TITLE screen -- auto-play only pilots during PLAYING -- and the
cycle played ~6s against ~25s for the others.

Poll for the pid the way the Android CLI multi-run job already does.
@jpcottin
jpcottin merged commit dc5df10 into main Jul 27, 2026
14 checks passed
@jpcottin
jpcottin deleted the ci/multirun-no-relaunch-and-failfast branch July 27, 2026 01:08
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.

1 participant