diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 0f54b02bea..8953c76fb6 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -62,6 +62,14 @@ Changes that only affect a single file can be tested with $ go test ``` +Sometimes you may need to create mocks for interfaces, in that case you will just execute: + +``` +$ make mock +``` + +The above command will generate mocks for all the interfaces inside the project! This command does not affect unchanged interfaces. + **8. Lint your changes.** Before opening a pull request be sure to run the linter diff --git a/Makefile b/Makefile index 59ae821174..c87b039a16 100644 --- a/Makefile +++ b/Makefile @@ -126,3 +126,16 @@ gossamer: clean ## install: install the gossamer binary in $GOPATH/bin install: GOBIN=$(GOPATH)/bin go run scripts/ci.go install + +MOCKGEN := $(shell command -v $(GOPATH)/bin/mockery 2> /dev/null) +mock: +ifndef MOCKGEN + @echo "> Installing mockery ..." + @go get github.com/vektra/mockery/v2/.../ +endif + @echo "> Generating mocks at ./tests/mocks ..." + $(GOPATH)/bin/mockery --all --recursive --inpackage --case underscore + + + + diff --git a/dot/core/digest.go b/dot/core/digest.go index f46fe41768..3034706499 100644 --- a/dot/core/digest.go +++ b/dot/core/digest.go @@ -404,20 +404,19 @@ func newGrandpaChange(raw []*types.GrandpaAuthoritiesRaw, delay uint32, currBloc } func (h *DigestHandler) handleBABEOnDisabled(d *types.ConsensusDigest, header *types.Header) error { - od := &types.BABEOnDisabled{} - dec, err := scale.Decode(d.Data[1:], od) + od := new(types.BABEOnDisabled) + _, err := scale.Decode(d.Data[1:], od) if err != nil { return err } - od = dec.(*types.BABEOnDisabled) logger.Debug("handling BABEOnDisabled", "data", od) err = h.verifier.SetOnDisabled(od.ID, header) + if err != nil { return err } - h.babe.SetOnDisabled(od.ID) return nil } diff --git a/dot/core/digest_test.go b/dot/core/digest_test.go index 51f78e11ff..b076e32db9 100644 --- a/dot/core/digest_test.go +++ b/dot/core/digest_test.go @@ -28,7 +28,10 @@ import ( "github.com/ChainSafe/gossamer/lib/crypto/sr25519" "github.com/ChainSafe/gossamer/lib/keystore" + . "github.com/ChainSafe/gossamer/dot/core/mocks" + log "github.com/ChainSafe/log15" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -45,13 +48,17 @@ func newTestDigestHandler(t *testing.T, withBABE, withGrandpa bool) *DigestHandl err = stateSrvc.Start() require.NoError(t, err) - var bp BlockProducer + var bp *MockBlockProducer if withBABE { - bp = &mockBlockProducer{} + bp = new(MockBlockProducer) + blockC := make(chan types.Block) + bp.On("GetBlockChannel", nil).Return(blockC) } - time.Sleep(time.Second) - dh, err := NewDigestHandler(stateSrvc.Block, stateSrvc.Epoch, stateSrvc.Grandpa, bp, &mockVerifier{}) + verifier := new(MockVerifier) + verifier.On("SetOnDisabled", mock.Anything, mock.Anything).Return(nil) + + dh, err := NewDigestHandler(stateSrvc.Block, stateSrvc.Epoch, stateSrvc.Grandpa, nil, nil) require.NoError(t, err) return dh } @@ -314,8 +321,19 @@ func TestNextGrandpaAuthorityChange_MultipleChanges(t *testing.T) { func TestDigestHandler_HandleBABEOnDisabled(t *testing.T) { handler := newTestDigestHandler(t, true, false) - handler.Start() - defer handler.Stop() + + babemock := new(MockBlockProducer) + babemock.On("SetOnDisabled", uint32(7)) + + header := &types.Header{ + Number: big.NewInt(1), + } + + verifier := new(MockVerifier) + verifier.On("SetOnDisabled", uint32(7), header).Return(nil) + + handler.babe = babemock + handler.verifier = verifier digest := &types.BABEOnDisabled{ ID: 7, @@ -329,9 +347,11 @@ func TestDigestHandler_HandleBABEOnDisabled(t *testing.T) { Data: data, } - err = handler.HandleConsensusDigest(d, nil) + err = handler.HandleConsensusDigest(d, header) + require.NoError(t, err) - require.Equal(t, uint32(7), handler.babe.(*mockBlockProducer).disabled) + + babemock.AssertCalled(t, "SetOnDisabled", uint32(7)) } func createHeaderWithPreDigest(slotNumber uint64) *types.Header { diff --git a/dot/core/messages_test.go b/dot/core/messages_test.go index e005c8d831..cbeaceb990 100644 --- a/dot/core/messages_test.go +++ b/dot/core/messages_test.go @@ -21,6 +21,7 @@ import ( "testing" "time" + . "github.com/ChainSafe/gossamer/dot/core/mocks" "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" @@ -36,7 +37,8 @@ import ( func TestService_ProcessBlockAnnounceMessage(t *testing.T) { // TODO: move to sync package - net := new(mockNetwork) + net := new(MockNetwork) + newBlocks := make(chan types.Block) cfg := &Config{ @@ -50,17 +52,8 @@ func TestService_ProcessBlockAnnounceMessage(t *testing.T) { err := s.Start() require.Nil(t, err) - expected := &network.BlockAnnounceMessage{ - Number: big.NewInt(1), - ParentHash: s.blockState.BestBlockHash(), - StateRoot: common.Hash{}, - ExtrinsicsRoot: common.Hash{}, - Digest: nil, - BestBlock: true, - } - // simulate block sent from BABE session - newBlocks <- types.Block{ + newBlock := types.Block{ Header: &types.Header{ Number: big.NewInt(1), ParentHash: s.blockState.BestBlockHash(), @@ -68,10 +61,22 @@ func TestService_ProcessBlockAnnounceMessage(t *testing.T) { Body: types.NewBody([]byte{}), } - time.Sleep(testMessageTimeout) - require.NotNil(t, net.Message) - require.Equal(t, network.BlockAnnounceMsgType, net.Message.(network.NotificationsMessage).Type()) - require.Equal(t, expected, net.Message) + expected := &network.BlockAnnounceMessage{ + ParentHash: newBlock.Header.ParentHash, + Number: newBlock.Header.Number, + StateRoot: newBlock.Header.StateRoot, + ExtrinsicsRoot: newBlock.Header.ExtrinsicsRoot, + Digest: newBlock.Header.Digest, + BestBlock: true, + } + + //setup the SendMessage function + net.On("SendMessage", expected) + newBlocks <- newBlock + + time.Sleep(time.Second * 2) + + net.AssertCalled(t, "SendMessage", expected) } func createExtrinsics(t *testing.T, rt runtime.Instance, genHash common.Hash, nonce uint64) types.Extrinsic { @@ -129,11 +134,15 @@ func TestService_HandleTransactionMessage(t *testing.T) { ks := keystore.NewGlobalKeystore() ks.Acco.Insert(kp) + bp := new(MockBlockProducer) + blockC := make(chan types.Block) + bp.On("GetBlockChannel", nil).Return(blockC) + cfg := &Config{ Keystore: ks, TransactionState: state.NewTransactionState(), IsBlockProducer: true, - BlockProducer: &mockBlockProducer{}, + BlockProducer: bp, } s := NewTestService(t, cfg) diff --git a/dot/core/mocks/block_producer.go b/dot/core/mocks/block_producer.go new file mode 100644 index 0000000000..341cc96b25 --- /dev/null +++ b/dot/core/mocks/block_producer.go @@ -0,0 +1,34 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package core + +import ( + types "github.com/ChainSafe/gossamer/dot/types" + mock "github.com/stretchr/testify/mock" +) + +// MockBlockProducer is an autogenerated mock type for the BlockProducer type +type MockBlockProducer struct { + mock.Mock +} + +// GetBlockChannel provides a mock function with given fields: +func (_m *MockBlockProducer) GetBlockChannel() <-chan types.Block { + ret := _m.Called() + + var r0 <-chan types.Block + if rf, ok := ret.Get(0).(func() <-chan types.Block); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(<-chan types.Block) + } + } + + return r0 +} + +// SetOnDisabled provides a mock function with given fields: authorityIndex +func (_m *MockBlockProducer) SetOnDisabled(authorityIndex uint32) { + _m.Called(authorityIndex) +} diff --git a/dot/core/mocks/network.go b/dot/core/mocks/network.go new file mode 100644 index 0000000000..d322695f34 --- /dev/null +++ b/dot/core/mocks/network.go @@ -0,0 +1,18 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package core + +import ( + network "github.com/ChainSafe/gossamer/dot/network" + mock "github.com/stretchr/testify/mock" +) + +// MockNetwork is an autogenerated mock type for the Network type +type MockNetwork struct { + mock.Mock +} + +// SendMessage provides a mock function with given fields: _a0 +func (_m *MockNetwork) SendMessage(_a0 network.NotificationsMessage) { + _m.Called(_a0) +} diff --git a/dot/core/mocks/verifier.go b/dot/core/mocks/verifier.go new file mode 100644 index 0000000000..4075b959ef --- /dev/null +++ b/dot/core/mocks/verifier.go @@ -0,0 +1,27 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package core + +import ( + types "github.com/ChainSafe/gossamer/dot/types" + mock "github.com/stretchr/testify/mock" +) + +// MockVerifier is an autogenerated mock type for the Verifier type +type MockVerifier struct { + mock.Mock +} + +// SetOnDisabled provides a mock function with given fields: authorityIndex, block +func (_m *MockVerifier) SetOnDisabled(authorityIndex uint32, block *types.Header) error { + ret := _m.Called(authorityIndex, block) + + var r0 error + if rf, ok := ret.Get(0).(func(uint32, *types.Header) error); ok { + r0 = rf(authorityIndex, block) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/dot/core/service_test.go b/dot/core/service_test.go index 77fc2b13ec..1419509ede 100644 --- a/dot/core/service_test.go +++ b/dot/core/service_test.go @@ -36,6 +36,8 @@ import ( "github.com/ChainSafe/gossamer/lib/utils" log "github.com/ChainSafe/log15" "github.com/stretchr/testify/require" + + coremocks "github.com/ChainSafe/gossamer/dot/core/mocks" ) func addTestBlocksToState(t *testing.T, depth int, blockState BlockState) []*types.Header { @@ -97,7 +99,7 @@ func TestStartService(t *testing.T) { } func TestAnnounceBlock(t *testing.T) { - net := new(mockNetwork) + net := new(coremocks.MockNetwork) newBlocks := make(chan types.Block) cfg := &Config{ @@ -111,7 +113,7 @@ func TestAnnounceBlock(t *testing.T) { defer s.Stop() // simulate block sent from BABE session - newBlocks <- types.Block{ + newBlock := types.Block{ Header: &types.Header{ ParentHash: s.blockState.BestBlockHash(), Number: big.NewInt(1), @@ -119,9 +121,21 @@ func TestAnnounceBlock(t *testing.T) { Body: &types.Body{}, } - time.Sleep(testMessageTimeout) - require.NotNil(t, net.Message) - require.Equal(t, network.BlockAnnounceMsgType, net.Message.(network.NotificationsMessage).Type()) + expected := &network.BlockAnnounceMessage{ + ParentHash: newBlock.Header.ParentHash, + Number: newBlock.Header.Number, + StateRoot: newBlock.Header.StateRoot, + ExtrinsicsRoot: newBlock.Header.ExtrinsicsRoot, + Digest: newBlock.Header.Digest, + BestBlock: true, + } + + net.On("SendMessage", expected) + + newBlocks <- newBlock + time.Sleep(time.Second * 2) + + net.AssertCalled(t, "SendMessage", expected) } func TestService_HasKey(t *testing.T) { diff --git a/dot/core/test_helpers.go b/dot/core/test_helpers.go index 17275fbe17..67221798de 100644 --- a/dot/core/test_helpers.go +++ b/dot/core/test_helpers.go @@ -20,7 +20,6 @@ import ( "io/ioutil" "math/big" "testing" - "time" "github.com/ChainSafe/gossamer/dot/network" "github.com/ChainSafe/gossamer/dot/state" @@ -29,16 +28,16 @@ import ( "github.com/ChainSafe/gossamer/lib/crypto/sr25519" "github.com/ChainSafe/gossamer/lib/genesis" "github.com/ChainSafe/gossamer/lib/keystore" - "github.com/ChainSafe/gossamer/lib/runtime" rtstorage "github.com/ChainSafe/gossamer/lib/runtime/storage" "github.com/ChainSafe/gossamer/lib/runtime/wasmer" "github.com/ChainSafe/gossamer/lib/trie" log "github.com/ChainSafe/log15" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" -) -// testMessageTimeout is the wait time for messages to be exchanged -var testMessageTimeout = time.Second + // importing packagemocks + coremocks "github.com/ChainSafe/gossamer/dot/core/mocks" +) func newTestGenesisWithTrieAndHeader(t *testing.T) (*genesis.Genesis, *trie.Trie, *types.Header) { gen, err := genesis.NewGenesisFromJSONRaw("../../chain/gssmr/genesis.json") @@ -55,47 +54,6 @@ func newTestGenesisWithTrieAndHeader(t *testing.T) (*genesis.Genesis, *trie.Trie return gen, genTrie, genesisHeader } -type mockVerifier struct{} - -func (v *mockVerifier) SetOnDisabled(_ uint32, _ *types.Header) error { - return nil -} - -// mockBlockProducer implements the BlockProducer interface -type mockBlockProducer struct { - disabled uint32 -} - -// Start mocks starting -func (bp *mockBlockProducer) Start() error { - return nil -} - -// Stop mocks stopping -func (bp *mockBlockProducer) Stop() error { - return nil -} - -func (bp *mockBlockProducer) SetOnDisabled(idx uint32) { - bp.disabled = idx -} - -// GetBlockChannel returns a new channel -func (bp *mockBlockProducer) GetBlockChannel() <-chan types.Block { - return make(chan types.Block) -} - -// SetRuntime mocks setting runtime -func (bp *mockBlockProducer) SetRuntime(rt runtime.Instance) {} - -type mockNetwork struct { - Message network.Message -} - -func (n *mockNetwork) SendMessage(m network.NotificationsMessage) { - n.Message = m -} - // NewTestService creates a new test core service func NewTestService(t *testing.T, cfg *Config) *Service { if cfg == nil { @@ -118,7 +76,9 @@ func NewTestService(t *testing.T, cfg *Config) *Service { } if cfg.Verifier == nil { - cfg.Verifier = new(mockVerifier) + verifier := new(coremocks.MockVerifier) + verifier.On("SetOnDisabled", mock.AnythingOfType("uint32"), mock.AnythingOfType("*types.Header")).Return(nil) + cfg.Verifier = nil } cfg.LogLvl = 3 @@ -171,7 +131,7 @@ func NewTestService(t *testing.T, cfg *Config) *Service { NoBootstrap: true, NoMDNS: true, BlockState: stateSrvc.Block, - TransactionHandler: &mockTransactionHandler{}, + TransactionHandler: network.NewMockTransactionHandler(), } cfg.Network = createTestNetworkService(t, config) } @@ -194,7 +154,7 @@ func createTestNetworkService(t *testing.T, cfg *network.Config) (srvc *network. } if cfg.Syncer == nil { - cfg.Syncer = newMockSyncer() + cfg.Syncer = network.NewMockSyncer() } srvc, err := network.NewService(cfg) @@ -209,41 +169,3 @@ func createTestNetworkService(t *testing.T, cfg *network.Config) (srvc *network. }) return srvc } - -type mockSyncer struct { - highestSeen *big.Int -} - -func newMockSyncer() *mockSyncer { - return &mockSyncer{ - highestSeen: big.NewInt(0), - } -} - -func (s *mockSyncer) CreateBlockResponse(msg *network.BlockRequestMessage) (*network.BlockResponseMessage, error) { - return nil, nil -} - -func (s *mockSyncer) HandleBlockAnnounce(msg *network.BlockAnnounceMessage) error { - return nil -} - -func (s *mockSyncer) ProcessBlockData(_ []*types.BlockData) (int, error) { - return 0, nil -} - -func (s *mockSyncer) ProcessJustification(data []*types.BlockData) (int, error) { - return 0, nil -} - -func (s *mockSyncer) IsSynced() bool { - return false -} - -func (s *mockSyncer) SetSyncing(bool) {} - -type mockTransactionHandler struct{} - -func (h *mockTransactionHandler) HandleTransactionMessage(_ *network.TransactionMessage) error { - return nil -} diff --git a/dot/network/discovery_test.go b/dot/network/discovery_test.go index c3b9adf01f..a72cf4290f 100644 --- a/dot/network/discovery_test.go +++ b/dot/network/discovery_test.go @@ -23,9 +23,9 @@ import ( "time" "github.com/ChainSafe/gossamer/lib/utils" + badger "github.com/ipfs/go-ds-badger2" "github.com/libp2p/go-libp2p-core/peer" - "github.com/libp2p/go-libp2p-kad-dht/dual" - kbucket "github.com/libp2p/go-libp2p-kbucket" + "github.com/libp2p/go-libp2p-core/routing" "github.com/stretchr/testify/require" ) @@ -42,10 +42,18 @@ func newTestDiscovery(t *testing.T, num int) []*discovery { } srvc := createTestService(t, config) + + opts := badger.DefaultOptions + opts.InMemory = true + + ds, err := badger.NewDatastore("", &opts) + require.NoError(t, err) disc := &discovery{ ctx: srvc.ctx, h: srvc.host.h, + ds: ds, } + go disc.start() discs = append(discs, disc) } @@ -74,42 +82,33 @@ func connectNoSync(t *testing.T, ctx context.Context, a, b *discovery) { require.NoError(t, err) } -// nolint -func wait(t *testing.T, ctx context.Context, a, b *dual.DHT) { - t.Helper() - - // Loop until connection notification has been received. - // Under high load, this may not happen as immediately as we would like. - for a.LAN.RoutingTable().Find(b.LAN.PeerID()) == "" { - select { - case <-ctx.Done(): - t.Fatal(ctx.Err()) - case <-time.After(time.Millisecond * 5): - } - } -} - // Set `NoMDNS` to true and test routing via kademlia DHT service. func TestKadDHT(t *testing.T) { if testing.Short() { return } + // setup 3 nodes nodes := newTestDiscovery(t, 3) ctx, cancel := context.WithTimeout(context.Background(), time.Minute) defer cancel() + // connects node 0 and node 2 + connectNoSync(t, ctx, nodes[2], nodes[0]) + + time.Sleep(startDHTTimeout + 1) + + // node 2 doesnt know about node 1 then should return error _, err := nodes[2].dht.FindPeer(ctx, nodes[1].h.ID()) - require.Equal(t, err, kbucket.ErrLookupFailure) + require.ErrorIs(t, err, routing.ErrNotFound) + // connects node 1 and node 0 connectNoSync(t, ctx, nodes[1], nodes[0]) - connectNoSync(t, ctx, nodes[2], nodes[0]) - // Can't use `connect` because b and c are only clients. - wait(t, ctx, nodes[1].dht, nodes[0].dht) - wait(t, ctx, nodes[2].dht, nodes[0].dht) + time.Sleep(startDHTTimeout + 1) + // node 2 should know node 1 because both are connected to 0 _, err = nodes[2].dht.FindPeer(ctx, nodes[1].h.ID()) require.NoError(t, err) } diff --git a/dot/network/mock_block_state.go b/dot/network/mock_block_state.go new file mode 100644 index 0000000000..57b3f4d155 --- /dev/null +++ b/dot/network/mock_block_state.go @@ -0,0 +1,146 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package network + +import ( + big "math/big" + + common "github.com/ChainSafe/gossamer/lib/common" + mock "github.com/stretchr/testify/mock" + + types "github.com/ChainSafe/gossamer/dot/types" +) + +// MockBlockState is an autogenerated mock type for the BlockState type +type MockBlockState struct { + mock.Mock +} + +// BestBlockHeader provides a mock function with given fields: +func (_m *MockBlockState) BestBlockHeader() (*types.Header, error) { + ret := _m.Called() + + var r0 *types.Header + if rf, ok := ret.Get(0).(func() *types.Header); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Header) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// BestBlockNumber provides a mock function with given fields: +func (_m *MockBlockState) BestBlockNumber() (*big.Int, error) { + ret := _m.Called() + + var r0 *big.Int + if rf, ok := ret.Get(0).(func() *big.Int); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*big.Int) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GenesisHash provides a mock function with given fields: +func (_m *MockBlockState) GenesisHash() common.Hash { + ret := _m.Called() + + var r0 common.Hash + if rf, ok := ret.Get(0).(func() common.Hash); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Hash) + } + } + + return r0 +} + +// GetFinalizedHeader provides a mock function with given fields: round, setID +func (_m *MockBlockState) GetFinalizedHeader(round uint64, setID uint64) (*types.Header, error) { + ret := _m.Called(round, setID) + + var r0 *types.Header + if rf, ok := ret.Get(0).(func(uint64, uint64) *types.Header); ok { + r0 = rf(round, setID) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Header) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(uint64, uint64) error); ok { + r1 = rf(round, setID) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetHashByNumber provides a mock function with given fields: num +func (_m *MockBlockState) GetHashByNumber(num *big.Int) (common.Hash, error) { + ret := _m.Called(num) + + var r0 common.Hash + if rf, ok := ret.Get(0).(func(*big.Int) common.Hash); ok { + r0 = rf(num) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Hash) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*big.Int) error); ok { + r1 = rf(num) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HasBlockBody provides a mock function with given fields: _a0 +func (_m *MockBlockState) HasBlockBody(_a0 common.Hash) (bool, error) { + ret := _m.Called(_a0) + + var r0 bool + if rf, ok := ret.Get(0).(func(common.Hash) bool); ok { + r0 = rf(_a0) + } else { + r0 = ret.Get(0).(bool) + } + + var r1 error + if rf, ok := ret.Get(1).(func(common.Hash) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} diff --git a/dot/network/mock_syncer.go b/dot/network/mock_syncer.go new file mode 100644 index 0000000000..efa21957b4 --- /dev/null +++ b/dot/network/mock_syncer.go @@ -0,0 +1,111 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package network + +import ( + types "github.com/ChainSafe/gossamer/dot/types" + mock "github.com/stretchr/testify/mock" +) + +// MockSyncer is an autogenerated mock type for the Syncer type +type MockSyncer struct { + mock.Mock +} + +// CreateBlockResponse provides a mock function with given fields: _a0 +func (_m *MockSyncer) CreateBlockResponse(_a0 *BlockRequestMessage) (*BlockResponseMessage, error) { + ret := _m.Called(_a0) + + var r0 *BlockResponseMessage + if rf, ok := ret.Get(0).(func(*BlockRequestMessage) *BlockResponseMessage); ok { + r0 = rf(_a0) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*BlockResponseMessage) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*BlockRequestMessage) error); ok { + r1 = rf(_a0) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HandleBlockAnnounce provides a mock function with given fields: _a0 +func (_m *MockSyncer) HandleBlockAnnounce(_a0 *BlockAnnounceMessage) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(*BlockAnnounceMessage) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// IsSynced provides a mock function with given fields: +func (_m *MockSyncer) IsSynced() bool { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} + +// ProcessBlockData provides a mock function with given fields: data +func (_m *MockSyncer) ProcessBlockData(data []*types.BlockData) (int, error) { + ret := _m.Called(data) + + var r0 int + if rf, ok := ret.Get(0).(func([]*types.BlockData) int); ok { + r0 = rf(data) + } else { + r0 = ret.Get(0).(int) + } + + var r1 error + if rf, ok := ret.Get(1).(func([]*types.BlockData) error); ok { + r1 = rf(data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// ProcessJustification provides a mock function with given fields: data +func (_m *MockSyncer) ProcessJustification(data []*types.BlockData) (int, error) { + ret := _m.Called(data) + + var r0 int + if rf, ok := ret.Get(0).(func([]*types.BlockData) int); ok { + r0 = rf(data) + } else { + r0 = ret.Get(0).(int) + } + + var r1 error + if rf, ok := ret.Get(1).(func([]*types.BlockData) error); ok { + r1 = rf(data) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SetSyncing provides a mock function with given fields: _a0 +func (_m *MockSyncer) SetSyncing(_a0 bool) { + _m.Called(_a0) +} diff --git a/dot/network/mock_transaction_handler.go b/dot/network/mock_transaction_handler.go new file mode 100644 index 0000000000..45ad335bdc --- /dev/null +++ b/dot/network/mock_transaction_handler.go @@ -0,0 +1,24 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package network + +import mock "github.com/stretchr/testify/mock" + +// MockTransactionHandler is an autogenerated mock type for the TransactionHandler type +type MockTransactionHandler struct { + mock.Mock +} + +// HandleTransactionMessage provides a mock function with given fields: _a0 +func (_m *MockTransactionHandler) HandleTransactionMessage(_a0 *TransactionMessage) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(*TransactionMessage) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/dot/network/service_test.go b/dot/network/service_test.go index 89ac77cf54..db20565b1d 100644 --- a/dot/network/service_test.go +++ b/dot/network/service_test.go @@ -25,6 +25,7 @@ import ( "time" "github.com/ChainSafe/gossamer/lib/utils" + mock "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -77,15 +78,13 @@ func createTestService(t *testing.T, cfg *Config) (srvc *Service) { } if cfg.BlockState == nil { - cfg.BlockState = newMockBlockState(nil) + cfg.BlockState = NewMockBlockState(nil) } if cfg.TransactionHandler == nil { - cfg.TransactionHandler = newMockTransactionHandler() - } - - if cfg.TransactionHandler == nil { - cfg.TransactionHandler = newMockTransactionHandler() + mocktxhandler := &MockTransactionHandler{} + mocktxhandler.On("HandleTransactionMessage", mock.AnythingOfType("*TransactionMessage")).Return(nil) + cfg.TransactionHandler = mocktxhandler } cfg.ProtocolID = TestProtocolID // default "/gossamer/gssmr/0" @@ -95,7 +94,7 @@ func createTestService(t *testing.T, cfg *Config) (srvc *Service) { } if cfg.Syncer == nil { - cfg.Syncer = newMockSyncer() + cfg.Syncer = NewMockSyncer() } cfg.noPreAllocate = true @@ -269,13 +268,19 @@ func TestService_Health(t *testing.T) { NoBootstrap: true, NoMDNS: true, } + mocksyncer := &MockSyncer{} + mocksyncer.On("SetSyncing", mock.AnythingOfType("bool")) + s := createTestService(t, config) + s.syncer = mocksyncer - require.Equal(t, s.Health().IsSyncing, true) - mockSync := s.syncer.(*mockSyncer) + mocksyncer.On("IsSynced").Return(false).Once() + h := s.Health() + require.Equal(t, true, h.IsSyncing) - mockSync.SetSyncing(false) - require.Equal(t, s.Health().IsSyncing, false) + mocksyncer.On("IsSynced").Return(true).Once() + h = s.Health() + require.Equal(t, false, h.IsSyncing) } func TestPersistPeerStore(t *testing.T) { diff --git a/dot/network/state_test.go b/dot/network/state_test.go deleted file mode 100644 index a268b9914e..0000000000 --- a/dot/network/state_test.go +++ /dev/null @@ -1,81 +0,0 @@ -// Copyright 2019 ChainSafe Systems (ON) Corp. -// This file is part of gossamer. -// -// The gossamer library is free software: you can redistribute it and/or modify -// it under the terms of the GNU Lesser General Public License as published by -// the Free Software Foundation, either version 3 of the License, or -// (at your option) any later version. -// -// The gossamer library is distributed in the hope that it will be useful, -// but WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -// GNU Lesser General Public License for more details. -// -// You should have received a copy of the GNU Lesser General Public License -// along with the gossamer library. If not, see . - -package network - -import ( - "math/big" - - "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/lib/common" -) - -// MockBlockState ... -type MockBlockState struct { - number *big.Int -} - -func newMockBlockState(number *big.Int) *MockBlockState { - return &MockBlockState{number: number} -} - -// BestBlockHeader for MockBlockState -func (mbs *MockBlockState) BestBlockHeader() (*types.Header, error) { - parentHash, err := common.HexToHash("0x4545454545454545454545454545454545454545454545454545454545454545") - if err != nil { - return nil, err - } - stateRoot, err := common.HexToHash("0xb3266de137d20a5d0ff3a6401eb57127525fd9b2693701f0bf5a8a853fa3ebe0") - if err != nil { - return nil, err - } - extrinsicsRoot, err := common.HexToHash("0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314") - if err != nil { - return nil, err - } - - if mbs.number == nil { - mbs.number = big.NewInt(1) - } - - return &types.Header{ - ParentHash: parentHash, - Number: mbs.number, - StateRoot: stateRoot, - ExtrinsicsRoot: extrinsicsRoot, - Digest: types.Digest{}, - }, nil -} - -func (mbs *MockBlockState) GenesisHash() common.Hash { - return common.NewHash([]byte{}) -} - -func (mbs *MockBlockState) BestBlockNumber() (*big.Int, error) { - return big.NewInt(1), nil -} - -func (mbs *MockBlockState) HasBlockBody(common.Hash) (bool, error) { - return false, nil -} - -func (mbs *MockBlockState) GetFinalizedHeader(_, _ uint64) (*types.Header, error) { - return mbs.BestBlockHeader() -} - -func (mbs *MockBlockState) GetHashByNumber(_ *big.Int) (common.Hash, error) { - return common.Hash{}, nil -} diff --git a/dot/network/sync_test.go b/dot/network/sync_test.go index f79a8d74f4..4529db0e7e 100644 --- a/dot/network/sync_test.go +++ b/dot/network/sync_test.go @@ -342,8 +342,8 @@ func TestSyncQueue_ProcessBlockRequests(t *testing.T) { req: testBlockRequestMessage, } - time.Sleep(time.Second * 2) - require.Equal(t, 128, len(nodeA.syncQueue.responses)) + time.Sleep(time.Second * 3) + require.Len(t, nodeA.syncQueue.responses, 128) testResp := testBlockResponseMessage() require.Equal(t, testResp.BlockData, nodeA.syncQueue.responses) } diff --git a/dot/network/test_helpers.go b/dot/network/test_helpers.go index 65d1855997..d5ff38f2ff 100644 --- a/dot/network/test_helpers.go +++ b/dot/network/test_helpers.go @@ -8,11 +8,60 @@ import ( "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/common/optional" "github.com/ChainSafe/gossamer/lib/common/variadic" + "github.com/stretchr/testify/mock" libp2pnetwork "github.com/libp2p/go-libp2p-core/network" "github.com/libp2p/go-libp2p-core/peer" ) +// NewMockBlockState create and return a network BlockState interface mock +func NewMockBlockState(n *big.Int) *MockBlockState { + parentHash, _ := common.HexToHash("0x4545454545454545454545454545454545454545454545454545454545454545") + stateRoot, _ := common.HexToHash("0xb3266de137d20a5d0ff3a6401eb57127525fd9b2693701f0bf5a8a853fa3ebe0") + extrinsicsRoot, _ := common.HexToHash("0x03170a2e7597b7b7e3d84c05391d139a62b157e78786d8c082f29dcf4c111314") + + if n == nil { + n = big.NewInt(1) + } + header := &types.Header{ + ParentHash: parentHash, + Number: n, + StateRoot: stateRoot, + ExtrinsicsRoot: extrinsicsRoot, + Digest: types.Digest{}, + } + + m := new(MockBlockState) + m.On("BestBlockHeader").Return(header, nil) + + m.On("GenesisHash").Return(common.NewHash([]byte{})) + m.On("BestBlockNumber").Return(big.NewInt(1), nil) + m.On("HasBlockBody", mock.AnythingOfType("common.Hash")).Return(false, nil) + m.On("GetFinalizedHeader", mock.AnythingOfType("uint64"), mock.AnythingOfType("uint64")).Return(header, nil) + m.On("GetHashByNumber", mock.AnythingOfType("*big.Int")).Return(common.Hash{}, nil) + + return m +} + +// NewMockSyncer create and return a network Syncer interface mock +func NewMockSyncer() *MockSyncer { + mocksyncer := new(MockSyncer) + mocksyncer.On("HandleBlockAnnounce", mock.AnythingOfType("*network.BlockAnnounceMessage")).Return(nil, nil) + mocksyncer.On("CreateBlockResponse", mock.AnythingOfType("*network.BlockRequestMessage")).Return(testBlockResponseMessage(), nil) + mocksyncer.On("ProcessJustification", mock.AnythingOfType("[]*types.BlockData")).Return(0, nil) + mocksyncer.On("ProcessBlockData", mock.AnythingOfType("[]*types.BlockData")).Return(0, nil) + mocksyncer.On("SetSyncing", mock.AnythingOfType("bool")) + mocksyncer.On("IsSynced").Return(false) + return mocksyncer +} + +// NewMockTransactionHandler create and return a network TransactionHandler interface +func NewMockTransactionHandler() *MockTransactionHandler { + mocktxhandler := new(MockTransactionHandler) + mocktxhandler.On("HandleTransactionMessage", mock.AnythingOfType("*network.TransactionMessage")).Return(nil) + return mocktxhandler +} + func testBlockResponseMessage() *BlockResponseMessage { msg := &BlockResponseMessage{ BlockData: []*types.BlockData{}, @@ -37,42 +86,6 @@ func testBlockResponseMessage() *BlockResponseMessage { return msg } -type mockSyncer struct { - highestSeen *big.Int - synced bool -} - -func newMockSyncer() *mockSyncer { - return &mockSyncer{ - highestSeen: big.NewInt(0), - synced: false, - } -} - -func (s *mockSyncer) CreateBlockResponse(msg *BlockRequestMessage) (*BlockResponseMessage, error) { - return testBlockResponseMessage(), nil -} - -func (s *mockSyncer) HandleBlockAnnounce(msg *BlockAnnounceMessage) error { - return nil -} - -func (s *mockSyncer) ProcessBlockData(data []*types.BlockData) (int, error) { - return 0, nil -} - -func (s *mockSyncer) ProcessJustification(data []*types.BlockData) (int, error) { - return 0, nil -} - -func (s *mockSyncer) IsSynced() bool { - return s.synced -} - -func (s *mockSyncer) SetSyncing(syncing bool) { - s.synced = !syncing -} - type testStreamHandler struct { messages map[peer.ID][]Message decoder messageDecoder diff --git a/dot/network/transaction_test.go b/dot/network/transaction_test.go index 1bfa54bde9..d38cf14f8d 100644 --- a/dot/network/transaction_test.go +++ b/dot/network/transaction_test.go @@ -20,11 +20,11 @@ import ( "testing" "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/lib/common" "github.com/ChainSafe/gossamer/lib/utils" "github.com/libp2p/go-libp2p-core/peer" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) @@ -52,35 +52,17 @@ func TestDecodeTransactionMessage(t *testing.T) { require.Equal(t, testTxMsg, msg) } -type mockTransactionHandler struct { - txs map[common.Hash]types.Extrinsic -} - -func newMockTransactionHandler() *mockTransactionHandler { - return &mockTransactionHandler{ - txs: make(map[common.Hash]types.Extrinsic), - } -} - -func (h *mockTransactionHandler) HandleTransactionMessage(msg *TransactionMessage) error { - for _, tx := range msg.Extrinsics { - h.txs[tx.Hash()] = tx - } - - return nil -} - func TestHandleTransactionMessage(t *testing.T) { basePath := utils.NewTestBasePath(t, "nodeA") - - handler := newMockTransactionHandler() + mockhandler := &MockTransactionHandler{} + mockhandler.On("HandleTransactionMessage", mock.AnythingOfType("*network.TransactionMessage")).Return(nil) config := &Config{ BasePath: basePath, Port: 7001, NoBootstrap: true, NoMDNS: true, - TransactionHandler: handler, + TransactionHandler: mockhandler, } s := createTestService(t, config) @@ -90,7 +72,5 @@ func TestHandleTransactionMessage(t *testing.T) { } s.handleTransactionMessage(peer.ID(""), msg) - for _, tx := range msg.Extrinsics { - require.NotNil(t, handler.txs[tx.Hash()]) - } + mockhandler.AssertCalled(t, "HandleTransactionMessage", msg) } diff --git a/dot/rpc/modules/api_mocks.go b/dot/rpc/modules/api_mocks.go new file mode 100644 index 0000000000..b5cefec6c9 --- /dev/null +++ b/dot/rpc/modules/api_mocks.go @@ -0,0 +1,50 @@ +package modules + +import ( + modulesmocks "github.com/ChainSafe/gossamer/dot/rpc/modules/mocks" + "github.com/ChainSafe/gossamer/lib/common" + "github.com/stretchr/testify/mock" +) + +// NewMockStorageAPI creates and return an rpc StorageAPI interface mock +func NewMockStorageAPI() *modulesmocks.MockStorageAPI { + m := new(modulesmocks.MockStorageAPI) + m.On("GetStorage", mock.AnythingOfType("*common.Hash"), mock.AnythingOfType("[]uint8")).Return(nil, nil) + m.On("Entries", mock.AnythingOfType("*common.Hash")).Return(nil, nil) + m.On("GetStorageByBlockHash", mock.AnythingOfType("common.Hash"), mock.AnythingOfType("[]uint8")).Return(nil, nil) + m.On("RegisterStorageObserver", mock.Anything) + m.On("UnregisterStorageObserver", mock.Anything) + m.On("GetStateRootFromBlock", mock.AnythingOfType("*common.Hash")).Return(nil, nil) + m.On("GetKeysWithPrefix", mock.AnythingOfType("*common.Hash"), mock.AnythingOfType("[]uint8")).Return(nil, nil) + return m +} + +// NewMockBlockAPI creates and return an rpc BlockAPI interface mock +func NewMockBlockAPI() *modulesmocks.MockBlockAPI { + m := new(modulesmocks.MockBlockAPI) + m.On("GetHeader", mock.AnythingOfType("common.Hash")).Return(nil, nil) + m.On("BestBlockHash").Return(common.Hash{}) + m.On("GetBlockByHash", mock.AnythingOfType("common.Hash")).Return(nil, nil) + m.On("GetBlockHash", mock.AnythingOfType("*big.Int")).Return(nil, nil) + m.On("GetFinalizedHash", mock.AnythingOfType("uint64"), mock.AnythingOfType("uint64")).Return(common.Hash{}, nil) + m.On("RegisterImportedChannel", mock.AnythingOfType("chan<- *types.Block")).Return(byte(0), nil) + m.On("UnregisterImportedChannel", mock.AnythingOfType("uint8")) + m.On("RegisterFinalizedChannel", mock.AnythingOfType("chan<- *types.FinalisationInfo")).Return(byte(0), nil) + m.On("UnregisterFinalizedChannel", mock.AnythingOfType("uint8")) + m.On("GetJustification", mock.AnythingOfType("common.Hash")).Return(make([]byte, 10), nil) + m.On("HasJustification", mock.AnythingOfType("common.Hash")).Return(true, nil) + m.On("SubChain", mock.AnythingOfType("common.Hash"), mock.AnythingOfType("common.Hash")).Return(make([]common.Hash, 0), nil) + return m +} + +// NewMockCoreAPI creates and return an rpc CoreAPI interface mock +func NewMockCoreAPI() *modulesmocks.MockCoreAPI { + m := new(modulesmocks.MockCoreAPI) + m.On("InsertKey", mock.AnythingOfType("crypto.Keypair")) + m.On("HasKey", mock.AnythingOfType("string"), mock.AnythingOfType("string")).Return(false, nil) + m.On("GetRuntimeVersion", mock.AnythingOfType("*common.Hash")).Return(nil, nil) + m.On("IsBlockProducer").Return(false) + m.On("HandleSubmittedExtrinsic", mock.AnythingOfType("types.Extrinsic")).Return(nil) + m.On("GetMetadata", mock.AnythingOfType("*common.Hash")).Return(nil, nil) + return m +} diff --git a/dot/rpc/modules/mocks/block_api.go b/dot/rpc/modules/mocks/block_api.go new file mode 100644 index 0000000000..bdde4b1be2 --- /dev/null +++ b/dot/rpc/modules/mocks/block_api.go @@ -0,0 +1,244 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package modules + +import ( + big "math/big" + + common "github.com/ChainSafe/gossamer/lib/common" + mock "github.com/stretchr/testify/mock" + + types "github.com/ChainSafe/gossamer/dot/types" +) + +// MockBlockAPI is an autogenerated mock type for the BlockAPI type +type MockBlockAPI struct { + mock.Mock +} + +// BestBlockHash provides a mock function with given fields: +func (_m *MockBlockAPI) BestBlockHash() common.Hash { + ret := _m.Called() + + var r0 common.Hash + if rf, ok := ret.Get(0).(func() common.Hash); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Hash) + } + } + + return r0 +} + +// GetBlockByHash provides a mock function with given fields: hash +func (_m *MockBlockAPI) GetBlockByHash(hash common.Hash) (*types.Block, error) { + ret := _m.Called(hash) + + var r0 *types.Block + if rf, ok := ret.Get(0).(func(common.Hash) *types.Block); ok { + r0 = rf(hash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Block) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(common.Hash) error); ok { + r1 = rf(hash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetBlockHash provides a mock function with given fields: blockNumber +func (_m *MockBlockAPI) GetBlockHash(blockNumber *big.Int) (*common.Hash, error) { + ret := _m.Called(blockNumber) + + var r0 *common.Hash + if rf, ok := ret.Get(0).(func(*big.Int) *common.Hash); ok { + r0 = rf(blockNumber) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*common.Hash) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*big.Int) error); ok { + r1 = rf(blockNumber) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetFinalizedHash provides a mock function with given fields: _a0, _a1 +func (_m *MockBlockAPI) GetFinalizedHash(_a0 uint64, _a1 uint64) (common.Hash, error) { + ret := _m.Called(_a0, _a1) + + var r0 common.Hash + if rf, ok := ret.Get(0).(func(uint64, uint64) common.Hash); ok { + r0 = rf(_a0, _a1) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Hash) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(uint64, uint64) error); ok { + r1 = rf(_a0, _a1) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetHeader provides a mock function with given fields: hash +func (_m *MockBlockAPI) GetHeader(hash common.Hash) (*types.Header, error) { + ret := _m.Called(hash) + + var r0 *types.Header + if rf, ok := ret.Get(0).(func(common.Hash) *types.Header); ok { + r0 = rf(hash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*types.Header) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(common.Hash) error); ok { + r1 = rf(hash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetJustification provides a mock function with given fields: hash +func (_m *MockBlockAPI) GetJustification(hash common.Hash) ([]byte, error) { + ret := _m.Called(hash) + + var r0 []byte + if rf, ok := ret.Get(0).(func(common.Hash) []byte); ok { + r0 = rf(hash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(common.Hash) error); ok { + r1 = rf(hash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HasJustification provides a mock function with given fields: hash +func (_m *MockBlockAPI) HasJustification(hash common.Hash) (bool, error) { + ret := _m.Called(hash) + + var r0 bool + if rf, ok := ret.Get(0).(func(common.Hash) bool); ok { + r0 = rf(hash) + } else { + r0 = ret.Get(0).(bool) + } + + var r1 error + if rf, ok := ret.Get(1).(func(common.Hash) error); ok { + r1 = rf(hash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RegisterFinalizedChannel provides a mock function with given fields: ch +func (_m *MockBlockAPI) RegisterFinalizedChannel(ch chan<- *types.FinalisationInfo) (byte, error) { + ret := _m.Called(ch) + + var r0 byte + if rf, ok := ret.Get(0).(func(chan<- *types.FinalisationInfo) byte); ok { + r0 = rf(ch) + } else { + r0 = ret.Get(0).(byte) + } + + var r1 error + if rf, ok := ret.Get(1).(func(chan<- *types.FinalisationInfo) error); ok { + r1 = rf(ch) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RegisterImportedChannel provides a mock function with given fields: ch +func (_m *MockBlockAPI) RegisterImportedChannel(ch chan<- *types.Block) (byte, error) { + ret := _m.Called(ch) + + var r0 byte + if rf, ok := ret.Get(0).(func(chan<- *types.Block) byte); ok { + r0 = rf(ch) + } else { + r0 = ret.Get(0).(byte) + } + + var r1 error + if rf, ok := ret.Get(1).(func(chan<- *types.Block) error); ok { + r1 = rf(ch) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// SubChain provides a mock function with given fields: start, end +func (_m *MockBlockAPI) SubChain(start common.Hash, end common.Hash) ([]common.Hash, error) { + ret := _m.Called(start, end) + + var r0 []common.Hash + if rf, ok := ret.Get(0).(func(common.Hash, common.Hash) []common.Hash); ok { + r0 = rf(start, end) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]common.Hash) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(common.Hash, common.Hash) error); ok { + r1 = rf(start, end) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// UnregisterFinalizedChannel provides a mock function with given fields: id +func (_m *MockBlockAPI) UnregisterFinalizedChannel(id byte) { + _m.Called(id) +} + +// UnregisterImportedChannel provides a mock function with given fields: id +func (_m *MockBlockAPI) UnregisterImportedChannel(id byte) { + _m.Called(id) +} diff --git a/dot/rpc/modules/mocks/core_api.go b/dot/rpc/modules/mocks/core_api.go new file mode 100644 index 0000000000..6a3c1da8d1 --- /dev/null +++ b/dot/rpc/modules/mocks/core_api.go @@ -0,0 +1,119 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package modules + +import ( + common "github.com/ChainSafe/gossamer/lib/common" + crypto "github.com/ChainSafe/gossamer/lib/crypto" + + mock "github.com/stretchr/testify/mock" + + runtime "github.com/ChainSafe/gossamer/lib/runtime" + + types "github.com/ChainSafe/gossamer/dot/types" +) + +// MockCoreAPI is an autogenerated mock type for the CoreAPI type +type MockCoreAPI struct { + mock.Mock +} + +// GetMetadata provides a mock function with given fields: bhash +func (_m *MockCoreAPI) GetMetadata(bhash *common.Hash) ([]byte, error) { + ret := _m.Called(bhash) + + var r0 []byte + if rf, ok := ret.Get(0).(func(*common.Hash) []byte); ok { + r0 = rf(bhash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*common.Hash) error); ok { + r1 = rf(bhash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetRuntimeVersion provides a mock function with given fields: bhash +func (_m *MockCoreAPI) GetRuntimeVersion(bhash *common.Hash) (runtime.Version, error) { + ret := _m.Called(bhash) + + var r0 runtime.Version + if rf, ok := ret.Get(0).(func(*common.Hash) runtime.Version); ok { + r0 = rf(bhash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(runtime.Version) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*common.Hash) error); ok { + r1 = rf(bhash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// HandleSubmittedExtrinsic provides a mock function with given fields: _a0 +func (_m *MockCoreAPI) HandleSubmittedExtrinsic(_a0 types.Extrinsic) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(types.Extrinsic) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// HasKey provides a mock function with given fields: pubKeyStr, keyType +func (_m *MockCoreAPI) HasKey(pubKeyStr string, keyType string) (bool, error) { + ret := _m.Called(pubKeyStr, keyType) + + var r0 bool + if rf, ok := ret.Get(0).(func(string, string) bool); ok { + r0 = rf(pubKeyStr, keyType) + } else { + r0 = ret.Get(0).(bool) + } + + var r1 error + if rf, ok := ret.Get(1).(func(string, string) error); ok { + r1 = rf(pubKeyStr, keyType) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// InsertKey provides a mock function with given fields: kp +func (_m *MockCoreAPI) InsertKey(kp crypto.Keypair) { + _m.Called(kp) +} + +// IsBlockProducer provides a mock function with given fields: +func (_m *MockCoreAPI) IsBlockProducer() bool { + ret := _m.Called() + + var r0 bool + if rf, ok := ret.Get(0).(func() bool); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(bool) + } + + return r0 +} diff --git a/dot/rpc/modules/mocks/storage_api.go b/dot/rpc/modules/mocks/storage_api.go new file mode 100644 index 0000000000..6f0611a351 --- /dev/null +++ b/dot/rpc/modules/mocks/storage_api.go @@ -0,0 +1,140 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package modules + +import ( + common "github.com/ChainSafe/gossamer/lib/common" + mock "github.com/stretchr/testify/mock" + + state "github.com/ChainSafe/gossamer/dot/state" +) + +// MockStorageAPI is an autogenerated mock type for the StorageAPI type +type MockStorageAPI struct { + mock.Mock +} + +// Entries provides a mock function with given fields: root +func (_m *MockStorageAPI) Entries(root *common.Hash) (map[string][]byte, error) { + ret := _m.Called(root) + + var r0 map[string][]byte + if rf, ok := ret.Get(0).(func(*common.Hash) map[string][]byte); ok { + r0 = rf(root) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string][]byte) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*common.Hash) error); ok { + r1 = rf(root) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetKeysWithPrefix provides a mock function with given fields: root, prefix +func (_m *MockStorageAPI) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) { + ret := _m.Called(root, prefix) + + var r0 [][]byte + if rf, ok := ret.Get(0).(func(*common.Hash, []byte) [][]byte); ok { + r0 = rf(root, prefix) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([][]byte) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*common.Hash, []byte) error); ok { + r1 = rf(root, prefix) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetStateRootFromBlock provides a mock function with given fields: bhash +func (_m *MockStorageAPI) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { + ret := _m.Called(bhash) + + var r0 *common.Hash + if rf, ok := ret.Get(0).(func(*common.Hash) *common.Hash); ok { + r0 = rf(bhash) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(*common.Hash) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*common.Hash) error); ok { + r1 = rf(bhash) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetStorage provides a mock function with given fields: root, key +func (_m *MockStorageAPI) GetStorage(root *common.Hash, key []byte) ([]byte, error) { + ret := _m.Called(root, key) + + var r0 []byte + if rf, ok := ret.Get(0).(func(*common.Hash, []byte) []byte); ok { + r0 = rf(root, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(*common.Hash, []byte) error); ok { + r1 = rf(root, key) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// GetStorageByBlockHash provides a mock function with given fields: bhash, key +func (_m *MockStorageAPI) GetStorageByBlockHash(bhash common.Hash, key []byte) ([]byte, error) { + ret := _m.Called(bhash, key) + + var r0 []byte + if rf, ok := ret.Get(0).(func(common.Hash, []byte) []byte); ok { + r0 = rf(bhash, key) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func(common.Hash, []byte) error); ok { + r1 = rf(bhash, key) + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// RegisterStorageObserver provides a mock function with given fields: observer +func (_m *MockStorageAPI) RegisterStorageObserver(observer state.Observer) { + _m.Called(observer) +} + +// UnregisterStorageObserver provides a mock function with given fields: observer +func (_m *MockStorageAPI) UnregisterStorageObserver(observer state.Observer) { + _m.Called(observer) +} diff --git a/dot/rpc/modules/system_test.go b/dot/rpc/modules/system_test.go index d606e5058e..34ee87317f 100644 --- a/dot/rpc/modules/system_test.go +++ b/dot/rpc/modules/system_test.go @@ -43,74 +43,14 @@ var ( testPeers = []common.PeerInfo{} ) -type mockSyncer struct{} - -func (s *mockSyncer) CreateBlockResponse(msg *network.BlockRequestMessage) (*network.BlockResponseMessage, error) { - return nil, nil -} - -func (s *mockSyncer) ProcessBlockData(_ []*types.BlockData) (int, error) { - return 0, nil -} - -func (s *mockSyncer) ProcessJustification(_ []*types.BlockData) (int, error) { - return 0, nil -} - -func (s *mockSyncer) HandleBlockAnnounce(msg *network.BlockAnnounceMessage) error { - return nil -} - -func (s *mockSyncer) HandleBlockAnnounceHandshake(num *big.Int) []*network.BlockRequestMessage { - return nil -} - -func (s *mockSyncer) IsSynced() bool { - return false -} - -func (s *mockSyncer) SetSyncing(_ bool) {} - -type mockBlockState struct{} - -func (s *mockBlockState) BestBlockHeader() (*types.Header, error) { - return genesisHeader, nil -} - -func (s *mockBlockState) BestBlockNumber() (*big.Int, error) { - return big.NewInt(0), nil -} - -func (s *mockBlockState) GenesisHash() common.Hash { - return genesisHeader.Hash() -} - -func (s *mockBlockState) HasBlockBody(_ common.Hash) (bool, error) { - return false, nil -} - -func (s *mockBlockState) GetFinalizedHeader(_, _ uint64) (*types.Header, error) { - return s.BestBlockHeader() -} - -func (s *mockBlockState) GetHashByNumber(_ *big.Int) (common.Hash, error) { - return common.Hash{}, nil -} - -type mockTransactionHandler struct{} - -func (h *mockTransactionHandler) HandleTransactionMessage(_ *network.TransactionMessage) error { - return nil -} - func newNetworkService(t *testing.T) *network.Service { testDir := path.Join(os.TempDir(), "test_data") cfg := &network.Config{ - BlockState: &mockBlockState{}, + BlockState: network.NewMockBlockState(nil), BasePath: testDir, - Syncer: &mockSyncer{}, - TransactionHandler: &mockTransactionHandler{}, + Syncer: network.NewMockSyncer(), + TransactionHandler: network.NewMockTransactionHandler(), } srv, err := network.NewService(cfg) diff --git a/dot/rpc/subscription/websocket_test.go b/dot/rpc/subscription/websocket_test.go index a469e2142e..5244a9d39f 100644 --- a/dot/rpc/subscription/websocket_test.go +++ b/dot/rpc/subscription/websocket_test.go @@ -2,17 +2,12 @@ package subscription import ( "log" - "math/big" "net/http" "os" "testing" "time" - "github.com/ChainSafe/gossamer/dot/state" - "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/lib/common" - "github.com/ChainSafe/gossamer/lib/crypto" - "github.com/ChainSafe/gossamer/lib/runtime" + "github.com/ChainSafe/gossamer/dot/rpc/modules" "github.com/gorilla/websocket" "github.com/stretchr/testify/require" ) @@ -66,7 +61,7 @@ func TestWSConn_HandleComm(t *testing.T) { require.NoError(t, err) require.Equal(t, []byte(`{"jsonrpc":"2.0","error":{"code":null,"message":"error StorageAPI not set"},"id":1}`+"\n"), msg) - wsconn.StorageAPI = new(MockStorageAPI) + wsconn.StorageAPI = modules.NewMockStorageAPI() res, err = wsconn.initStorageChangeListener(1, nil) require.EqualError(t, err, "unknown parameter type") @@ -176,7 +171,7 @@ func TestWSConn_HandleComm(t *testing.T) { require.NoError(t, err) require.Equal(t, []byte(`{"jsonrpc":"2.0","error":{"code":null,"message":"error BlockAPI not set"},"id":1}`+"\n"), msg) - wsconn.BlockAPI = new(MockBlockAPI) + wsconn.BlockAPI = modules.NewMockBlockAPI() res, err = wsconn.initBlockListener(1) require.NoError(t, err) @@ -205,7 +200,7 @@ func TestWSConn_HandleComm(t *testing.T) { require.NoError(t, err) require.Equal(t, []byte(`{"jsonrpc":"2.0","error":{"code":null,"message":"error BlockAPI not set"},"id":1}`+"\n"), msg) - wsconn.BlockAPI = new(MockBlockAPI) + wsconn.BlockAPI = modules.NewMockBlockAPI() res, err = wsconn.initBlockFinalizedListener(1) require.NoError(t, err) @@ -215,7 +210,7 @@ func TestWSConn_HandleComm(t *testing.T) { require.Equal(t, []byte(`{"jsonrpc":"2.0","result":7,"id":1}`+"\n"), msg) // test initExtrinsicWatch - wsconn.CoreAPI = new(MockCoreAPI) + wsconn.CoreAPI = modules.NewMockCoreAPI() wsconn.BlockAPI = nil res, err = wsconn.initExtrinsicWatch(0, []interface{}{"NotHex"}) require.EqualError(t, err, "could not byteify non 0x prefixed string") @@ -225,96 +220,9 @@ func TestWSConn_HandleComm(t *testing.T) { require.EqualError(t, err, "error BlockAPI not set") require.Equal(t, uint(0), res) - wsconn.BlockAPI = new(MockBlockAPI) + wsconn.BlockAPI = modules.NewMockBlockAPI() res, err = wsconn.initExtrinsicWatch(0, []interface{}{"0x26aa"}) require.NoError(t, err) require.Equal(t, uint(8), res) } - -type MockStorageAPI struct{} - -func (m *MockStorageAPI) GetStorage(_ *common.Hash, key []byte) ([]byte, error) { - return nil, nil -} -func (m *MockStorageAPI) Entries(_ *common.Hash) (map[string][]byte, error) { - return nil, nil -} -func (m *MockStorageAPI) GetStorageByBlockHash(_ common.Hash, key []byte) ([]byte, error) { - return nil, nil -} -func (m *MockStorageAPI) RegisterStorageObserver(observer state.Observer) { -} - -func (m *MockStorageAPI) UnregisterStorageObserver(observer state.Observer) { -} -func (m *MockStorageAPI) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { - return nil, nil -} -func (m *MockStorageAPI) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) { - return nil, nil -} - -type MockBlockAPI struct { -} - -func (m *MockBlockAPI) GetHeader(hash common.Hash) (*types.Header, error) { - return nil, nil -} -func (m *MockBlockAPI) BestBlockHash() common.Hash { - return common.Hash{} -} -func (m *MockBlockAPI) GetBlockByHash(hash common.Hash) (*types.Block, error) { - return nil, nil -} -func (m *MockBlockAPI) GetBlockHash(blockNumber *big.Int) (*common.Hash, error) { - return nil, nil -} -func (m *MockBlockAPI) GetFinalizedHash(uint64, uint64) (common.Hash, error) { - return common.Hash{}, nil -} -func (m *MockBlockAPI) RegisterImportedChannel(ch chan<- *types.Block) (byte, error) { - return 0, nil -} -func (m *MockBlockAPI) UnregisterImportedChannel(id byte) { -} -func (m *MockBlockAPI) RegisterFinalizedChannel(ch chan<- *types.FinalisationInfo) (byte, error) { - return 0, nil -} -func (m *MockBlockAPI) UnregisterFinalizedChannel(id byte) {} - -func (m *MockBlockAPI) GetJustification(hash common.Hash) ([]byte, error) { - return make([]byte, 10), nil -} - -func (m *MockBlockAPI) HasJustification(hash common.Hash) (bool, error) { - return true, nil -} - -func (m *MockBlockAPI) SubChain(start, end common.Hash) ([]common.Hash, error) { - return make([]common.Hash, 0), nil -} - -type MockCoreAPI struct{} - -func (m *MockCoreAPI) InsertKey(kp crypto.Keypair) {} - -func (m *MockCoreAPI) HasKey(pubKeyStr string, keyType string) (bool, error) { - return false, nil -} - -func (m *MockCoreAPI) GetRuntimeVersion(bhash *common.Hash) (runtime.Version, error) { - return nil, nil -} - -func (m *MockCoreAPI) IsBlockProducer() bool { - return false -} - -func (m *MockCoreAPI) HandleSubmittedExtrinsic(types.Extrinsic) error { - return nil -} - -func (m *MockCoreAPI) GetMetadata(bhash *common.Hash) ([]byte, error) { - return nil, nil -} diff --git a/dot/rpc/websocket_test.go b/dot/rpc/websocket_test.go index e03a8d8e7d..25cff1dc96 100644 --- a/dot/rpc/websocket_test.go +++ b/dot/rpc/websocket_test.go @@ -18,16 +18,14 @@ package rpc import ( "flag" "log" - "math/big" "net/url" "testing" "time" "github.com/ChainSafe/gossamer/dot/core" - "github.com/ChainSafe/gossamer/dot/state" + "github.com/ChainSafe/gossamer/dot/rpc/modules" "github.com/ChainSafe/gossamer/dot/system" "github.com/ChainSafe/gossamer/dot/types" - "github.com/ChainSafe/gossamer/lib/common" "github.com/gorilla/websocket" "github.com/stretchr/testify/require" ) @@ -54,8 +52,8 @@ func TestHTTPServer_ServeHTTP(t *testing.T) { SystemName: "gossamer", } sysAPI := system.NewService(si, nil) - bAPI := new(MockBlockAPI) - sAPI := new(MockStorageAPI) + bAPI := modules.NewMockBlockAPI() + sAPI := modules.NewMockStorageAPI() cfg := &HTTPServerConfig{ Modules: []string{"system", "chain"}, External: false, @@ -96,66 +94,3 @@ func TestHTTPServer_ServeHTTP(t *testing.T) { require.Equal(t, item.expected, message) } } - -type MockBlockAPI struct { -} - -func (m *MockBlockAPI) GetHeader(hash common.Hash) (*types.Header, error) { - return nil, nil -} -func (m *MockBlockAPI) BestBlockHash() common.Hash { - return common.Hash{} -} -func (m *MockBlockAPI) GetBlockByHash(hash common.Hash) (*types.Block, error) { - return nil, nil -} -func (m *MockBlockAPI) GetBlockHash(blockNumber *big.Int) (*common.Hash, error) { - return nil, nil -} -func (m *MockBlockAPI) GetFinalizedHash(uint64, uint64) (common.Hash, error) { - return common.Hash{}, nil -} -func (m *MockBlockAPI) RegisterImportedChannel(ch chan<- *types.Block) (byte, error) { - return 0, nil -} -func (m *MockBlockAPI) UnregisterImportedChannel(id byte) { -} -func (m *MockBlockAPI) RegisterFinalizedChannel(ch chan<- *types.FinalisationInfo) (byte, error) { - return 0, nil -} -func (m *MockBlockAPI) UnregisterFinalizedChannel(id byte) {} - -func (m *MockBlockAPI) GetJustification(hash common.Hash) ([]byte, error) { - return make([]byte, 10), nil -} - -func (m *MockBlockAPI) HasJustification(hash common.Hash) (bool, error) { - return true, nil -} - -func (m *MockBlockAPI) SubChain(start, end common.Hash) ([]common.Hash, error) { - return make([]common.Hash, 0), nil -} - -type MockStorageAPI struct{} - -func (m *MockStorageAPI) GetStorage(_ *common.Hash, key []byte) ([]byte, error) { - return nil, nil -} -func (m *MockStorageAPI) Entries(_ *common.Hash) (map[string][]byte, error) { - return nil, nil -} -func (m *MockStorageAPI) GetStorageByBlockHash(_ common.Hash, key []byte) ([]byte, error) { - return nil, nil -} -func (m *MockStorageAPI) RegisterStorageObserver(observer state.Observer) { -} - -func (m *MockStorageAPI) UnregisterStorageObserver(observer state.Observer) { -} -func (m *MockStorageAPI) GetStateRootFromBlock(bhash *common.Hash) (*common.Hash, error) { - return nil, nil -} -func (m *MockStorageAPI) GetKeysWithPrefix(root *common.Hash, prefix []byte) ([][]byte, error) { - return nil, nil -} diff --git a/dot/services_test.go b/dot/services_test.go index 2a6746d186..7ce9a6a74b 100644 --- a/dot/services_test.go +++ b/dot/services_test.go @@ -23,6 +23,7 @@ import ( "time" "github.com/ChainSafe/gossamer/dot/network" + "github.com/ChainSafe/gossamer/dot/sync" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/utils" @@ -136,7 +137,7 @@ func TestCreateSyncService(t *testing.T) { ver, err := createBlockVerifier(stateSrvc) require.NoError(t, err) - _, err = createSyncService(cfg, stateSrvc, nil, nil, nil, ver, rt) + _, err = createSyncService(cfg, stateSrvc, sync.NewMockBlockProducer(), nil, nil, ver, rt) require.NoError(t, err) } diff --git a/dot/state/mock_observer.go b/dot/state/mock_observer.go new file mode 100644 index 0000000000..06c7bcabb7 --- /dev/null +++ b/dot/state/mock_observer.go @@ -0,0 +1,45 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package state + +import mock "github.com/stretchr/testify/mock" + +// MockObserver is an autogenerated mock type for the Observer type +type MockObserver struct { + mock.Mock +} + +// GetFilter provides a mock function with given fields: +func (_m *MockObserver) GetFilter() map[string][]byte { + ret := _m.Called() + + var r0 map[string][]byte + if rf, ok := ret.Get(0).(func() map[string][]byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(map[string][]byte) + } + } + + return r0 +} + +// GetID provides a mock function with given fields: +func (_m *MockObserver) GetID() uint { + ret := _m.Called() + + var r0 uint + if rf, ok := ret.Get(0).(func() uint); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(uint) + } + + return r0 +} + +// Update provides a mock function with given fields: result +func (_m *MockObserver) Update(result *SubscriptionResult) { + _m.Called(result) +} diff --git a/dot/state/service.go b/dot/state/service.go index dc3788d9bd..2a8f890065 100644 --- a/dot/state/service.go +++ b/dot/state/service.go @@ -175,6 +175,7 @@ func (s *Service) Start() error { num, _ := s.Block.BestBlockNumber() logger.Info("created state service", "head", s.Block.BestBlockHash(), "highest number", num) + // Start background goroutine to GC pruned keys. go s.Storage.pruneStorage(s.closeCh) return nil diff --git a/dot/state/storage_notify_test.go b/dot/state/storage_notify_test.go index 20be087aa8..f8e8e581b1 100644 --- a/dot/state/storage_notify_test.go +++ b/dot/state/storage_notify_test.go @@ -27,39 +27,25 @@ import ( "github.com/ChainSafe/chaindb" "github.com/ChainSafe/gossamer/lib/common" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) -type MockStorageObserver struct { - id uint - filter map[string][]byte - lastUpdate *SubscriptionResult - m sync.RWMutex -} - -func (m *MockStorageObserver) Update(change *SubscriptionResult) { - m.m.Lock() - m.lastUpdate = change - m.m.Unlock() - -} -func (m *MockStorageObserver) GetID() uint { - return m.id -} -func (m *MockStorageObserver) GetFilter() map[string][]byte { - return m.filter -} - func TestStorageState_RegisterStorageObserver(t *testing.T) { ss := newTestStorageState(t) ts, err := ss.TrieState(nil) require.NoError(t, err) - observer := &MockStorageObserver{} - ss.RegisterStorageObserver(observer) + mockfilter := map[string][]byte{} + mockobs := &MockObserver{} - defer ss.UnregisterStorageObserver(observer) + mockobs.On("Update", mock.AnythingOfType("*state.SubscriptionResult")) + mockobs.On("GetID").Return(uint(10)) + mockobs.On("GetFilter").Return(mockfilter) + + ss.RegisterStorageObserver(mockobs) + defer ss.UnregisterStorageObserver(mockobs) ts.Set([]byte("mackcom"), []byte("wuz here")) err = ss.StoreTrie(ts) @@ -72,10 +58,12 @@ func TestStorageState_RegisterStorageObserver(t *testing.T) { Value: []byte("wuz here"), }}, } + time.Sleep(time.Millisecond) - observer.m.RLock() - defer observer.m.RUnlock() - require.Equal(t, expectedResult, observer.lastUpdate) + // called when register and called when store trie + mockobs.AssertNumberOfCalls(t, "GetFilter", 2) + mockobs.AssertNumberOfCalls(t, "Update", 1) + mockobs.AssertCalled(t, "Update", expectedResult) } func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) { @@ -85,14 +73,18 @@ func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) { num := 5 - var observers []*MockStorageObserver + var mocks []*MockObserver for i := 0; i < num; i++ { - observer := &MockStorageObserver{ - id: uint(i), - } - observers = append(observers, observer) - ss.RegisterStorageObserver(observer) + mockfilter := map[string][]byte{} + mockobs := &MockObserver{} + + mockobs.On("Update", mock.AnythingOfType("*state.SubscriptionResult")) + mockobs.On("GetID").Return(uint(10)) + mockobs.On("GetFilter").Return(mockfilter) + + mocks = append(mocks, mockobs) + ss.RegisterStorageObserver(mockobs) require.NoError(t, err) } @@ -106,15 +98,21 @@ func TestStorageState_RegisterStorageObserver_Multi(t *testing.T) { time.Sleep(time.Millisecond * 10) - for _, observer := range observers { - observer.m.RLock() - require.NotNil(t, observer.lastUpdate.Hash) - require.Equal(t, key1, observer.lastUpdate.Changes[0].Key) - require.Equal(t, value1, observer.lastUpdate.Changes[0].Value) - observer.m.RUnlock() + expectedResult := &SubscriptionResult{ + Hash: ts.MustRoot(), + Changes: []KeyValue{{ + Key: key1, + Value: value1, + }}, + } + + for _, mockobs := range mocks { + mockobs.AssertNumberOfCalls(t, "GetFilter", 2) + mockobs.AssertNumberOfCalls(t, "Update", 1) + mockobs.AssertCalled(t, "Update", expectedResult) } - for _, observer := range observers { + for _, observer := range mocks { ss.UnregisterStorageObserver(observer) } } @@ -129,17 +127,19 @@ func TestStorageState_RegisterStorageObserver_Multi_Filter(t *testing.T) { value1 := []byte("value1") num := 5 - var observers []*MockStorageObserver + var mocks []*MockObserver + filter := map[string][]byte{ + common.BytesToHex(key1): {}, + } for i := 0; i < num; i++ { - observer := &MockStorageObserver{ - id: uint(i), - filter: map[string][]byte{ - common.BytesToHex(key1): {}, - }, - } - observers = append(observers, observer) - ss.RegisterStorageObserver(observer) + mockobs := &MockObserver{} + mockobs.On("Update", mock.AnythingOfType("*state.SubscriptionResult")) + mockobs.On("GetID").Return(uint(i)) + mockobs.On("GetFilter").Return(filter) + + mocks = append(mocks, mockobs) + ss.RegisterStorageObserver(mockobs) } ts.Set(key1, value1) @@ -148,15 +148,21 @@ func TestStorageState_RegisterStorageObserver_Multi_Filter(t *testing.T) { time.Sleep(time.Millisecond * 10) - for _, observer := range observers { - observer.m.RLock() - require.NotNil(t, observer.lastUpdate.Hash) - require.Equal(t, key1, observer.lastUpdate.Changes[0].Key) - require.Equal(t, value1, observer.lastUpdate.Changes[0].Value) - observer.m.RUnlock() + expectedResult := &SubscriptionResult{ + Hash: ts.MustRoot(), + Changes: []KeyValue{{ + Key: key1, + Value: value1, + }}, + } + + for _, mockobs := range mocks { + mockobs.AssertNumberOfCalls(t, "GetFilter", len(filter)+3) + mockobs.AssertNumberOfCalls(t, "Update", 1) + mockobs.AssertCalled(t, "Update", expectedResult) } - for _, observer := range observers { + for _, observer := range mocks { ss.UnregisterStorageObserver(observer) } } diff --git a/dot/sync/mocks/block_producer.go b/dot/sync/mocks/block_producer.go new file mode 100644 index 0000000000..7d4d62556f --- /dev/null +++ b/dot/sync/mocks/block_producer.go @@ -0,0 +1,46 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package sync + +import ( + runtime "github.com/ChainSafe/gossamer/lib/runtime" + mock "github.com/stretchr/testify/mock" +) + +// MockBlockProducer is an autogenerated mock type for the BlockProducer type +type MockBlockProducer struct { + mock.Mock +} + +// Pause provides a mock function with given fields: +func (_m *MockBlockProducer) Pause() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Resume provides a mock function with given fields: +func (_m *MockBlockProducer) Resume() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// SetRuntime provides a mock function with given fields: rt +func (_m *MockBlockProducer) SetRuntime(rt runtime.Instance) { + _m.Called(rt) +} diff --git a/dot/sync/mocks/finality_gadget.go b/dot/sync/mocks/finality_gadget.go new file mode 100644 index 0000000000..5386205968 --- /dev/null +++ b/dot/sync/mocks/finality_gadget.go @@ -0,0 +1,24 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package sync + +import mock "github.com/stretchr/testify/mock" + +// MockFinalityGadget is an autogenerated mock type for the FinalityGadget type +type MockFinalityGadget struct { + mock.Mock +} + +// VerifyBlockJustification provides a mock function with given fields: _a0 +func (_m *MockFinalityGadget) VerifyBlockJustification(_a0 []byte) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func([]byte) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/dot/sync/mocks/verifier.go b/dot/sync/mocks/verifier.go new file mode 100644 index 0000000000..3dac9db92f --- /dev/null +++ b/dot/sync/mocks/verifier.go @@ -0,0 +1,28 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package sync + +import ( + mock "github.com/stretchr/testify/mock" + + types "github.com/ChainSafe/gossamer/dot/types" +) + +// MockVerifier is an autogenerated mock type for the Verifier type +type MockVerifier struct { + mock.Mock +} + +// VerifyBlock provides a mock function with given fields: header +func (_m *MockVerifier) VerifyBlock(header *types.Header) error { + ret := _m.Called(header) + + var r0 error + if rf, ok := ret.Get(0).(func(*types.Header) error); ok { + r0 = rf(header) + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/dot/sync/syncer.go b/dot/sync/syncer.go index e88f4a2fd8..5d0a024509 100644 --- a/dot/sync/syncer.go +++ b/dot/sync/syncer.go @@ -90,7 +90,7 @@ func NewService(cfg *Config) (*Service, error) { } if cfg.BlockProducer == nil { - cfg.BlockProducer = newMockBlockProducer() + cfg.BlockProducer = NewMockBlockProducer() } handler := log.StreamHandler(os.Stdout, log.TerminalFormat()) diff --git a/dot/sync/test_helpers.go b/dot/sync/test_helpers.go index f2350e1e29..66c1b9b67f 100644 --- a/dot/sync/test_helpers.go +++ b/dot/sync/test_helpers.go @@ -22,6 +22,8 @@ import ( "testing" "time" + "github.com/stretchr/testify/mock" + "github.com/ChainSafe/gossamer/dot/state" "github.com/ChainSafe/gossamer/dot/types" "github.com/ChainSafe/gossamer/lib/babe" @@ -35,43 +37,33 @@ import ( "github.com/ChainSafe/gossamer/lib/trie" log "github.com/ChainSafe/log15" "github.com/stretchr/testify/require" -) - -// mockVerifier implements the Verifier interface -type mockVerifier struct{} - -// VerifyBlock mocks verifying a block -func (v *mockVerifier) VerifyBlock(header *types.Header) error { - return nil -} - -// mockBlockProducer implements the BlockProducer interface -type mockBlockProducer struct { - auths []*types.Authority -} -func newMockBlockProducer() *mockBlockProducer { - return &mockBlockProducer{ - auths: []*types.Authority{}, - } -} + syncmocks "github.com/ChainSafe/gossamer/dot/sync/mocks" +) -// Pause mocks pausing -func (bp *mockBlockProducer) Pause() error { - return nil +// NewMockFinalityGadget create and return sync FinalityGadget interface mock +func NewMockFinalityGadget() *syncmocks.MockFinalityGadget { + m := new(syncmocks.MockFinalityGadget) + // using []uint8 instead of []byte: https://github.com/stretchr/testify/pull/969 + m.On("VerifyBlockJustification", mock.AnythingOfType("[]uint8")).Return(nil) + return m } -// Resume mocks resuming -func (bp *mockBlockProducer) Resume() error { - return nil +// NewMockVerifier create and return sync Verifier interface mock +func NewMockVerifier() *syncmocks.MockVerifier { + m := new(syncmocks.MockVerifier) + m.On("VerifyBlock", mock.AnythingOfType("*types.Header")).Return(nil) + return m } -func (bp *mockBlockProducer) SetRuntime(_ runtime.Instance) {} +// NewMockBlockProducer create and return sync BlockProducer interface mock +func NewMockBlockProducer() *syncmocks.MockBlockProducer { + m := new(syncmocks.MockBlockProducer) + m.On("Pause").Return(nil) + m.On("Resume").Return(nil) + m.On("SetRuntime", mock.AnythingOfType("runtime.Instance")) -type mockFinalityGadget struct{} - -func (m mockFinalityGadget) VerifyBlockJustification(_ []byte) error { - return nil + return m } // NewTestSyncer ... @@ -98,6 +90,10 @@ func NewTestSyncer(t *testing.T) *Service { cfg.StorageState = stateSrvc.Storage } + if cfg.BlockProducer == nil { + cfg.BlockProducer = NewMockBlockProducer() + } + if cfg.Runtime == nil { // set state to genesis state genState, err := rtstorage.NewTrieState(genTrie) //nolint @@ -117,7 +113,7 @@ func NewTestSyncer(t *testing.T) *Service { } if cfg.Verifier == nil { - cfg.Verifier = &mockVerifier{} + cfg.Verifier = NewMockVerifier() } if cfg.LogLvl == 0 { @@ -125,7 +121,7 @@ func NewTestSyncer(t *testing.T) *Service { } if cfg.FinalityGadget == nil { - cfg.FinalityGadget = &mockFinalityGadget{} + cfg.FinalityGadget = NewMockFinalityGadget() } syncer, err := NewService(cfg) diff --git a/dot/types/mocks/digest_item.go b/dot/types/mocks/digest_item.go new file mode 100644 index 0000000000..66d1d04a10 --- /dev/null +++ b/dot/types/mocks/digest_item.go @@ -0,0 +1,79 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package types + +import ( + io "io" + + mock "github.com/stretchr/testify/mock" +) + +// MockDigestItem is an autogenerated mock type for the DigestItem type +type MockDigestItem struct { + mock.Mock +} + +// Decode provides a mock function with given fields: _a0 +func (_m *MockDigestItem) Decode(_a0 io.Reader) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(io.Reader) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Encode provides a mock function with given fields: +func (_m *MockDigestItem) Encode() ([]byte, error) { + ret := _m.Called() + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + var r1 error + if rf, ok := ret.Get(1).(func() error); ok { + r1 = rf() + } else { + r1 = ret.Error(1) + } + + return r0, r1 +} + +// String provides a mock function with given fields: +func (_m *MockDigestItem) String() string { + ret := _m.Called() + + var r0 string + if rf, ok := ret.Get(0).(func() string); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(string) + } + + return r0 +} + +// Type provides a mock function with given fields: +func (_m *MockDigestItem) Type() byte { + ret := _m.Called() + + var r0 byte + if rf, ok := ret.Get(0).(func() byte); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(byte) + } + + return r0 +} diff --git a/go.sum b/go.sum index 55816427d5..814e8c95c4 100644 --- a/go.sum +++ b/go.sum @@ -625,6 +625,7 @@ github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnIn github.com/spf13/viper v1.3.2/go.mod h1:ZiWeW+zYFKm7srdB9IoDzzZXaJaI5eL9QjNiN/DMA2s= github.com/src-d/envconfig v1.0.0/go.mod h1:Q9YQZ7BKITldTBnoxsE5gOeB5y66RyPXeue/R4aaNBc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.1.1 h1:2vfRuCMp5sSVIDSqO8oNnWJq7mPa6KVP3iPIwFBuy8A= github.com/stretchr/objx v0.1.1/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.3.0/go.mod h1:M5WIy9Dh21IEIfnGCwXGc5bZfKNJtfHm1UVUgZn+9EI= diff --git a/lib/grandpa/grandpa_test.go b/lib/grandpa/grandpa_test.go index 511515d687..42dce94604 100644 --- a/lib/grandpa/grandpa_test.go +++ b/lib/grandpa/grandpa_test.go @@ -33,6 +33,8 @@ import ( "github.com/ChainSafe/gossamer/lib/utils" "github.com/stretchr/testify/require" + + . "github.com/ChainSafe/gossamer/lib/grandpa/mocks" ) // testGenesisHeader is a test block header @@ -46,10 +48,10 @@ var ( voters = newTestVoters() ) -type mockDigestHandler struct{} - -func (h *mockDigestHandler) NextGrandpaAuthorityChange() uint64 { - return 2 ^ 64 - 1 +func NewMockDigestHandler() *MockDigestHandler { + m := new(MockDigestHandler) + m.On("NextGrandpaAuthorityChange").Return(uint64(2 ^ 64 - 1)) + return m } func newTestState(t *testing.T) *state.Service { @@ -90,7 +92,7 @@ func newTestService(t *testing.T) (*Service, *state.Service) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Alice().(*ed25519.Keypair), Authority: true, diff --git a/lib/grandpa/mocks/digest_handler.go b/lib/grandpa/mocks/digest_handler.go new file mode 100644 index 0000000000..7665858eae --- /dev/null +++ b/lib/grandpa/mocks/digest_handler.go @@ -0,0 +1,24 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package grandpa + +import mock "github.com/stretchr/testify/mock" + +// MockDigestHandler is an autogenerated mock type for the DigestHandler type +type MockDigestHandler struct { + mock.Mock +} + +// NextGrandpaAuthorityChange provides a mock function with given fields: +func (_m *MockDigestHandler) NextGrandpaAuthorityChange() uint64 { + ret := _m.Called() + + var r0 uint64 + if rf, ok := ret.Get(0).(func() uint64); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(uint64) + } + + return r0 +} diff --git a/lib/grandpa/round_test.go b/lib/grandpa/round_test.go index 949eebd092..a4bfe44e91 100644 --- a/lib/grandpa/round_test.go +++ b/lib/grandpa/round_test.go @@ -102,7 +102,7 @@ func setupGrandpa(t *testing.T, kp *ed25519.Keypair) (*Service, chan GrandpaMess cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kp, LogLvl: log.LvlInfo, diff --git a/lib/grandpa/vote_message_test.go b/lib/grandpa/vote_message_test.go index c5e4d9f75b..b24b728923 100644 --- a/lib/grandpa/vote_message_test.go +++ b/lib/grandpa/vote_message_test.go @@ -38,7 +38,7 @@ func TestCheckForEquivocation_NoEquivocation(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Bob().(*ed25519.Keypair), Network: net, @@ -70,7 +70,7 @@ func TestCheckForEquivocation_WithEquivocation(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Bob().(*ed25519.Keypair), Network: net, @@ -112,7 +112,7 @@ func TestCheckForEquivocation_WithExistingEquivocation(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Bob().(*ed25519.Keypair), Network: net, @@ -169,7 +169,7 @@ func TestValidateMessage_Valid(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Bob().(*ed25519.Keypair), Network: net, @@ -200,7 +200,7 @@ func TestValidateMessage_InvalidSignature(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Bob().(*ed25519.Keypair), Network: net, @@ -232,7 +232,7 @@ func TestValidateMessage_SetIDMismatch(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Keypair: kr.Bob().(*ed25519.Keypair), Network: net, } @@ -263,7 +263,7 @@ func TestValidateMessage_Equivocation(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Bob().(*ed25519.Keypair), Network: net, @@ -307,7 +307,7 @@ func TestValidateMessage_BlockDoesNotExist(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Bob().(*ed25519.Keypair), Network: net, @@ -340,7 +340,7 @@ func TestValidateMessage_IsNotDescendant(t *testing.T) { cfg := &Config{ BlockState: st.Block, GrandpaState: st.Grandpa, - DigestHandler: &mockDigestHandler{}, + DigestHandler: NewMockDigestHandler(), Voters: voters, Keypair: kr.Bob().(*ed25519.Keypair), Network: net, diff --git a/lib/runtime/allocator_test.go b/lib/runtime/allocator_test.go index 9af46b6880..97a62b8d7d 100644 --- a/lib/runtime/allocator_test.go +++ b/lib/runtime/allocator_test.go @@ -22,32 +22,28 @@ import ( "reflect" "testing" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" ) -// struct to mock memory interface -type mockMemory struct { - buffer []byte -} - -// return mock memory as byte slice -func (m *mockMemory) Data() []byte { - return m.buffer -} +func NewMemoryMock(size uint32) *MockMemory { + m := new(MockMemory) + testobj := make([]byte, size) -// return mock memory size -func (m *mockMemory) Length() uint32 { - return uint32(len(m.buffer)) -} + m.On("Data").Return(testobj) + lengthcall := m.On("Length") + lengthcall.RunFn = func(args mock.Arguments) { + lengthcall.ReturnArguments = mock.Arguments{uint32(len(testobj))} + } -func (m *mockMemory) Grow(numPages uint32) error { - m.buffer = append(m.buffer, make([]byte, PageSize*numPages)...) - return nil -} + growcall := m.On("Grow", mock.Anything) + growcall.RunFn = func(args mock.Arguments) { + arg := args[0].(uint32) + testobj = append(testobj, make([]byte, PageSize*arg)...) + growcall.ReturnArguments = mock.Arguments{nil} + } -// create new mock memory of specified size -func newMockMemory(size uint32) *mockMemory { - return &mockMemory{buffer: make([]byte, size)} + return m } // struct to hold data for a round of tests @@ -295,13 +291,13 @@ var allTests = []testHolder{ // test holder func TestAllocator(t *testing.T) { for _, test := range allTests { - allocator := NewAllocator(newMockMemory(1<<16), test.offset) + memmock := NewMemoryMock(1 << 16) + allocator := NewAllocator(memmock, test.offset) for _, theTest := range test.tests { switch v := theTest.test.(type) { case *allocateTest: - result, err1 := - allocator.Allocate(v.size) + result, err1 := allocator.Allocate(v.size) if err1 != nil { t.Fatal(err1) } @@ -340,8 +336,9 @@ func compareState(allocator FreeingBumpHeapAllocator, state allocatorState, resu // test that allocator should grow memory if the allocation request is larger than current size func TestShouldGrowMemory(t *testing.T) { - mem := newMockMemory(1 << 16) + mem := NewMemoryMock(1 << 16) currentSize := mem.Length() + fbha := NewAllocator(mem, 0) // when @@ -352,7 +349,7 @@ func TestShouldGrowMemory(t *testing.T) { // test that the allocator should grow memory if it's already full func TestShouldGrowMemoryIfFull(t *testing.T) { - mem := newMockMemory(1 << 16) + mem := NewMemoryMock(1 << 16) currentSize := mem.Length() fbha := NewAllocator(mem, 0) @@ -372,10 +369,10 @@ func TestShouldGrowMemoryIfFull(t *testing.T) { // test to confirm that allocator can allocate the MaxPossibleAllocation func TestShouldAllocateMaxPossibleAllocationSize(t *testing.T) { // given, grow heap memory so that we have at least MaxPossibleAllocation available - mem := newMockMemory(1 << 16) + mem := NewMemoryMock(1 << 16) pagesNeeded := (MaxPossibleAllocation / PageSize) - (mem.Length() / PageSize) + 1 - mem = newMockMemory(mem.Length() + pagesNeeded*65*1024) + mem = NewMemoryMock(mem.Length() + pagesNeeded*65*1024) fbha := NewAllocator(mem, 0) @@ -391,7 +388,7 @@ func TestShouldAllocateMaxPossibleAllocationSize(t *testing.T) { // test that allocator should not allocate memory if request is too large func TestShouldNotAllocateIfRequestSizeTooLarge(t *testing.T) { - fbha := NewAllocator(newMockMemory(1<<16), 0) + fbha := NewAllocator(NewMemoryMock(1<<16), 0) // when _, err := fbha.Allocate(MaxPossibleAllocation + 1) diff --git a/lib/runtime/mock_memory.go b/lib/runtime/mock_memory.go new file mode 100644 index 0000000000..a8c0bcf45b --- /dev/null +++ b/lib/runtime/mock_memory.go @@ -0,0 +1,54 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package runtime + +import mock "github.com/stretchr/testify/mock" + +// MockMemory is an autogenerated mock type for the Memory type +type MockMemory struct { + mock.Mock +} + +// Data provides a mock function with given fields: +func (_m *MockMemory) Data() []byte { + ret := _m.Called() + + var r0 []byte + if rf, ok := ret.Get(0).(func() []byte); ok { + r0 = rf() + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).([]byte) + } + } + + return r0 +} + +// Grow provides a mock function with given fields: _a0 +func (_m *MockMemory) Grow(_a0 uint32) error { + ret := _m.Called(_a0) + + var r0 error + if rf, ok := ret.Get(0).(func(uint32) error); ok { + r0 = rf(_a0) + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Length provides a mock function with given fields: +func (_m *MockMemory) Length() uint32 { + ret := _m.Called() + + var r0 uint32 + if rf, ok := ret.Get(0).(func() uint32); ok { + r0 = rf() + } else { + r0 = ret.Get(0).(uint32) + } + + return r0 +} diff --git a/lib/runtime/mock_transaction_state.go b/lib/runtime/mock_transaction_state.go new file mode 100644 index 0000000000..e27caec9e4 --- /dev/null +++ b/lib/runtime/mock_transaction_state.go @@ -0,0 +1,31 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package runtime + +import ( + common "github.com/ChainSafe/gossamer/lib/common" + mock "github.com/stretchr/testify/mock" + + transaction "github.com/ChainSafe/gossamer/lib/transaction" +) + +// MockTransactionState is an autogenerated mock type for the TransactionState type +type MockTransactionState struct { + mock.Mock +} + +// AddToPool provides a mock function with given fields: vt +func (_m *MockTransactionState) AddToPool(vt *transaction.ValidTransaction) common.Hash { + ret := _m.Called(vt) + + var r0 common.Hash + if rf, ok := ret.Get(0).(func(*transaction.ValidTransaction) common.Hash); ok { + r0 = rf(vt) + } else { + if ret.Get(0) != nil { + r0 = ret.Get(0).(common.Hash) + } + } + + return r0 +} diff --git a/lib/runtime/wasmer/test_helpers.go b/lib/runtime/wasmer/test_helpers.go index 437fddd00e..d2ae4491db 100644 --- a/lib/runtime/wasmer/test_helpers.go +++ b/lib/runtime/wasmer/test_helpers.go @@ -24,9 +24,9 @@ import ( "github.com/ChainSafe/gossamer/lib/keystore" "github.com/ChainSafe/gossamer/lib/runtime" "github.com/ChainSafe/gossamer/lib/runtime/storage" - "github.com/ChainSafe/gossamer/lib/transaction" "github.com/ChainSafe/gossamer/lib/trie" log "github.com/ChainSafe/log15" + "github.com/stretchr/testify/mock" "github.com/stretchr/testify/require" wasm "github.com/wasmerio/go-ext-wasm/wasmer" ) @@ -100,15 +100,14 @@ func setupConfig(t *testing.T, targetRuntime string, tt *trie.Trie, lvl log.Lvl, cfg.LogLvl = lvl cfg.NodeStorage = ns cfg.Network = new(runtime.TestRuntimeNetwork) - cfg.Transaction = new(mockTransactionState) + cfg.Transaction = NewTransactionStateMock() cfg.Role = role return fp, cfg } -type mockTransactionState struct { -} - -// AddToPool adds a transaction to the pool -func (mt *mockTransactionState) AddToPool(vt *transaction.ValidTransaction) common.Hash { - return common.BytesToHash([]byte("test")) +// NewTransactionStateMock create and return an runtime Transaction State interface mock +func NewTransactionStateMock() *runtime.MockTransactionState { + m := new(runtime.MockTransactionState) + m.On("AddToPool", mock.AnythingOfType("*transaction.ValidTransaction")).Return(common.BytesToHash([]byte("test"))) + return m } diff --git a/lib/services/mocks/service.go b/lib/services/mocks/service.go new file mode 100644 index 0000000000..604f83f568 --- /dev/null +++ b/lib/services/mocks/service.go @@ -0,0 +1,38 @@ +// Code generated by mockery v2.8.0. DO NOT EDIT. + +package services + +import mock "github.com/stretchr/testify/mock" + +// MockService is an autogenerated mock type for the Service type +type MockService struct { + mock.Mock +} + +// Start provides a mock function with given fields: +func (_m *MockService) Start() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} + +// Stop provides a mock function with given fields: +func (_m *MockService) Stop() error { + ret := _m.Called() + + var r0 error + if rf, ok := ret.Get(0).(func() error); ok { + r0 = rf() + } else { + r0 = ret.Error(0) + } + + return r0 +} diff --git a/lib/services/services_test.go b/lib/services/services_test.go index 67a3ee7f72..3ee162f893 100644 --- a/lib/services/services_test.go +++ b/lib/services/services_test.go @@ -18,104 +18,46 @@ package services import ( "testing" -) - -// ------------------- Mock Services -------------------- -type MockSrvcA struct { - running bool -} - -func (s *MockSrvcA) Start() error { - s.running = true - return nil -} -func (s *MockSrvcA) Stop() error { - s.running = false - return nil -} - -type MockSrvcB struct { - running bool -} - -func (s *MockSrvcB) Start() error { - s.running = true - return nil -} -func (s *MockSrvcB) Stop() error { - s.running = false - return nil -} -type FakeService struct{} - -func (s *FakeService) Start() error { return nil } -func (s *FakeService) Stop() {} - -// -------------------------------------------------------- + . "github.com/ChainSafe/gossamer/lib/services/mocks" + "github.com/stretchr/testify/require" +) func TestServiceRegistry_RegisterService(t *testing.T) { r := NewServiceRegistry() - a1 := &MockSrvcA{} - a2 := &MockSrvcA{} + r.RegisterService(&MockService{}) + r.RegisterService(&MockService{}) - r.RegisterService(a1) - r.RegisterService(a2) - - if len(r.serviceTypes) > 1 { - t.Fatalf("should not allow services of the same type to be registered") - } + require.Len(t, r.services, 1) } func TestServiceRegistry_StartStopAll(t *testing.T) { r := NewServiceRegistry() - a := &MockSrvcA{} - b := &MockSrvcB{} + m := new(MockService) + m.On("Start").Return(nil) + m.On("Stop").Return(nil) - r.RegisterService(a) - r.RegisterService(b) + r.RegisterService(m) r.StartAll() - - if a.running != true || b.running != true { - t.Fatal("failed to start service") - } + m.AssertCalled(t, "Start") r.StopAll() - - if a.running != false || b.running != false { - t.Fatal("failed to stop service") - } - + m.AssertCalled(t, "Stop") } func TestServiceRegistry_Get_Err(t *testing.T) { r := NewServiceRegistry() - a := &MockSrvcA{} - b := &MockSrvcB{} + a := new(MockService) + a.On("Start").Return(nil) + a.On("Stop").Return(nil) r.RegisterService(a) - r.RegisterService(b) - - if r.Get(a) == nil { - t.Fatalf("Failed to fetch service: %T", a) - } - if err := r.Get(a).Start(); err != nil { - t.Fatal(err) - } - - if r.Get(b) == nil { - t.Fatalf("Failed to fetch service: %T", b) - } - if err := r.Get(b).Start(); err != nil { - t.Fatal(err) - } + require.NotNil(t, r.Get(a)) - f := &FakeService{} - if s := r.Get(f); s != nil { - t.Fatalf("Expected nil. Fetched service: %T", s) - } + f := struct{}{} + require.Nil(t, r.Get(f)) } diff --git a/lib/utils/test_utils.go b/lib/utils/test_utils.go index a690eb99c9..a9a80e3f80 100644 --- a/lib/utils/test_utils.go +++ b/lib/utils/test_utils.go @@ -18,10 +18,12 @@ package utils import ( "fmt" - "io" "os" "path" "testing" + + typesmocks "github.com/ChainSafe/gossamer/dot/types/mocks" + "github.com/stretchr/testify/mock" ) // TestDir test data directory @@ -76,34 +78,13 @@ func RemoveTestDir(t *testing.T) { } } -// MockDigestItem ... -type MockDigestItem struct { - i int -} - // NewMockDigestItem creates a mock digest item for testing purposes. -func NewMockDigestItem(i int) *MockDigestItem { - return &MockDigestItem{ - i: i, - } -} - -// String ... -func (d *MockDigestItem) String() string { - return "" -} - -// Type ... -func (d *MockDigestItem) Type() byte { - return byte(d.i) -} - -// Encode ... -func (d *MockDigestItem) Encode() ([]byte, error) { - return []byte{byte(d.i)}, nil -} - -// Decode ... -func (d *MockDigestItem) Decode(_ io.Reader) error { - return nil +func NewMockDigestItem(i int) *typesmocks.MockDigestItem { + mockDigestItem := new(typesmocks.MockDigestItem) + mockDigestItem.On("String").Return("") + mockDigestItem.On("Type").Return(byte(i)) + mockDigestItem.On("Encode").Return([]byte{byte(i)}, nil) + mockDigestItem.On("Decode", mock.AnythingOfType("io.Reader")).Return(nil) + + return mockDigestItem }