mirror of
https://github.com/callstack/agent-device.git
synced 2026-09-14 20:06:34 +08:00
0fb38f1da2
* test: prune abandoned test-run tmp directories at run setup A run killed before its teardown (tool-timeout SIGKILL, OOM, cancelled job) left /tmp/agent-device-test-run-<pid>-* behind, and check:tmpdir-leaks — which runs after test:unit in check:unit — flagged every dead-pid directory it found. It could not tell this run's leak from a historical one, so one killed run made every later, otherwise-green gate on the host fail. Both TMPDIR redirection entry points (the Vitest global setup and the node --test wrapper) now prune dead-pid run directories before creating their own, printing one [tmpdir] line when they did; the post-run check keeps its semantics and can now only ever name the run that just finished. Live owners (a concurrent run in another worktree) are never touched. The root/prefix constants move into check-tmpdir-leaks-model.ts, next to the liveness classification, so the setup can import the prune without a cycle. * test(tmpdir): a run directory is live while any process still holds it as TMPDIR, not only while its owner runs Review (P1): owner-pid liveness alone would prune a directory out from under the orphaned children of a SIGKILLed run — the node --test chain, Vitest forks, or a daemon a test spawned all keep running with that TMPDIR. The liveness model now reads every process's TMPDIR (ps -E on macOS, /proc/<pid>/environ on Linux) and treats a run directory as live while its owner pid is alive OR any process's TMPDIR points into it; both the prune and the post-run leak check use it. Regression: a wrapped probe spawns a detached long-lived child, only the wrapper is SIGKILLed, the next prune preserves the directory; after every consumer exits, the next prune removes it. Planted red with owner-only liveness: the orphaned directory is pruned.
33 lines
1.8 KiB
TypeScript
33 lines
1.8 KiB
TypeScript
// Fails if any agent-device-test-run-* directory under TEST_RUN_TMP_ROOT is
|
|
// abandoned — its owning process has exited without running its cleanup
|
|
// (crash, OOM, timeout kill) AND no live process still holds it as TMPDIR.
|
|
// Directories owned by a still-running process are left alone: a concurrent
|
|
// `vitest run` (or node --test lane, wrapped by scripts/node-test-tmpdir.ts) in
|
|
// another worktree keeps its own directory present until its own teardown,
|
|
// which is not a leak; so are the orphaned children of a killed run, until the
|
|
// last of them exits. See check-tmpdir-leaks-model.ts for the liveness model.
|
|
//
|
|
// Covers both redirection mechanisms sharing this root/prefix: Vitest's
|
|
// globalSetup/globalTeardown (scripts/vitest-tmpdir-global-setup.ts) and the
|
|
// node --test wrapper (scripts/node-test-tmpdir.ts, #1595) that every
|
|
// `node --test` package.json script now runs through. Both prune what an
|
|
// earlier killed run left behind before creating their own directory, so a
|
|
// failure here names the run that just finished — never a historical one.
|
|
|
|
import path from 'node:path';
|
|
import { TEST_RUN_TMP_ROOT, findLeakedRunDirectories } from './check-tmpdir-leaks-model.ts';
|
|
|
|
const leaks = findLeakedRunDirectories(TEST_RUN_TMP_ROOT);
|
|
|
|
if (leaks.length > 0) {
|
|
const details = leaks.map((name) => `- ${path.join(TEST_RUN_TMP_ROOT, name)}`).join('\n');
|
|
throw new Error(
|
|
`Found ${leaks.length} abandoned agent-device-test-run-* director${leaks.length === 1 ? 'y' : 'ies'} in ${TEST_RUN_TMP_ROOT}:\n${details}\n` +
|
|
'Their owning process has already exited, so their globalTeardown never ran (crash, OOM, timeout kill); investigate the run that produced them.',
|
|
);
|
|
}
|
|
|
|
process.stdout.write(
|
|
`No abandoned agent-device-test-run-* directories found in ${TEST_RUN_TMP_ROOT}.\n`,
|
|
);
|