Repository navigation
fix(oracle-gaps): retire a batch's copies from Vitest's state - #61
KyleAMathews wants to merge 3 commits into
Conversation
A check runs each mutant in a new copy of its test file. Vitest's state kept every file and test task it ever ran (filesMap by path, idMap by task id), so a check held every test of every copy: about 377k test cases on a four-file suite, which exhausted a 2 GB heap. Once a batch's units are plain data, its copies leave the state: their stale idMap entries go first (shape-guarded), then clearFiles replaces each path's file entry. Co-authored-by: Isaac <no-reply@databricks.com>
|
Important Draft PR not reviewedDraft PRs are not automatically reviewed by default.
To automatically review draft PRs, update your CodeRabbit configuration: reviews:
auto_review:
drafts: true
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. |
|
commit: |
The gap CLI's e2e driver sets ORACLE_GAPS_TEST_RETENTION on each run and records one line per batch: the count of Vitest state entries (filesMap, pathsSet, idMap) and Vite module nodes that still name the batch's retired copies. The law: each count is 0 after retirement. This commit adds the hook and the law, not the fix, so CI records the RED on the parent code. Co-authored-by: Isaac <no-reply@databricks.com>
… file entry Vitest's clearFiles replaces a copy's file entry, and leaves its path in pathsSet, one placeholder task in idMap, and Vite's module node and transform for the copy. The retention law (bounded retention, after each batch) fails on 46dfd3e in CI: each count is nonzero. retireCopies now removes the copy's filesMap key, pathsSet entry, and idMap tasks. retireModules invalidates each copy's module through Vite's API and removes it from every environment's graph maps. Both guard the shapes they touch and throw if one changes, so a Vitest or Vite that changes them fails loudly rather than leaking. Co-authored-by: Isaac <no-reply@databricks.com>
Summary
The gap CLI kept every test of every mutant copy alive for the whole check. Each mutant runs in a new copy of its test file, and Vitest's state holds each copy's file and test tasks (
filesMapby path,idMapby task id) and never releases them. On the klona four-file suite (295 mutants, two contexts), a 2 GB heap runs out and the check fails. The default 4 GB heap is close to the limit (3.66 GB peak in the child).This PR retires a batch's copies from Vitest's state once their units are plain data. It removes their stale
idMapentries behind a shape guard, then calls Vitest'sstate.clearFiles.clearFilesexists with the same semantics in Vitest 4.1.12 and 5.1.0. On its own it leaves the test tasks inidMap, so the explicit delete is needed.Decisions
results.jsonis the stable record (the same C ruling).retireCopieschecks thatstate.filesMapandstate.idMapare Maps and throws otherwise. It callsclearFiles, which exists in Vitest 4.1.12 and 5.1.0.Evidence
affeb1a,node --max-old-space-size=2048on the klona copy, same seed and mutants. Result:FATAL ERROR: Ineffective mark-compacts near heap limit ... JavaScript heap out of memory, thenoracle-gaps: done error, the run's process exited with SIGABRT: it ran out of memory; give Node more (NODE_OPTIONS=--max-old-space-size=<MB>) or run fewer --contexts.3924eb6): completed, 43 gaps (provisional), the same done line, child peak heap 1862 MB (3659 MB before the change at the default heap). Log/tmp/oom/green.log.results.jsonfrom the baseline run and the GREEN run are identical once timing fields and the output path are dropped (392 entries each). The run id changes, because it hashes the CLI's owncheck.mjs. One streamed gap line moved position in stdout order; the results do not change.idMapstep removed (clearFileskept). Both run at--max-old-space-size=2048on the same inputs, and both endFATAL ERROR: ... JavaScript heap out of memorywithoracle-gaps: done error ... ran out of memory. The oracle run rejects each. Logs/tmp/oom/mutant-noretire.logand/tmp/oom/mutant-noidmap.log.results, which are not the dominant term in the snapshot. The fast suites run in CI. The Vitest state fields are internal (filesMap,idMap); a shape change throws instead of leaking.This pull request and its description were written by Isaac.