proxy-pool/docs/testing/test-strategy.md
youfak 4de3ffb85f
Some checks are pending
ci / test (ubuntu-latest) (push) Waiting to run
ci / test (windows-latest) (push) Waiting to run
ci / race (push) Waiting to run
feat: add ephemeral proxy activity pool
2026-07-29 12:51:18 +08:00

6.4 KiB
Raw Blame History

测试与容量验证策略

1. 原则

  • 先证明领域不变量,再证明 Adapter 契约,最后证明跨进程行为。
  • 并发测试必须在 race detector 下运行,不能只依赖单线程示例。
  • 时间、随机、网络、Provider 和存储均通过可替换接口或 fixture 控制。
  • 生产 Adapter 必须证明数据边界Proxy 明细只进入 Redis TTL 活动池和节点 内存PostgreSQL 不得出现 Proxy 明细或逐次提取记录。
  • 100,000 QPS 是待验证的集群目标,不以架构图、副本数或短时峰值替代证据。
  • 性能通过与正确性通过相互独立;高 QPS 下出现超卖、重复 Extract 或状态 回退时,结果一律失败。

2. 测试分层

单元测试

  • Proxy 唯一键、TTL 优先级、状态机和 safety margin。
  • Atomic Capacity 的 Reserve、Commit、Cancel、Release 与幂等错误。
  • Routing first-match 与五种策略。
  • Fetch Success、Empty、Duplicate-only、Error 分类。
  • Backoff、jitter、Retry-After、requestInterval、maxInFlight。
  • Extraction eligibility、partial、allOrNothing、health age、TTL、reserve。
  • 配置严格字段、交叉引用、正则、监听保护和独立计数语义。

契约测试

  • Provider 响应模板的大小、超时、函数白名单和解析边界。
  • Redis Lua/Function 对候选筛选、库存预留、独占移除和短期幂等结果执行单次 原子操作;并发与主从切换下不得部分提交。
  • PostgreSQL 配置版本、Upstream/Routing 管理状态、Admin 审计与 outbox 的事务 更新及幂等重放;测试库断言不包含 Proxy 明细或逐次提取记录。
  • Redis TTL 活动池、Leader 租约、限流、短期幂等窗口和失联恢复。
  • Snapshot/Delta/ACK/Report 的版本与校验和兼容性。
  • OpenAPI 错误模型、认证矩阵、批量 fulfillment。

集成与端到端

  • HTTP 正向代理成功、上游连接前失败和安全重试。
  • HTTPS CONNECT 建立后不透明重放。
  • Controller Fetch -> Redis TTL 活动池 -> Check -> AVAILABLE -> Worker Snapshot -> Gateway 转发Gateway 请求线程始终只读节点内存。
  • Distribution 原子提取后 Gateway 不再分配同一 Proxy。
  • 配置热更新失败保留旧 Revision成功后新请求使用新 Snapshot。

3. 必测的 11 类场景

  1. 并发容量1000 协程争用同一 Proxy始终满足 active + reserved <= effectiveMaxConcurrency
  2. Reservation 生命周期Dial 成功/失败、超时、取消和重复 Release 均不 泄漏或产生负计数。
  3. singleflight100 个缺池信号只产生一个有效 Fetch 调度。
  4. Provider 限流requestInterval、maxInFlight、timeout、重试和 429 Retry-After 在虚拟时钟下准确。
  5. Fetch 分类Error 不动 Empty合法空响应 Empty++duplicate-only 重置 EmptySuccess 重置 Empty。
  6. Sequential 竞态:达到阈值时多协程只能将 A 切到 B 一次,不能越过 B。
  7. Drain:切换或禁用 Upstream 后停止新分配,已有连接完成后才回收。
  8. Extract 竞态:多个请求并发提取同一候选集合,同一 Redis 活动池代次内 每个 Proxy 最多返回一次。
  9. Extract 批量语义partial 提交实际数量allOrNothing 不足时 Redis 活动池和幂等结果均不变;始终保留 reserveForGateway
  10. Worker ownership:回收过程严格经过 DRAINING、ACK、active/reserved=0、 unowned旧 Snapshot 不可再分配。
  11. 控制面故障Redis、PostgreSQL、Controller、Checker 与 Provider 分别 失效时,行为与 Runbook 一致Gateway 热路径不被同步依赖拖垮。

4. 测试命令

所有后台测试都设置 60 秒上限:

go test -timeout 60s ./...
go test -timeout 60s -race ./internal/...
go vet ./...
go build ./...

需要 PostgreSQL/Redis 的测试使用独立实例和短生命周期容器,不复用开发数据。 测试结束后验证没有残留 Worker ownership、Leader 租约、活动池条目或幂等键, 并检查 PostgreSQL 中不存在 Proxy 明细和逐次提取记录。

5. 负载模型

必须分开运行,避免不同瓶颈互相掩盖:

HTTP QPS

  • GET/HEAD 占比、响应体大小、Keep-Alive 复用率与生产预测一致。
  • 依次运行 10k 稳态、阶梯升压和 100k 峰值。
  • 同时记录端到端与 Gateway 内部 Dispatch 延迟。

CONNECT

  • 分开测试活跃隧道数和每秒新建隧道数。
  • 包含短连接、长连接、半关闭、Client 取消和上游主动断开。
  • 验证 200 已发送后不发生透明重放。

Snapshot

  • 1k、10k、100k Proxy Snapshot测构建、校验、原子切换、内存峰值和 GC。
  • 在满负载下发布 Snapshot确认请求线程不参与索引构建。

Extract

  • 小批 partial、大批 allOrNothing、高冲突 filter 和库存不足。
  • 与 Gateway 同时运行,持续检查 reserveForGateway 和无重复返回。

故障负载

  • 负载运行中断开 Controller、Redis、PostgreSQL、一个 Worker 和一个可用区。
  • Provider 注入 DNS、超时、500、429、超大响应、模板错误和合法空响应。
  • Checker 注入慢目标与队列积压。

6. 通过条件

业务 SLO 由产品最终确认,但至少满足以下工程门槛:

  • 无容量超卖、负计数、幂等窗口内重复 Extract、Admin 审计缺失或状态非法回退。
  • 100k 峰值期间无进程 OOM、FD 耗尽、无界队列或全局锁热点。
  • Gateway 热路径在 PostgreSQL、Redis、Provider 失效时不发起同步访问。
  • p99 Dispatch 小于 100 微秒的设计预算需要在 100k Proxy Snapshot 下单独证明。
  • 最大故障域丢失后,剩余容量仍满足约定 SLO否则增加副本或降低承诺容量。
  • Snapshot 超过 maxStaleAge 后 Gateway 拒绝新流量,已有连接按时排空。
  • 所有数据、命令、Git SHA、镜像 digest、环境和原始指标可以复现。

7. 测试报告模板

版本Git SHA / image digest / Go version
环境节点、CPU、内存、NIC、内核、Kubernetes/CNI
配置Snapshot 规模、Proxy 容量、路由、重试、日志级别
场景:协议、连接复用、响应体、持续时间、升压曲线、故障注入
结果QPS、建连速率、active、p50/p95/p99、错误、CPU、RSS、GC、FD、网络
不变量capacity、ownership、extraction、idempotency、admin audit、reserve 检查结果
结论:通过/失败,以及适用边界