store: add some tests, fix deadlocks (#297)

This commit is contained in:
Ethan Buchman 2017-12-12 02:36:50 -05:00 committed by Jae Kwon
parent af7a621440
commit 1a28c4b89c
2 changed files with 120 additions and 24 deletions

View File

@ -7,6 +7,13 @@ import (
dbm "github.com/tendermint/tmlibs/db" dbm "github.com/tendermint/tmlibs/db"
) )
// iavlStoreLoader contains info on what store we want to load from
type iavlStoreLoader struct {
db dbm.DB
cacheSize int
numHistory int64
}
// NewIAVLStoreLoader returns a CommitStoreLoader that returns an iavlStore // NewIAVLStoreLoader returns a CommitStoreLoader that returns an iavlStore
func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreLoader { func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreLoader {
l := iavlStoreLoader{ l := iavlStoreLoader{
@ -17,6 +24,19 @@ func NewIAVLStoreLoader(db dbm.DB, cacheSize int, numHistory int64) CommitStoreL
return l.Load return l.Load
} }
// Load implements CommitLoader.
func (isl iavlStoreLoader) Load(id CommitID) (CommitStore, error) {
tree := iavl.NewVersionedTree(isl.db, isl.cacheSize)
err := tree.Load()
if err != nil {
return nil, err
}
store := newIAVLStore(tree, isl.numHistory)
return store, nil
}
//----------------------------------------
var _ IterKVStore = (*iavlStore)(nil) var _ IterKVStore = (*iavlStore)(nil)
var _ CommitStore = (*iavlStore)(nil) var _ CommitStore = (*iavlStore)(nil)
@ -243,8 +263,6 @@ func (iter *iavlIterator) Release() {
//---------------------------------------- //----------------------------------------
func (iter *iavlIterator) setNext(key, value []byte) { func (iter *iavlIterator) setNext(key, value []byte) {
iter.mtx.Lock()
defer iter.mtx.Unlock()
iter.assertIsValid() iter.assertIsValid()
iter.key = key iter.key = key
@ -252,8 +270,6 @@ func (iter *iavlIterator) setNext(key, value []byte) {
} }
func (iter *iavlIterator) setInvalid() { func (iter *iavlIterator) setInvalid() {
iter.mtx.Lock()
defer iter.mtx.Unlock()
iter.assertIsValid() iter.assertIsValid()
iter.invalid = true iter.invalid = true
@ -280,26 +296,6 @@ func (iter *iavlIterator) assertIsValid() {
//---------------------------------------- //----------------------------------------
// iavlStoreLoader contains info on what store we want to load from
type iavlStoreLoader struct {
db dbm.DB
cacheSize int
numHistory int64
}
// Load implements CommitLoader.
func (isl iavlStoreLoader) Load(id CommitID) (CommitStore, error) {
tree := iavl.NewVersionedTree(isl.db, isl.cacheSize)
err := tree.Load()
if err != nil {
return nil, err
}
store := newIAVLStore(tree, isl.numHistory)
return store, nil
}
//----------------------------------------
func cp(bz []byte) (ret []byte) { func cp(bz []byte) (ret []byte) {
ret = make([]byte, len(bz)) ret = make([]byte, len(bz))
copy(ret, bz) copy(ret, bz)

100
store/iavlstore_test.go Normal file
View File

@ -0,0 +1,100 @@
package store
import (
"testing"
"github.com/stretchr/testify/assert"
cmn "github.com/tendermint/tmlibs/common"
dbm "github.com/tendermint/tmlibs/db"
"github.com/tendermint/iavl"
)
var (
cacheSize = 100
numHistory int64 = 5
)
var (
treeData = map[string]string{
"hello": "goodbye",
"aloha": "shalom",
}
nMoreData = 0
)
// make a tree and save it
func newTree(t *testing.T, db dbm.DB) (*iavl.VersionedTree, CommitID) {
tree := iavl.NewVersionedTree(db, cacheSize)
for k, v := range treeData {
tree.Set([]byte(k), []byte(v))
}
for i := 0; i < nMoreData; i++ {
key := cmn.RandBytes(12)
value := cmn.RandBytes(50)
tree.Set(key, value)
}
hash, ver, err := tree.SaveVersion()
assert.Nil(t, err)
return tree, CommitID{ver, hash}
}
func TestIAVLStoreLoader(t *testing.T) {
db := dbm.NewMemDB()
_, id := newTree(t, db)
iavlLoader := NewIAVLStoreLoader(db, cacheSize, numHistory)
commitStore, err := iavlLoader(id)
assert.Nil(t, err)
id2 := commitStore.Commit()
assert.Equal(t, id.Hash, id2.Hash)
assert.Equal(t, id.Version+1, id2.Version)
}
func TestIAVLStoreGetSetHasRemove(t *testing.T) {
db := dbm.NewMemDB()
tree, _ := newTree(t, db)
iavlStore := newIAVLStore(tree, numHistory)
key := "hello"
exists := iavlStore.Has([]byte(key))
assert.True(t, exists)
value, exists := iavlStore.Get([]byte(key))
assert.True(t, exists)
assert.EqualValues(t, value, treeData[key])
value2 := "notgoodbye"
prev := iavlStore.Set([]byte(key), []byte(value2))
assert.EqualValues(t, value, prev)
value, exists = iavlStore.Get([]byte(key))
assert.True(t, exists)
assert.EqualValues(t, value, value2)
prev, removed := iavlStore.Remove([]byte(key))
assert.True(t, removed)
assert.EqualValues(t, value2, prev)
exists = iavlStore.Has([]byte(key))
assert.False(t, exists)
}
func TestIAVLIterator(t *testing.T) {
db := dbm.NewMemDB()
tree, _ := newTree(t, db)
iavlStore := newIAVLStore(tree, numHistory)
iter := iavlStore.Iterator([]byte("aloha"), []byte("hellz"))
expected := []string{"aloha", "hello"}
for i := 0; iter.Valid(); iter.Next() {
expectedKey := expected[i]
key, value := iter.Key(), iter.Value()
assert.EqualValues(t, key, expectedKey)
assert.EqualValues(t, value, treeData[expectedKey])
i += 1
}
}