Where a package tcm runs with is installed (its directory): beside the tcm being tested (a packed one), or in the cache of the codebase these tests run in, where tcm provides it under an alias (the codebase's own tcm).
Stop a process this one started once this one ends, however it ends: killed (SIGKILL, a hung test's time limit), it can't stop anything itself, and what it started would run on for good, orphaned. A watchdog process (one for this process, started with the first it's told of: `WATCHDOG`) is told each process kept and each that ends; this process's end closes the pipe to it, and it stops those still running: asked to (SIGTERM), then made to (SIGKILL) if one hasn't in 5 seconds. (Something kept that isn't a child process, a server in this one, is withChildren's.)
Run tcm in `dir` alongside other things (another tcm, a server it calls), as `tcmIn` does, kept by `withChildren`'s `keep`: its exit status, and what it printed on both streams, once it has ended.
A new empty directory, resolved through symlinks; the space in its name catches quoting bugs.
withChildren<T>(fn: (keep: <C extends ChildProcess>(c: C) => C) => T | Promise<T>) => Promise<T>
Run `fn` with a way to keep the processes it starts (servers, watchers), and stop them when it's done, waiting until they have: a tcm stopped so writes what code it ran as it exits (coverage, which the suite reads once this test's process ends), and one still writing would be missed, its suite's result cached as though that code hadn't run. One that doesn't stop in 10 seconds is killed. And if this process ends first, however it ends (a test that hangs is killed by its suite's time limit, and its `finally` never runs), they're stopped all the same (`stopWhenThisEnds`).
Shared
WATCHDOG"\nconst pids = new Set();\nlet buf = \"\";\nprocess.stdin.setEncoding(\"utf8\");\nprocess.stdin.on…
The watchdog's program: reads `+<pid>` (kept) and `-<pid>` (ended) lines; when what it reads ends (the process that started it has), stops those still running: SIGTERM, then SIGKILL after 5 seconds.
A test's servers stop when it does, however it ends: one that fails midway stops them as it fails, and one that hangs, killed by its suite's time limit (SIGKILL: its `finally` never runs), has them stopped by its watchdog rather than left running for good. (This test is both: run again as a program of its own, with `role` saying which, it keeps a tcm server and fails, or hangs.)