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.

222 lines
7.3 KiB

7 years ago
7 years ago
7 years ago
  1. package db
  2. import (
  3. "fmt"
  4. "io/ioutil"
  5. "os"
  6. "path/filepath"
  7. "testing"
  8. "github.com/stretchr/testify/assert"
  9. "github.com/stretchr/testify/require"
  10. cmn "github.com/tendermint/tendermint/libs/common"
  11. )
  12. func cleanupDBDir(dir, name string) {
  13. err := os.RemoveAll(filepath.Join(dir, name) + ".db")
  14. if err != nil {
  15. panic(err)
  16. }
  17. }
  18. func testBackendGetSetDelete(t *testing.T, backend DBBackendType) {
  19. // Default
  20. dirname, err := ioutil.TempDir("", fmt.Sprintf("test_backend_%s_", backend))
  21. require.Nil(t, err)
  22. db := NewDB("testdb", backend, dirname)
  23. defer cleanupDBDir(dirname, "testdb")
  24. // A nonexistent key should return nil, even if the key is empty
  25. require.Nil(t, db.Get([]byte("")))
  26. // A nonexistent key should return nil, even if the key is nil
  27. require.Nil(t, db.Get(nil))
  28. // A nonexistent key should return nil.
  29. key := []byte("abc")
  30. require.Nil(t, db.Get(key))
  31. // Set empty value.
  32. db.Set(key, []byte(""))
  33. require.NotNil(t, db.Get(key))
  34. require.Empty(t, db.Get(key))
  35. // Set nil value.
  36. db.Set(key, nil)
  37. require.NotNil(t, db.Get(key))
  38. require.Empty(t, db.Get(key))
  39. // Delete.
  40. db.Delete(key)
  41. require.Nil(t, db.Get(key))
  42. }
  43. func TestBackendsGetSetDelete(t *testing.T) {
  44. for dbType := range backends {
  45. testBackendGetSetDelete(t, dbType)
  46. }
  47. }
  48. func withDB(t *testing.T, creator dbCreator, fn func(DB)) {
  49. name := fmt.Sprintf("test_%x", cmn.RandStr(12))
  50. dir := os.TempDir()
  51. db, err := creator(name, dir)
  52. require.Nil(t, err)
  53. defer cleanupDBDir(dir, name)
  54. fn(db)
  55. db.Close()
  56. }
  57. func TestBackendsNilKeys(t *testing.T) {
  58. // Test all backends.
  59. for dbType, creator := range backends {
  60. withDB(t, creator, func(db DB) {
  61. t.Run(fmt.Sprintf("Testing %s", dbType), func(t *testing.T) {
  62. // Nil keys are treated as the empty key for most operations.
  63. expect := func(key, value []byte) {
  64. if len(key) == 0 { // nil or empty
  65. assert.Equal(t, db.Get(nil), db.Get([]byte("")))
  66. assert.Equal(t, db.Has(nil), db.Has([]byte("")))
  67. }
  68. assert.Equal(t, db.Get(key), value)
  69. assert.Equal(t, db.Has(key), value != nil)
  70. }
  71. // Not set
  72. expect(nil, nil)
  73. // Set nil value
  74. db.Set(nil, nil)
  75. expect(nil, []byte(""))
  76. // Set empty value
  77. db.Set(nil, []byte(""))
  78. expect(nil, []byte(""))
  79. // Set nil, Delete nil
  80. db.Set(nil, []byte("abc"))
  81. expect(nil, []byte("abc"))
  82. db.Delete(nil)
  83. expect(nil, nil)
  84. // Set nil, Delete empty
  85. db.Set(nil, []byte("abc"))
  86. expect(nil, []byte("abc"))
  87. db.Delete([]byte(""))
  88. expect(nil, nil)
  89. // Set empty, Delete nil
  90. db.Set([]byte(""), []byte("abc"))
  91. expect(nil, []byte("abc"))
  92. db.Delete(nil)
  93. expect(nil, nil)
  94. // Set empty, Delete empty
  95. db.Set([]byte(""), []byte("abc"))
  96. expect(nil, []byte("abc"))
  97. db.Delete([]byte(""))
  98. expect(nil, nil)
  99. // SetSync nil, DeleteSync nil
  100. db.SetSync(nil, []byte("abc"))
  101. expect(nil, []byte("abc"))
  102. db.DeleteSync(nil)
  103. expect(nil, nil)
  104. // SetSync nil, DeleteSync empty
  105. db.SetSync(nil, []byte("abc"))
  106. expect(nil, []byte("abc"))
  107. db.DeleteSync([]byte(""))
  108. expect(nil, nil)
  109. // SetSync empty, DeleteSync nil
  110. db.SetSync([]byte(""), []byte("abc"))
  111. expect(nil, []byte("abc"))
  112. db.DeleteSync(nil)
  113. expect(nil, nil)
  114. // SetSync empty, DeleteSync empty
  115. db.SetSync([]byte(""), []byte("abc"))
  116. expect(nil, []byte("abc"))
  117. db.DeleteSync([]byte(""))
  118. expect(nil, nil)
  119. })
  120. })
  121. }
  122. }
  123. func TestGoLevelDBBackend(t *testing.T) {
  124. name := fmt.Sprintf("test_%x", cmn.RandStr(12))
  125. db := NewDB(name, GoLevelDBBackend, "")
  126. defer cleanupDBDir("", name)
  127. _, ok := db.(*GoLevelDB)
  128. assert.True(t, ok)
  129. }
  130. func TestDBIterator(t *testing.T) {
  131. for dbType := range backends {
  132. t.Run(fmt.Sprintf("%v", dbType), func(t *testing.T) {
  133. testDBIterator(t, dbType)
  134. })
  135. }
  136. }
  137. func testDBIterator(t *testing.T, backend DBBackendType) {
  138. name := fmt.Sprintf("test_%x", cmn.RandStr(12))
  139. dir := os.TempDir()
  140. db := NewDB(name, backend, dir)
  141. defer cleanupDBDir(dir, name)
  142. for i := 0; i < 10; i++ {
  143. if i != 6 { // but skip 6.
  144. db.Set(int642Bytes(int64(i)), nil)
  145. }
  146. }
  147. verifyIterator(t, db.Iterator(nil, nil), []int64{0, 1, 2, 3, 4, 5, 7, 8, 9}, "forward iterator")
  148. verifyIterator(t, db.ReverseIterator(nil, nil), []int64{9, 8, 7, 5, 4, 3, 2, 1, 0}, "reverse iterator")
  149. verifyIterator(t, db.Iterator(nil, int642Bytes(0)), []int64(nil), "forward iterator to 0")
  150. verifyIterator(t, db.ReverseIterator(int642Bytes(10), nil), []int64(nil), "reverse iterator from 10 (ex)")
  151. verifyIterator(t, db.Iterator(int642Bytes(0), nil), []int64{0, 1, 2, 3, 4, 5, 7, 8, 9}, "forward iterator from 0")
  152. verifyIterator(t, db.Iterator(int642Bytes(1), nil), []int64{1, 2, 3, 4, 5, 7, 8, 9}, "forward iterator from 1")
  153. verifyIterator(t, db.ReverseIterator(nil, int642Bytes(10)), []int64{9, 8, 7, 5, 4, 3, 2, 1, 0}, "reverse iterator from 10 (ex)")
  154. verifyIterator(t, db.ReverseIterator(nil, int642Bytes(9)), []int64{8, 7, 5, 4, 3, 2, 1, 0}, "reverse iterator from 9 (ex)")
  155. verifyIterator(t, db.ReverseIterator(nil, int642Bytes(8)), []int64{7, 5, 4, 3, 2, 1, 0}, "reverse iterator from 8 (ex)")
  156. verifyIterator(t, db.Iterator(int642Bytes(5), int642Bytes(6)), []int64{5}, "forward iterator from 5 to 6")
  157. verifyIterator(t, db.Iterator(int642Bytes(5), int642Bytes(7)), []int64{5}, "forward iterator from 5 to 7")
  158. verifyIterator(t, db.Iterator(int642Bytes(5), int642Bytes(8)), []int64{5, 7}, "forward iterator from 5 to 8")
  159. verifyIterator(t, db.Iterator(int642Bytes(6), int642Bytes(7)), []int64(nil), "forward iterator from 6 to 7")
  160. verifyIterator(t, db.Iterator(int642Bytes(6), int642Bytes(8)), []int64{7}, "forward iterator from 6 to 8")
  161. verifyIterator(t, db.Iterator(int642Bytes(7), int642Bytes(8)), []int64{7}, "forward iterator from 7 to 8")
  162. verifyIterator(t, db.ReverseIterator(int642Bytes(4), int642Bytes(5)), []int64{4}, "reverse iterator from 5 (ex) to 4")
  163. verifyIterator(t, db.ReverseIterator(int642Bytes(4), int642Bytes(6)), []int64{5, 4}, "reverse iterator from 6 (ex) to 4")
  164. verifyIterator(t, db.ReverseIterator(int642Bytes(4), int642Bytes(7)), []int64{5, 4}, "reverse iterator from 7 (ex) to 4")
  165. verifyIterator(t, db.ReverseIterator(int642Bytes(5), int642Bytes(6)), []int64{5}, "reverse iterator from 6 (ex) to 5")
  166. verifyIterator(t, db.ReverseIterator(int642Bytes(5), int642Bytes(7)), []int64{5}, "reverse iterator from 7 (ex) to 5")
  167. verifyIterator(t, db.ReverseIterator(int642Bytes(6), int642Bytes(7)), []int64(nil), "reverse iterator from 7 (ex) to 6")
  168. verifyIterator(t, db.Iterator(int642Bytes(0), int642Bytes(1)), []int64{0}, "forward iterator from 0 to 1")
  169. verifyIterator(t, db.ReverseIterator(int642Bytes(8), int642Bytes(9)), []int64{8}, "reverse iterator from 9 (ex) to 8")
  170. verifyIterator(t, db.Iterator(int642Bytes(2), int642Bytes(4)), []int64{2, 3}, "forward iterator from 2 to 4")
  171. verifyIterator(t, db.Iterator(int642Bytes(4), int642Bytes(2)), []int64(nil), "forward iterator from 4 to 2")
  172. verifyIterator(t, db.ReverseIterator(int642Bytes(2), int642Bytes(4)), []int64{3, 2}, "reverse iterator from 4 (ex) to 2")
  173. verifyIterator(t, db.ReverseIterator(int642Bytes(4), int642Bytes(2)), []int64(nil), "reverse iterator from 2 (ex) to 4")
  174. }
  175. func verifyIterator(t *testing.T, itr Iterator, expected []int64, msg string) {
  176. var list []int64
  177. for itr.Valid() {
  178. list = append(list, bytes2Int64(itr.Key()))
  179. itr.Next()
  180. }
  181. assert.Equal(t, expected, list, msg)
  182. }