2017-11-09 14:42:32 -08:00
|
|
|
package db
|
|
|
|
|
|
|
|
import (
|
|
|
|
"fmt"
|
2018-03-15 09:43:23 -07:00
|
|
|
"sync"
|
2017-11-09 14:42:32 -08:00
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/assert"
|
2017-12-12 17:58:35 -08:00
|
|
|
"github.com/stretchr/testify/require"
|
2017-11-09 14:42:32 -08:00
|
|
|
cmn "github.com/tendermint/tmlibs/common"
|
|
|
|
)
|
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
//----------------------------------------
|
|
|
|
// Helper functions.
|
|
|
|
|
|
|
|
func checkValue(t *testing.T, db DB, key []byte, valueWanted []byte) {
|
|
|
|
valueGot := db.Get(key)
|
|
|
|
assert.Equal(t, valueWanted, valueGot)
|
|
|
|
}
|
|
|
|
|
2017-11-09 14:42:32 -08:00
|
|
|
func checkValid(t *testing.T, itr Iterator, expected bool) {
|
|
|
|
valid := itr.Valid()
|
2017-12-12 17:58:35 -08:00
|
|
|
require.Equal(t, expected, valid)
|
2017-11-09 14:42:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
func checkNext(t *testing.T, itr Iterator, expected bool) {
|
|
|
|
itr.Next()
|
|
|
|
valid := itr.Valid()
|
2017-12-12 17:58:35 -08:00
|
|
|
require.Equal(t, expected, valid)
|
2017-11-09 14:42:32 -08:00
|
|
|
}
|
|
|
|
|
|
|
|
func checkNextPanics(t *testing.T, itr Iterator) {
|
|
|
|
assert.Panics(t, func() { itr.Next() }, "checkNextPanics expected panic but didn't")
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkItem(t *testing.T, itr Iterator, key []byte, value []byte) {
|
|
|
|
k, v := itr.Key(), itr.Value()
|
|
|
|
assert.Exactly(t, key, k)
|
|
|
|
assert.Exactly(t, value, v)
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkInvalid(t *testing.T, itr Iterator) {
|
|
|
|
checkValid(t, itr, false)
|
|
|
|
checkKeyPanics(t, itr)
|
|
|
|
checkValuePanics(t, itr)
|
|
|
|
checkNextPanics(t, itr)
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkKeyPanics(t *testing.T, itr Iterator) {
|
|
|
|
assert.Panics(t, func() { itr.Key() }, "checkKeyPanics expected panic but didn't")
|
|
|
|
}
|
|
|
|
|
|
|
|
func checkValuePanics(t *testing.T, itr Iterator) {
|
|
|
|
assert.Panics(t, func() { itr.Key() }, "checkValuePanics expected panic but didn't")
|
|
|
|
}
|
|
|
|
|
2018-02-02 19:31:17 -08:00
|
|
|
func newTempDB(t *testing.T, backend DBBackendType) (db DB) {
|
2018-03-15 09:43:23 -07:00
|
|
|
dir, dirname := cmn.Tempdir("db_common_test")
|
2017-11-09 14:42:32 -08:00
|
|
|
db = NewDB("testdb", backend, dirname)
|
|
|
|
dir.Close()
|
|
|
|
return db
|
|
|
|
}
|
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
//----------------------------------------
|
|
|
|
// mockDB
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
// NOTE: not actually goroutine safe.
|
|
|
|
// If you want something goroutine safe, maybe you just want a MemDB.
|
|
|
|
type mockDB struct {
|
|
|
|
mtx sync.Mutex
|
|
|
|
calls map[string]int
|
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func newMockDB() *mockDB {
|
|
|
|
return &mockDB{
|
|
|
|
calls: make(map[string]int),
|
2017-11-09 14:42:32 -08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) Mutex() *sync.Mutex {
|
|
|
|
return &(mdb.mtx)
|
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) Get([]byte) []byte {
|
|
|
|
mdb.calls["Get"] += 1
|
|
|
|
return nil
|
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) Has([]byte) bool {
|
|
|
|
mdb.calls["Has"] += 1
|
|
|
|
return false
|
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) Set([]byte, []byte) {
|
|
|
|
mdb.calls["Set"] += 1
|
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) SetSync([]byte, []byte) {
|
|
|
|
mdb.calls["SetSync"] += 1
|
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) SetNoLock([]byte, []byte) {
|
|
|
|
mdb.calls["SetNoLock"] += 1
|
2017-11-09 14:42:32 -08:00
|
|
|
}
|
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) SetNoLockSync([]byte, []byte) {
|
|
|
|
mdb.calls["SetNoLockSync"] += 1
|
|
|
|
}
|
2017-12-17 13:11:28 -08:00
|
|
|
|
2018-03-17 17:52:28 -07:00
|
|
|
func (mdb *mockDB) Delete([]byte) {
|
2018-03-15 09:43:23 -07:00
|
|
|
mdb.calls["Delete"] += 1
|
|
|
|
}
|
2017-12-17 13:11:28 -08:00
|
|
|
|
2018-03-17 17:52:28 -07:00
|
|
|
func (mdb *mockDB) DeleteSync([]byte) {
|
2018-03-15 09:43:23 -07:00
|
|
|
mdb.calls["DeleteSync"] += 1
|
|
|
|
}
|
2017-12-17 13:11:28 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) DeleteNoLock([]byte) {
|
|
|
|
mdb.calls["DeleteNoLock"] += 1
|
2017-12-17 13:11:28 -08:00
|
|
|
}
|
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) DeleteNoLockSync([]byte) {
|
|
|
|
mdb.calls["DeleteNoLockSync"] += 1
|
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) Iterator(start, end []byte) Iterator {
|
|
|
|
mdb.calls["Iterator"] += 1
|
|
|
|
return &mockIterator{}
|
2017-11-09 14:42:32 -08:00
|
|
|
}
|
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) ReverseIterator(start, end []byte) Iterator {
|
|
|
|
mdb.calls["ReverseIterator"] += 1
|
|
|
|
return &mockIterator{}
|
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) Close() {
|
|
|
|
mdb.calls["Close"] += 1
|
2017-11-09 14:42:32 -08:00
|
|
|
}
|
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) NewBatch() Batch {
|
|
|
|
mdb.calls["NewBatch"] += 1
|
|
|
|
return &memBatch{db: mdb}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (mdb *mockDB) Print() {
|
|
|
|
mdb.calls["Print"] += 1
|
2018-03-17 17:52:28 -07:00
|
|
|
fmt.Printf("mockDB{%v}", mdb.Stats())
|
2018-03-15 09:43:23 -07:00
|
|
|
}
|
2017-11-09 14:42:32 -08:00
|
|
|
|
2018-03-15 09:43:23 -07:00
|
|
|
func (mdb *mockDB) Stats() map[string]string {
|
|
|
|
mdb.calls["Stats"] += 1
|
|
|
|
|
|
|
|
res := make(map[string]string)
|
|
|
|
for key, count := range mdb.calls {
|
|
|
|
res[key] = fmt.Sprintf("%d", count)
|
2017-11-09 14:42:32 -08:00
|
|
|
}
|
2018-03-15 09:43:23 -07:00
|
|
|
return res
|
|
|
|
}
|
|
|
|
|
|
|
|
//----------------------------------------
|
|
|
|
// mockIterator
|
|
|
|
|
|
|
|
type mockIterator struct{}
|
|
|
|
|
|
|
|
func (_ mockIterator) Domain() (start []byte, end []byte) {
|
|
|
|
return nil, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (_ mockIterator) Valid() bool {
|
|
|
|
return false
|
|
|
|
}
|
|
|
|
|
|
|
|
func (_ mockIterator) Next() {
|
|
|
|
}
|
|
|
|
|
|
|
|
func (_ mockIterator) Key() []byte {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (_ mockIterator) Value() []byte {
|
|
|
|
return nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (_ mockIterator) Close() {
|
2017-11-09 14:42:32 -08:00
|
|
|
}
|