mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-11-03 07:47:45 +00:00
test(core): 修偶发红的 rtchild 用例,登记另一处未修的
## 背景
CI 的 `-race` 门两次变红(提交 `merge: pr31` 与 `style(webui)`),
都是 `TestRTChild_InterruptTruncatesOutput`:
--- FAIL: TestRTChild_InterruptTruncatesOutput (5.00s)
rtchild_r3_test.go:271: 等待超时:开始输出
本地 `-race` 单测 6/6、整包连跑 4 轮全过,复现不出来。
## 查到的真相
CI 日志里 `[rtchild] t started` 之后再无任何 round 行 —— **一轮都没跑到
provider**。所以不是输出丢包,是轮次根本没启动起来(CI 的 2 核 runner +
race 插桩下启动更慢)。
原写法把两件事塞进同一个固定 5 秒窗口:
waitFor(t, "开始输出", func() bool { return len(dev.snapshot()) >= 2 })
「输出已开始」是**前置条件**,「Stop 后输出冻结」才是被测行为。混在一起后,
超时只能报"没等到输出",看不出到底是「轮次没启动」还是「输出没外发」。
## 改法(同 2026-10-24 TestStress_Nesting... 的先例:等状态,不等时间)
waitForWithin(t, "轮次进入 ChatStream", 30s, p.callCount() >= 1)
waitForWithin(t, "开始输出(chunk 到设备)", 30s, len(dev.snapshot()) >= 2)
两段分开等、各自 30 秒:超时能直接指认卡在哪一步。被测断言一字未改。
顺带把原来丢弃的 `PushRTInput` 返回值改成检查(同文件第 297 行本来就这么写)。
## 另一处已定位但**没修**
`TestResidualDropNotifiesSyncCaller`:本地整包 `-race` 8 轮偶发 1 次
(`应处置 1 条,实际 0`),CI 从未出现。
根因是 `waitSchedulerStopped()` 只等 `running == nil`,**不等调度循环退出** ——
cancel 之后循环仍有窗口把测试刚入队的任务取走。要修得给生产代码加
「循环已退出」信号,不是改测试能解决的。已记入 `docs/zh/future-plan.md` §5.0。
## 验证
go vet ./internal/agent/core/ ✓
go test ./internal/agent/core/ -count=1 ✓
go test -race ./internal/agent/core/ -count=1 ✓(连跑 3 轮)
单测 -race -count=5 ✓
This commit is contained in:
@ -327,6 +327,35 @@ retention 修好之后这些会被逐步清掉,但不会立刻(要等跨月
|
||||
|
||||
## 五、文档与工程卫生
|
||||
|
||||
### 5.0 🟡 两个测试用例存在「固定时间假设」导致偶发红
|
||||
|
||||
**2026-10-31 记录。** CI 的 `-race` 门两次因偶发失败变红(提交 `merge: pr31`、
|
||||
`style(webui)`),本地却复现不出来。
|
||||
|
||||
#### 已修:`TestRTChild_InterruptTruncatesOutput`
|
||||
|
||||
失败信息 `等待超时:开始输出`(正好 5.00s)。查 CI 日志:`[rtchild] t started`
|
||||
之后**一轮都没跑到 provider** —— 不是输出丢了,是轮次没启动。
|
||||
|
||||
原写法把「前置条件(输出已开始)」和「被测行为(Stop 后输出冻结)」塞进同一个
|
||||
固定 5 秒的 `waitFor` 里,超时时看不出卡在哪一步。已改成两段**等状态**:
|
||||
先等 `p.callCount() >= 1`(轮次真进入 ChatStream),再等 chunk 到设备。
|
||||
超时直接指认卡在哪步。同 2026-10-24 `TestStress_Nesting...` 的修法。
|
||||
|
||||
#### 未修:`TestResidualDropNotifiesSyncCaller`
|
||||
|
||||
本地整包 `-race` 8 轮里偶发 1 次(`应处置 1 条,实际 0`),CI 从未出现。
|
||||
|
||||
根因已定位:`scheduler.waitSchedulerStopped()` 只等 **`running == nil`**
|
||||
(没有任务在跑),**不等调度循环退出**。于是 `child.cancel()` 之后仍有一个窗口:
|
||||
循环可能还停在下一轮顶部、或正走到 `pumpInbox`/`nextRef`,把测试刚入队的任务
|
||||
取走执行 ⇒ 残余任务为 0 ⇒ 断言失效。
|
||||
|
||||
**要修得给生产代码加一个「循环已退出」的信号**(`schedulerLoop` 退出时 close
|
||||
一个 channel,`waitSchedulerStopped` 改为等它),不是改测试能解决的。
|
||||
因此先登记、不改:它在 CI 里从未出现过,而改调度器退出信号属于生产路径改动,
|
||||
收益与风险不匹配。
|
||||
|
||||
### 5.1 🟡 README / ARCHITECTURE 的工具名陈旧
|
||||
|
||||
实际工具名是 `stablemem_*` / `coldcontext_*`,但对外文档仍写 `memory_recall` /
|
||||
|
||||
Reference in New Issue
Block a user