github.com/iotexproject/iotex-core@v1.14.1-rc1/blockchain/blockdao/blockindexer_test.go (about) 1 // Copyright (c) 2019 IoTeX Foundation 2 // This source code is provided 'as is' and no warranties are given as to title or non-infringement, merchantability 3 // or fitness for purpose and, to the extent permitted by law, all liability for your use of the code is disclaimed. 4 // This source code is governed by Apache License 2.0 that can be found in the LICENSE file. 5 6 package blockdao 7 8 import ( 9 "context" 10 "strconv" 11 "testing" 12 13 "github.com/golang/mock/gomock" 14 "github.com/stretchr/testify/require" 15 "google.golang.org/protobuf/types/known/timestamppb" 16 17 "github.com/iotexproject/iotex-proto/golang/iotextypes" 18 19 "github.com/iotexproject/iotex-core/action/protocol" 20 "github.com/iotexproject/iotex-core/blockchain/block" 21 "github.com/iotexproject/iotex-core/blockchain/genesis" 22 "github.com/iotexproject/iotex-core/test/identityset" 23 "github.com/iotexproject/iotex-core/test/mock/mock_blockdao" 24 ) 25 26 func TestCheckIndexer(t *testing.T) { 27 28 cases := []struct { 29 daoHeight uint64 30 indexerTipHeight uint64 31 expectedPutBlocks []uint64 32 noErr bool 33 }{ 34 {5, 0, []uint64{1, 2, 3, 4, 5}, true}, 35 {5, 1, []uint64{2, 3, 4, 5}, true}, 36 {5, 2, []uint64{3, 4, 5}, true}, 37 {5, 3, []uint64{4, 5}, true}, 38 {5, 4, []uint64{5}, true}, 39 {5, 5, []uint64{}, true}, 40 {5, 6, []uint64{}, false}, 41 } 42 43 for i, c := range cases { 44 t.Run(strconv.FormatUint(uint64(i), 10), func(t *testing.T) { 45 require := require.New(t) 46 ctrl := gomock.NewController(t) 47 defer ctrl.Finish() 48 mockDao := mock_blockdao.NewMockBlockDAO(ctrl) 49 checker := NewBlockIndexerChecker(mockDao) 50 indexer := mock_blockdao.NewMockBlockIndexer(ctrl) 51 52 putBlocks := make([]*block.Block, 0) 53 mockDao.EXPECT().Height().Return(c.daoHeight, nil).Times(1) 54 mockDao.EXPECT().GetBlockByHeight(gomock.Any()).DoAndReturn(func(arg0 uint64) (*block.Block, error) { 55 pb := &iotextypes.BlockHeader{ 56 Core: &iotextypes.BlockHeaderCore{ 57 Height: arg0, 58 Timestamp: timestamppb.Now(), 59 }, 60 ProducerPubkey: identityset.PrivateKey(1).PublicKey().Bytes(), 61 } 62 blk := &block.Block{} 63 err := blk.LoadFromBlockHeaderProto(pb) 64 return blk, err 65 }).AnyTimes() 66 mockDao.EXPECT().GetReceipts(gomock.Any()).Return(nil, nil).AnyTimes() 67 indexer.EXPECT().Height().Return(c.indexerTipHeight, nil).Times(1) 68 indexer.EXPECT().PutBlock(gomock.Any(), gomock.Any()).DoAndReturn(func(arg0 context.Context, arg1 *block.Block) error { 69 putBlocks = append(putBlocks, arg1) 70 return nil 71 }).AnyTimes() 72 73 ctx := protocol.WithBlockchainCtx(context.Background(), protocol.BlockchainCtx{}) 74 ctx = genesis.WithGenesisContext(ctx, genesis.Default) 75 err := checker.CheckIndexer(ctx, indexer, 0, func(u uint64) {}) 76 require.Equalf(c.noErr, err == nil, "error: %v", err) 77 require.Len(putBlocks, len(c.expectedPutBlocks)) 78 for k, h := range c.expectedPutBlocks { 79 require.Equal(h, putBlocks[k].Height()) 80 } 81 }) 82 } 83 } 84 85 func TestCheckIndexerWithStart(t *testing.T) { 86 87 cases := []struct { 88 daoHeight uint64 89 indexerTipHeight uint64 90 indexerStartHeight uint64 91 expectedPutBlocks []uint64 92 noErr bool 93 }{ 94 {5, 0, 3, []uint64{3, 4, 5}, true}, 95 {5, 1, 3, []uint64{3, 4, 5}, true}, 96 {5, 2, 3, []uint64{3, 4, 5}, true}, 97 {5, 3, 3, []uint64{4, 5}, true}, 98 {5, 4, 3, []uint64{5}, true}, 99 {5, 5, 3, []uint64{}, true}, 100 {5, 6, 3, []uint64{}, false}, 101 } 102 103 for i, c := range cases { 104 t.Run(strconv.FormatUint(uint64(i), 10), func(t *testing.T) { 105 require := require.New(t) 106 ctrl := gomock.NewController(t) 107 defer ctrl.Finish() 108 mockDao := mock_blockdao.NewMockBlockDAO(ctrl) 109 checker := NewBlockIndexerChecker(mockDao) 110 indexer := mock_blockdao.NewMockBlockIndexerWithStart(ctrl) 111 112 putBlocks := make([]*block.Block, 0) 113 mockDao.EXPECT().Height().Return(c.daoHeight, nil).Times(1) 114 mockDao.EXPECT().GetBlockByHeight(gomock.Any()).DoAndReturn(func(arg0 uint64) (*block.Block, error) { 115 pb := &iotextypes.BlockHeader{ 116 Core: &iotextypes.BlockHeaderCore{ 117 Height: arg0, 118 Timestamp: timestamppb.Now(), 119 }, 120 ProducerPubkey: identityset.PrivateKey(1).PublicKey().Bytes(), 121 } 122 blk := &block.Block{} 123 err := blk.LoadFromBlockHeaderProto(pb) 124 return blk, err 125 }).AnyTimes() 126 mockDao.EXPECT().GetReceipts(gomock.Any()).Return(nil, nil).AnyTimes() 127 indexer.EXPECT().Height().Return(c.indexerTipHeight, nil).Times(1) 128 indexer.EXPECT().StartHeight().Return(c.indexerStartHeight).AnyTimes() 129 indexer.EXPECT().PutBlock(gomock.Any(), gomock.Any()).DoAndReturn(func(arg0 context.Context, arg1 *block.Block) error { 130 putBlocks = append(putBlocks, arg1) 131 return nil 132 }).AnyTimes() 133 134 ctx := protocol.WithBlockchainCtx(context.Background(), protocol.BlockchainCtx{}) 135 ctx = genesis.WithGenesisContext(ctx, genesis.Default) 136 err := checker.CheckIndexer(ctx, indexer, 0, func(u uint64) {}) 137 require.Equalf(c.noErr, err == nil, "error: %v", err) 138 require.Len(putBlocks, len(c.expectedPutBlocks)) 139 for k, h := range c.expectedPutBlocks { 140 require.Equal(h, putBlocks[k].Height()) 141 } 142 }) 143 } 144 }