FXJ Wiki

Back

运行测试#

cd labs/src/kvraft

# 运行所有测试
go test -race

# 只运行 3A
go test -race -run 3A

# 只运行 3B
go test -race -run 3B
bash

3A 测试#

TestBasicGet3A

验证:基本的 Get/Put/Append 操作正确。

失败原因:

  • RPC 处理函数逻辑有 bug
  • apply 线程没有正确执行操作

TestConcurrentClients3A

验证:多个客户端并发操作时,结果满足线性一致性。

失败原因:

  • 没有去重,重复请求被执行多次
  • Get 操作没有通过 Raft 提交,读到了过时的数据

TestUnreliable3A

验证:在不可靠网络下(随机丢包),操作仍然正确。

失败原因:

  • 客户端没有正确重试
  • 去重逻辑有 bug

TestUnreliableOneKey3A

验证:多个客户端并发 Append 同一个 key,最终结果包含所有 Append 的值。

失败原因:

  • Append 被执行了多次(去重失败)
  • Append 被漏掉了(客户端没有重试)

TestOnePartition3A

验证:网络分区时,少数节点一侧不能提交操作;分区恢复后,操作能正确完成。

失败原因:

  • 客户端没有超时重试
  • 分区恢复后,旧 Leader 没有退回 Follower

3B 测试#

TestSnapshotRPC3B

验证:快照 RPC(InstallSnapshot)正确工作。

失败原因:

  • InstallSnapshot 处理逻辑有 bug
  • 快照后日志索引计算错误

TestSnapshotSize3B

验证:快照后,Raft 日志大小不超过 maxraftstate

失败原因:

  • 没有触发快照,或者触发时机不对

TestSnapshotRecover3B

验证:节点崩溃重启后,能从快照恢复状态。

失败原因:

  • 启动时没有恢复快照
  • 快照序列化/反序列化有 bug

TestSnapshotRecoverManyClients3B

验证:在多客户端并发操作和节点崩溃的情况下,快照和恢复都正确。


测试失败时的排查步骤#

  1. 先跑 3A,确保基本功能正确
  2. 加日志:在 apply 线程里打印每个操作的执行情况
  3. 检查去重逻辑:打印每个请求的 ClientID 和 SeqNum
  4. 检查线性一致性错误:Porcupine 的错误信息会告诉你哪个操作违反了线性一致性
// 在 applyLoop 里加日志
log.Printf("[%d] apply op=%v clientID=%d seqNum=%d result=%v",
    kv.me, op.Type, op.ClientID, op.SeqNum, result)
go