github.com/aergoio/aergo@v1.3.1/p2p/subproto/getblock_test.go (about)

     1  /*
     2   * @file
     3   * @copyright defined in aergo/LICENSE.txt
     4   */
     5  
     6  package subproto
     7  
     8  import (
     9  	"github.com/aergoio/aergo-lib/log"
    10  	"github.com/aergoio/aergo/internal/enc"
    11  	"github.com/aergoio/aergo/message"
    12  	"github.com/aergoio/aergo/p2p/p2pcommon"
    13  	"github.com/aergoio/aergo/p2p/p2pmock"
    14  	"github.com/aergoio/aergo/types"
    15  	"github.com/golang/mock/gomock"
    16  	"github.com/stretchr/testify/assert"
    17  	"testing"
    18  	"time"
    19  )
    20  
    21  func TestBlockRequestHandler_handle(t *testing.T) {
    22  	ctrl := gomock.NewController(t)
    23  	defer ctrl.Finish()
    24  
    25  	logger := log.NewLogger("test.subproto")
    26  
    27  	var dummyPeerID, _ = types.IDB58Decode("16Uiu2HAmN5YU8V2LnTy9neuuJCLNsxLnd5xVSRZqkjvZUHS3mLoD")
    28  
    29  	bigHash := make([]byte, 2*1024*1024)
    30  	//validSmallBlockRsp := &message.GetBlockRsp{Block:&types.Block{Hash:make([]byte,40)},Err:nil}
    31  	validBlock := &types.Block{Hash: bigHash}
    32  	//validBigBlockRsp := message.GetBlockRsp{Block:validBlock,Err:nil}
    33  	//notExistBlockRsp := message.GetBlockRsp{Block:nil,Err:nil}
    34  	//dummyMO := p2pmock.NewMockMsgOrder(ctrl)
    35  	tests := []struct {
    36  		name              string
    37  		hashCnt           int
    38  		validCallCount    int
    39  		expectedSendCount int
    40  		succResult        bool
    41  	}{
    42  		{"TSingle", 1, 1, 1, true},
    43  		// not found return err result (ResultStatus_NOT_FOUND)
    44  		{"TNotFounds", 10, 0, 1, false},
    45  		{"TFound10", 100, 10, 4, false},
    46  		{"TFoundAll", 20, 100, 7, true},
    47  		// TODO: test cases
    48  	}
    49  	for _, test := range tests {
    50  		t.Run(test.name, func(t *testing.T) {
    51  			mockPM := p2pmock.NewMockPeerManager(ctrl)
    52  			mockPeer := p2pmock.NewMockRemotePeer(ctrl)
    53  			mockActor := p2pmock.NewMockActorService(ctrl)
    54  			// mockery Mock can't handle big byte slice sell. it takes to much time to do. so use dummy stub instead and give up verify code.
    55  			mockMF := &testDoubleMOFactory{}
    56  			mockPeer.EXPECT().MF().Return(mockMF).AnyTimes()
    57  			mockPeer.EXPECT().ID().Return(dummyPeerID).AnyTimes()
    58  			mockPeer.EXPECT().Name().Return("16..aadecf@1").AnyTimes()
    59  			mockPeer.EXPECT().SendAndWaitMessage(gomock.Any(), gomock.AssignableToTypeOf(time.Duration(0))).Return(nil).Times(test.expectedSendCount)
    60  
    61  			callReqCount := 0
    62  			mockCA := p2pmock.NewMockChainAccessor(ctrl)
    63  			mockActor.EXPECT().GetChainAccessor().Return(mockCA).AnyTimes()
    64  			mockCA.EXPECT().GetBlock(gomock.Any()).DoAndReturn(func(blockHash []byte) (*types.Block, error) {
    65  				callReqCount++
    66  				if callReqCount <= test.validCallCount {
    67  					return validBlock, nil
    68  				}
    69  				return nil, nil
    70  			}).MinTimes(1)
    71  
    72  			h := NewBlockReqHandler(mockPM, mockPeer, logger, mockActor)
    73  			dummyMsg := &testMessage{subProtocol: p2pcommon.GetBlocksRequest,id: p2pcommon.NewMsgID()}
    74  			msgBody := &types.GetBlockRequest{Hashes: make([][]byte, test.hashCnt)}
    75  			//h.Handle(dummyMsg, msgBody)
    76  			h.handleBlkReq(dummyMsg, msgBody)
    77  
    78  			// wait to work finished
    79  			<-h.w
    80  
    81  			mockMF.mutex.Lock()
    82  			lastStatus := mockMF.lastStatus
    83  			mockMF.mutex.Unlock()
    84  
    85  			assert.Equal(t, test.succResult, lastStatus== types.ResultStatus_OK)
    86  		})
    87  	}
    88  }
    89  
    90  func TestBlockResponseHandler_handle(t *testing.T) {
    91  	ctrl := gomock.NewController(t)
    92  	defer ctrl.Finish()
    93  
    94  	logger := log.NewLogger("test.subproto")
    95  	var dummyPeerID, _ = types.IDB58Decode("16Uiu2HAmN5YU8V2LnTy9neuuJCLNsxLnd5xVSRZqkjvZUHS3mLoD")
    96  	dummyBlockHash, _ := enc.ToBytes("v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6")
    97  	var sampleBlksB58 = []string{
    98  		"v6zbuQ4aVSdbTwQhaiZGp5pcL5uL55X3kt2wfxor5W6",
    99  		"2VEPg4MqJUoaS3EhZ6WWSAUuFSuD4oSJ645kSQsGV7H9",
   100  		"AtzTZ2CZS45F1276RpTdLfYu2DLgRcd9HL3aLqDT1qte",
   101  		"2n9QWNDoUvML756X7xdHWCFLZrM4CQEtnVH2RzG5FYAw",
   102  		"6cy7U7XKYtDTMnF3jNkcJvJN5Rn85771NSKjc5Tfo2DM",
   103  		"3bmB8D37XZr4DNPs64NiGRa2Vw3i8VEgEy6Xc2XBmRXC",
   104  	}
   105  	var sampleBlks [][]byte
   106  	var sampleBlksHashes []types.BlockID
   107  
   108  	sampleBlks = make([][]byte, len(sampleBlksB58))
   109  	sampleBlksHashes = make([]types.BlockID, len(sampleBlksB58))
   110  	for i, hashb58 := range sampleBlksB58 {
   111  		hash, _ := enc.ToBytes(hashb58)
   112  		sampleBlks[i] = hash
   113  		copy(sampleBlksHashes[i][:], hash)
   114  	}
   115  
   116  	blkNo := uint64(100)
   117  	prevHash := dummyBlockHash
   118  	inputHashes := make([]message.BlockHash, len(sampleBlks))
   119  	inputBlocks := make([]*types.Block, len(sampleBlks))
   120  	for i, hash := range sampleBlks {
   121  		inputHashes[i] = hash
   122  		inputBlocks[i] = &types.Block{Hash: hash, Header: &types.BlockHeader{PrevBlockHash: prevHash, BlockNo: blkNo}}
   123  		blkNo++
   124  		prevHash = hash
   125  	}
   126  
   127  	tests := []struct {
   128  		name string
   129  
   130  		receiver    p2pcommon.ResponseReceiver
   131  		wantConsume int
   132  		wantCallSM  int
   133  	}{
   134  		// 1. not exist receiver and consumed message
   135  		//{"Tnothing",nil, true},
   136  		// 2. exist receiver and consume successfully
   137  		{"TexistAndConsume", func(msg p2pcommon.Message, body p2pcommon.MessageBody) bool {
   138  			return true
   139  		}, 0, 0},
   140  		// 2. exist receiver but not consumed
   141  		{"TExistWrong", func (msg p2pcommon.Message, msgBody p2pcommon.MessageBody) bool {
   142  			return false
   143  		}, 1, 1},
   144  		// TODO: test cases
   145  	}
   146  	for _, test := range tests {
   147  		t.Run(test.name, func(t *testing.T) {
   148  			mockPM := p2pmock.NewMockPeerManager(ctrl)
   149  			mockPeer := p2pmock.NewMockRemotePeer(ctrl)
   150  			mockPeer.EXPECT().ID().Return(dummyPeerID).AnyTimes()
   151  			mockPeer.EXPECT().ConsumeRequest(gomock.AssignableToTypeOf(p2pcommon.MsgID{})).Times(test.wantConsume)
   152  			mockActor := p2pmock.NewMockActorService(ctrl)
   153  			mockSM := p2pmock.NewMockSyncManager(ctrl)
   154  			mockSM.EXPECT().HandleGetBlockResponse(mockPeer, gomock.Any(), gomock.AssignableToTypeOf(&types.GetBlockResponse{})).Times(test.wantCallSM)
   155  
   156  			mockPeer.EXPECT().GetReceiver(gomock.AssignableToTypeOf(p2pcommon.MsgID{})).Return(test.receiver)
   157  			msg := &testMessage{subProtocol: p2pcommon.GetBlocksResponse, id: p2pcommon.NewMsgID()}
   158  			body := &types.GetBlockResponse{Blocks: make([]*types.Block, 2)}
   159  			h := NewBlockRespHandler(mockPM, mockPeer, logger, mockActor, mockSM)
   160  			h.Handle(msg, body)
   161  		})
   162  	}
   163  }