Repository navigation
DEVICE-SPEED b: Android quickboot from a golden snapshot (same device results, ~25-30 s less per emulator boot) - #157
Merged
Merged
Conversation
…nes-host on xcode-27), regen --skip/--only, ci.yml workflow_dispatch
…ery Chrome round (it is a sink, ~50 min on 3 cores)
…he result of the job they need)
…hes are invisible to other branches); never pushes there
…ion, sorted .gitattributes fixtures.ts registers each group on one line of GROUPS, sorted by id, and runs the legacy groups in their frozen order, then every later group by id. scripts/regen.ts keeps the legacy steps and MANUAL entries and gathers each feature's steps (placed after the step they name), extra outputs and MANUAL entries from scripts/regen-steps/<feature>.ts, one sorted line per feature. .gitattributes is sorted (same patterns, same attribute). STEPS, MANUAL, FIXTURE_GROUPS and FIXTURES are unchanged; registry-claims.test fails when two features claim one group, fixture id, step name, output or command.
…itattributes keeps master's animator line in sorted order
…lap, and registry-claims checks no tracked file has two writers; fixtures.ts documents the run order of later groups
…ode (8x faster compiles; same digests)
…of one browser (same snapshot)
…ules, so ua:capture's regen inputs leave out the compiler
…umented node:crypto fast path
….ts; the compiler and the internal entry no longer import it, and regen keys a workspace package on the entry Node picks under the step's conditions
…ault) planted-swift.test.ts and planted-kotlin.test.ts compiled and ran a planted harness for each of the 7 FAULTS in one test (planted-swift took 734 s on the CI runner, planted-kotlin 329 s). Each (target, fault) pair is now its own test file (planted.ts holds the shared test), so vitest schedules them across workers and shards. planted-union.test.ts proves the files cover FAULTS on both targets exactly once.
The determinism describe of parity.test.ts (356 tests, 290 s of its 548 s on the CI runner) runs from parity-determinism-<k>.test.ts, one chunk of FIXTURES per file under the same describe titles, each with its own Chrome and its own coverage check. parity.test.ts keeps a coverage test proving the chunk files together check every fixture once.
… with any NaN; corpus inputs, results and digests write every NaN as 7ff8000000000000 (x86-64 makes some fff8...)
… are not serialized through Playwright's value serializer
…each in its own context (same bytes)
…s run; only the vectors verdict waits for its host run
…cold boot and prepareAvd, keyed by emulator, image, AVD config, flags and provisioning code
Commands: pnpm regen
Commands: pnpm regen
HOTSPOT-SPLIT 2/2: per-feature fixture groups and regen steps; sorted .gitattributes
CI-OFFLOAD step 2: regen-on-ci (pnpm regen on GitHub runners, pushed back to the branch)
…napshot and retries cold; a failed save or key read never fails the boot
Commands: pnpm regen
Commands: pnpm regen
Commands: pnpm regen
translate: a stale harness cache entry (artifact deleted, directory kept) is replaced, never returned; root cause of the land-147 'Unable to access jarfile' failures
land: keep the translate harness build caches when cleaning ignored outputs
land: an idle machine is quiet even with a heavy slot held
SLOW-SPLIT 2: parity determinism shards in 4 chunk files
Commands: pnpm regen
Commands: pnpm regen
Commands: pnpm regen
NaN-any: a NaN matches any NaN in the bit-exact corpus comparison (PM ruling)
tw-sweep: compile on every core; Chrome checks on 8 pages, each capture one JSON string (same snapshot)
Chrome captures: pixel, DPR and break captures take 8 cases at once (same bytes)
Commands: pnpm regen
Lanes verdict at the edge: lanes.json no longer invalidates every regen step
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
Commands: pnpm regen; pnpm run parity:devices; pnpm regen
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What changed (DEVICE-SPEED b, speed-research.md item 7): a matrix AVD now quickboots from a golden snapshot instead of always booting cold with
-no-snapshot.How the snapshot is made (device-run.ts):
liveProblems) andprepareAvd(settings, text scale, stay-awake, keyguard, the settled-launcher wait) run.saveGoldenuninstalls the host app, removes the vectors dir, savesadb emu avd snapshot save dragon-golden, and only then writes the snapshot's key next to the AVD (dragon-golden.key).How it is used:
-snapshot dragon-golden -force-snapshot-load -no-snapshot-save, so a run never writes back into it.liveProblems,prepareAvdand the focus wait all run again.The key is a sha256 over:
source.properties;config.ini;prepareAvd,waitForSettledFocusandsaveGolden, the text scale and the settle constants.Change any of them and the next boot is cold and saves a new snapshot.
Failure paths:
failedAttemptStepdecides what a failed attempt does next, and is tested on every combination.provision = false) always boots cold.Unchanged:
-gpu swiftshader_indirect(the pixel evidence's renderer), and every other flag. All emulator arguments now come fromemulatorArgs.Proof. Full local device runs through
/tmp/device-lease.sh, compared with master's committed records (/tmp/dds/compare.mts): the land driver'sdeviceRunProblems, byte equality of bothdevice-failures-*.json, and a deep diff oflanes.jsonwith onlyevidence.laneCodemasked.-no-snapshotSo results are identical with and without the snapshot. Each emulator boot saves about 25–30 s, and the memory budget admits the next device sooner.
Disk: each golden snapshot is about the AVD's 2 GB of RAM, under
~/.android/avd/<name>.avd/snapshots/dragon-golden.Tests:
emulatorArgs;failedAttemptStepon every combination.vitest rundevice-run, lanes-concurrent and emulator-log: 65/65 pass (head 0169767).pnpm typecheck: pass.Device step pending: lanes-records, p6a-promotion and device-failures fail only on the changed laneCode. Regen outputs are not committed for the same reason.
Overlap: #132 edits device-run.ts (
androidImage,IOS_RUNTIME,memoryReserve). Those hunks are textually apart from this one. On CI (CI=true, GitHub's runners) quickboot is off (goldenEnabled): a runner is fresh every job, so a saved snapshot would never be loaded, and its boots stay cold and save nothing, as today. No workflow file changes.Size: about 14 KB of reviewed diff in 2 files.
Review round (precomputed review of 0169767), head 1ae7ac1:
Medium, fixed: on the boot that saves the snapshot, the device now settles again after the save (
saveGoldenAndSettle: the uninstall, vectors-dir removal and paused VM all come before the secondwaitForSettledFocus). That function is in the snapshot key.Fixed guest timezone: every boot, cold or snapshot, runs with
-timezone Etc/UTC(GUEST_TIMEZONE, part of the flags in the key), so neither depends on the host's zone.Boot mode recorded: an Android device record now carries
boot: 'snapshot' | 'cold' | 'running'. iOS records and older records have none.Drop only on load failures: the snapshot is dropped only when the emulator's log says the snapshot failed to load (
snapshotLoadFailed), or when a live emulator failed to boot from it. Any other exit (a taken port, a full disk) keeps it and leaves the serial alone, as a cold boot does.Proof on the new head (full local device runs through the device lease, compared with master):
Both: the judge reports no problems, and both failure lists are byte-identical. The only
lanes.jsondifferences are the 18 newdevice.bootfields on Android sets (intended).Tests: device-run, lanes-concurrent, emulator-log, device-lanes and state-lanes: 115/115 pass.
pnpm typecheck: pass. CI green on 1ae7ac1.Review round 2, head d910710: an emulator that exits while booting from the snapshot, with no load-failure line in its log (for example a truncated snapshot that crashes), no longer leaves the AVD stuck. The retry is cold. The snapshot is dropped, and retaken, only if that cold boot succeeds (
dropSuspect). If the cold boot fails too (a taken port, a full disk), the snapshot is kept. Tests: device-run, lanes-concurrent, emulator-log, device-lanes and state-lanes, 116/116 pass.pnpm typecheck: pass. CI green. Only failure paths changed, so I did not repeat the device run; the r157a and r157b proof above still covers successful boots.🤖 Generated with Claude Code