You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

236 lines
6.1 KiB

  1. package kvdb
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "testing"
  7. "github.com/hermeznetwork/hermez-node/common"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. )
  11. func addTestKV(t *testing.T, db *KVDB, k, v []byte) {
  12. tx, err := db.db.NewTx()
  13. require.NoError(t, err)
  14. err = tx.Put(k, v)
  15. require.NoError(t, err)
  16. err = tx.Commit()
  17. require.NoError(t, err)
  18. }
  19. func printCheckpoints(t *testing.T, path string) {
  20. files, err := ioutil.ReadDir(path)
  21. require.NoError(t, err)
  22. fmt.Println(path)
  23. for _, f := range files {
  24. fmt.Println(" " + f.Name())
  25. }
  26. }
  27. func TestCheckpoints(t *testing.T) {
  28. dir, err := ioutil.TempDir("", "sdb")
  29. require.NoError(t, err)
  30. defer require.NoError(t, os.RemoveAll(dir))
  31. db, err := NewKVDB(Config{Path: dir, Keep: 128})
  32. require.NoError(t, err)
  33. // add test key-values
  34. for i := 0; i < 10; i++ {
  35. addTestKV(t, db, []byte{byte(i), byte(i)}, []byte{byte(i * 2), byte(i * 2)})
  36. }
  37. // do checkpoints and check that currentBatch is correct
  38. err = db.MakeCheckpoint()
  39. require.NoError(t, err)
  40. cb, err := db.GetCurrentBatch()
  41. require.NoError(t, err)
  42. assert.Equal(t, common.BatchNum(1), cb)
  43. for i := 1; i < 10; i++ {
  44. err = db.MakeCheckpoint()
  45. require.NoError(t, err)
  46. cb, err = db.GetCurrentBatch()
  47. require.NoError(t, err)
  48. assert.Equal(t, common.BatchNum(i+1), cb)
  49. }
  50. // printCheckpoints(t, db.path)
  51. // reset checkpoint
  52. err = db.Reset(3)
  53. require.NoError(t, err)
  54. // check that reset can be repeated (as there exist the 'current' and
  55. // 'BatchNum3', from where the 'current' is a copy)
  56. err = db.Reset(3)
  57. require.NoError(t, err)
  58. printCheckpoints(t, db.cfg.Path)
  59. // check that currentBatch is as expected after Reset
  60. cb, err = db.GetCurrentBatch()
  61. require.NoError(t, err)
  62. assert.Equal(t, common.BatchNum(3), cb)
  63. // advance one checkpoint and check that currentBatch is fine
  64. err = db.MakeCheckpoint()
  65. require.NoError(t, err)
  66. cb, err = db.GetCurrentBatch()
  67. require.NoError(t, err)
  68. assert.Equal(t, common.BatchNum(4), cb)
  69. err = db.DeleteCheckpoint(common.BatchNum(1))
  70. require.NoError(t, err)
  71. err = db.DeleteCheckpoint(common.BatchNum(2))
  72. require.NoError(t, err)
  73. err = db.DeleteCheckpoint(common.BatchNum(1)) // does not exist, should return err
  74. assert.NotNil(t, err)
  75. err = db.DeleteCheckpoint(common.BatchNum(2)) // does not exist, should return err
  76. assert.NotNil(t, err)
  77. // Create a new KVDB which will get Reset from the initial KVDB
  78. dirLocal, err := ioutil.TempDir("", "ldb")
  79. require.NoError(t, err)
  80. defer require.NoError(t, os.RemoveAll(dirLocal))
  81. ldb, err := NewKVDB(Config{Path: dirLocal, Keep: 128})
  82. require.NoError(t, err)
  83. // get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
  84. err = ldb.ResetFromSynchronizer(4, db)
  85. require.NoError(t, err)
  86. // check that currentBatch is 4 after the Reset
  87. cb, err = ldb.GetCurrentBatch()
  88. require.NoError(t, err)
  89. assert.Equal(t, common.BatchNum(4), cb)
  90. // advance one checkpoint in ldb
  91. err = ldb.MakeCheckpoint()
  92. require.NoError(t, err)
  93. cb, err = ldb.GetCurrentBatch()
  94. require.NoError(t, err)
  95. assert.Equal(t, common.BatchNum(5), cb)
  96. // Create a 3rd KVDB which will get Reset from the initial KVDB
  97. dirLocal2, err := ioutil.TempDir("", "ldb2")
  98. require.NoError(t, err)
  99. defer require.NoError(t, os.RemoveAll(dirLocal2))
  100. ldb2, err := NewKVDB(Config{Path: dirLocal2, Keep: 128})
  101. require.NoError(t, err)
  102. // get checkpoint 4 from sdb (StateDB) to ldb (LocalStateDB)
  103. err = ldb2.ResetFromSynchronizer(4, db)
  104. require.NoError(t, err)
  105. // check that currentBatch is 4 after the Reset
  106. cb, err = ldb2.GetCurrentBatch()
  107. require.NoError(t, err)
  108. assert.Equal(t, common.BatchNum(4), cb)
  109. // advance one checkpoint in ldb2
  110. err = ldb2.MakeCheckpoint()
  111. require.NoError(t, err)
  112. cb, err = ldb2.GetCurrentBatch()
  113. require.NoError(t, err)
  114. assert.Equal(t, common.BatchNum(5), cb)
  115. debug := false
  116. if debug {
  117. printCheckpoints(t, db.cfg.Path)
  118. printCheckpoints(t, ldb.cfg.Path)
  119. printCheckpoints(t, ldb2.cfg.Path)
  120. }
  121. }
  122. func TestListCheckpoints(t *testing.T) {
  123. dir, err := ioutil.TempDir("", "tmpdb")
  124. require.NoError(t, err)
  125. defer require.NoError(t, os.RemoveAll(dir))
  126. db, err := NewKVDB(Config{Path: dir, Keep: 128})
  127. require.NoError(t, err)
  128. numCheckpoints := 16
  129. // do checkpoints
  130. for i := 0; i < numCheckpoints; i++ {
  131. err = db.MakeCheckpoint()
  132. require.NoError(t, err)
  133. }
  134. list, err := db.ListCheckpoints()
  135. require.NoError(t, err)
  136. assert.Equal(t, numCheckpoints, len(list))
  137. assert.Equal(t, 1, list[0])
  138. assert.Equal(t, numCheckpoints, list[len(list)-1])
  139. numReset := 10
  140. err = db.Reset(common.BatchNum(numReset))
  141. require.NoError(t, err)
  142. list, err = db.ListCheckpoints()
  143. require.NoError(t, err)
  144. assert.Equal(t, numReset, len(list))
  145. assert.Equal(t, 1, list[0])
  146. assert.Equal(t, numReset, list[len(list)-1])
  147. }
  148. func TestDeleteOldCheckpoints(t *testing.T) {
  149. dir, err := ioutil.TempDir("", "tmpdb")
  150. require.NoError(t, err)
  151. defer require.NoError(t, os.RemoveAll(dir))
  152. keep := 16
  153. db, err := NewKVDB(Config{Path: dir, Keep: keep})
  154. require.NoError(t, err)
  155. numCheckpoints := 32
  156. // do checkpoints and check that we never have more than `keep`
  157. // checkpoints
  158. for i := 0; i < numCheckpoints; i++ {
  159. err = db.MakeCheckpoint()
  160. require.NoError(t, err)
  161. checkpoints, err := db.ListCheckpoints()
  162. require.NoError(t, err)
  163. assert.LessOrEqual(t, len(checkpoints), keep)
  164. }
  165. }
  166. func TestGetCurrentIdx(t *testing.T) {
  167. dir, err := ioutil.TempDir("", "tmpdb")
  168. require.NoError(t, err)
  169. defer require.NoError(t, os.RemoveAll(dir))
  170. keep := 16
  171. db, err := NewKVDB(Config{Path: dir, Keep: keep})
  172. require.NoError(t, err)
  173. idx, err := db.GetCurrentIdx()
  174. require.NoError(t, err)
  175. assert.Equal(t, common.Idx(255), idx)
  176. db.Close()
  177. db, err = NewKVDB(Config{Path: dir, Keep: keep})
  178. require.NoError(t, err)
  179. idx, err = db.GetCurrentIdx()
  180. require.NoError(t, err)
  181. assert.Equal(t, common.Idx(255), idx)
  182. err = db.MakeCheckpoint()
  183. require.NoError(t, err)
  184. idx, err = db.GetCurrentIdx()
  185. require.NoError(t, err)
  186. assert.Equal(t, common.Idx(255), idx)
  187. db.Close()
  188. db, err = NewKVDB(Config{Path: dir, Keep: keep})
  189. require.NoError(t, err)
  190. idx, err = db.GetCurrentIdx()
  191. require.NoError(t, err)
  192. assert.Equal(t, common.Idx(255), idx)
  193. }