Skip to content

test: reap owned runtime children during drain cleanup - #6651

Merged
huangruiteng merged 1 commit into
mainfrom
codex/runtime-fixture-owned-cleanup-20261016
Oct 16, 2026
Merged

huangruiteng merged 1 commit into
mainfrom
codex/runtime-fixture-owned-cleanup-20261016

Conversation

@loopx-agent

@loopx-agent loopx-agent commented Oct 16, 2026 •

Copy link
Copy Markdown
Collaborator

The Windows job for #6645 returned the expected permanent I/O error in the drain fault test, then failed in fixture cleanup with WinError 5 from a raw PID signal. Retain the subprocess launched by the existing copied-runtime observer and reap that child through Popen.wait/terminate. This removes the stale PID check/signal race and keeps real termination errors visible.

A regression injects the same stale liveness observation and signal refusal after a real runtime write failure: it fails on the base with PermissionError and passes with this change while retaining the expected I/O error. Additional real-process cases verify an already exited child, forced cleanup, neighbor survival, uncaptured PID rejection and unsuppressed termination failure. The related refactor stays inside the existing test fixture helper.

Validation:

  • macOS, Python 3.11.17 / Node 24.21, two workers: both complete modules 101 passed, 0 skipped, with coverage and the CI timing observer enabled. This includes all 12 drain/cache combinations and both existing diagnostic failure cases.
  • Native Windows job passed. Its actual checkout has the same complete Git tree as the author head: lifecycle 203 passed / 19 skipped on Node 24.21; subsequent Node 22.22.3 batches passed SQLite CLI 9 and native scheduler/authority 448. The 19 skip identities were not reported.
  • Ruff, semantic advisory/full vocabulary check, public-boundary inspection and exact-scope change-quality verification passed.
  • Native premerge passed its four direct diff/compile checks; the catalog selected no additional smokes. The real runtime module above supplies the behavioral coverage.

Independent PR review is pending. Full six-shard/JUnit/coverage and sustained qualification remain open; this proposes the fixture cleanup repair. Production runtime behavior, CI worker counts and job deadlines are unchanged.

Signed-off-by: LoopX Agent <337587101+loopx-agent@users.noreply.github.com>

@loopx-agent loopx-agent left a comment

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reviewer: model_agent | gpt-6.1-sol | OpenAI | runtime_reported | reasoning_effort=max

Approval conclusion (author-owned PR; GitHub blocks formal self-approval)

完整 PR 评审,精确 head:d0dbbb9a8c42853e1dcd5434871f2198c5665700。

未发现阻塞本次夹具修复的缺陷。原生平台和持续完整lane的资格仍单独保留。

动机

维护运行器排空测试的开发者,需要让真实写入失败保留原错误,并只清理这次测试自己启动的子进程。

真实写入遇到目录替换时,旧清理会在过期探活与拒绝信号下抛PermissionError,遮住原I/O错误;新清理等待保留的Popen对象,只在超时后终止自己捕获的那个孩子,并保持真正的终止失败可见。

同一个真实运行器故障与同一Python解释器下,旧基线失败于清理PermissionError,新head保留预期I/O错误并通过;邻居进程存活、未知PID拒绝和终止错误不被吞掉也得到实跑验证。

本次完成测试夹具的清理修复,不修改生产运行器、调度、CI并发或超时;没有独立验证原生Windows整lane、完整六分片、覆盖率终门或持续运行资格。

改动思路

在现有观察夹具中保留Popen并复用一个近邻清理函数,取代裸PID探活后发信号的竞态;不新建进程管理框架,也不复制生产生命周期owner。

本PR只修复测试所拥有孩子的清理和故障可见性,真实生产状态机与共享协议保持逐字不变。

生产运行器仍决定接受写入、排空和退役。夹具只在原启动包装处保留其创建的Popen对象,finally按原PID从捕获列表中要求恰好一个对象;先等待退出,只有等待超时才终止,再等待回收。已退出孩子不再因一次过期探活而接收裸PID信号,真正的wait/terminate错误仍会使测试失败。

条件 旧夹具 本 head
真实 I/O 失败后探活过期、信号被拒 清理 PermissionError 覆盖原错误 等待所拥有孩子,保留预期 I/O 错误
孩子尚在运行 裸 PID 信号 仅对捕获的 Popen 等待、超时后终止
邻居/未捕获 PID/真实终止拒绝 所有权证据不足 邻居保留、未知 PID 拒绝、拒绝错误外露

具体改动

关键代码讲解

  • observe_copied_runtime:observe_copied_runtime扩展已有stderr观察包装,参数省略仍保持旧调用;只有启动参数包含此隔离副本server路径时才把真实Popen加入调用方列表。
  • reap_copied_runtime:reap_copied_runtime要求恰好一个匹配的所拥有孩子,以Popen.wait完成回收,超时后terminate再wait;没有捕获或吞掉真正的终止失败。
  • test_runtime_drains_admitted_write_before_exit:既有drain测试finally移除裸PID探活和os.kill,调用上述近邻helper;接受写入、真实文件锁、排空、日志及原错误断言保留。
  • test_drain_cleanup_keeps_io_error_after_stale_pid_probe:新回归在真实写入EISDIR之后注入过期探活和信号拒绝;另外用真实孩子/邻居验证正常退出、超时清理、邻居存活及拒绝路径。

三个测试文件 +121/-13。loopx、packages、scripts、Desktop及Dashboard的完整Git对象清单与实际base逐字相同;既有fixture内的Python实现有明确归属,不是新增平行控制面决策源。

规范:docs/development/testing-and-quality.md,spec_revision=dfcb03e6d31361ab65d882e3294b9fdf92b39f6a。看diff之前已读这份实际基线的相关条款;原PR没有额外评审评论框架,作者验证不代替验收。逐项映射:

  • Refactor Real-Path Gate — implemented:Use immutable baseline/head real entrypoints and a historical-defect-sensitive counterexample; do not substitute mocks. 对应的实际入口、负例及公开边界已经核对。
  • Risk-Based Review — implemented:Run focused validation and preserve actual failures, skips and scope limits. 对应的实际入口、负例及公开边界已经核对。
  • Evidence Boundary — implemented:Use isolated synthetic state and public-safe reusable tests. 对应的实际入口、负例及公开边界已经核对。

对主干的风险

关键风险是清理仍掩盖第一处真实失败,或者误把同号PID的新进程当成自己的孩子。这里不靠只含mock的单测:运行隔离副本的真实TypeScript server,实际把写目标替换成目录,待I/O失败以后才注入过期探活和拒绝信号。同一个不可变夹具、同一个Python3.12.15解释器,实际base失败于清理PermissionError,本head通过且保留EffectRuntimePermanentIOError。head另外实跑孩子/邻居、未捕获PID和live-child终止拒绝;原错误断言没有删除。

完整原integration模块base为97 passed;head两完整模块101 passed、0 skipped,均为两worker并开启coverage和CI timing observer,包含12个drain/cache组合及两个原诊断失败用例。基线完整模块使用Python3.11.17、head使用3.12.15;不能拿不同环境的时长作性能比较,所以上述决定性的单个反例另外用同一个3.12.15跑两端。Node24.21。

Ruff、diff、公私扫描三路径、先advisory后全树语义通过;原生premerge四项direct通过,catalog实际选择0项,不把“未选中”冒充行为测试。最初猜错的semantic脚本路径未运行,真实检查入口重跑通过并保留原失败记录。源码及真实子进程行为覆盖足够支持这个夹具修复;本机没有原生Windows运行,不独立背书作者引用的Windows job、19个skip身份、六分片覆盖率或持续通过。未查询、等待或触发远端CI。

我的整体评价

本PR只修复测试所拥有孩子的清理和故障可见性,真实生产状态机与共享协议保持逐字不变。

long_horizon:preserved。生产生命周期和所有权契约没有改变;夹具不再用清理异常掩盖原I/O错误,不能据此宣布生产Windows或持续运行已全面合格。

user_experience:improved。这里的直接使用者是维护者,重复故障时能读到原错误,邻居不受清理影响;没有新增人工准备、参数填写或批准轮次。

有界未来重构判断:这次已把启动捕获和近邻清理连在既有helper边界,删除裸PID竞态;进一步抽通用进程框架会增加维护面,没有当前收益。新回归具备真实旧缺陷敏感性,未发现重复造smoke或同形批量产物。原生Windows与持续完整lane不由macOS夹具回归证明;原有跨平台和CI资格仍由现有owner验收。

APPROVE;整个 d0dbbb9a8c42853e1dcd5434871f2198c5665700 的有界夹具修复达到本次目标,未发现阻断项。本次完成测试夹具的清理修复,不修改生产运行器、调度、CI并发或超时;没有独立验证原生Windows整lane、完整六分片、覆盖率终门或持续运行资格。 精确head合并门与权限仍单独判断。

English verdict: APPROVE - d0dbbb9; retained owned subprocess handles prevent stale-PID cleanup from masking the real IO error. Full local modules, same-interpreter base/head fault sensitivity and real ownership/error cases pass; native Windows and sustained complete-lane qualification remain separate.

@huangruiteng
huangruiteng merged commit 5bac1c1 into main Oct 16, 2026
28 of 36 checks passed
@huangruiteng
huangruiteng deleted the codex/runtime-fixture-owned-cleanup-20261016 branch October 16, 2026 17:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants