github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/gossip/election/adapter_test.go (about) 1 /* 2 Copyright hechain. 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 "github.com/hechain20/hechain/common/metrics/disabled" 18 "github.com/hechain20/hechain/gossip/common" 19 "github.com/hechain20/hechain/gossip/discovery" 20 "github.com/hechain20/hechain/gossip/metrics" 21 "github.com/hechain20/hechain/gossip/metrics/mocks" 22 "github.com/hechain20/hechain/gossip/protoext" 23 "github.com/hechain20/hechain/gossip/util" 24 proto "github.com/hyperledger/fabric-protos-go/gossip" 25 "github.com/stretchr/testify/require" 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 func TestAdapterImpl_Stop(t *testing.T) { 124 _, adapters := createCluster(nil, 0, 1, 2, 3, 4, 5) 125 126 for _, adapter := range adapters { 127 adapter.Accept() 128 } 129 130 for _, adapter := range adapters { 131 adapter.Stop() 132 } 133 } 134 135 func TestAdapterImpl_Gossip(t *testing.T) { 136 _, adapters := createCluster(nil, 0, 1, 2) 137 138 channels := make(map[string]<-chan Msg) 139 140 for peerID, adapter := range adapters { 141 channels[peerID] = adapter.Accept() 142 } 143 144 sender := adapters[fmt.Sprintf("Peer%d", 0)] 145 146 sender.Gossip(sender.CreateMessage(true)) 147 148 totalMsg := 0 149 150 timer := time.After(time.Duration(1) * time.Second) 151 152 for { 153 select { 154 case <-timer: 155 if totalMsg != 2 { 156 t.Error("Not all messages accepted") 157 t.FailNow() 158 } else { 159 return 160 } 161 case msg := <-channels[fmt.Sprintf("Peer%d", 1)]: 162 if !msg.IsDeclaration() { 163 t.Error("Msg should be declaration") 164 } else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) { 165 t.Error("Msg Sender is wrong") 166 } else { 167 totalMsg++ 168 } 169 case msg := <-channels[fmt.Sprintf("Peer%d", 2)]: 170 if !msg.IsDeclaration() { 171 t.Error("Msg should be declaration") 172 } else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) { 173 t.Error("Msg Sender is wrong") 174 } else { 175 totalMsg++ 176 } 177 } 178 } 179 } 180 181 type mockAcceptor struct { 182 ch chan *proto.GossipMessage 183 acceptor common.MessageAcceptor 184 } 185 186 type peerMockGossip struct { 187 cluster *clusterOfPeers 188 member *discovery.NetworkMember 189 acceptors []*mockAcceptor 190 acceptorLock *sync.RWMutex 191 clusterLock *sync.RWMutex 192 id string 193 pki2org map[string]string 194 } 195 196 func (g *peerMockGossip) PeersOfChannel(channel common.ChannelID) []discovery.NetworkMember { 197 g.clusterLock.RLock() 198 if g.cluster == nil { 199 g.clusterLock.RUnlock() 200 return []discovery.NetworkMember{*g.member} 201 } 202 peerLock := g.cluster.peersLock 203 g.clusterLock.RUnlock() 204 205 peerLock.RLock() 206 res := make([]discovery.NetworkMember, 0) 207 g.clusterLock.RLock() 208 for _, val := range g.cluster.peersGossip { 209 res = append(res, *val.member) 210 } 211 g.clusterLock.RUnlock() 212 peerLock.RUnlock() 213 return res 214 } 215 216 func (g *peerMockGossip) Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan protoext.ReceivedMessage) { 217 ch := make(chan *proto.GossipMessage, 100) 218 g.acceptorLock.Lock() 219 g.acceptors = append(g.acceptors, &mockAcceptor{ 220 ch: ch, 221 acceptor: acceptor, 222 }) 223 g.acceptorLock.Unlock() 224 return ch, nil 225 } 226 227 func (g *peerMockGossip) Gossip(msg *proto.GossipMessage) { 228 g.clusterLock.RLock() 229 if g.cluster == nil { 230 g.clusterLock.RUnlock() 231 return 232 } 233 peersLock := g.cluster.peersLock 234 g.clusterLock.RUnlock() 235 236 peersLock.RLock() 237 g.clusterLock.RLock() 238 for _, val := range g.cluster.peersGossip { 239 if strings.Compare(val.id, g.id) != 0 { 240 val.putToAcceptors(msg) 241 } 242 } 243 g.clusterLock.RUnlock() 244 peersLock.RUnlock() 245 } 246 247 func (g *peerMockGossip) putToAcceptors(msg *proto.GossipMessage) { 248 g.acceptorLock.RLock() 249 for _, acceptor := range g.acceptors { 250 if acceptor.acceptor(msg) { 251 if len(acceptor.ch) < 10 { 252 acceptor.ch <- msg 253 } 254 } 255 } 256 g.acceptorLock.RUnlock() 257 } 258 259 func (g *peerMockGossip) IsInMyOrg(member discovery.NetworkMember) bool { 260 var myOrg, memberOrg string 261 var exists bool 262 if myOrg, exists = g.pki2org[g.id]; !exists { 263 return false 264 } 265 if memberOrg, exists = g.pki2org[member.Endpoint]; !exists { 266 return false 267 } 268 return myOrg == memberOrg 269 } 270 271 func newGossip(peerID string, member *discovery.NetworkMember, pki2org map[string]string) *peerMockGossip { 272 return &peerMockGossip{ 273 id: peerID, 274 member: member, 275 acceptorLock: &sync.RWMutex{}, 276 clusterLock: &sync.RWMutex{}, 277 acceptors: make([]*mockAcceptor, 0), 278 pki2org: pki2org, 279 } 280 } 281 282 type clusterOfPeers struct { 283 peersGossip map[string]*peerMockGossip 284 peersLock *sync.RWMutex 285 id string 286 } 287 288 func (cop *clusterOfPeers) addPeer(peerID string, gossip *peerMockGossip) { 289 cop.peersLock.Lock() 290 cop.peersGossip[peerID] = gossip 291 gossip.clusterLock.Lock() 292 gossip.cluster = cop 293 gossip.clusterLock.Unlock() 294 cop.peersLock.Unlock() 295 } 296 297 func newClusterOfPeers(id string) *clusterOfPeers { 298 return &clusterOfPeers{ 299 id: id, 300 peersGossip: make(map[string]*peerMockGossip), 301 peersLock: &sync.RWMutex{}, 302 } 303 } 304 305 func createCluster(pki2org map[string]string, peers ...int) (*clusterOfPeers, map[string]*adapterImpl) { 306 adapters := make(map[string]*adapterImpl) 307 cluster := newClusterOfPeers("0") 308 for _, peer := range peers { 309 peerEndpoint := fmt.Sprintf("Peer%d", peer) 310 peerPKID := []byte{byte(peer)} 311 peerMember := &discovery.NetworkMember{ 312 Metadata: []byte{}, 313 Endpoint: peerEndpoint, 314 PKIid: peerPKID, 315 } 316 317 mockGossip := newGossip(peerEndpoint, peerMember, pki2org) 318 adapter := NewAdapter(mockGossip, peerMember.PKIid, []byte("channel0"), 319 metrics.NewGossipMetrics(&disabled.Provider{}).ElectionMetrics) 320 adapters[peerEndpoint] = adapter.(*adapterImpl) 321 cluster.addPeer(peerEndpoint, mockGossip) 322 } 323 324 return cluster, adapters 325 } 326 327 func TestReportMetrics(t *testing.T) { 328 testMetricProvider := mocks.TestUtilConstructMetricProvider() 329 electionMetrics := metrics.NewGossipMetrics(testMetricProvider.FakeProvider).ElectionMetrics 330 331 mockGossip := newGossip("", &discovery.NetworkMember{}, nil) 332 adapter := NewAdapter(mockGossip, nil, []byte("channel0"), electionMetrics) 333 334 adapter.ReportMetrics(true) 335 336 require.Equal(t, 337 []string{"channel", "channel0"}, 338 testMetricProvider.FakeDeclarationGauge.WithArgsForCall(0), 339 ) 340 require.EqualValues(t, 341 1, 342 testMetricProvider.FakeDeclarationGauge.SetArgsForCall(0), 343 ) 344 345 adapter.ReportMetrics(false) 346 347 require.Equal(t, 348 []string{"channel", "channel0"}, 349 testMetricProvider.FakeDeclarationGauge.WithArgsForCall(1), 350 ) 351 require.EqualValues(t, 352 0, 353 testMetricProvider.FakeDeclarationGauge.SetArgsForCall(1), 354 ) 355 }