test: remove dsh-* temp dirs created by unit tests at teardown

Spec files that create /tmp/dsh-* directories via mkdtemp now track and
delete them in afterEach/afterAll; module-scope fixture dirs (executor
spill dirs) are removed in afterAll. The file list came from the
observed-residue inventory on the self-hosted CI host: only specs whose
dirs actually accumulated were leak sources (issue #3134), superseding
the kept-but-unmerged CI sweep branch per the #3233 review decision.

Product per-process spill roots (dsh-subprocess-local spawn,
dsh-spill-local store) register a process-exit handler that removes the
memoized dir, so processes that used the spawn/spill path clean up on
normal exit. A SIGKILLed process cannot run in-process teardown; the
machine-side timer remains the backstop for that path.

Agent Note: .agents/notes/implemented/process/2026-08-28-test-temp-dir-self-cleanup.md
This commit is contained in:
Chinesezjc
2026-09-03 16:19:18 +08:00
parent 9fe2112a63
commit 0364343a7e
39 changed files with 461 additions and 73 deletions
@@ -1,4 +1,4 @@
import { existsSync, mkdirSync, mkdtempSync, realpathSync } from 'node:fs'
import { existsSync, mkdirSync, mkdtempSync, realpathSync, rmSync } from 'node:fs'
import { tmpdir } from 'node:os'
import { join } from 'node:path'
import { afterEach, describe, expect, it, vi } from 'vitest'
@@ -22,8 +22,12 @@ declare module '@deepseek-ai/dsh-typert-protocol' {
const roots: Context[] = []
/** Workspace roots created per test, removed after their context settles. */
const tempDirs: string[] = []
afterEach(async () => {
await Promise.all(roots.splice(0).map(ctx => ctx.fiber.dispose()))
for (const dir of tempDirs.splice(0)) rmSync(dir, { recursive: true, force: true })
})
interface Deferred<T> {
@@ -39,6 +43,7 @@ function deferred<T>(): Deferred<T> {
async function harness() {
const root = realpathSync.native(mkdtempSync(join(tmpdir(), 'dsh-workspace-controller-')))
tempDirs.push(root)
const ctx = new Context()
roots.push(ctx)
await ctx.plugin(SessionStore)