github.com/aergoio/aergo@v1.3.1/p2p/rolemanager_test.go (about) 1 /* 2 * @file 3 * @copyright defined in aergo/LICENSE.txt 4 */ 5 6 package p2p 7 8 import ( 9 "fmt" 10 "reflect" 11 "testing" 12 13 "github.com/aergoio/aergo/message" 14 "github.com/aergoio/aergo/p2p/p2pcommon" 15 "github.com/aergoio/aergo/p2p/p2pmock" 16 "github.com/aergoio/aergo/types" 17 "github.com/golang/mock/gomock" 18 ) 19 20 func TestRaftRoleManager_updateBP(t *testing.T) { 21 ctrl := gomock.NewController(t) 22 defer ctrl.Finish() 23 24 p1, p2, p3 := dummyPeerID, dummyPeerID2, dummyPeerID3 25 26 tests := []struct { 27 name string 28 preset []types.PeerID 29 args message.RaftClusterEvent 30 31 wantCnt int 32 wantExist []types.PeerID 33 wantNot []types.PeerID 34 }{ 35 {"TAdd", nil, (&EB{}).A(p1, p2).C(), 2, []types.PeerID{p1, p2}, nil}, 36 {"TRm", []types.PeerID{p1, p2, p3}, (&EB{}).R(p3, p2).C(), 1, []types.PeerID{p1}, []types.PeerID{p2, p3}}, 37 {"TOverlap", []types.PeerID{p3}, (&EB{}).A(p1, p2).R(p3, p2).C(), 2, []types.PeerID{p1, p2}, []types.PeerID{p3}}, 38 {"TEmpty", nil, (&EB{}).C(), 0, []types.PeerID{}, nil}, 39 } 40 for _, tt := range tests { 41 t.Run(tt.name, func(t *testing.T) { 42 presetIDs := make(map[types.PeerID]bool) 43 for _, id := range tt.preset { 44 presetIDs[id] = true 45 } 46 mockPM := p2pmock.NewMockPeerManager(ctrl) 47 mockPM.EXPECT().GetPeer(gomock.Any()).Return(nil, false).AnyTimes() 48 mockPM.EXPECT().UpdatePeerRole(gomock.Any()).AnyTimes() 49 50 p2ps := &P2P{pm: mockPM} 51 rm := &RaftRoleManager{ 52 p2ps: p2ps, 53 logger: logger, 54 raftBP: presetIDs, 55 } 56 rm.UpdateBP(tt.args.BPAdded, tt.args.BPRemoved) 57 58 if len(rm.raftBP) != tt.wantCnt { 59 t.Errorf("P2P.UpdateBP() len = %v, want %v", len(rm.raftBP), tt.wantCnt) 60 } 61 for _, id := range tt.wantExist { 62 if _, found := rm.raftBP[id]; !found { 63 t.Errorf("P2P.UpdateBP() not exist %v, want exist ", id) 64 } else { 65 if rm.GetRole(id) != p2pcommon.BlockProducer { 66 t.Errorf("P2P.GetRole(%v) false, want true", id) 67 } 68 } 69 } 70 for _, id := range tt.wantNot { 71 if _, found := rm.raftBP[id]; found { 72 t.Errorf("P2P.UpdateBP() exist %v, want not ", id) 73 } 74 } 75 }) 76 } 77 } 78 79 type EB struct { 80 a, r []types.PeerID 81 } 82 83 func (e *EB) A(ids ...types.PeerID) *EB { 84 e.a = append(e.a, ids...) 85 return e 86 } 87 func (e *EB) R(ids ...types.PeerID) *EB { 88 e.r = append(e.r, ids...) 89 return e 90 } 91 func (e *EB) C() message.RaftClusterEvent { 92 return message.RaftClusterEvent{BPAdded: e.a, BPRemoved: e.r} 93 } 94 95 func TestRaftRoleManager_NotifyNewBlockMsg(t *testing.T) { 96 ctrl := gomock.NewController(t) 97 defer ctrl.Finish() 98 99 pids := []types.PeerID{dummyPeerID, dummyPeerID2, dummyPeerID3} 100 101 tests := []struct { 102 name string 103 104 argPeer []rs 105 106 wantSkipped int 107 wantSent int 108 }{ 109 {"TAllBP", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}}, 3, 0}, 110 {"TAllWat", []rs{{p2pcommon.Watcher, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 0, 3}, 111 {"TMIX", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 2, 1}, 112 {"TMIXStop", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.STOPPING}}, 3, 0}, 113 {"TMixStop2", []rs{{p2pcommon.BlockProducer, types.STOPPING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 2, 1}, 114 } 115 for _, tt := range tests { 116 t.Run(tt.name, func(t *testing.T) { 117 mockPM := p2pmock.NewMockPeerManager(ctrl) 118 mockPM.EXPECT().GetPeer(gomock.Any()).Return(nil, false).AnyTimes() 119 mockPM.EXPECT().UpdatePeerRole(gomock.Any()).AnyTimes() 120 121 mockMO := p2pmock.NewMockMsgOrder(ctrl) 122 123 rm := &RaftRoleManager{ 124 p2ps: nil, 125 logger: logger, 126 } 127 mockPeers := make([]p2pcommon.RemotePeer, 0, len(tt.argPeer)) 128 for i, ap := range tt.argPeer { 129 mpeer := p2pmock.NewMockRemotePeer(ctrl) 130 mpeer.EXPECT().ID().Return(pids[i]).AnyTimes() 131 mpeer.EXPECT().Role().Return(ap.r).AnyTimes() 132 mpeer.EXPECT().State().Return(ap.s).AnyTimes() 133 mpeer.EXPECT().SendMessage(gomock.Any()).MaxTimes(1) 134 135 mockPeers = append(mockPeers, mpeer) 136 } 137 gotSkipped, gotSent := rm.NotifyNewBlockMsg(mockMO, mockPeers) 138 if gotSkipped != tt.wantSkipped { 139 t.Errorf("RaftRoleManager.NotifyNewBlockMsg() gotSkipped = %v, want %v", gotSkipped, tt.wantSkipped) 140 } 141 if gotSent != tt.wantSent { 142 t.Errorf("RaftRoleManager.NotifyNewBlockMsg() gotSent = %v, want %v", gotSent, tt.wantSent) 143 } 144 }) 145 } 146 } 147 148 func TestDefaultRoleManager_updateBP(t *testing.T) { 149 ctrl := gomock.NewController(t) 150 defer ctrl.Finish() 151 152 p1, p2, p3 := dummyPeerID, dummyPeerID2, dummyPeerID3 153 154 tests := []struct { 155 name string 156 args message.RaftClusterEvent 157 158 wantCnt int 159 wantExist []types.PeerID 160 }{ 161 {"TAdd", (&EB{}).A(p1, p2).C(), 2, []types.PeerID{p1, p2}}, 162 {"TRemove", (&EB{}).R(p3, p2).C(), 2, []types.PeerID{p3, p2}}, 163 {"TOverlap", (&EB{}).A(p1, p2).R(p3, p2).C(), 3, []types.PeerID{p1, p2, p3}}, 164 {"TEmpty", (&EB{}).C(), 0, []types.PeerID{}}, 165 } 166 for _, tt := range tests { 167 t.Run(tt.name, func(t *testing.T) { 168 var sentIds []types.PeerID = nil 169 mockPM := p2pmock.NewMockPeerManager(ctrl) 170 mockPM.EXPECT().GetPeer(gomock.Any()).Return(nil, false).AnyTimes() 171 mockPM.EXPECT().UpdatePeerRole(gomock.Any()).Do(func(cs []p2pcommon.AttrModifier) { 172 for _, id := range cs { 173 sentIds = append(sentIds, id.ID) 174 } 175 }) 176 177 p2ps := &P2P{pm: mockPM} 178 rm := &DefaultRoleManager{ 179 p2ps: p2ps, 180 } 181 rm.UpdateBP(tt.args.BPAdded, tt.args.BPRemoved) 182 183 for _, id := range tt.wantExist { 184 found := false 185 for _, sent := range sentIds { 186 if id.Pretty() == sent.Pretty() { 187 found = true 188 break 189 } 190 } 191 if !found { 192 t.Errorf("DefaultRoleManager.UpdateBP() not exist %v, want exist ", id) 193 } 194 } 195 }) 196 } 197 } 198 199 func TestDefaultRoleManager_NotifyNewBlockMsg(t *testing.T) { 200 ctrl := gomock.NewController(t) 201 defer ctrl.Finish() 202 203 pids := []types.PeerID{dummyPeerID, dummyPeerID2, dummyPeerID3} 204 205 tests := []struct { 206 name string 207 208 argPeer []rs 209 210 wantSkipped int 211 wantSent int 212 }{ 213 {"TAllBP", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}}, 0, 3}, 214 {"TAllWat", []rs{{p2pcommon.Watcher, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 0, 3}, 215 {"TMix", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 0, 3}, 216 {"TMixStop", []rs{{p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.STOPPING}}, 1, 2}, 217 {"TMixStop2", []rs{{p2pcommon.BlockProducer, types.STOPPING}, {p2pcommon.BlockProducer, types.RUNNING}, {p2pcommon.Watcher, types.RUNNING}}, 1, 2}, 218 } 219 for _, tt := range tests { 220 t.Run(tt.name, func(t *testing.T) { 221 mockPM := p2pmock.NewMockPeerManager(ctrl) 222 mockPM.EXPECT().GetPeer(gomock.Any()).Return(nil, false).AnyTimes() 223 mockPM.EXPECT().UpdatePeerRole(gomock.Any()).AnyTimes() 224 225 mockMO := p2pmock.NewMockMsgOrder(ctrl) 226 227 rm := &DefaultRoleManager{ 228 p2ps: nil, 229 } 230 mockPeers := make([]p2pcommon.RemotePeer, 0, len(tt.argPeer)) 231 for i, ap := range tt.argPeer { 232 mPeer := p2pmock.NewMockRemotePeer(ctrl) 233 mPeer.EXPECT().ID().Return(pids[i]).AnyTimes() 234 mPeer.EXPECT().Role().Return(ap.r).AnyTimes() 235 mPeer.EXPECT().State().Return(ap.s).AnyTimes() 236 mPeer.EXPECT().SendMessage(gomock.Any()).MaxTimes(1) 237 238 mockPeers = append(mockPeers, mPeer) 239 } 240 gotSkipped, gotSent := rm.NotifyNewBlockMsg(mockMO, mockPeers) 241 if gotSkipped != tt.wantSkipped { 242 t.Errorf("RaftRoleManager.NotifyNewBlockMsg() gotSkipped = %v, want %v", gotSkipped, tt.wantSkipped) 243 } 244 if gotSent != tt.wantSent { 245 t.Errorf("RaftRoleManager.NotifyNewBlockMsg() gotSent = %v, want %v", gotSent, tt.wantSent) 246 } 247 }) 248 } 249 } 250 251 type rs struct { 252 r p2pcommon.PeerRole 253 s types.PeerState 254 } 255 256 func TestDefaultRoleManager_GetRole(t *testing.T) { 257 ctrl := gomock.NewController(t) 258 defer ctrl.Finish() 259 p1, p2, p3 := dummyPeerID, dummyPeerID2, dummyPeerID3 260 261 tests := []struct { 262 name string 263 264 presetIds []types.PeerID 265 pid types.PeerID 266 want p2pcommon.PeerRole 267 }{ 268 {"TBP", toPIDS(p1,p2), p1, p2pcommon.BlockProducer}, 269 {"TWat", toPIDS(p1,p2), p3, p2pcommon.Watcher}, 270 } 271 for i, tt := range tests { 272 t.Run(tt.name, func(t *testing.T) { 273 bps := make([]string,0,len(tt.presetIds)) 274 for _, id := range tt.presetIds { 275 bps = append(bps, fmt.Sprintf("{\"%d\":\"%s\"}",i,id.Pretty())) 276 } 277 dummyConsensus := &types.ConsensusInfo{Bps:bps} 278 mockCC := p2pmock.NewMockConsensusAccessor(ctrl) 279 mockCC.EXPECT().ConsensusInfo().Return(dummyConsensus) 280 p2ps := &P2P{consacc: mockCC} 281 rm := &DefaultRoleManager{ 282 p2ps: p2ps, 283 } 284 if got := rm.GetRole(tt.pid); !reflect.DeepEqual(got, tt.want) { 285 t.Errorf("DefaultRoleManager.GetRole() = %v, want %v", got, tt.want) 286 } 287 }) 288 } 289 } 290 291 func toPIDS(ids ...types.PeerID) []types.PeerID { 292 return ids 293 }