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.

155 lines
3.5 KiB

  1. package db
  2. import (
  3. "fmt"
  4. "testing"
  5. "github.com/stretchr/testify/assert"
  6. "github.com/stretchr/testify/require"
  7. cmn "github.com/tendermint/tmlibs/common"
  8. )
  9. func checkValid(t *testing.T, itr Iterator, expected bool) {
  10. valid := itr.Valid()
  11. require.Equal(t, expected, valid)
  12. }
  13. func checkNext(t *testing.T, itr Iterator, expected bool) {
  14. itr.Next()
  15. valid := itr.Valid()
  16. require.Equal(t, expected, valid)
  17. }
  18. func checkNextPanics(t *testing.T, itr Iterator) {
  19. assert.Panics(t, func() { itr.Next() }, "checkNextPanics expected panic but didn't")
  20. }
  21. func checkItem(t *testing.T, itr Iterator, key []byte, value []byte) {
  22. k, v := itr.Key(), itr.Value()
  23. assert.Exactly(t, key, k)
  24. assert.Exactly(t, value, v)
  25. }
  26. func checkInvalid(t *testing.T, itr Iterator) {
  27. checkValid(t, itr, false)
  28. checkKeyPanics(t, itr)
  29. checkValuePanics(t, itr)
  30. checkNextPanics(t, itr)
  31. }
  32. func checkKeyPanics(t *testing.T, itr Iterator) {
  33. assert.Panics(t, func() { itr.Key() }, "checkKeyPanics expected panic but didn't")
  34. }
  35. func checkValuePanics(t *testing.T, itr Iterator) {
  36. assert.Panics(t, func() { itr.Key() }, "checkValuePanics expected panic but didn't")
  37. }
  38. func newTempDB(t *testing.T, backend DBBackendType) (db DB) {
  39. dir, dirname := cmn.Tempdir("test_go_iterator")
  40. db = NewDB("testdb", backend, dirname)
  41. dir.Close()
  42. return db
  43. }
  44. func TestDBIteratorSingleKey(t *testing.T) {
  45. for backend, _ := range backends {
  46. t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) {
  47. db := newTempDB(t, backend)
  48. db.SetSync(bz("1"), bz("value_1"))
  49. itr := db.Iterator(nil, nil)
  50. checkValid(t, itr, true)
  51. checkNext(t, itr, false)
  52. checkValid(t, itr, false)
  53. checkNextPanics(t, itr)
  54. // Once invalid...
  55. checkInvalid(t, itr)
  56. })
  57. }
  58. }
  59. func TestDBIteratorTwoKeys(t *testing.T) {
  60. for backend, _ := range backends {
  61. t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) {
  62. db := newTempDB(t, backend)
  63. db.SetSync(bz("1"), bz("value_1"))
  64. db.SetSync(bz("2"), bz("value_1"))
  65. { // Fail by calling Next too much
  66. itr := db.Iterator(nil, nil)
  67. checkValid(t, itr, true)
  68. checkNext(t, itr, true)
  69. checkValid(t, itr, true)
  70. checkNext(t, itr, false)
  71. checkValid(t, itr, false)
  72. checkNextPanics(t, itr)
  73. // Once invalid...
  74. checkInvalid(t, itr)
  75. }
  76. })
  77. }
  78. }
  79. func TestDBIteratorMany(t *testing.T) {
  80. for backend, _ := range backends {
  81. t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) {
  82. db := newTempDB(t, backend)
  83. keys := make([][]byte, 100)
  84. for i := 0; i < 100; i++ {
  85. keys[i] = []byte{byte(i)}
  86. }
  87. value := []byte{5}
  88. for _, k := range keys {
  89. db.Set(k, value)
  90. }
  91. itr := db.Iterator(nil, nil)
  92. defer itr.Close()
  93. for ; itr.Valid(); itr.Next() {
  94. assert.Equal(t, db.Get(itr.Key()), itr.Value())
  95. }
  96. })
  97. }
  98. }
  99. func TestDBIteratorEmpty(t *testing.T) {
  100. for backend, _ := range backends {
  101. t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) {
  102. db := newTempDB(t, backend)
  103. itr := db.Iterator(nil, nil)
  104. checkInvalid(t, itr)
  105. })
  106. }
  107. }
  108. func TestDBIteratorEmptyBeginAfter(t *testing.T) {
  109. for backend, _ := range backends {
  110. t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) {
  111. db := newTempDB(t, backend)
  112. itr := db.Iterator(bz("1"), nil)
  113. checkInvalid(t, itr)
  114. })
  115. }
  116. }
  117. func TestDBIteratorNonemptyBeginAfter(t *testing.T) {
  118. for backend, _ := range backends {
  119. t.Run(fmt.Sprintf("Backend %s", backend), func(t *testing.T) {
  120. db := newTempDB(t, backend)
  121. db.SetSync(bz("1"), bz("value_1"))
  122. itr := db.Iterator(bz("2"), nil)
  123. checkInvalid(t, itr)
  124. })
  125. }
  126. }