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  }