2021-03-30 13:13:51 -07:00
|
|
|
package listenkv_test
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"fmt"
|
|
|
|
"io"
|
|
|
|
"testing"
|
|
|
|
|
|
|
|
"github.com/cosmos/cosmos-sdk/codec"
|
|
|
|
codecTypes "github.com/cosmos/cosmos-sdk/codec/types"
|
|
|
|
"github.com/cosmos/cosmos-sdk/store/dbadapter"
|
|
|
|
"github.com/cosmos/cosmos-sdk/store/listenkv"
|
|
|
|
"github.com/cosmos/cosmos-sdk/store/prefix"
|
|
|
|
"github.com/cosmos/cosmos-sdk/store/types"
|
|
|
|
|
|
|
|
"github.com/stretchr/testify/require"
|
|
|
|
|
|
|
|
dbm "github.com/tendermint/tm-db"
|
|
|
|
)
|
|
|
|
|
|
|
|
func bz(s string) []byte { return []byte(s) }
|
|
|
|
|
|
|
|
func keyFmt(i int) []byte { return bz(fmt.Sprintf("key%0.8d", i)) }
|
|
|
|
func valFmt(i int) []byte { return bz(fmt.Sprintf("value%0.8d", i)) }
|
|
|
|
|
|
|
|
var kvPairs = []types.KVPair{
|
|
|
|
{Key: keyFmt(1), Value: valFmt(1)},
|
|
|
|
{Key: keyFmt(2), Value: valFmt(2)},
|
|
|
|
{Key: keyFmt(3), Value: valFmt(3)},
|
|
|
|
}
|
|
|
|
|
|
|
|
var testStoreKey = types.NewKVStoreKey("listen_test")
|
|
|
|
var interfaceRegistry = codecTypes.NewInterfaceRegistry()
|
|
|
|
var testMarshaller = codec.NewProtoCodec(interfaceRegistry)
|
|
|
|
|
|
|
|
func newListenKVStore(w io.Writer) *listenkv.Store {
|
|
|
|
store := newEmptyListenKVStore(w)
|
|
|
|
|
|
|
|
for _, kvPair := range kvPairs {
|
|
|
|
store.Set(kvPair.Key, kvPair.Value)
|
|
|
|
}
|
|
|
|
|
|
|
|
return store
|
|
|
|
}
|
|
|
|
|
|
|
|
func newEmptyListenKVStore(w io.Writer) *listenkv.Store {
|
|
|
|
listener := types.NewStoreKVPairWriteListener(w, testMarshaller)
|
|
|
|
memDB := dbadapter.Store{DB: dbm.NewMemDB()}
|
|
|
|
|
|
|
|
return listenkv.NewStore(memDB, testStoreKey, []types.WriteListener{listener})
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStoreGet(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
key []byte
|
|
|
|
expectedValue []byte
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
key: kvPairs[0].Key,
|
|
|
|
expectedValue: kvPairs[0].Value,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: []byte("does-not-exist"),
|
|
|
|
expectedValue: nil,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
|
|
|
store := newListenKVStore(&buf)
|
|
|
|
buf.Reset()
|
|
|
|
value := store.Get(tc.key)
|
|
|
|
|
|
|
|
require.Equal(t, tc.expectedValue, value)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStoreSet(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
key []byte
|
|
|
|
value []byte
|
|
|
|
expectedOut *types.StoreKVPair
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
key: kvPairs[0].Key,
|
|
|
|
value: kvPairs[0].Value,
|
|
|
|
expectedOut: &types.StoreKVPair{
|
|
|
|
Key: kvPairs[0].Key,
|
|
|
|
Value: kvPairs[0].Value,
|
|
|
|
StoreKey: testStoreKey.Name(),
|
|
|
|
Delete: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: kvPairs[1].Key,
|
|
|
|
value: kvPairs[1].Value,
|
|
|
|
expectedOut: &types.StoreKVPair{
|
|
|
|
Key: kvPairs[1].Key,
|
|
|
|
Value: kvPairs[1].Value,
|
|
|
|
StoreKey: testStoreKey.Name(),
|
|
|
|
Delete: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
{
|
|
|
|
key: kvPairs[2].Key,
|
|
|
|
value: kvPairs[2].Value,
|
|
|
|
expectedOut: &types.StoreKVPair{
|
|
|
|
Key: kvPairs[2].Key,
|
|
|
|
Value: kvPairs[2].Value,
|
|
|
|
StoreKey: testStoreKey.Name(),
|
|
|
|
Delete: false,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
|
|
|
store := newEmptyListenKVStore(&buf)
|
|
|
|
buf.Reset()
|
|
|
|
store.Set(tc.key, tc.value)
|
|
|
|
storeKVPair := new(types.StoreKVPair)
|
2021-04-29 03:46:22 -07:00
|
|
|
testMarshaller.UnmarshalLengthPrefixed(buf.Bytes(), storeKVPair)
|
2021-03-30 13:13:51 -07:00
|
|
|
|
|
|
|
require.Equal(t, tc.expectedOut, storeKVPair)
|
|
|
|
}
|
|
|
|
|
|
|
|
var buf bytes.Buffer
|
|
|
|
store := newEmptyListenKVStore(&buf)
|
|
|
|
require.Panics(t, func() { store.Set([]byte(""), []byte("value")) }, "setting an empty key should panic")
|
|
|
|
require.Panics(t, func() { store.Set(nil, []byte("value")) }, "setting a nil key should panic")
|
|
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStoreDelete(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
key []byte
|
|
|
|
expectedOut *types.StoreKVPair
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
key: kvPairs[0].Key,
|
|
|
|
expectedOut: &types.StoreKVPair{
|
|
|
|
Key: kvPairs[0].Key,
|
|
|
|
Value: nil,
|
|
|
|
StoreKey: testStoreKey.Name(),
|
|
|
|
Delete: true,
|
|
|
|
},
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
|
|
|
store := newListenKVStore(&buf)
|
|
|
|
buf.Reset()
|
|
|
|
store.Delete(tc.key)
|
|
|
|
storeKVPair := new(types.StoreKVPair)
|
2021-04-29 03:46:22 -07:00
|
|
|
testMarshaller.UnmarshalLengthPrefixed(buf.Bytes(), storeKVPair)
|
2021-03-30 13:13:51 -07:00
|
|
|
|
|
|
|
require.Equal(t, tc.expectedOut, storeKVPair)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStoreHas(t *testing.T) {
|
|
|
|
testCases := []struct {
|
|
|
|
key []byte
|
|
|
|
expected bool
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
key: kvPairs[0].Key,
|
|
|
|
expected: true,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
|
|
|
store := newListenKVStore(&buf)
|
|
|
|
buf.Reset()
|
|
|
|
ok := store.Has(tc.key)
|
|
|
|
|
|
|
|
require.Equal(t, tc.expected, ok)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTestListenKVStoreIterator(t *testing.T) {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
|
|
|
store := newListenKVStore(&buf)
|
|
|
|
iterator := store.Iterator(nil, nil)
|
|
|
|
|
|
|
|
s, e := iterator.Domain()
|
|
|
|
require.Equal(t, []byte(nil), s)
|
|
|
|
require.Equal(t, []byte(nil), e)
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
expectedKey []byte
|
|
|
|
expectedValue []byte
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
expectedKey: kvPairs[0].Key,
|
|
|
|
expectedValue: kvPairs[0].Value,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
expectedKey: kvPairs[1].Key,
|
|
|
|
expectedValue: kvPairs[1].Value,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
expectedKey: kvPairs[2].Key,
|
|
|
|
expectedValue: kvPairs[2].Value,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
ka := iterator.Key()
|
|
|
|
require.Equal(t, tc.expectedKey, ka)
|
|
|
|
|
|
|
|
va := iterator.Value()
|
|
|
|
require.Equal(t, tc.expectedValue, va)
|
|
|
|
|
|
|
|
iterator.Next()
|
|
|
|
}
|
|
|
|
|
|
|
|
require.False(t, iterator.Valid())
|
|
|
|
require.Panics(t, iterator.Next)
|
|
|
|
require.NoError(t, iterator.Close())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestTestListenKVStoreReverseIterator(t *testing.T) {
|
|
|
|
var buf bytes.Buffer
|
|
|
|
|
|
|
|
store := newListenKVStore(&buf)
|
|
|
|
iterator := store.ReverseIterator(nil, nil)
|
|
|
|
|
|
|
|
s, e := iterator.Domain()
|
|
|
|
require.Equal(t, []byte(nil), s)
|
|
|
|
require.Equal(t, []byte(nil), e)
|
|
|
|
|
|
|
|
testCases := []struct {
|
|
|
|
expectedKey []byte
|
|
|
|
expectedValue []byte
|
|
|
|
}{
|
|
|
|
{
|
|
|
|
expectedKey: kvPairs[2].Key,
|
|
|
|
expectedValue: kvPairs[2].Value,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
expectedKey: kvPairs[1].Key,
|
|
|
|
expectedValue: kvPairs[1].Value,
|
|
|
|
},
|
|
|
|
{
|
|
|
|
expectedKey: kvPairs[0].Key,
|
|
|
|
expectedValue: kvPairs[0].Value,
|
|
|
|
},
|
|
|
|
}
|
|
|
|
|
|
|
|
for _, tc := range testCases {
|
|
|
|
ka := iterator.Key()
|
|
|
|
require.Equal(t, tc.expectedKey, ka)
|
|
|
|
|
|
|
|
va := iterator.Value()
|
|
|
|
require.Equal(t, tc.expectedValue, va)
|
|
|
|
|
|
|
|
iterator.Next()
|
|
|
|
}
|
|
|
|
|
|
|
|
require.False(t, iterator.Valid())
|
|
|
|
require.Panics(t, iterator.Next)
|
|
|
|
require.NoError(t, iterator.Close())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStorePrefix(t *testing.T) {
|
|
|
|
store := newEmptyListenKVStore(nil)
|
|
|
|
pStore := prefix.NewStore(store, []byte("listen_prefix"))
|
|
|
|
require.IsType(t, prefix.Store{}, pStore)
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStoreGetStoreType(t *testing.T) {
|
|
|
|
memDB := dbadapter.Store{DB: dbm.NewMemDB()}
|
|
|
|
store := newEmptyListenKVStore(nil)
|
|
|
|
require.Equal(t, memDB.GetStoreType(), store.GetStoreType())
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStoreCacheWrap(t *testing.T) {
|
|
|
|
store := newEmptyListenKVStore(nil)
|
|
|
|
require.Panics(t, func() { store.CacheWrap() })
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStoreCacheWrapWithTrace(t *testing.T) {
|
|
|
|
store := newEmptyListenKVStore(nil)
|
|
|
|
require.Panics(t, func() { store.CacheWrapWithTrace(nil, nil) })
|
|
|
|
}
|
|
|
|
|
|
|
|
func TestListenKVStoreCacheWrapWithListeners(t *testing.T) {
|
|
|
|
store := newEmptyListenKVStore(nil)
|
|
|
|
require.Panics(t, func() { store.CacheWrapWithListeners(nil, nil) })
|
|
|
|
}
|