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.

276 lines
5.7 KiB

  1. /**
  2. * @file
  3. * @copyright defined in aergo/LICENSE.txt
  4. */
  5. package db
  6. import (
  7. "fmt"
  8. "io/ioutil"
  9. "log"
  10. "os"
  11. "strconv"
  12. "testing"
  13. "github.com/stretchr/testify/assert"
  14. )
  15. const (
  16. tmpDbTestKey1 = "tempkey1"
  17. tmpDbTestKey2 = "tempkey2"
  18. tmpDbTestStrVal1 = "val1"
  19. tmpDbTestStrVal2 = "val2"
  20. tmpDbTestIntVal1 = 1
  21. tmpDbTestIntVal2 = 2
  22. )
  23. func createTmpDB(key ImplType) (dir string, db DB) {
  24. dir, err := ioutil.TempDir("", string(key))
  25. if err != nil {
  26. log.Fatal(err)
  27. }
  28. db = NewDB(key, dir)
  29. return
  30. }
  31. func setInitData(db DB) {
  32. tx := db.NewTx()
  33. tx.Set([]byte("1"), []byte("1"))
  34. tx.Set([]byte("2"), []byte("2"))
  35. tx.Set([]byte("3"), []byte("3"))
  36. tx.Set([]byte("4"), []byte("4"))
  37. tx.Set([]byte("5"), []byte("5"))
  38. tx.Set([]byte("6"), []byte("6"))
  39. tx.Set([]byte("7"), []byte("7"))
  40. tx.Commit()
  41. }
  42. func TestGetSetDeleteExist(t *testing.T) {
  43. // for each db implementation
  44. for key := range dbImpls {
  45. dir, db := createTmpDB(key)
  46. // initial value of empty key must be empty byte
  47. assert.Empty(t, db.Get([]byte(tmpDbTestKey1)), db.Type())
  48. assert.False(t, db.Exist([]byte(tmpDbTestKey1)), db.Type())
  49. // set value
  50. db.Set([]byte(tmpDbTestKey1), []byte(tmpDbTestStrVal1))
  51. // check value set
  52. assert.Equal(t, tmpDbTestStrVal1, string(db.Get([]byte(tmpDbTestKey1))), db.Type())
  53. assert.True(t, db.Exist([]byte(tmpDbTestKey1)), db.Type())
  54. // delete value
  55. db.Delete([]byte(tmpDbTestKey1))
  56. // value must be erased
  57. assert.Empty(t, db.Get([]byte(tmpDbTestKey1)), db.Type())
  58. assert.False(t, db.Exist([]byte(tmpDbTestKey1)), db.Type())
  59. db.Close()
  60. os.RemoveAll(dir)
  61. }
  62. }
  63. func TestTransactionSet(t *testing.T) {
  64. for key := range dbImpls {
  65. dir, db := createTmpDB(key)
  66. // create a new writable tx
  67. tx := db.NewTx()
  68. // set the value in the tx
  69. tx.Set([]byte(tmpDbTestKey1), []byte(tmpDbTestStrVal1))
  70. // the value will not visible at a db
  71. assert.Empty(t, db.Get([]byte(tmpDbTestKey1)), db.Type())
  72. tx.Commit()
  73. // after commit, the value visible from the db
  74. assert.Equal(t, tmpDbTestStrVal1, string(db.Get([]byte(tmpDbTestKey1))), db.Type())
  75. db.Close()
  76. os.RemoveAll(dir)
  77. }
  78. }
  79. func TestTransactionDiscard(t *testing.T) {
  80. for key := range dbImpls {
  81. dir, db := createTmpDB(key)
  82. // create a new writable tx
  83. tx := db.NewTx()
  84. // discard test
  85. tx = db.NewTx()
  86. // set the value in the tx
  87. tx.Set([]byte(tmpDbTestKey1), []byte(tmpDbTestStrVal2))
  88. // discard tx
  89. tx.Discard()
  90. assert.Panics(t, func() { tx.Commit() }, "commit after discard is not allowed")
  91. // after discard, the value must be reset at the db
  92. assert.False(t, db.Exist([]byte(tmpDbTestKey1)), db.Type())
  93. db.Close()
  94. os.RemoveAll(dir)
  95. }
  96. }
  97. func TestTransactionDelete(t *testing.T) {
  98. for key := range dbImpls {
  99. dir, db := createTmpDB(key)
  100. // create a new writable tx
  101. tx := db.NewTx()
  102. // set the value in the tx
  103. tx.Set([]byte(tmpDbTestKey1), []byte(tmpDbTestStrVal1))
  104. // delete the value in the tx
  105. tx.Delete([]byte(tmpDbTestKey1))
  106. tx.Commit()
  107. // after commit, chekc the value from the db
  108. assert.Equal(t, "", string(db.Get([]byte(tmpDbTestKey1))), db.Type())
  109. db.Close()
  110. os.RemoveAll(dir)
  111. }
  112. }
  113. func TestTransactionCommitTwice(t *testing.T) {
  114. for key := range dbImpls {
  115. dir, db := createTmpDB(key)
  116. // create a new writable tx
  117. tx := db.NewTx()
  118. // a first commit will success
  119. tx.Commit()
  120. // a second commit will cause panic
  121. assert.Panics(t, func() { tx.Commit() })
  122. db.Close()
  123. os.RemoveAll(dir)
  124. }
  125. }
  126. func TestBulk(t *testing.T) {
  127. for key := range dbImpls {
  128. dir, db := createTmpDB(key)
  129. // create a new Bulk instance
  130. bulk := db.NewBulk()
  131. // set the huge number of value in the bulk
  132. for i := 0; i < 1000000; i++ {
  133. bulk.Set([]byte(fmt.Sprintf("key%d", i)),
  134. []byte(tmpDbTestStrVal1))
  135. }
  136. bulk.Flush()
  137. // after commit, the value visible from the db
  138. for i := 0; i < 1000000; i++ {
  139. assert.Equal(t, tmpDbTestStrVal1, string(db.Get([]byte(fmt.Sprintf("key%d", i)))), db.Type())
  140. }
  141. db.Close()
  142. os.RemoveAll(dir)
  143. }
  144. }
  145. func TestIter(t *testing.T) {
  146. for key := range dbImpls {
  147. dir, db := createTmpDB(key)
  148. setInitData(db)
  149. i := 1
  150. for iter := db.Iterator(nil, nil); iter.Valid(); iter.Next() {
  151. assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
  152. i++
  153. }
  154. db.Close()
  155. os.RemoveAll(dir)
  156. }
  157. }
  158. func TestRangeIter(t *testing.T) {
  159. for key := range dbImpls {
  160. dir, db := createTmpDB(key)
  161. setInitData(db)
  162. // test iteration 2 -> 5
  163. i := 2
  164. for iter := db.Iterator([]byte("2"), []byte("5")); iter.Valid(); iter.Next() {
  165. assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
  166. assert.EqualValues(t, strconv.Itoa(i), string(iter.Value()))
  167. i++
  168. }
  169. assert.EqualValues(t, i, 5)
  170. // nil sames with []byte("0")
  171. // test iteration 0 -> 5
  172. i = 1
  173. for iter := db.Iterator(nil, []byte("5")); iter.Valid(); iter.Next() {
  174. assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
  175. assert.EqualValues(t, strconv.Itoa(i), string(iter.Value()))
  176. i++
  177. }
  178. assert.EqualValues(t, i, 5)
  179. db.Close()
  180. os.RemoveAll(dir)
  181. }
  182. }
  183. func TestReverseIter(t *testing.T) {
  184. for key := range dbImpls {
  185. dir, db := createTmpDB(key)
  186. setInitData(db)
  187. // test reverse iteration 5 <- 2
  188. i := 5
  189. for iter := db.Iterator([]byte("5"), []byte("2")); iter.Valid(); iter.Next() {
  190. assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
  191. assert.EqualValues(t, strconv.Itoa(i), string(iter.Value()))
  192. i--
  193. }
  194. assert.EqualValues(t, i, 2)
  195. // nil sames with []byte("0")
  196. // test reverse iteration 5 -> 0
  197. i = 5
  198. for iter := db.Iterator([]byte("5"), nil); iter.Valid(); iter.Next() {
  199. assert.EqualValues(t, strconv.Itoa(i), string(iter.Key()))
  200. assert.EqualValues(t, strconv.Itoa(i), string(iter.Value()))
  201. i--
  202. }
  203. assert.EqualValues(t, i, 0)
  204. db.Close()
  205. os.RemoveAll(dir)
  206. }
  207. }