github.com/defanghe/fabric@v2.1.1+incompatible/gossip/election/adapter_test.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package election 8 9 import ( 10 "bytes" 11 "fmt" 12 "strings" 13 "sync" 14 "testing" 15 "time" 16 17 proto "github.com/hyperledger/fabric-protos-go/gossip" 18 "github.com/hyperledger/fabric/common/metrics/disabled" 19 "github.com/hyperledger/fabric/gossip/common" 20 "github.com/hyperledger/fabric/gossip/discovery" 21 "github.com/hyperledger/fabric/gossip/metrics" 22 "github.com/hyperledger/fabric/gossip/metrics/mocks" 23 "github.com/hyperledger/fabric/gossip/protoext" 24 "github.com/hyperledger/fabric/gossip/util" 25 "github.com/stretchr/testify/assert" 26 ) 27 28 func init() { 29 util.SetupTestLogging() 30 } 31 32 func TestNewAdapter(t *testing.T) { 33 selfNetworkMember := &discovery.NetworkMember{ 34 Endpoint: "p0", 35 Metadata: []byte{}, 36 PKIid: []byte{byte(0)}, 37 } 38 mockGossip := newGossip("peer0", selfNetworkMember, nil) 39 40 peersCluster := newClusterOfPeers("0") 41 peersCluster.addPeer("peer0", mockGossip) 42 43 NewAdapter(mockGossip, selfNetworkMember.PKIid, []byte("channel0"), 44 metrics.NewGossipMetrics(&disabled.Provider{}).ElectionMetrics) 45 } 46 47 func TestAdapterImpl_CreateMessage(t *testing.T) { 48 selfNetworkMember := &discovery.NetworkMember{ 49 Endpoint: "p0", 50 Metadata: []byte{}, 51 PKIid: []byte{byte(0)}, 52 } 53 mockGossip := newGossip("peer0", selfNetworkMember, nil) 54 55 adapter := NewAdapter(mockGossip, selfNetworkMember.PKIid, []byte("channel0"), 56 metrics.NewGossipMetrics(&disabled.Provider{}).ElectionMetrics) 57 msg := adapter.CreateMessage(true) 58 59 if !protoext.IsLeadershipMsg(msg.(*msgImpl).msg) { 60 t.Error("Newly created message should be LeadershipMsg") 61 } 62 63 if !msg.IsDeclaration() { 64 t.Error("Newly created msg should be Declaration msg") 65 } 66 67 msg = adapter.CreateMessage(false) 68 69 if !protoext.IsLeadershipMsg(msg.(*msgImpl).msg) { 70 t.Error("Newly created message should be LeadershipMsg") 71 } 72 73 if !msg.IsProposal() || msg.IsDeclaration() { 74 t.Error("Newly created msg should be Proposal msg") 75 } 76 } 77 78 func TestAdapterImpl_Peers(t *testing.T) { 79 peersOrgA := map[string]struct{}{ 80 "Peer0": {}, 81 "Peer1": {}, 82 "Peer2": {}, 83 "Peer3": {}, 84 "Peer4": {}, 85 "Peer5": {}, 86 } 87 peersOrgB := map[string]struct{}{ 88 "Peer6": {}, 89 "Peer7": {}, 90 "Peer8": {}, 91 } 92 93 pki2org := make(map[string]string) 94 for id := range peersOrgA { 95 pki2org[id] = "A" 96 } 97 for id := range peersOrgB { 98 pki2org[id] = "B" 99 } 100 101 _, adapters := createCluster(pki2org, 0, 1, 2, 3, 4, 5, 6, 7, 8) 102 103 for id, adapter := range adapters { 104 var myPeersOrg map[string]struct{} 105 if pki2org[id] == "A" { 106 myPeersOrg = peersOrgA 107 } else { 108 myPeersOrg = peersOrgB 109 } 110 peers := adapter.Peers() 111 if len(peers) != len(myPeersOrg) { 112 t.Errorf("Should return %d peers, not %d", len(myPeersOrg), len(peers)) 113 } 114 115 for _, peer := range peers { 116 if _, exist := myPeersOrg[peer.(*peerImpl).member.Endpoint]; !exist { 117 t.Errorf("Peer %s PKID not found", peer.(*peerImpl).member.Endpoint) 118 } 119 } 120 } 121 122 } 123 124 func TestAdapterImpl_Stop(t *testing.T) { 125 _, adapters := createCluster(nil, 0, 1, 2, 3, 4, 5) 126 127 for _, adapter := range adapters { 128 adapter.Accept() 129 } 130 131 for _, adapter := range adapters { 132 adapter.Stop() 133 } 134 } 135 136 func TestAdapterImpl_Gossip(t *testing.T) { 137 _, adapters := createCluster(nil, 0, 1, 2) 138 139 channels := make(map[string]<-chan Msg) 140 141 for peerID, adapter := range adapters { 142 channels[peerID] = adapter.Accept() 143 } 144 145 sender := adapters[fmt.Sprintf("Peer%d", 0)] 146 147 sender.Gossip(sender.CreateMessage(true)) 148 149 totalMsg := 0 150 151 timer := time.After(time.Duration(1) * time.Second) 152 153 for { 154 select { 155 case <-timer: 156 if totalMsg != 2 { 157 t.Error("Not all messages accepted") 158 t.FailNow() 159 } else { 160 return 161 } 162 case msg := <-channels[fmt.Sprintf("Peer%d", 1)]: 163 if !msg.IsDeclaration() { 164 t.Error("Msg should be declaration") 165 } else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) { 166 t.Error("Msg Sender is wrong") 167 } else { 168 totalMsg++ 169 } 170 case msg := <-channels[fmt.Sprintf("Peer%d", 2)]: 171 if !msg.IsDeclaration() { 172 t.Error("Msg should be declaration") 173 } else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) { 174 t.Error("Msg Sender is wrong") 175 } else { 176 totalMsg++ 177 } 178 } 179 180 } 181 182 } 183 184 type mockAcceptor struct { 185 ch chan *proto.GossipMessage 186 acceptor common.MessageAcceptor 187 } 188 189 type peerMockGossip struct { 190 cluster *clusterOfPeers 191 member *discovery.NetworkMember 192 acceptors []*mockAcceptor 193 acceptorLock *sync.RWMutex 194 clusterLock *sync.RWMutex 195 id string 196 pki2org map[string]string 197 } 198 199 func (g *peerMockGossip) PeersOfChannel(channel common.ChannelID) []discovery.NetworkMember { 200 g.clusterLock.RLock() 201 if g.cluster == nil { 202 g.clusterLock.RUnlock() 203 return []discovery.NetworkMember{*g.member} 204 } 205 peerLock := g.cluster.peersLock 206 g.clusterLock.RUnlock() 207 208 peerLock.RLock() 209 res := make([]discovery.NetworkMember, 0) 210 g.clusterLock.RLock() 211 for _, val := range g.cluster.peersGossip { 212 res = append(res, *val.member) 213 } 214 g.clusterLock.RUnlock() 215 peerLock.RUnlock() 216 return res 217 } 218 219 func (g *peerMockGossip) Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan protoext.ReceivedMessage) { 220 ch := make(chan *proto.GossipMessage, 100) 221 g.acceptorLock.Lock() 222 g.acceptors = append(g.acceptors, &mockAcceptor{ 223 ch: ch, 224 acceptor: acceptor, 225 }) 226 g.acceptorLock.Unlock() 227 return ch, nil 228 } 229 230 func (g *peerMockGossip) Gossip(msg *proto.GossipMessage) { 231 g.clusterLock.RLock() 232 if g.cluster == nil { 233 g.clusterLock.RUnlock() 234 return 235 } 236 peersLock := g.cluster.peersLock 237 g.clusterLock.RUnlock() 238 239 peersLock.RLock() 240 g.clusterLock.RLock() 241 for _, val := range g.cluster.peersGossip { 242 if strings.Compare(val.id, g.id) != 0 { 243 val.putToAcceptors(msg) 244 } 245 } 246 g.clusterLock.RUnlock() 247 peersLock.RUnlock() 248 249 } 250 251 func (g *peerMockGossip) putToAcceptors(msg *proto.GossipMessage) { 252 g.acceptorLock.RLock() 253 for _, acceptor := range g.acceptors { 254 if acceptor.acceptor(msg) { 255 if len(acceptor.ch) < 10 { 256 acceptor.ch <- msg 257 } 258 } 259 } 260 g.acceptorLock.RUnlock() 261 262 } 263 264 func (g *peerMockGossip) IsInMyOrg(member discovery.NetworkMember) bool { 265 var myOrg, memberOrg string 266 var exists bool 267 if myOrg, exists = g.pki2org[g.id]; !exists { 268 return false 269 } 270 if memberOrg, exists = g.pki2org[member.Endpoint]; !exists { 271 return false 272 } 273 return myOrg == memberOrg 274 } 275 276 func newGossip(peerID string, member *discovery.NetworkMember, pki2org map[string]string) *peerMockGossip { 277 return &peerMockGossip{ 278 id: peerID, 279 member: member, 280 acceptorLock: &sync.RWMutex{}, 281 clusterLock: &sync.RWMutex{}, 282 acceptors: make([]*mockAcceptor, 0), 283 pki2org: pki2org, 284 } 285 } 286 287 type clusterOfPeers struct { 288 peersGossip map[string]*peerMockGossip 289 peersLock *sync.RWMutex 290 id string 291 } 292 293 func (cop *clusterOfPeers) addPeer(peerID string, gossip *peerMockGossip) { 294 cop.peersLock.Lock() 295 cop.peersGossip[peerID] = gossip 296 gossip.clusterLock.Lock() 297 gossip.cluster = cop 298 gossip.clusterLock.Unlock() 299 cop.peersLock.Unlock() 300 301 } 302 303 func newClusterOfPeers(id string) *clusterOfPeers { 304 return &clusterOfPeers{ 305 id: id, 306 peersGossip: make(map[string]*peerMockGossip), 307 peersLock: &sync.RWMutex{}, 308 } 309 310 } 311 312 func createCluster(pki2org map[string]string, peers ...int) (*clusterOfPeers, map[string]*adapterImpl) { 313 adapters := make(map[string]*adapterImpl) 314 cluster := newClusterOfPeers("0") 315 for _, peer := range peers { 316 peerEndpoint := fmt.Sprintf("Peer%d", peer) 317 peerPKID := []byte{byte(peer)} 318 peerMember := &discovery.NetworkMember{ 319 Metadata: []byte{}, 320 Endpoint: peerEndpoint, 321 PKIid: peerPKID, 322 } 323 324 mockGossip := newGossip(peerEndpoint, peerMember, pki2org) 325 adapter := NewAdapter(mockGossip, peerMember.PKIid, []byte("channel0"), 326 metrics.NewGossipMetrics(&disabled.Provider{}).ElectionMetrics) 327 adapters[peerEndpoint] = adapter.(*adapterImpl) 328 cluster.addPeer(peerEndpoint, mockGossip) 329 } 330 331 return cluster, adapters 332 } 333 334 func TestReportMetrics(t *testing.T) { 335 336 testMetricProvider := mocks.TestUtilConstructMetricProvider() 337 electionMetrics := metrics.NewGossipMetrics(testMetricProvider.FakeProvider).ElectionMetrics 338 339 mockGossip := newGossip("", &discovery.NetworkMember{}, nil) 340 adapter := NewAdapter(mockGossip, nil, []byte("channel0"), electionMetrics) 341 342 adapter.ReportMetrics(true) 343 344 assert.Equal(t, 345 []string{"channel", "channel0"}, 346 testMetricProvider.FakeDeclarationGauge.WithArgsForCall(0), 347 ) 348 assert.EqualValues(t, 349 1, 350 testMetricProvider.FakeDeclarationGauge.SetArgsForCall(0), 351 ) 352 353 adapter.ReportMetrics(false) 354 355 assert.Equal(t, 356 []string{"channel", "channel0"}, 357 testMetricProvider.FakeDeclarationGauge.WithArgsForCall(1), 358 ) 359 assert.EqualValues(t, 360 0, 361 testMetricProvider.FakeDeclarationGauge.SetArgsForCall(1), 362 ) 363 364 }