Skip to content

android: smoke-test sentinel + local runner script#347

Open
leaiss wants to merge 5 commits into
fix/android-preload-fixed-pointfrom
ci/android-emulator-smoke-test
Open

android: smoke-test sentinel + local runner script#347
leaiss wants to merge 5 commits into
fix/android-preload-fixed-pointfrom
ci/android-emulator-smoke-test

Conversation

@leaiss
Copy link
Copy Markdown
Collaborator

@leaiss leaiss commented May 27, 2026

Summary

Stacked on PR #343 (preload fix). Adds two things to make the runtime+plug-in regression that #343 fixed catchable going forward:

  1. ANDROID_POC_SENTINEL log line in cube_handle_vk_android immediately after xrCreateInstance -> XR_SUCCESS. Distinctive string a single grep can match.
  2. scripts/android-smoketest.sh — single-command local validation: boots an emulator if no device attached, builds the leia-plugin + drops 16 transitive .so into the runtime APK's jniLibs/, builds runtime + test APKs, installs both, launches the test app, polls logcat for the sentinel with a 60s timeout.

Tested locally end-to-end on an Android-36 x86_64 emulator: passes in ~6s.

Why local instead of CI

I originally tried adding a CI emulator gate to build-android.yml, but cross-org CNSDK fetch from LeiaInc/leiainc.github.io is wedged:

  • Workflow GITHUB_TOKEN is App-scoped to DisplayXR → 404 against LeiaInc repos via either REST or git+token.
  • Anonymous git clone is rejected — github.com requires auth, and the runner's credential helper turns the auth prompt into a hard fail (GIT_TERMINAL_PROMPT=0).
  • LFS raw URLs 404.

Three commit attempts (sparse LFS checkout, token clone, GIT_ASKPASS=/bin/true) all failed at different layers. None is a 5-min fix — they all need either a PAT secret with cross-org read or vendoring CNSDK into a DisplayXR repo. Both are doable later; neither is needed to ship regression-catching now.

Usage

# From the runtime repo root:
scripts/android-smoketest.sh

# Common env overrides:
PLUGIN_DIR=/c/displayxr-leia-plugin \
CNSDK_ROOT=./cnsdk \
SKIP_EMULATOR=1 \
scripts/android-smoketest.sh

Exits 0 on pass, 1 on hard fail (FATAL / XR_ERROR), 2 on timeout, 3 on missing prereq.

Stacking

Based on PR #343. Rebase onto main after #343 merges.

🤖 Generated with Claude Code

@leaiss leaiss requested a review from dfattal as a code owner May 27, 2026 20:42
@leaiss leaiss force-pushed the ci/android-emulator-smoke-test branch from f90b2f0 to 0358093 Compare May 27, 2026 21:08
@leaiss leaiss changed the title ci(android): emulator smoke test + test-app sentinel android: smoke-test sentinel + local runner script May 27, 2026
leaiss added 2 commits June 2, 2026 08:57
…ccess

Adds a single distinctive log line after xrCreateInstance returns
XR_SUCCESS. The CI emulator smoke test (next commit) greps logcat for
this exact string to assert the full broker -> runtime dlopen ->
plug-in load -> xrCreateInstance chain reached success — same chain
PR #343's preload regression broke.

Tag intentionally specific so the grep can't false-match other log
output. Do not rename without updating the CI workflow.
Single-cmd local replacement for the CI emulator gate we backed out:
- Boots emulator if no device attached
- Builds plug-in + installs 16 transitive .so into runtime tree
- Builds runtime APK + test app APK
- Installs both, launches test app
- Greps logcat for the ANDROID_POC_SENTINEL line, with 60s timeout
- Returns 0 on pass / 1 on hard fail / 2 on timeout / 3 on missing prereq

Validated locally end-to-end: passes in ~6s on Android-36 emulator.

Why local instead of CI: the CI smoke test needs to clone CNSDK from
LeiaInc/leiainc.github.io which the workflow's GITHUB_TOKEN can't read
(App-scoped to DisplayXR), and anonymous clones are rejected by
github.com's auth path. Cross-org access needs a PAT secret or
vendoring CNSDK — not blocking on either for now. Devs running this
already have CNSDK on disk.
@leaiss leaiss force-pushed the fix/android-preload-fixed-point branch from d7ff93e to 95eb761 Compare June 2, 2026 15:57
@leaiss leaiss force-pushed the ci/android-emulator-smoke-test branch from 0358093 to e390c66 Compare June 2, 2026 15:57
leaiss and others added 3 commits June 2, 2026 09:06
…Activity

The test app's entry point became a Kotlin .MainActivity wrapper (#359:
requests CAMERA at onCreate, then hands off to NativeActivity). The
hard-coded `am start -n $PKG/android.app.NativeActivity` then fails with
"Activity class does not exist" — a cross-stack break only visible when
the smoke-test (this stack) and the permission wrapper (#350/#359 stack)
are combined. Resolve the launcher activity via the LAUNCHER intent so
the smoke test survives activity-class renames.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Review-pass robustness fixes so a hardware/CI run reports the true cause
instead of always-"sentinel timeout":
- bound the emulator boot wait with EMULATOR_BOOT_TIMEOUT (default 300s);
  bare wait-for-device / boot_completed poll could hang forever.
- assert_abi(): arm64-v8a must be in the device's cpu.abilist before building
  (the test app is arm64-only; an x86_64 AVD otherwise dies late with a
  confusing INSTALL_FAILED_NO_MATCHING_ABIS).
- after launch, confirm the app process actually started (monkey returns 0
  even on a no-op / instant crash) — fail with return 1, not a timeout.
- single logcat capture per poll; distinguish 'adb died' (return 3) from
  'not seen yet', and detect the process vanishing mid-bring-up (crash → 1).

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The script header advertised PLUGIN_BRANCH ("branch to check out in the
plug-in repo") but build_plugin_and_install_jnilibs never acted on it —
a silent no-op that built whatever the plug-in tip happened to be. Check
it out (requiring a clean plug-in tree, aborting otherwise) so a smoke
run pins a known plug-in revision, matching the bring-up checklist's
`PLUGIN_BRANCH=docs/cnsdk-c-abi-surface` instruction.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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