deepseek-harness/scripts/test-fixture-cleanup.ts

50 lines
1.9 KiB
TypeScript
Raw Permalink Normal View History

fix: Windows-native CI findings on latest master Local run of check:ci:windows-complete (the windows-native gate) on latest master surfaced five Windows-only failures, all unreachable by current CI because the native windows job is disabled and the wine gate only covers build+site. - install-lefthook/translation-pairing-merge specs junctioned the real scripts/ and tsx package into fixtures; Windows recursive deletion (Node rmSync and git worktree remove) follows MOUNT_POINT junctions and deleted the repository's own directories mid-run. Fixtures now unlink their reparse points before any recursive removal (shared helper in scripts/test-fixture-cleanup.ts). - workflow-workerthread spawned its worker with an empty env; on Windows os.tmpdir() then degrades to the literal relative path undefined\temp, so tsx wrote its transform cache into a cwd-relative undefined/ directory inside the repo. The worker env now injects the host temp path on win32 (workerSpawnEnv, platform-parameterized and unit-tested on both arms). - workspace-context spec did not stub USERPROFILE (win32 homedir) or a set DSH_HOME, leaking the developer machine's real ~/.dsh/AGENTS.md into discovery. - ui-trajectory client-bundle spec mounted the built artifact without the remote/settingsScope provides the locale plugin needs, so the plugin never activated and no view registered. - subagent temp-fixture cleanup lacked the maxRetries Windows handle release needs under load (EPERM); added retries to the three affected specs and the fixture-cleanup helper.
2026-08-12 01:11:46 +08:00
/**
* Junction-safe fixture cleanup for Windows. Test fixtures junction the REAL
* `scripts/`, `node_modules`, and tsx package directories so installer probes
* resolve through them; Windows recursive deletion — both Node's `rmSync` and
* Git's `worktree remove` — follows MOUNT_POINT junctions into their targets
* and would delete the repository's own directories. POSIX `unlink`/`rm`
* already remove symlinks without following them, so the walk is a no-op
* there.
*/
import { lstatSync, readdirSync, rmSync, unlinkSync } from 'node:fs'
import { join } from 'node:path'
/**
* Recursively unlink every symbolic link (junction) under `path`.
* @param path - the fixture tree whose reparse points are unlinked.
*/
export function unlinkFixtureLinks(path: string): void {
const visit = (entry: string): void => {
let stat: ReturnType<typeof lstatSync>
try {
stat = lstatSync(entry)
} catch (error) {
if ((error as NodeJS.ErrnoException).code === 'ENOENT') return
throw error
}
if (stat.isSymbolicLink() || !stat.isDirectory()) {
if (stat.isSymbolicLink()) unlinkSync(entry)
return
}
for (const child of readdirSync(entry)) visit(join(entry, child))
}
visit(path)
}
/**
* Remove one fixture tree after its junctions are unlinked (see
* {@link unlinkFixtureLinks}). Retries the removal: Windows releases child
* process and antivirus file handles asynchronously, and an unretried
* `rmSync` fails immediately with EPERM under load. A 10-second retry window
* (50 attempts × 200 ms) covers the failover pool's slow handle release;
* release is one-shot (a terminated child's handles drain, not reacquired),
* so a bounded window suffices and never pins afterEach cleanup.
fix: Windows-native CI findings on latest master Local run of check:ci:windows-complete (the windows-native gate) on latest master surfaced five Windows-only failures, all unreachable by current CI because the native windows job is disabled and the wine gate only covers build+site. - install-lefthook/translation-pairing-merge specs junctioned the real scripts/ and tsx package into fixtures; Windows recursive deletion (Node rmSync and git worktree remove) follows MOUNT_POINT junctions and deleted the repository's own directories mid-run. Fixtures now unlink their reparse points before any recursive removal (shared helper in scripts/test-fixture-cleanup.ts). - workflow-workerthread spawned its worker with an empty env; on Windows os.tmpdir() then degrades to the literal relative path undefined\temp, so tsx wrote its transform cache into a cwd-relative undefined/ directory inside the repo. The worker env now injects the host temp path on win32 (workerSpawnEnv, platform-parameterized and unit-tested on both arms). - workspace-context spec did not stub USERPROFILE (win32 homedir) or a set DSH_HOME, leaking the developer machine's real ~/.dsh/AGENTS.md into discovery. - ui-trajectory client-bundle spec mounted the built artifact without the remote/settingsScope provides the locale plugin needs, so the plugin never activated and no view registered. - subagent temp-fixture cleanup lacked the maxRetries Windows handle release needs under load (EPERM); added retries to the three affected specs and the fixture-cleanup helper.
2026-08-12 01:11:46 +08:00
* @param path - the fixture tree to remove.
*/
export function removeFixtureSafely(path: string): void {
unlinkFixtureLinks(path)
rmSync(path, { recursive: true, force: true, maxRetries: 50, retryDelay: 200 })
fix: Windows-native CI findings on latest master Local run of check:ci:windows-complete (the windows-native gate) on latest master surfaced five Windows-only failures, all unreachable by current CI because the native windows job is disabled and the wine gate only covers build+site. - install-lefthook/translation-pairing-merge specs junctioned the real scripts/ and tsx package into fixtures; Windows recursive deletion (Node rmSync and git worktree remove) follows MOUNT_POINT junctions and deleted the repository's own directories mid-run. Fixtures now unlink their reparse points before any recursive removal (shared helper in scripts/test-fixture-cleanup.ts). - workflow-workerthread spawned its worker with an empty env; on Windows os.tmpdir() then degrades to the literal relative path undefined\temp, so tsx wrote its transform cache into a cwd-relative undefined/ directory inside the repo. The worker env now injects the host temp path on win32 (workerSpawnEnv, platform-parameterized and unit-tested on both arms). - workspace-context spec did not stub USERPROFILE (win32 homedir) or a set DSH_HOME, leaking the developer machine's real ~/.dsh/AGENTS.md into discovery. - ui-trajectory client-bundle spec mounted the built artifact without the remote/settingsScope provides the locale plugin needs, so the plugin never activated and no view registered. - subagent temp-fixture cleanup lacked the maxRetries Windows handle release needs under load (EPERM); added retries to the three affected specs and the fixture-cleanup helper.
2026-08-12 01:11:46 +08:00
}