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 }