header_comment_test.go 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119
  1. package core
  2. import (
  3. "strings"
  4. "testing"
  5. "git.ycl.pub/yl32940/TsDB2/DB/core/page"
  6. "git.ycl.pub/yl32940/TsDB2/DB/core/types"
  7. )
  8. // TestHeaderCommentAutoIntro 新建库未提供介绍时, Comment 默认写入 VersionComment
  9. // (当前版本的功能介绍与修复点)。
  10. func TestHeaderCommentAutoIntro(t *testing.T) {
  11. db := fixOpenDB(t)
  12. c := db.Comment()
  13. if c == "" {
  14. t.Fatal("新建库的 Comment 不应为空")
  15. }
  16. if c != VersionComment {
  17. t.Fatalf("新建库的 Comment 应等于 VersionComment, 得到 %q", c)
  18. }
  19. if !strings.Contains(c, "v11") {
  20. t.Fatalf("默认介绍应含版本号 %q", c[:min(64, len(c))])
  21. }
  22. }
  23. // TestHeaderCommentSetAndReopen SetComment 写入后经关闭重开仍能原样读回 (含多字节字符)。
  24. func TestHeaderCommentSetAndReopen(t *testing.T) {
  25. path := t.TempDir() + "/comment.db"
  26. db, err := Open(path)
  27. if err != nil {
  28. t.Fatalf("open: %v", err)
  29. }
  30. db.SetAutoCommitDelay(0)
  31. const want = "hello 数据库"
  32. if err := db.SetComment(want); err != nil {
  33. t.Fatalf("SetComment: %v", err)
  34. }
  35. if c := db.Comment(); c != want {
  36. t.Fatalf("SetComment 后 Comment()=%q, 想要 %q", c, want)
  37. }
  38. if err := db.Close(); err != nil {
  39. t.Fatalf("close: %v", err)
  40. }
  41. db2, err := Open(path)
  42. if err != nil {
  43. t.Fatalf("reopen: %v", err)
  44. }
  45. defer db2.Close()
  46. if c := db2.Comment(); c != want {
  47. t.Fatalf("重开后 Comment()=%q, 想要 %q", c, want)
  48. }
  49. }
  50. // TestHeaderCommentTooLong 超过介绍区容量 (PageSize4K-844 = 3252 字节) 必须报错,
  51. // 而不是静默截断; 恰好 3252 字节允许。
  52. func TestHeaderCommentTooLong(t *testing.T) {
  53. db := fixOpenDB(t)
  54. before := db.Comment()
  55. const cap1 = PageSize4K - 332 // 介绍区实际容量 (3764B)
  56. if err := db.SetComment(strings.Repeat("x", cap1+1)); err == nil {
  57. t.Fatalf("SetComment(%d 字节) 应报错", cap1+1)
  58. }
  59. if c := db.Comment(); c != before {
  60. t.Fatalf("超长写入失败后 Comment 被改写成 %q", c)
  61. }
  62. if err := db.SetComment(strings.Repeat("x", cap1)); err != nil {
  63. t.Fatalf("SetComment(%d 字节, 恰好等于容量) 不应报错: %v", cap1, err)
  64. }
  65. if c := db.Comment(); len(c) != cap1 {
  66. t.Fatalf("恰好容量的写入后长度 = %d, 想要 %d", len(c), cap1)
  67. }
  68. }
  69. // TestHeaderCommentSurvivesTableOps 建时序表 / 插入 / 删除 / 提交后 Comment 不变。
  70. func TestHeaderCommentSurvivesTableOps(t *testing.T) {
  71. db := fixOpenDB(t)
  72. before := db.Comment()
  73. tbl, err := db.CreateTable("tick", []types.FieldInfo{
  74. {FieldType: types.FieldType_Uint64, FieldName: []byte("ts")},
  75. {FieldType: types.FieldType_Float64, FieldName: []byte("price")},
  76. })
  77. if err != nil {
  78. t.Fatalf("建表: %v", err)
  79. }
  80. if _, err := tbl.CreateIndex("ts_tick", page.IndexTypeTime, []byte{0}); err != nil {
  81. t.Fatalf("建时序索引: %v", err)
  82. }
  83. for i := 1; i <= 50; i++ {
  84. if _, err := tbl.InsertRowWithID(uint64(i), []types.FieldValue{
  85. {FieldName: []byte("ts"), Value: uint64(i * 10)},
  86. {FieldName: []byte("price"), Value: float64(i) + 0.5},
  87. }); err != nil {
  88. t.Fatalf("插入 %d: %v", i, err)
  89. }
  90. }
  91. if err := db.Commit(); err != nil {
  92. t.Fatalf("commit: %v", err)
  93. }
  94. // 按时间键删几行
  95. for _, ts := range []uint64{100, 200, 300} {
  96. key, err := tbl.BuildIndexKey("ts_tick", ts)
  97. if err != nil {
  98. t.Fatalf("BuildIndexKey: %v", err)
  99. }
  100. if err := tbl.DeleteRow("ts_tick", key); err != nil {
  101. t.Fatalf("删除 ts=%d: %v", ts, err)
  102. }
  103. }
  104. if err := db.Commit(); err != nil {
  105. t.Fatalf("commit: %v", err)
  106. }
  107. if c := db.Comment(); c != before {
  108. t.Fatalf("时序表建/插/删后 Comment=%q, 想要保持 %q", c, before)
  109. }
  110. }