Skip to content

fix(test): wait for message persistence and preserve failure diagnostics - #111

Draft
ULookup wants to merge 30 commits into
3.0-devfrom
fix/104-message-readiness-diagnostics
Draft

ULookup wants to merge 30 commits into
3.0-devfrom
fix/104-message-readiness-diagnostics

Conversation

@ULookup

@ULookup ULookup commented Sep 13, 2026 •

Copy link
Copy Markdown
Owner

Primary Issue

Closes #104

Target Version

3.0-dev

Scope

消息发送响应只保证 broker 确认,原有 Message 测试立即读取或修改消息,重复运行出现 4001。共享文本夹具现在只发送一次,并等待 MySQL 消息记录;Message 测试复用该夹具。搜索测试等待精确消息的索引并断言真实搜索结果,指定 client ID 的查询也先等待持久化。

失败响应输出保留业务错误码、brpc 分类及安全 trace,省略原始错误文本和身份数据。BVT、Functional、Reliability 在测试前采集服务状态,在失败后、销毁容器前采集进程/注册状态与筛选后的错误事件,并保存七天诊断产物。采集进程使用二十秒总预算和每命令两秒限制。

Non-goals

不修改生产 C++、消息发送成功边界、协议、事务、幂等或产品语义;不重试失败的业务请求;不以本地 4001 解释历史云端 9002;不关闭 #96 的崩溃调查;不包含同级构建修复 #110。

Architecture Impact

No — 服务、存储和网络拓扑不变;新增的是测试诊断产物。

Core-flow Impact

Yes — 明确 broker acceptance 与测试持久化就绪之间的区别并更新夹具;生产消息与 timeline、conversation watermark 的既有事务不变。

Updated Skills

  • .agents/skills/chatnow-testing/references/framework.md
  • .agents/skills/chatnow-testing/references/case-catalog.md
  • .agents/skills/chatnow-orienting/references/core-flows.md

RED Evidence

原有消息组 go test -tags=func ./func/... -run 'Test(SyncMessages|GetHistory|GetMessagesById|SearchMessages|RecallMessage|AddReaction|RemoveReaction|GetReactions|PinMessage|UnpinMessage|ListPinned|DeleteMessages|ClearConversation)' -v -count=20 -timeout=600s:278 通过、2 失败。失败为 ListPinned 的 Pin 前置调用及 RemoveReaction 的 AddReaction 前置调用;Message 文件日志对应 4001,未取得对应 Gateway RPC 失败日志。此结果不证明历史云端 9002 的根因。

go test -tags=reliability ./reliability/... -run '^TestRL_TextFixtureWaitsForPersistence$' -v -count=1 -timeout=120s:RL-MESSAGE-02 在 Message 停止且 Redis 已记录 accepted 的条件下,实际断言消息表为 0 行、夹具过早返回,exit=1。先修正故障扫描使用的 Redis 端口,随后取得只针对持久化缺口的有效 RED,见 fixture-red-confirmed.log。

go test ./pkg/client -run '^TestHTTPFailureDiagnostics$' -v -count=1:四个客户端边界子用例都失败于诊断输出为空,exit=1;HTTP 请求本身完成且只执行一次,见 diagnostic-red.log。

GREEN Evidence

相同 RL-MESSAGE-02 命令通过,13.969s,exit=0:受控故障期间不再提前返回,恢复消费者后读取实际 MySQL 行。相同 HTTP 诊断命令四个子用例通过;验证原始业务响应保留、请求不重试、敏感原文不出现在诊断输出。

go test ./pkg/contracts -run 'Test(RuntimeDiagnosticsAreBoundedAndRedacted|CorrectnessGatesPreserveFailureDiagnostics)$' -v -count=1:通过,1.117s;覆盖真实采集脚本的进程边界、字段筛选、总超时与 CI 失败产物接入。真实本地采集获得九服务运行状态及八项注册,均可用,完整 JSON 已保存。该快照不替代故障根因证明。

Regression Verification

以下命令在 Linux 虚拟机的独立源码目录执行;所有完整 stdout/stderr 都保留于本次任务的 issue104 审计目录。

检查 命令 当前实际结果
最终消息重复组 RED 段的消息组命令,启用 CHATNOW_TEST_DIAGNOSTICS=1 280/280,通过,168.002s,message-repeat-final.log
搜索/指定 ID 查询 `go test -tags=func ./func/... -run '^Test(SearchMessages_Success FN_MS_SelectByClientMsgId_Found)$' -v -count=3 -timeout=120s`
Go 契约与支持包 go test ./pkg/contracts ./pkg/agentpolicy ./cmd/agent-policy ./pkg/client ./pkg/cleanup ./pkg/chaos -count=1 六包通过,static-final.log
vet go vet -tags=reliability ./... / go vet -tags=func ./... 均 exit=0,vet-final.log / vet-functional.log
格式 test -z "$(gofmt -l .)" exit=0,fmt-final.log
BVT make test-bvt 18 通过,6.530s,exit=0,bvt.log
完整 Functional make test-func 191 通过、2 个外部 SMTP 条件跳过,245.515s,exit=0,functional.log
完整 Scenario make test-scenario 12 通过,38.913s,exit=0,scenario.log
完整 Reliability make test-reliability 7 通过、1 失败,131.628s,exit=2;RL-MESSAGE-01 的 persisted_true 恢复返回 9002,reliability.log
客户端竞争检查 go test -race ./pkg/client -run '^TestHTTPFailureDiagnostics$' -count=1 exit=0,1.045s,race-client.log
CI e3acfd6,CI 34772003960;Agent Policy 34772003961 首次 BVT 在 Docker Hub 拉取 Redis 镜像时连接被重置,测试未启动;同提交 attempt 2 的 BVT、Functional 通过;build、service-artifacts、Reliability、Agent Policy 均通过。非触发条件的性能作业跳过;原失败保留

完整 Reliability 使用合成栈的 8/40 限流,finally 恢复普通配置并确认九个业务服务运行、八项注册齐全。失败时 Gateway 能查询到完整原消息,但 Transmite 的重复发送仍为 9002。随后定向三轮得到两轮通过、一轮失败(恢复后十秒未持久化;下一子用例在故障前的重复发送失败),idempotent-investigation.log。额外只读健康检查配合 go test -json -tags=reliability ./reliability/... -run '^TestRL_IdempotentResponseDuringMessageOutage$' -count=3 -timeout=360s,三轮六子用例通过;完整输出和时间线在 idempotent-observed.jsonl、recovery-health.jsonl。后一次通过不视为修复先前失败,也不提高超时或放宽断言。

云端首次失败真实执行了采集与上传:test-diagnostics-bvt 产物包含 failure.json,确认业务容器尚未创建、注册状态不可读取,符合镜像拉取阶段失败。未执行的测试前快照没有伪造为可用状态。云端原始失败完整保存在 ci-bvt.log,诊断产物已下载保存。

首次源码归档保留了 Windows 换行,导致 shell 契约和格式检查失败;独立 Linux 副本已归一化 LF,并为需要 tracked-file 语义的策略检查建立本地索引,相关检查重新通过。初始失败日志 static.log、fmt.log 和完整后续结果均保留;这不是生产服务修复或放宽测试。

当前提交的 501 个 tracked 路径已核对:本次十二个改动文件和其余非生成源码匹配;tests/func/config.yaml 的符号链接目标也一致。九个既有 Go Protobuf 输出由 make proto 重新生成,使用 protoc-gen-go v1.36.11 / protoc v3.12.4,未将生成器版本差异混入本 PR。完整比对在 source-equivalence.json;VM 全部日志已同步为本地 vm-audit.tar.gz 及展开目录。

Security and Compatibility

Security: 只使用已有合成测试栈。诊断不保留环境、配置、凭据、用户/设备标识、原始错误文本、消息内容、etcd 值或命令 stderr;只保留约束字段和数值错误码。故障用例先登记恢复,恢复消费者与持久化后清理合成数据。
Compatibility: 生产发送确认、HTTP/Protobuf、数据库及重试语义不变;普通文本夹具增加就绪等待,显式 client ID 与直接 RPC 夹具继续用于 acceptance/outage 测试。
Migration: 无数据、协议或运行配置迁移。

Unverified Items

历史云端 RPC 9002 尚未取得真实根因 RED,因此 #104 的整体验收仍未完成;本 PR 保持 Draft / not ready,不能仅凭本地重复通过关闭该调查。#96 历史 Identity 崩溃也未被本次证据解释。

本地完整 Reliability 的恢复失败仍未解释,额外定向通过不能覆盖该失败;需要对失败时 Transmite → Message 的实际内部 RPC 和服务启动阶段取得进一步证据。当前提交适用 CI 已通过,但本地恢复失败仍使完整验证结论保持 Draft / not ready。本次云端失败产物上传已经实际发生;应用故障阶段的完整云端诊断仍需对应失败样本。Performance 不属于本次测试就绪和诊断变更的必需门禁;没有生产吞吐改变。前序堆叠合入后仍需同步及最终集成检查。

Rollback Plan

回退本 PR 的测试、采集脚本、CI 和文档增量即可;无业务数据回退,会重新暴露原有测试时序缺口并失去诊断产物。合并与生产操作由人工决定。

Stacked PR Dependencies

Dependency: #89 → #98 → #100 → #103 → #106 → #107 → #109
Final target version: 3.0-dev
Merge order: #89 → #98 → #100 → #103 → #106 → #107 → #109 → 本 PR。
After predecessor merge: 同步开发线、复核祖先关系及最终集成,保持 3.0-dev 目标,不重写共享历史;#110 为同级独立修复。

Full-diff Self-review

Base and range: origin/3.0-dev...HEAD;本轮增量 2bdd7c6...HEAD。
Verdict: 核对完整范围的文件、提交与已声明前序继承关系;本轮十二文件逐项复核,涵盖单次发送、事务就绪、故障恢复、搜索有效断言、安全诊断、采集预算、CI 失败顺序和三份 Skill 同步。生产文件与前序 #109 相同;不包含生成代码、凭据或无关清理。历史根因与剩余门禁明确保留,Draft 不代表就绪或合并授权。

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.

1 participant