test(windows): cover final native branches

This commit is contained in:
Tianyi Cui
2026-08-09 03:50:06 +08:00
parent bfb456e0c6
commit e7e75e7972
5 changed files with 42 additions and 3 deletions

View File

@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write .agents/notes/implemented/process/2026-08-08-native-windows-pull-request-ci.md
2026-08-08-native-windows-pull-request-ci.md: 419d1138bbd3ab9296b38ed136e03146ceca686d
2026-08-08-native-windows-pull-request-ci.zh.md: 5353b21c5a69e6ad847065d124d1bddb4d793e56
2026-08-08-native-windows-pull-request-ci.md: 0d85517e877694a09adf454a9acad3da78ebf0e1
2026-08-08-native-windows-pull-request-ci.zh.md: 4c7dfe6f1ec290a1dee4cb91f7e78ea7a52f32bb

View File

@@ -44,6 +44,8 @@ The project-skill composition fixture had one separate eventual-consistency race
The next exact-head run passed all 10,933 instrumented tests but correctly failed the per-file threshold at 99.95%, exposing five branches that Linux happened to cover. Deterministic cross-platform fixtures now exercise backward PTY scrollback pagination, a settings document that names a directory, an invalid SQLite filename, and an atomic-writer lock beneath a regular-file parent. The credentials provider's remaining `stat` and mode-enforcement arm is intrinsically POSIX, so it carries the same narrow annotated peer ignore used by the durable JSONL and storage backends; its behavior test remains enforced on POSIX. The threshold and source-file inventory remain unchanged.
The follow-up exact-head run passed all 10,937 instrumented tests and narrowed the threshold result to 99.99%. Its two remaining lines showed that the first PTY fixture had reached the page-offset helper but only supplied two pages, and that Windows path canonicalization rejected the real invalid-path fixture before `readFile` reached the reload-policy branch. The PTY fixture now supplies three backward pages, while the watcher fixture injects one non-absence read failure after the real permission check; both retain the observable output or last-good-snapshot assertions they exist to prove.
POSIX mode bits, chmod-based unreadability, and chmod-based writer-lock refusal do not exist as equivalent Windows facilities. Those acceptance cases remain enforced on POSIX and are skipped on Windows; content, atomic replacement, symlink safety, rollback and recovery through platform-independent filesystem conflicts, and native Windows long-path behavior remain covered. Only intrinsically POSIX source arms carry narrow, explained denominator ignores; no source file or platform-independent branch is excluded from Windows coverage to accommodate these differences.
Wine-only infrastructure is absent from the supported workflow: there is no apt-cache producer, compatibility script, hoisted snapshot install, Windows Node download, or local `check:windows-wine` command. The [archived Wine experiment](../../archived/process/2026-07-27-wine-windows-gates-experiment.md) remains historical evidence for its measured latency and fidelity trade-offs, not a current execution path.

View File

@@ -44,6 +44,8 @@ Status: implemented
下一次分支头精确运行通过了全部 10,933 项插桩测试,但逐文件阈值仍在 99.95% 正确失败,从而暴露出 5 个此前恰由 Linux 覆盖的分支。新增的确定性跨平台 fixture 会分别覆盖 PTY 向后翻页拼接 scrollback、以目录作为 settings 文档、非法 SQLite 文件名,以及 regular file普通文件父级之下的原子写入锁。credentials provider 剩余的 `stat` 与模式位强制分支本质上只属于 POSIX因此采用与持久 JSONL、storage backend 相同的窄范围、带说明的对等分支忽略;其行为测试仍会在 POSIX 上强制执行。阈值与源码文件清单均未改变。
后续分支头精确运行通过了全部 10,937 项插桩测试,并把阈值结果收窄到 99.99%。剩余的两行表明,首版 PTY fixture 已到达页偏移 helper却只提供了两页数据Windows 路径规范化还会在 `readFile` 到达 reload policy重载策略分支前先拒绝真实的非法路径 fixture。PTY fixture 现在会提供 3 个向后翻页页面watcher fixture 则会在真实权限检查之后注入一次非“文件不存在”的读取失败。两项 fixture 仍保留其本来要证明的可观察输出或 last-good snapshot最后有效快照断言。
POSIX 模式位、基于 chmod 的不可读状态和基于 chmod 的 writer lock 拒绝在 Windows 上没有等价机制。这些验收场景继续在 POSIX 上强制执行,并在 Windows 上跳过;内容、原子替换、符号链接安全、通过平台无关文件系统冲突验证的回滚与恢复,以及原生 Windows 长路径行为仍保有覆盖。只有本质上属于 POSIX 的源码分支带有窄范围且说明明确的分母忽略;没有任何源码文件或平台无关分支为适应这些差异而从 Windows 覆盖率中排除。
受支持的工作流不含 Wine 专属基础设施:不存在 apt 缓存生产者、兼容性脚本、对仓库快照执行的 hoisted 安装、Windows Node 下载或本地 `check:windows-wine` 命令。[已归档的 Wine 实验](../../archived/process/2026-07-27-wine-windows-gates-experiment.md)仍作为其实测延迟与保真度取舍的历史证据,而非当前执行路径。

View File

@@ -6,6 +6,25 @@ import { join } from 'node:path'
import { credentialRef } from '@deepseek-ai/dsh-credentials'
import { CredentialsLocal } from '../src/index.ts'
const fsHarness = vi.hoisted(() => ({
nextReadError: undefined as NodeJS.ErrnoException | undefined,
}))
vi.mock('node:fs/promises', async (importOriginal) => {
const actual = await importOriginal<typeof import('node:fs/promises')>()
return {
...actual,
readFile: (async (path: unknown, ...rest: never[]) => {
const error = fsHarness.nextReadError
if (error !== undefined) {
fsHarness.nextReadError = undefined
throw error
}
return (actual.readFile as (path: unknown, ...args: never[]) => Promise<unknown>)(path, ...rest)
}) as typeof actual.readFile,
}
})
/** Credential documents are seeded owner-only, exactly as the provider creates them. */
function writeCredentials(file: string, text: string): Promise<void> {
return writeFile(file, text, { mode: 0o600 })
@@ -48,6 +67,7 @@ const KEY = credentialRef('DSH_CRED_PIPE')
const cleanups: Array<() => Promise<void>> = []
afterEach(async () => {
fsHarness.nextReadError = undefined
while (cleanups.length > 0) await cleanups.pop()!()
;(await fakeInstances()).length = 0
})
@@ -107,6 +127,21 @@ describe('watcher pipeline', () => {
expect(await ctx.credentials.resolve(KEY)).toEqual({ value: 'good', source: 'file' })
})
it('keeps the last good snapshot when the read fails after its permission check', async () => {
const dir = await tempDir()
const path = join(dir, '.credentials.yaml')
await writeCredentials(path, 'DSH_CRED_PIPE: good\n')
const ctx = await boot({ path, debounceMs: 5 })
fsHarness.nextReadError = Object.assign(new Error('EACCES: injected read failure'), { code: 'EACCES' })
const [instance] = await fakeInstances()
instance!.watcher.emit('all', 'change', path)
await vi.waitFor(() => {
expect(fsHarness.nextReadError).toBeUndefined()
})
expect(await ctx.credentials.resolve(KEY)).toEqual({ value: 'good', source: 'file' })
})
it('keeps the reload queue alive after an invariant violation escapes the fan-out', async () => {
const dir = await tempDir()
const path = join(dir, '.credentials.yaml')

View File

@@ -421,7 +421,7 @@ describe('tool-bash-persistent', () => {
await call(ctx, owner, 'warm up')
const session = stub.sessions[0]!
session.mode = 'paged-scrollback'
session.scrollback = ''
session.scrollback = 'older one\nolder two\nolder three\nolder four\n'
expect(text(await call(ctx, owner, 'paged output'))).toBe('hello from stub')
})