From 5f14dc2e4214151064069779233c47939aab9412 Mon Sep 17 00:00:00 2001 From: Alessio Treglia Date: Fri, 28 Feb 2020 23:05:28 +0000 Subject: [PATCH] Increase coverage across the store package (#5727) --- Makefile | 1 + store/dbadapter/store_test.go | 70 ++++++++++ store/transient/store_test.go | 15 ++- store/types/pruning_test.go | 79 +++++++++++ tests/mocks/account_retriever.go | 13 +- tests/mocks/tendermint_tm_db_DB.go | 206 +++++++++++++++++++++++++++++ 6 files changed, 380 insertions(+), 4 deletions(-) create mode 100644 store/dbadapter/store_test.go create mode 100644 store/types/pruning_test.go create mode 100644 tests/mocks/tendermint_tm_db_DB.go diff --git a/Makefile b/Makefile index 68d7a359ab..a634915bfe 100644 --- a/Makefile +++ b/Makefile @@ -26,6 +26,7 @@ build: go.sum mocks: $(MOCKS_DIR) mockgen -source=x/auth/types/account_retriever.go -package mocks -destination tests/mocks/account_retriever.go + mockgen -package mocks -destination tests/mocks/tendermint_tm_db_DB.go github.com/tendermint/tm-db DB .PHONY: mocks $(MOCKS_DIR): diff --git a/store/dbadapter/store_test.go b/store/dbadapter/store_test.go new file mode 100644 index 0000000000..a29e3f6c8d --- /dev/null +++ b/store/dbadapter/store_test.go @@ -0,0 +1,70 @@ +package dbadapter_test + +import ( + "bytes" + "errors" + "testing" + + "github.com/golang/mock/gomock" + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/store/dbadapter" + "github.com/cosmos/cosmos-sdk/store/types" + "github.com/cosmos/cosmos-sdk/tests/mocks" +) + +var errFoo = errors.New("dummy") + +func TestAccessors(t *testing.T) { + mockCtrl := gomock.NewController(t) + defer mockCtrl.Finish() + + mockDB := mocks.NewMockDB(mockCtrl) + store := dbadapter.Store{mockDB} + key := []byte("test") + value := []byte("testvalue") + + require.Equal(t, types.StoreTypeDB, store.GetStoreType()) + store.GetStoreType() + + retFoo := []byte("xxx") + mockDB.EXPECT().Get(gomock.Eq(key)).Times(1).Return(retFoo, nil) + require.True(t, bytes.Equal(retFoo, store.Get(key))) + + mockDB.EXPECT().Get(gomock.Eq(key)).Times(1).Return(nil, errFoo) + require.Panics(t, func() { store.Get(key) }) + + mockDB.EXPECT().Has(gomock.Eq(key)).Times(1).Return(true, nil) + require.True(t, store.Has(key)) + + mockDB.EXPECT().Has(gomock.Eq(key)).Times(1).Return(false, nil) + require.False(t, store.Has(key)) + + mockDB.EXPECT().Has(gomock.Eq(key)).Times(1).Return(false, errFoo) + require.Panics(t, func() { store.Has(key) }) + + mockDB.EXPECT().Set(gomock.Eq(key), gomock.Eq(value)).Times(1).Return(nil) + require.NotPanics(t, func() { store.Set(key, value) }) + + mockDB.EXPECT().Set(gomock.Eq(key), gomock.Eq(value)).Times(1).Return(errFoo) + require.Panics(t, func() { store.Set(key, value) }) + + mockDB.EXPECT().Delete(gomock.Eq(key)).Times(1).Return(nil) + require.NotPanics(t, func() { store.Delete(key) }) + + mockDB.EXPECT().Delete(gomock.Eq(key)).Times(1).Return(errFoo) + require.Panics(t, func() { store.Delete(key) }) + + start, end := []byte("start"), []byte("end") + mockDB.EXPECT().Iterator(gomock.Eq(start), gomock.Eq(end)).Times(1).Return(nil, nil) + require.NotPanics(t, func() { store.Iterator(start, end) }) + + mockDB.EXPECT().Iterator(gomock.Eq(start), gomock.Eq(end)).Times(1).Return(nil, errFoo) + require.Panics(t, func() { store.Iterator(start, end) }) + + mockDB.EXPECT().ReverseIterator(gomock.Eq(start), gomock.Eq(end)).Times(1).Return(nil, nil) + require.NotPanics(t, func() { store.ReverseIterator(start, end) }) + + mockDB.EXPECT().ReverseIterator(gomock.Eq(start), gomock.Eq(end)).Times(1).Return(nil, errFoo) + require.Panics(t, func() { store.ReverseIterator(start, end) }) +} diff --git a/store/transient/store_test.go b/store/transient/store_test.go index 846c8a3a43..113d95be86 100644 --- a/store/transient/store_test.go +++ b/store/transient/store_test.go @@ -1,15 +1,18 @@ -package transient +package transient_test import ( + "bytes" "testing" + "github.com/cosmos/cosmos-sdk/store/transient" + "github.com/cosmos/cosmos-sdk/store/types" "github.com/stretchr/testify/require" ) var k, v = []byte("hello"), []byte("world") func TestTransientStore(t *testing.T) { - tstore := NewStore() + tstore := transient.NewStore() require.Nil(t, tstore.Get(k)) @@ -20,4 +23,12 @@ func TestTransientStore(t *testing.T) { tstore.Commit() require.Nil(t, tstore.Get(k)) + + // no-op + tstore.SetPruning(types.PruningOptions{}) + + emptyCommitID := tstore.LastCommitID() + require.Equal(t, emptyCommitID.Version, int64(0)) + require.True(t, bytes.Equal(emptyCommitID.Hash, nil)) + require.Equal(t, types.StoreTypeTransient, tstore.GetStoreType()) } diff --git a/store/types/pruning_test.go b/store/types/pruning_test.go new file mode 100644 index 0000000000..4187d16a4c --- /dev/null +++ b/store/types/pruning_test.go @@ -0,0 +1,79 @@ +package types_test + +import ( + "testing" + + "github.com/stretchr/testify/require" + + "github.com/cosmos/cosmos-sdk/store/types" +) + +func TestPruningOptions_FlushVersion(t *testing.T) { + t.Parallel() + require.True(t, types.PruneEverything.FlushVersion(-1)) + require.True(t, types.PruneEverything.FlushVersion(0)) + require.True(t, types.PruneEverything.FlushVersion(1)) + require.True(t, types.PruneEverything.FlushVersion(2)) + + require.True(t, types.PruneNothing.FlushVersion(-1)) + require.True(t, types.PruneNothing.FlushVersion(0)) + require.True(t, types.PruneNothing.FlushVersion(1)) + require.True(t, types.PruneNothing.FlushVersion(2)) + + require.False(t, types.PruneSyncable.FlushVersion(-1)) + require.True(t, types.PruneSyncable.FlushVersion(0)) + require.False(t, types.PruneSyncable.FlushVersion(1)) + require.True(t, types.PruneSyncable.FlushVersion(100)) + require.False(t, types.PruneSyncable.FlushVersion(101)) +} + +func TestPruningOptions_SnapshotVersion(t *testing.T) { + t.Parallel() + require.False(t, types.PruneEverything.SnapshotVersion(-1)) + require.False(t, types.PruneEverything.SnapshotVersion(0)) + require.False(t, types.PruneEverything.SnapshotVersion(1)) + require.False(t, types.PruneEverything.SnapshotVersion(2)) + + require.True(t, types.PruneNothing.SnapshotVersion(-1)) + require.True(t, types.PruneNothing.SnapshotVersion(0)) + require.True(t, types.PruneNothing.SnapshotVersion(1)) + require.True(t, types.PruneNothing.SnapshotVersion(2)) + + require.False(t, types.PruneSyncable.SnapshotVersion(-1)) + require.True(t, types.PruneSyncable.SnapshotVersion(0)) + require.False(t, types.PruneSyncable.SnapshotVersion(1)) + require.True(t, types.PruneSyncable.SnapshotVersion(10000)) + require.False(t, types.PruneSyncable.SnapshotVersion(10001)) +} + +func TestPruningOptions_IsValid(t *testing.T) { + t.Parallel() + type fields struct { + KeepEvery int64 + SnapshotEvery int64 + } + tests := []struct { + name string + fields fields + want bool + }{ + {"PruneEverything", fields{types.PruneEverything.KeepEvery, types.PruneEverything.SnapshotEvery}, true}, + {"PruneNothing", fields{types.PruneNothing.KeepEvery, types.PruneNothing.SnapshotEvery}, true}, + {"PruneSyncable", fields{types.PruneSyncable.KeepEvery, types.PruneSyncable.SnapshotEvery}, true}, + {"KeepEvery=0", fields{0, 0}, false}, + {"KeepEvery<0", fields{-1, 0}, false}, + {"SnapshotEvery<0", fields{1, -1}, false}, + {"SnapshotEvery%KeepEvery!=0", fields{15, 30}, true}, + {"SnapshotEvery%KeepEvery!=0", fields{15, 20}, false}, + } + for _, tt := range tests { + tt := tt + t.Run(tt.name, func(t *testing.T) { + po := types.PruningOptions{ + KeepEvery: tt.fields.KeepEvery, + SnapshotEvery: tt.fields.SnapshotEvery, + } + require.Equal(t, tt.want, po.IsValid(), "IsValid() = %v, want %v", po.IsValid(), tt.want) + }) + } +} diff --git a/tests/mocks/account_retriever.go b/tests/mocks/account_retriever.go index 9f8ee69282..a3086c77bd 100644 --- a/tests/mocks/account_retriever.go +++ b/tests/mocks/account_retriever.go @@ -1,30 +1,38 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: x/auth/types/account_retriever.go + +// Package mocks is a generated GoMock package. package mocks import ( - reflect "reflect" - gomock "github.com/golang/mock/gomock" + reflect "reflect" ) +// MockNodeQuerier is a mock of NodeQuerier interface type MockNodeQuerier struct { ctrl *gomock.Controller recorder *MockNodeQuerierMockRecorder } +// MockNodeQuerierMockRecorder is the mock recorder for MockNodeQuerier type MockNodeQuerierMockRecorder struct { mock *MockNodeQuerier } +// NewMockNodeQuerier creates a new mock instance func NewMockNodeQuerier(ctrl *gomock.Controller) *MockNodeQuerier { mock := &MockNodeQuerier{ctrl: ctrl} mock.recorder = &MockNodeQuerierMockRecorder{mock} return mock } +// EXPECT returns an object that allows the caller to indicate expected use func (m *MockNodeQuerier) EXPECT() *MockNodeQuerierMockRecorder { return m.recorder } +// QueryWithData mocks base method func (m *MockNodeQuerier) QueryWithData(path string, data []byte) ([]byte, int64, error) { m.ctrl.T.Helper() ret := m.ctrl.Call(m, "QueryWithData", path, data) @@ -34,6 +42,7 @@ func (m *MockNodeQuerier) QueryWithData(path string, data []byte) ([]byte, int64 return ret0, ret1, ret2 } +// QueryWithData indicates an expected call of QueryWithData func (mr *MockNodeQuerierMockRecorder) QueryWithData(path, data interface{}) *gomock.Call { mr.mock.ctrl.T.Helper() return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "QueryWithData", reflect.TypeOf((*MockNodeQuerier)(nil).QueryWithData), path, data) diff --git a/tests/mocks/tendermint_tm_db_DB.go b/tests/mocks/tendermint_tm_db_DB.go new file mode 100644 index 0000000000..bed59a498d --- /dev/null +++ b/tests/mocks/tendermint_tm_db_DB.go @@ -0,0 +1,206 @@ +// Code generated by MockGen. DO NOT EDIT. +// Source: github.com/tendermint/tm-db (interfaces: DB) + +// Package mocks is a generated GoMock package. +package mocks + +import ( + gomock "github.com/golang/mock/gomock" + tm_db "github.com/tendermint/tm-db" + reflect "reflect" +) + +// MockDB is a mock of DB interface +type MockDB struct { + ctrl *gomock.Controller + recorder *MockDBMockRecorder +} + +// MockDBMockRecorder is the mock recorder for MockDB +type MockDBMockRecorder struct { + mock *MockDB +} + +// NewMockDB creates a new mock instance +func NewMockDB(ctrl *gomock.Controller) *MockDB { + mock := &MockDB{ctrl: ctrl} + mock.recorder = &MockDBMockRecorder{mock} + return mock +} + +// EXPECT returns an object that allows the caller to indicate expected use +func (m *MockDB) EXPECT() *MockDBMockRecorder { + return m.recorder +} + +// Close mocks base method +func (m *MockDB) Close() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Close") + ret0, _ := ret[0].(error) + return ret0 +} + +// Close indicates an expected call of Close +func (mr *MockDBMockRecorder) Close() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Close", reflect.TypeOf((*MockDB)(nil).Close)) +} + +// Delete mocks base method +func (m *MockDB) Delete(arg0 []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Delete", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// Delete indicates an expected call of Delete +func (mr *MockDBMockRecorder) Delete(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Delete", reflect.TypeOf((*MockDB)(nil).Delete), arg0) +} + +// DeleteSync mocks base method +func (m *MockDB) DeleteSync(arg0 []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "DeleteSync", arg0) + ret0, _ := ret[0].(error) + return ret0 +} + +// DeleteSync indicates an expected call of DeleteSync +func (mr *MockDBMockRecorder) DeleteSync(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "DeleteSync", reflect.TypeOf((*MockDB)(nil).DeleteSync), arg0) +} + +// Get mocks base method +func (m *MockDB) Get(arg0 []byte) ([]byte, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Get", arg0) + ret0, _ := ret[0].([]byte) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Get indicates an expected call of Get +func (mr *MockDBMockRecorder) Get(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Get", reflect.TypeOf((*MockDB)(nil).Get), arg0) +} + +// Has mocks base method +func (m *MockDB) Has(arg0 []byte) (bool, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Has", arg0) + ret0, _ := ret[0].(bool) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Has indicates an expected call of Has +func (mr *MockDBMockRecorder) Has(arg0 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Has", reflect.TypeOf((*MockDB)(nil).Has), arg0) +} + +// Iterator mocks base method +func (m *MockDB) Iterator(arg0, arg1 []byte) (tm_db.Iterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Iterator", arg0, arg1) + ret0, _ := ret[0].(tm_db.Iterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// Iterator indicates an expected call of Iterator +func (mr *MockDBMockRecorder) Iterator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Iterator", reflect.TypeOf((*MockDB)(nil).Iterator), arg0, arg1) +} + +// NewBatch mocks base method +func (m *MockDB) NewBatch() tm_db.Batch { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "NewBatch") + ret0, _ := ret[0].(tm_db.Batch) + return ret0 +} + +// NewBatch indicates an expected call of NewBatch +func (mr *MockDBMockRecorder) NewBatch() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "NewBatch", reflect.TypeOf((*MockDB)(nil).NewBatch)) +} + +// Print mocks base method +func (m *MockDB) Print() error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Print") + ret0, _ := ret[0].(error) + return ret0 +} + +// Print indicates an expected call of Print +func (mr *MockDBMockRecorder) Print() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Print", reflect.TypeOf((*MockDB)(nil).Print)) +} + +// ReverseIterator mocks base method +func (m *MockDB) ReverseIterator(arg0, arg1 []byte) (tm_db.Iterator, error) { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "ReverseIterator", arg0, arg1) + ret0, _ := ret[0].(tm_db.Iterator) + ret1, _ := ret[1].(error) + return ret0, ret1 +} + +// ReverseIterator indicates an expected call of ReverseIterator +func (mr *MockDBMockRecorder) ReverseIterator(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "ReverseIterator", reflect.TypeOf((*MockDB)(nil).ReverseIterator), arg0, arg1) +} + +// Set mocks base method +func (m *MockDB) Set(arg0, arg1 []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Set", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// Set indicates an expected call of Set +func (mr *MockDBMockRecorder) Set(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Set", reflect.TypeOf((*MockDB)(nil).Set), arg0, arg1) +} + +// SetSync mocks base method +func (m *MockDB) SetSync(arg0, arg1 []byte) error { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "SetSync", arg0, arg1) + ret0, _ := ret[0].(error) + return ret0 +} + +// SetSync indicates an expected call of SetSync +func (mr *MockDBMockRecorder) SetSync(arg0, arg1 interface{}) *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "SetSync", reflect.TypeOf((*MockDB)(nil).SetSync), arg0, arg1) +} + +// Stats mocks base method +func (m *MockDB) Stats() map[string]string { + m.ctrl.T.Helper() + ret := m.ctrl.Call(m, "Stats") + ret0, _ := ret[0].(map[string]string) + return ret0 +} + +// Stats indicates an expected call of Stats +func (mr *MockDBMockRecorder) Stats() *gomock.Call { + mr.mock.ctrl.T.Helper() + return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "Stats", reflect.TypeOf((*MockDB)(nil).Stats)) +}