diff --git a/reports/工程改动报告-单元闸挂死守护-2026-10-28.md b/reports/工程改动报告-单元闸挂死守护-2026-10-28.md new file mode 100644 index 00000000..7109bd33 --- /dev/null +++ b/reports/工程改动报告-单元闸挂死守护-2026-10-28.md @@ -0,0 +1,32 @@ +# 工程改动报告——单元闸挂死守护(run_all.gd 每套件阻塞面超时) + +**承接**:待办清单 2026-10-25 条目「闸与探针批上下文挂死防护——probe_gate 进程树回收与 run_all 阻塞面超时」件②(件① battle_log_view 已随迭代 38 卡⑥ 出账,probe_gate.sh 整树回收件 2026-10-28 已落;本批完成后该条目整条删除,git 历史可考)。 +**车道**:工程改动直改批(改动四类,不写卡不编迭代),触及代码面走 worktree 批——分支 `runall-hangguard-20261028`,改动提交 a2710f22,并 master 后合并提交 4afe6c47。 +**实证**:迭代 40 批末阻塞面挂死实拍三例(测试 `_init` 在 `quit()` 前中断,进程挂至外层超时 124),与件②同根。 + +## 改动—验收对照表 + +| 需求点 | 改动(文件:行为) | 验收测试 | 层级 | 真实入口 | 判据绑定面 | 结果 | +|---|---|---|---|---|---|---| +| 每套件截止时间守护(默认 120s,环境变量 `RUN_ALL_SUITE_TIMEOUT_SEC` 可覆盖,非法值回落默认) | `run_all.gd` `_run_suite` 阻塞调用换 `OS.create_process` 非阻塞+200ms 轮询+截止判定;常量 `SUITE_TIMEOUT_*` 与 `_suite_timeout_sec()` | 机制验证:临时挂死夹具(`_init` 死循环不 quit)登记 manifest 后 `--only` 选跑,`RUN_ALL_SUITE_TIMEOUT_SEC=8` → 输出 `[run_all] FAIL …dev_hang_fixture… — 超时挂死(8s),进程树已整树回收(pid=…)`+`[run_all] 1 个套件失败`,进程退出码 1 | 闸基建 | `run_all.gd` `--script` 直跑(选跑态) | FAIL 行文本+批退出码 | 绿(夹具与 manifest 行验证后即删,未提交) | +| 超时整树回收零孤儿 | `taskkill /F /T /PID`(杀 cmd wrapper 连引擎孙进程)+等死确认 10s 宽限(确认不了报红留 PID)+临界窗口 `.code` 同删 | 杀树后 PowerShell 按命令行清点该 worktree 路径 Godot 进程=0 | 闸基建 | 同上+外部进程清点 | 清点输出 | 绿 | +| 退出码通道等价(文件通道值=原 cmd 回传值,判定形态不变) | 命令串追加 `& echo !ERRORLEVEL! > 文件`(`cmd /V:ON`);读毕即删+起跑前清陈值;缺文件/非数字 fail-closed 判红 | 负面套件 expect=1 照常判 PASS;全量 65 套件 `all green (65 suites)` 退出码 0 | 闸基建 | `run_all.gd` 全量直跑(与收口闸 02 同源) | PASS 行 exit 值+all green 行 | 绿 | +| README 超时记载换代 | `game/tests/README.md` 工具速查表 run_all 行补守护说明;Running Tests 段失真行「本地闸必须配外部 wall-clock 超时(run_all_gates.sh 已内置)」删除(该脚本实测无 timeout 包装),换代为内建守护说明 | 收口闸 06 gdd_lint/07 doc_link/08 doc_term/08c 流水线闸/08d 引用可核全绿 | 文档 | 闸机扫描 | 闸退出码 | 绿 | +| 非行为改动:文件头注重写 | 只描述现行行为;原头注「本地闸 02 闸包装外部超时:timeout 120s」与闸机现实不符,属失真句换代 | — | — | — | — | 非行为改动 | + +验证集清单(`game/tests/验证集清单.md`)零变化:本批不增删不改判任何套件断言,改动全部在运行器进程机制层。 + +## 机制验证的 API 实证(开工探针四件,30 秒级临时件,验证后即删) + +1. 现行 `OS.execute(…, out, true, false)` 实测同步等待(ping 约 3s 计时吻合)、返回退出码——第五参在 Godot 4.7.2 上不是阻塞开关,阻塞面挂死根因坐实; +2. `OS.create_process` 返回真实 Windows PID,`is_process_running` 存活期 true、taskkill 后 false; +3. `cmd /V:ON /C "… & echo !ERRORLEVEL! > 文件"` 退出码落盘通道成立(错误命令落 1); +4. `taskkill /F /T` 对 cmd→ping 树整树连坐闭环(存活计数 1→杀→0,cmd 自身 running=false)——镜像 probe_gate 已落件的同款机制。 + +## 闸况 + +全量域闸回执 2955c049(domain=full,dirty_game=False,总判定验收通过):影响面选闸判测量面(diff 全在 `game/tests/`)→ 00 冒烟/03/04 探针/05 渲染闸/11 回放确定性 SKIP;01 系统测试、02 单元与集成测试、06–08d 文档域闸、10 熵增闸全绿;09 静态扫描退出码 1=存量红(`level_map_screen.gd|quality/max-class-variables` 22 对基线登记 21 的恶化留账,还债归迭代 41 在案;指纹与入库基线一致,本批零新增)。合并后两件秒级事:`--editor --quit` 重刷类名缓存退出码 0+冒烟启动 17 项 0 失败三闸全过。 + +## 移交与观察 + +`game/tests/README.md`「套件 manifest 现况」行记 64 条,manifest 实数 65 条(62 单元+3 集成)——漂移先于本批存在(主区与任务分支同值),本批未动套件数,已登记待办清单新条目(tests/README manifest 计数行漂移订正)归文档批。 diff --git a/待办清单.md b/待办清单.md index 09eb20ad..5b7f9577 100644 --- a/待办清单.md +++ b/待办清单.md @@ -389,13 +389,11 @@ **状态**:待写卡(备选) -#### 闸与探针批上下文挂死防护——probe_gate 进程树回收与 run_all 阻塞面超时(2026-10-25 登记,来源=批次移交) +#### tests/README manifest 计数行漂移订正——「64 条」对实际 65 条(2026-10-28 登记,来源=批次移交) -**实况**:证据=迭代 36 批末闸机观测(非本批引入)。原登记两件存量噪声,件①(battle_log_view.gd:17 类型声明错致运行期 TypedArray 错误、日志失真)已随迭代 38 卡⑥ 收口出账(git 提交 ce49a8ee),本条只剩件②:`level_shop_economy_test` 在闸批量上下文存在挂死形态(直跑恒绿),`tools/probe_gate.sh` 的 per-suite timeout 只杀 wrapper 不杀引擎子进程,孤儿泄漏会殃及后续全部 Godot 启动(批末四次闸跑批中断的根源,处置=清杀泄漏进程+删重建 `game/.godot`)。挂死防护=闸壳/测试基建,按改动四类属**工程改动走直改通道**。 -- 直改落点:tools/probe_gate.sh(per-suite 进程树回收)+game/tests/run_all.gd(OS.execute 阻塞面超时守护)——测试基建直改。**2026-10-28 用户裁四批全做,probe_gate 件已落**(run_suite 整树回收:启动记 WINPID → 超时先 `taskkill /T` 杀全树再 `kill -9` 收 MSYS 侧〔顺序颠倒会让 /T 走不到已死父进程〕→ 标志文件判超时〔taskkill 强杀后 MSYS wait 可能报 0〕;默认五段实跑全绿+超时/正常双路径机制验证通过)。run_all.gd 件属代码面(game/tests),按车道铁律留待触及测试基建的 worktree 批顺带,本条目保持待执行。**2026-10-28 迭代 40 批末补实证(阻塞面挂死实拍)**:迁移类改动的回退使测试 `_init` 在 `quit()` 前中断(红行形态 `Invalid call. Nonexistent function`),进程挂至外层超时 124——卡① wr1/wr4/wr9 取证轮三例复现,与件②同根(阻塞面无超时守护),实证链在案(实现报告 §三第 1 条)。 +**实况**:证据=单元闸挂死守护批收尾实数(合并提交 4afe6c47,报告 reports/工程改动报告-单元闸挂死守护-2026-10-28.md)——`game/tests/run_all.gd` manifest 实为 65 条(62 单元+3 集成,grep '{"path"' 计数),`game/tests/README.md`「套件 manifest 现况」行仍记「64 条(61 单元+3 集成,2026-10-28 实数)」。漂移先于该批存在(主区与任务分支同值),该批未动套件数不属其 scope,登记归文档批订正。 - -**改动面**:工具代码 +**改动面**:文档 **状态**:待执行