Design, review, and diagnose DeepSeek Harness tests and fixtures that can fail nondeterministically under CI concurrency, shared host resources, clocks, process
复制下面这句话,粘贴给 Claude Code、Codex、Cursor 等 AI 编程工具,它会读取安装说明并在你确认后完成安装。
请阅读 https://ai.atlankj.com/install/asset/gh-dsh-ci-test-reliability-f681d6fca173 ,按照其中的说明把「dsh-ci-test-reliability」安装到你(当前 AI 工具)中。执行前先告诉我将运行的命令和写入的位置,等我确认。
查看 AI 将读取的安装说明正在读取 GitHub 原文…
内容来自 GitHub 原始文件,由原作者维护。在 GitHub 查看
Build tests that remain correct under the repository's real CI topology, not only when run alone on a quiet workstation. This skill owns isolation and reliability decisions; it does not replace the repository's test-tier policy or select every command for a push.
Assume these layers can overlap unless the active configuration proves otherwise:
Process isolation does not isolate host ports, predictable filesystem paths, external services, databases, sockets, or inherited child processes. For every acquired resource, identify its owner, atomic allocation mechanism, observable readiness signal, registered cleanup, and quiescent completion signal.
Do not serialize an entire suite merely because one fixture lacks isolation. Narrow the exclusive scope or change the resource allocation first. A sequential Vitest block cannot protect a host resource from another file, process, job, or runner.
Use the resource owner's allocator instead of checking availability and claiming it later.
listen(0) and read the assigned address only after the server reports that it is listening. Never scan for a free port and bind it later.mkdtemp; do not acquire predictable shared paths.Literal paths and URLs used only as parser inputs or expected values are not acquired resources. Do not rewrite them merely because they look fixed.
Treat process.env, cwd, fake timers, locale and timezone, module mocks, registries, console hooks, globalThis, and global fetch interception as exclusive mutable resources.
Prefer an injected dependency or instance-local adapter. When mutation is required:
try/finally around the smallest mutation scope;afterEach fallback when failure before the local finally is plausible;CI runs the same suite on Windows and on POSIX hosts, and a value the operating system owns does not always come back the way a test wrote it.
mtime to prove that a fingerprint invalidates anyway holds everywhere; restoring it to prove that a record stays valid assumes a lossless round trip, which NTFS's 100-nanosecond ticks do not give a fractional millisecond. When the assertion depends on the restoration, take the expected value from a fresh read rather than from the remembered one.http_proxy and HTTP_PROXY as separate keys holds one entry there.Prefer an observation that holds on every platform. When a case genuinely cannot, exclude it on that platform explicitly.
A describe or case timeout overrides the runner's --testTimeout instead of yielding to it, so a value below the lane's budget lowers what CI already granted — and the same literal reads as a widening on a host whose default is smaller. A suite bound by process creation takes the lane budget; a tighter value carries the reason it is tighter.
Raise the hook budget with the test budget. Setup and teardown pay the same contention, so lifting only the case budget moves a contended failure into afterEach.
Where a timeout is the subject, keep the outer wait far larger than the timeout under test. A case proving that a 20 ms deadline fires must not race the harness's own wait, or load decides which deadline reports first.
A fixed sleep is not evidence that setup completed or cleanup settled.
Register cleanup immediately after acquisition so assertion failures also release the resource. Cleanup stops new callbacks or requests, detaches listeners, restores global hooks, terminates owned work, and awaits child exit, server close, worker termination, or the equivalent completion signal.
Calling abort(), close(), or kill() without awaiting the owned completion signal is incomplete teardown. When late completion is possible, prove that disposal prevents it from mutating another test.
Stress runs supplement a deterministic regression; they do not replace one.
Do not present these as root-cause fixes for deterministic local tests:
Retries remain valid for documented transient external-provider tests under the real-API policy. Keep that exception at the external boundary.
Restoring a budget is not masking. Raising a suite to the lane budget it already had, or sizing a bounded retry to the contention actually measured on the runner, names the awaited work and returns what the lane granted; neither invents headroom around an unexamined wait.
For an existing probabilistic CI failure, read the CI flake diagnosis workflow. A diagnosis-only request remains read-only: report the cause and evidence unless the user also asks for a fix.
Run the smallest focused regression for the affected behavior. Add topology-specific evidence only when the change owns that risk:
Before a push, use dsh-pre-push-checks. Report exact commands and observed results; do not describe retries, skipped tests, or pending CI as passing.