github.com/aergoio/aergo@v1.3.1/p2p/blkreceiver_test.go (about) 1 /* 2 * @file 3 * @copyright defined in aergo/LICENSE.txt 4 */ 5 6 package p2p 7 8 import ( 9 "github.com/aergoio/aergo/chain" 10 "github.com/aergoio/aergo/p2p/p2pcommon" 11 "testing" 12 "time" 13 14 "github.com/aergoio/aergo/message" 15 "github.com/aergoio/aergo/p2p/p2pmock" 16 "github.com/aergoio/aergo/types" 17 "github.com/golang/mock/gomock" 18 "github.com/stretchr/testify/assert" 19 ) 20 21 func TestBlocksChunkReceiver_StartGet(t *testing.T) { 22 ctrl := gomock.NewController(t) 23 defer ctrl.Finish() 24 25 inputHashes := make([]message.BlockHash, len(sampleBlks)) 26 for i, hash := range sampleBlks { 27 inputHashes[i] = hash 28 } 29 tests := []struct { 30 name string 31 input []message.BlockHash 32 ttl time.Duration 33 }{ 34 {"TSimple", inputHashes, time.Millisecond * 10}, 35 // TODO: test cases 36 } 37 for _, test := range tests { 38 t.Run(test.name, func(t *testing.T) { 39 //mockContext := new(mockContext) 40 mockActor := p2pmock.NewMockActorService(ctrl) 41 //mockActor.On("SendRequest", message.P2PSvc, mock.AnythingOfType("*types.GetBlock")) 42 //mockActor.On("TellRequest", message.SyncerSvc, mock.AnythingOfType("*types.GetBlock")) 43 mockMF := p2pmock.NewMockMoFactory(ctrl) 44 mockMo := createDummyMo(ctrl) 45 mockMF.EXPECT().NewMsgBlockRequestOrder(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMo) 46 mockPeer := p2pmock.NewMockRemotePeer(ctrl) 47 mockPeer.EXPECT().MF().Return(mockMF) 48 mockPeer.EXPECT().SendMessage(mockMo).Times(1) 49 50 expire := time.Now().Add(test.ttl) 51 br := NewBlockReceiver(mockActor, mockPeer, 0, test.input, test.ttl) 52 53 br.StartGet() 54 55 assert.Equal(t, len(test.input), len(br.blockHashes)) 56 assert.False(t, expire.After(br.timeout)) 57 }) 58 } 59 } 60 61 func TestBlocksChunkReceiver_ReceiveResp(t *testing.T) { 62 ctrl := gomock.NewController(t) 63 defer ctrl.Finish() 64 chain.Init(1<<20 , "", false, 1, 1 ) 65 66 seqNo := uint64(8723) 67 blkNo := uint64(100) 68 prevHash := dummyBlockHash 69 inputHashes := make([]message.BlockHash, len(sampleBlks)) 70 inputBlocks := make([]*types.Block, len(sampleBlks)) 71 for i, hash := range sampleBlks { 72 inputHashes[i] = hash 73 inputBlocks[i] = &types.Block{Hash: hash, Header: &types.BlockHeader{PrevBlockHash: prevHash, BlockNo: blkNo}} 74 blkNo++ 75 prevHash = hash 76 } 77 tests := []struct { 78 name string 79 input []message.BlockHash 80 blkInput [][]*types.Block 81 82 // to verify 83 consumed int 84 respError bool 85 }{ 86 {"TSingleResp", inputHashes, [][]*types.Block{inputBlocks}, 1, false}, 87 {"TMultiResp", inputHashes, [][]*types.Block{inputBlocks[:1], inputBlocks[1:3], inputBlocks[3:]}, 1, false}, 88 // Fail1 remote err 89 {"TRemoteFail", inputHashes, [][]*types.Block{inputBlocks[:0]}, 1, true}, 90 // server didn't sent last parts. and it is very similar to timeout 91 //{"TNotComplete", inputHashes, time.Minute,0,[][]*types.Block{inputBlocks[:2]},1,0, false}, 92 // Fail2 missing some blocks in the middle 93 {"TMissingBlk", inputHashes, [][]*types.Block{inputBlocks[:1],inputBlocks[2:3],inputBlocks[3:]},0, true}, 94 // Fail2-1 missing some blocks in last 95 {"TMissingBlkLast", inputHashes, [][]*types.Block{inputBlocks[:1],inputBlocks[1:2],inputBlocks[3:]},1, true}, 96 // Fail3 unexpected block 97 {"TDupBlock", inputHashes, [][]*types.Block{inputBlocks[:2],inputBlocks[1:3],inputBlocks[3:]},0, true}, 98 {"TTooManyBlks", inputHashes[:4], [][]*types.Block{inputBlocks[:1],inputBlocks[1:3],inputBlocks[3:]},1, true}, 99 {"TTooManyBlksMiddle", inputHashes[:2], [][]*types.Block{inputBlocks[:1],inputBlocks[1:3],inputBlocks[3:]},0, true}, 100 } 101 for _, test := range tests { 102 t.Run(test.name, func(t *testing.T) { 103 //mockContext := new(mockContext) 104 mockActor := p2pmock.NewMockActorService(ctrl) 105 mockActor.EXPECT().TellRequest(message.SyncerSvc, gomock.Any()). 106 DoAndReturn(func(a string, arg *message.GetBlockChunksRsp) { 107 if !((arg.Err != nil) == test.respError) { 108 t.Fatalf("Wrong error (have %v)\n", arg.Err) 109 } 110 if arg.Seq != seqNo { 111 t.Fatalf("Wrong seqNo %d, want %d)\n", arg.Seq, seqNo) 112 } 113 }).Times(1) 114 115 mockMF := p2pmock.NewMockMoFactory(ctrl) 116 mockMo := createDummyMo(ctrl) 117 mockMF.EXPECT().NewMsgBlockRequestOrder(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMo) 118 mockPeer := p2pmock.NewMockRemotePeer(ctrl) 119 mockPeer.EXPECT().ID().Return(dummyPeerID).AnyTimes() 120 mockPeer.EXPECT().MF().Return(mockMF) 121 mockPeer.EXPECT().SendMessage(gomock.Any()).Times(1) 122 if test.consumed > 0 { 123 mockPeer.EXPECT().ConsumeRequest(gomock.Any()).Times(test.consumed) 124 } 125 126 //expire := time.Now().Add(test.ttl) 127 br := NewBlockReceiver(mockActor, mockPeer, seqNo, test.input, time.Minute<<2) 128 br.StartGet() 129 130 msg := p2pcommon.NewSimpleMsgVal(p2pcommon.GetBlocksResponse, sampleMsgID) 131 for i, blks := range test.blkInput { 132 body := &types.GetBlockResponse{Blocks: blks, HasNext: i < len(test.blkInput)-1} 133 br.ReceiveResp(msg, body) 134 if br.status == receiverStatusFinished { 135 break 136 } 137 } 138 139 }) 140 } 141 } 142 143 144 func TestBlocksChunkReceiver_ReceiveRespTimeout(t *testing.T) { 145 ctrl := gomock.NewController(t) 146 defer ctrl.Finish() 147 chain.Init(1<<20 , "", false, 1, 1 ) 148 149 seqNo := uint64(8723) 150 blkNo := uint64(100) 151 prevHash := dummyBlockHash 152 inputHashes := make([]message.BlockHash, len(sampleBlks)) 153 inputBlocks := make([]*types.Block, len(sampleBlks)) 154 for i, hash := range sampleBlks { 155 inputHashes[i] = hash 156 inputBlocks[i] = &types.Block{Hash: hash, Header: &types.BlockHeader{PrevBlockHash: prevHash, BlockNo: blkNo}} 157 blkNo++ 158 prevHash = hash 159 } 160 tests := []struct { 161 name string 162 input []message.BlockHash 163 ttl time.Duration 164 blkInterval time.Duration 165 blkInput [][]*types.Block 166 167 // to verify 168 consumed int 169 sentResp int 170 }{ 171 // Fail4 response sent after timeout 172 {"TBefore", inputHashes, time.Millisecond * 40, time.Millisecond * 100, [][]*types.Block{inputBlocks[:1], inputBlocks[1:3], inputBlocks[3:]}, 1, 0}, 173 } 174 for _, test := range tests { 175 t.Run(test.name, func(t *testing.T) { 176 //mockContext := new(mockContext) 177 mockActor := p2pmock.NewMockActorService(ctrl) 178 if test.sentResp > 0 { 179 mockActor.EXPECT().TellRequest(message.SyncerSvc, gomock.Any()). 180 DoAndReturn(func(a string, arg *message.GetBlockChunksRsp) { 181 // timeout should resp with timeout error or not send response 182 if arg.Err == nil { 183 t.Fatalf("Wrong error (have %v)\n", arg.Err) 184 } 185 if arg.Seq != seqNo { 186 t.Fatalf("Wrong seqNo %d, want %d)\n", arg.Seq, seqNo) 187 } 188 }).Times(test.sentResp) 189 } 190 191 mockMF := p2pmock.NewMockMoFactory(ctrl) 192 mockMo := createDummyMo(ctrl) 193 mockMF.EXPECT().NewMsgBlockRequestOrder(gomock.Any(), gomock.Any(), gomock.Any()).Return(mockMo) 194 mockPeer := p2pmock.NewMockRemotePeer(ctrl) 195 mockPeer.EXPECT().ID().Return(dummyPeerID).AnyTimes() 196 mockPeer.EXPECT().MF().Return(mockMF) 197 mockPeer.EXPECT().SendMessage(gomock.Any()).Times(1) 198 if test.consumed > 0 { 199 mockPeer.EXPECT().ConsumeRequest(gomock.Any()).MinTimes(test.consumed) 200 } 201 202 //expire := time.Now().Add(test.ttl) 203 br := NewBlockReceiver(mockActor, mockPeer, seqNo, test.input, test.ttl) 204 br.StartGet() 205 206 msg := p2pcommon.NewSimpleMsgVal(p2pcommon.GetBlocksResponse, sampleMsgID) 207 for i, blks := range test.blkInput { 208 time.Sleep(test.blkInterval) 209 210 body := &types.GetBlockResponse{Blocks: blks, HasNext: i < len(test.blkInput)-1} 211 br.ReceiveResp(msg, body) 212 if br.status == receiverStatusFinished { 213 break 214 } 215 } 216 217 }) 218 } 219 }