验证 W1–W3 Windows/WSL 工作¶
三层覆盖,因为每一层都能捕获其他层在结构上无法捕获的内容。
1. 单元测试——到处运行,每个 PR¶
| 套件 | 固定点 |
|---|---|
src/main/wsl/wsl-runner.test.ts |
分隔符、通道选择、围栏、WSLENV、来宾 cwd、脚本解释器、预算拆分、未解析 PATH 时拒绝 |
src/main/wsl/wsl-guest-environment.test.ts |
突发合并、按发行版隔离、畸形负载拒绝、临时与永久、重试窗口、加入者预算 |
src/main/wsl/wsl-w1-w3-contract.test.ts |
W1→W3 链路端到端:绝对路径 wsl.exe、argv 数组、有界调用、无 --、脚本逐字节一致、WSLENV、探测不使用 shell、登录 PATH 仍然生效 |
src/shared/source-scan/source-tree-scan.test.ts |
守卫辅助函数。一个少报的守卫比没有守卫更糟 |
2. 棘轮——标杆,持续强制¶
| 守卫 | 度量 |
|---|---|
wsl-invocation-boundary.test.ts |
在 runner 之外生成 wsl.exe 的文件,以及未声明 shell: 'bash' 的仅 bash 负载 |
windows-console-visibility.test.ts |
缺少 windowsHide 的直接子进程调用 |
child-process-import-boundary.test.ts |
在 chokepoint 之外导入 child_process 的文件 |
wsl-exec-mode-separator.test.ts |
被禁止的 -- 分隔符 |
pty-descendant-termination-job-coverage.test.ts |
每次清扫都传递 terminateOwnedTree |
每个守卫都会因新增违规项 以及 过期条目而失败,因此数量只会下降。通过植入一个违规项并观察它被点名来验证守卫——这一步已经三次发现守卫自身的 bug。
3. 真实二进制——其他任何方式都无法做出的断言¶
Windows CI(pr.yml 中的 package (windows) 任务)从打过补丁的源码重新构建 node-pty,并针对真实 ConPTY 运行 win32 套件:一个真实的分离孙进程、一次真实的作业终止,以及相反情况——干净的 exit 必须让后台工作保持原样。
真实 WSL 发行版——不在 CI 中;托管 runner 上不可用 WSL。
ORCA_REAL_WSL_RUNNER_TEST=1 ORCA_WSL_TEST_DISTRO=Ubuntu-24.04 \
pnpm vitest run src/main/wsl/wsl-runner.wsl.test.ts
它会向发行版的 ~/.profile 追加 sleep 60,并断言探测通道仍能在其预算内响应——复现了 #14288,而非模拟——然后恢复 profile。它还覆盖 banner 剥离、携带引号和 $ 的脚本逐字节到达、WSLENV 传递以及来宾 cwd。
在发布对 src/main/wsl/ 的更改之前运行它。这是探测通道确实如工作流所声称那样工作的唯一证据,而且它已经因为 runner 更改而过时一次,同时在 CI 中通过,因为 CI 会跳过它。
windowsHide 守卫的已知缺口¶
明确记录而非暗示,因为看似完整的守卫比有已记录边缘情况的守卫更糟。
- 未扫描
fork。 Node 在运行时会将windowsHide转发给 spawn,但ForkOptions未声明它,因此两个现存位置——main/daemon/daemon-init.ts和main/plugins/plugin-host-process.ts——不经过类型断言无法修复。两者在 Windows 上都是控制台子系统子进程。 - 允许列表是文件粒度的,因此被允许的文件存在盲区。 其中约 18 个条目是误报(
RegExp.prototype.exec、provider.exec,以及词法分析器失步的文件),并且每个条目都持续预先批准该文件中的真实回归。这些条目也无法通过修复代码来移除,因此按当前写法列表无法归零。将其改为调用粒度是修复方法。 stripComments没有失步报告。 失败关闭检查运行在已剥离的文本上,因此包含斜杠星号的正则字面量仍可能静默吞掉代码。目前src/中没有出现。
验证守卫更改¶
植入一个违规项并观察它失败。本工作流中每个仅通过阅读验证的守卫修复都是错误的——连续三次尝试精确词法分析器,每次发布的失步都_减少_了违规项数量,这看起来像是进展。至少植入:一个普通调用、一个在模板字符串密集文件中的调用、一个在正则密集文件中的调用、windowsHide: false、一个三元表达式第一个参数,以及一个重命名的导入。
本页原文 Markdown:在 AtomGit 查看·内容源自开源项目 orca48/orca