mirror of
https://gitcode.com/JianFeeeee/HomeAgent.git
synced 2026-10-01 23:12:52 +00:00
test(seq): 三个压力测试 —— 超长序列 / 100 工具并行 / 串行降级
与单元判据的分工:单元判据钉住**语义**(一条路径对不对);压力测试钉住
**规模下的不变量**。沿用仓内既有范式(media/soak_test.go):
testing.Short() 跳过 + 独立 -run 跑。
① 超长序列
· 解析 10 / 100 / 1000 组(250KB 文本):6.8ms,无硬上限误报
· 执行 200 组 × 5 工具 = 1000 次调用:2.0ms
断言:每工具恰好被调 nGroups 次(无遗漏/重复)、结果含**最后一组**
—— 组间串行在规模下仍成立
② 100 工具组内并行
· 100 工具全声明并发安全 ⇒ 11ms,完成顺序**确实被打乱**(判据会校验
这一点,否则它测不到并发)
· 断言每个槽拿到**自己**的结果(并发下若按完成顺序合并就会错位)
③ 串行降级
· 50 个工具里**一个**未声明并发安全 ⇒ 整批退回串行,
完成顺序严格等于声明序(106ms vs 并发的 11ms,降级确实生效)
★ 压力测试第一次跑就抓到一个**真实分层缺陷**:
「含非并发安全工具则整批串行」这条规则**只在上层 runGroup 实现**,
而引擎层 execGroup 只信 g.Parallel 字段 ⇒ 任何人直接调 execGroup
都会拿到不受约束的并发。
已修:降级判据下沉到引擎层,新增 batchCanRun(g, runner),
toolRunner 增加 parallelSafe 方法(生产路径行为不变,只是把判据
放到了它本该在的层)。
过程中压测自身也暴露了两个测试缺陷(都修了):
· fixture 让 100 个工具写同一个标量槽 o,被静态校验正确拦下
("组内并行下同名写入是数据竞争")—— 压测不该去撞这条规则;
· ★ e2eRunner.called 是无锁 append,100 工具并发时 -race 报出**真竞态**
(不是误报)—— 加锁 + 提供 calledSnapshot 供断言。
另:建序列与跑序列原本用了**不同 plugin 实例**(序列存在实例的 store 里,
换实例就读不到自己刚建的),已改为同一实例。
回归:go test -race ./internal/plugins/seq 全绿;go test ./internal/... 全绿。
This commit is contained in:
@ -49,6 +49,11 @@ func (f *fakeTool) call(name string, _ map[string]interface{}) (string, error) {
|
||||
return "ran:" + name, nil
|
||||
}
|
||||
|
||||
// parallelSafe:默认全部视为可并发(工具级压测通过 toolDefs 控制)。
|
||||
// 本文件用 fakeTool 的用例关注的是**组内顺序/合并**不变式,
|
||||
// 并发资格由 TestStress_* 单独检验。
|
||||
func (f *fakeTool) parallelSafe(string) bool { return true }
|
||||
|
||||
func (f *fakeTool) called() []string {
|
||||
f.mu.Lock()
|
||||
defer f.mu.Unlock()
|
||||
@ -322,6 +327,8 @@ type capturingTool struct {
|
||||
args map[string]interface{}
|
||||
}
|
||||
|
||||
func (c *capturingTool) parallelSafe(string) bool { return true }
|
||||
|
||||
func (c *capturingTool) call(name string, args map[string]interface{}) (string, error) {
|
||||
c.mu.Lock()
|
||||
c.args = args
|
||||
|
||||
Reference in New Issue
Block a user