github.com/leonlxy/hyperledger@v1.0.0-alpha.0.20170427033203-34922035d248/gossip/election/adapter_test.go (about) 1 /* 2 Copyright IBM Corp. 2017 All Rights Reserved. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 package election 18 19 import ( 20 "bytes" 21 "fmt" 22 "strings" 23 "sync" 24 "testing" 25 "time" 26 27 "github.com/hyperledger/fabric/gossip/api" 28 "github.com/hyperledger/fabric/gossip/common" 29 "github.com/hyperledger/fabric/gossip/discovery" 30 "github.com/hyperledger/fabric/gossip/util" 31 proto "github.com/hyperledger/fabric/protos/gossip" 32 ) 33 34 func init() { 35 util.SetupTestLogging() 36 } 37 38 func TestNewAdapter(t *testing.T) { 39 selfNetworkMember := &discovery.NetworkMember{ 40 Endpoint: "p0", 41 Metadata: []byte{}, 42 PKIid: []byte{byte(0)}, 43 } 44 mockGossip := newGossip("peer0", selfNetworkMember) 45 46 peersCluster := newClusterOfPeers("0") 47 peersCluster.addPeer("peer0", mockGossip) 48 49 NewAdapter(mockGossip, selfNetworkMember.PKIid, []byte("channel0")) 50 } 51 52 func TestAdapterImpl_CreateMessage(t *testing.T) { 53 selfNetworkMember := &discovery.NetworkMember{ 54 Endpoint: "p0", 55 Metadata: []byte{}, 56 PKIid: []byte{byte(0)}, 57 } 58 mockGossip := newGossip("peer0", selfNetworkMember) 59 60 adapter := NewAdapter(mockGossip, selfNetworkMember.PKIid, []byte("channel0")) 61 msg := adapter.CreateMessage(true) 62 63 if !msg.(*msgImpl).msg.IsLeadershipMsg() { 64 t.Error("Newly created message should be LeadershipMsg") 65 } 66 67 if !msg.IsDeclaration() { 68 t.Error("Newly created msg should be Declaration msg") 69 } 70 71 msg = adapter.CreateMessage(false) 72 73 if !msg.(*msgImpl).msg.IsLeadershipMsg() { 74 t.Error("Newly created message should be LeadershipMsg") 75 } 76 77 if !msg.IsProposal() || msg.IsDeclaration() { 78 t.Error("Newly created msg should be Proposal msg") 79 } 80 } 81 82 func TestAdapterImpl_Peers(t *testing.T) { 83 _, adapters := createCluster(0, 1, 2, 3, 4, 5) 84 85 peersPKIDs := make(map[string]string) 86 peersPKIDs[string([]byte{0})] = string([]byte{0}) 87 peersPKIDs[string([]byte{1})] = string([]byte{1}) 88 peersPKIDs[string([]byte{2})] = string([]byte{2}) 89 peersPKIDs[string([]byte{3})] = string([]byte{2}) 90 peersPKIDs[string([]byte{4})] = string([]byte{4}) 91 peersPKIDs[string([]byte{5})] = string([]byte{5}) 92 93 for _, adapter := range adapters { 94 peers := adapter.Peers() 95 if len(peers) != 6 { 96 t.Errorf("Should return 6 peers, not %d", len(peers)) 97 } 98 99 for _, peer := range peers { 100 if _, exist := peersPKIDs[string(peer.ID())]; !exist { 101 t.Errorf("Peer %s PKID not found", peer.(*peerImpl).member.Endpoint) 102 } 103 } 104 } 105 106 } 107 108 func TestAdapterImpl_Stop(t *testing.T) { 109 _, adapters := createCluster(0, 1, 2, 3, 4, 5) 110 111 for _, adapter := range adapters { 112 adapter.Accept() 113 } 114 115 for _, adapter := range adapters { 116 adapter.Stop() 117 } 118 } 119 120 func TestAdapterImpl_Gossip(t *testing.T) { 121 _, adapters := createCluster(0, 1, 2) 122 123 channels := make(map[string]<-chan Msg) 124 125 for peerID, adapter := range adapters { 126 channels[peerID] = adapter.Accept() 127 } 128 129 sender := adapters[fmt.Sprintf("Peer%d", 0)] 130 131 sender.Gossip(sender.CreateMessage(true)) 132 133 totalMsg := 0 134 135 timer := time.After(time.Duration(1) * time.Second) 136 137 for { 138 select { 139 case <-timer: 140 if totalMsg != 2 { 141 t.Error("Not all messages accepted") 142 t.FailNow() 143 } else { 144 return 145 } 146 case msg := <-channels[fmt.Sprintf("Peer%d", 1)]: 147 if !msg.IsDeclaration() { 148 t.Error("Msg should be declaration") 149 } else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) { 150 t.Error("Msg Sender is wrong") 151 } else { 152 totalMsg++ 153 } 154 case msg := <-channels[fmt.Sprintf("Peer%d", 2)]: 155 if !msg.IsDeclaration() { 156 t.Error("Msg should be declaration") 157 } else if !bytes.Equal(msg.SenderID(), sender.selfPKIid) { 158 t.Error("Msg Sender is wrong") 159 } else { 160 totalMsg++ 161 } 162 } 163 164 } 165 166 } 167 168 type mockMsgCrypto struct { 169 } 170 171 // Sign signs a message, returns a signed message on success 172 // or an error on failure 173 func (is *mockMsgCrypto) Sign(msg []byte) ([]byte, error) { 174 return msg, nil 175 } 176 177 // Verify verifies a signed message 178 func (is *mockMsgCrypto) Verify(vkID, signature, message []byte) error { 179 return nil 180 } 181 182 // Get returns the identity of a given pkiID, or error if such an identity 183 // isn't found 184 func (is *mockMsgCrypto) Get(pkiID common.PKIidType) (api.PeerIdentityType, error) { 185 return nil, nil 186 } 187 188 type mockAcceptor struct { 189 ch chan *proto.GossipMessage 190 acceptor common.MessageAcceptor 191 } 192 193 type peerMockGossip struct { 194 cluster *clusterOfPeers 195 member *discovery.NetworkMember 196 acceptors []*mockAcceptor 197 acceptorLock *sync.RWMutex 198 clusterLock *sync.RWMutex 199 id string 200 } 201 202 func (g *peerMockGossip) Peers() []discovery.NetworkMember { 203 204 g.clusterLock.RLock() 205 if g.cluster == nil { 206 return []discovery.NetworkMember{*g.member} 207 } 208 peerLock := g.cluster.peersLock 209 g.clusterLock.RUnlock() 210 211 peerLock.RLock() 212 res := make([]discovery.NetworkMember, 0) 213 g.clusterLock.RLock() 214 for _, val := range g.cluster.peersGossip { 215 res = append(res, *val.member) 216 217 } 218 g.clusterLock.RUnlock() 219 peerLock.RUnlock() 220 return res 221 } 222 223 func (g *peerMockGossip) Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan proto.ReceivedMessage) { 224 ch := make(chan *proto.GossipMessage, 100) 225 g.acceptorLock.Lock() 226 g.acceptors = append(g.acceptors, &mockAcceptor{ 227 ch: ch, 228 acceptor: acceptor, 229 }) 230 g.acceptorLock.Unlock() 231 return ch, nil 232 } 233 234 func (g *peerMockGossip) Gossip(msg *proto.GossipMessage) { 235 g.clusterLock.RLock() 236 if g.cluster == nil { 237 return 238 } 239 peersLock := g.cluster.peersLock 240 g.clusterLock.RUnlock() 241 242 peersLock.RLock() 243 g.clusterLock.RLock() 244 for _, val := range g.cluster.peersGossip { 245 if strings.Compare(val.id, g.id) != 0 { 246 val.putToAcceptors(msg) 247 } 248 } 249 g.clusterLock.RUnlock() 250 peersLock.RUnlock() 251 252 } 253 254 func (g *peerMockGossip) putToAcceptors(msg *proto.GossipMessage) { 255 g.acceptorLock.RLock() 256 for _, acceptor := range g.acceptors { 257 if acceptor.acceptor(msg) { 258 if len(acceptor.ch) < 10 { 259 acceptor.ch <- msg 260 } 261 } 262 } 263 g.acceptorLock.RUnlock() 264 265 } 266 267 func newGossip(peerID string, member *discovery.NetworkMember) *peerMockGossip { 268 return &peerMockGossip{ 269 id: peerID, 270 member: member, 271 acceptorLock: &sync.RWMutex{}, 272 clusterLock: &sync.RWMutex{}, 273 acceptors: make([]*mockAcceptor, 0), 274 } 275 } 276 277 type clusterOfPeers struct { 278 peersGossip map[string]*peerMockGossip 279 peersLock *sync.RWMutex 280 id string 281 } 282 283 func (cop *clusterOfPeers) addPeer(peerID string, gossip *peerMockGossip) { 284 cop.peersLock.Lock() 285 cop.peersGossip[peerID] = gossip 286 gossip.clusterLock.Lock() 287 gossip.cluster = cop 288 gossip.clusterLock.Unlock() 289 cop.peersLock.Unlock() 290 291 } 292 293 func newClusterOfPeers(id string) *clusterOfPeers { 294 return &clusterOfPeers{ 295 id: id, 296 peersGossip: make(map[string]*peerMockGossip), 297 peersLock: &sync.RWMutex{}, 298 } 299 300 } 301 302 func createCluster(peers ...int) (*clusterOfPeers, map[string]*adapterImpl) { 303 adapters := make(map[string]*adapterImpl) 304 cluster := newClusterOfPeers("0") 305 for _, peer := range peers { 306 peerEndpoint := fmt.Sprintf("Peer%d", peer) 307 peerPKID := []byte{byte(peer)} 308 peerMember := &discovery.NetworkMember{ 309 Metadata: []byte{}, 310 Endpoint: peerEndpoint, 311 PKIid: peerPKID, 312 } 313 314 mockGossip := newGossip(peerEndpoint, peerMember) 315 adapter := NewAdapter(mockGossip, peerMember.PKIid, []byte("channel0")) 316 adapters[peerEndpoint] = adapter.(*adapterImpl) 317 cluster.addPeer(peerEndpoint, mockGossip) 318 } 319 320 return cluster, adapters 321 }