cosmos-sdk/store/listenkv/store_test.go

299 lines
6.6 KiB
Go

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)
testMarshaller.UnmarshalLengthPrefixed(buf.Bytes(), storeKVPair)
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)
testMarshaller.UnmarshalLengthPrefixed(buf.Bytes(), storeKVPair)
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) })
}