audit_crc_test.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263
  1. package main
  2. import (
  3. "encoding/binary"
  4. "testing"
  5. "git.ycl.pub/yl32940/TsDB2/DB/core"
  6. )
  7. // 构造一个 CRC 自洽的头页字节块 (Magic + Version + Comment + 正确 CRC)。
  8. func buildHeaderPage(t *testing.T, version uint32, comment string) []byte {
  9. t.Helper()
  10. b := make([]byte, 4096)
  11. copy(b[0:4], "VRTX")
  12. binary.LittleEndian.PutUint32(b[4:8], version)
  13. copy(b[332:], comment)
  14. // 与 core.PrepareWrite 同法: 清零 CRC 字段后整页散列
  15. for i := 84; i < 88; i++ {
  16. b[i] = 0
  17. }
  18. binary.LittleEndian.PutUint32(b[84:88], core.XXH32(b))
  19. return b
  20. }
  21. func TestCheckHeaderCrc(t *testing.T) {
  22. // 正常: CRC 自洽 → OK
  23. ok := buildHeaderPage(t, 11, "hello")
  24. if v, d := checkHeaderCrc(ok, 11); v != "OK" {
  25. t.Fatalf("自洽头页应 OK, 得到 %s (%s)", v, d)
  26. }
  27. // 损坏: 改 Comment 区一字节 → CRC 不符
  28. bad := buildHeaderPage(t, 11, "hello")
  29. bad[400] ^= 0x01
  30. if v, _ := checkHeaderCrc(bad, 11); v != "CRC 不符" {
  31. t.Fatalf("损坏头页应 CRC 不符, 得到 %s", v)
  32. }
  33. // 旧库: v11 且 CRC==0 → 跳过
  34. legacy := buildHeaderPage(t, 11, "old")
  35. for i := 84; i < 88; i++ {
  36. legacy[i] = 0
  37. }
  38. if v, _ := checkHeaderCrc(legacy, 11); v != "跳过" {
  39. t.Fatalf("旧 v11 库应跳过, 得到 %s", v)
  40. }
  41. // 未来版本 (v12): CRC==0 也要校验 → 不符
  42. if v, _ := checkHeaderCrc(legacy, 12); v != "CRC 不符" {
  43. t.Fatalf("v12 零 CRC 应按失配处理, 得到 %s", v)
  44. }
  45. // checkHeaderCrc 不得改动调用方的字节
  46. mine := buildHeaderPage(t, 11, "immutable")
  47. snapshot := make([]byte, len(mine))
  48. copy(snapshot, mine)
  49. checkHeaderCrc(mine, 11)
  50. for i := range mine {
  51. if mine[i] != snapshot[i] {
  52. t.Fatalf("checkHeaderCrc 改动了输入字节 @ %d", i)
  53. }
  54. }
  55. }