github.com/myafeier/fabric@v1.0.1-0.20170722181825-3a4b1f2bce86/gossip/comm/mock/mock_comm.go (about) 1 /* 2 Copyright IBM Corp. All Rights Reserved. 3 4 SPDX-License-Identifier: Apache-2.0 5 */ 6 7 package mock 8 9 import ( 10 "github.com/hyperledger/fabric/gossip/api" 11 "github.com/hyperledger/fabric/gossip/comm" 12 "github.com/hyperledger/fabric/gossip/common" 13 "github.com/hyperledger/fabric/gossip/util" 14 proto "github.com/hyperledger/fabric/protos/gossip" 15 ) 16 17 // Mock which aims to simulate socket 18 type socketMock struct { 19 // socket endpoint 20 endpoint string 21 22 // To simulate simple tcp socket 23 socket chan interface{} 24 } 25 26 // Mock of primitive tcp packet structure 27 type packetMock struct { 28 // Sender channel message sent from 29 src *socketMock 30 31 // Destination channel sent to 32 dst *socketMock 33 34 msg interface{} 35 } 36 37 type channelMock struct { 38 accept common.MessageAcceptor 39 40 channel chan proto.ReceivedMessage 41 } 42 43 type commMock struct { 44 id string 45 46 members map[string]*socketMock 47 48 acceptors []*channelMock 49 50 deadChannel chan common.PKIidType 51 52 done chan struct{} 53 } 54 55 var logger = util.GetLogger(util.LoggingMockModule, "") 56 57 // NewCommMock creates mocked communication object 58 func NewCommMock(id string, members map[string]*socketMock) comm.Comm { 59 res := &commMock{ 60 id: id, 61 62 members: members, 63 64 acceptors: make([]*channelMock, 0), 65 66 done: make(chan struct{}), 67 68 deadChannel: make(chan common.PKIidType), 69 } 70 // Start communication service 71 go res.start() 72 73 return res 74 } 75 76 // Respond sends a GossipMessage to the origin from which this ReceivedMessage was sent from 77 func (packet *packetMock) Respond(msg *proto.GossipMessage) { 78 sMsg, _ := msg.NoopSign() 79 packet.src.socket <- &packetMock{ 80 src: packet.dst, 81 dst: packet.src, 82 msg: sMsg, 83 } 84 } 85 86 // GetSourceEnvelope Returns the Envelope the ReceivedMessage was 87 // constructed with 88 func (packet *packetMock) GetSourceEnvelope() *proto.Envelope { 89 return nil 90 } 91 92 // GetGossipMessage returns the underlying GossipMessage 93 func (packet *packetMock) GetGossipMessage() *proto.SignedGossipMessage { 94 return packet.msg.(*proto.SignedGossipMessage) 95 } 96 97 // GetConnectionInfo returns information about the remote peer 98 // that sent the message 99 func (packet *packetMock) GetConnectionInfo() *proto.ConnectionInfo { 100 return nil 101 } 102 103 func (mock *commMock) start() { 104 logger.Debug("Starting communication mock module...") 105 for { 106 select { 107 case <-mock.done: 108 { 109 // Got final signal, exiting... 110 logger.Debug("Exiting...") 111 return 112 } 113 case msg := <-mock.members[mock.id].socket: 114 { 115 logger.Debug("Got new message", msg) 116 packet := msg.(*packetMock) 117 for _, channel := range mock.acceptors { 118 // if message acceptor agrees to get 119 // new message forward it to the received 120 // messages channel 121 if channel.accept(packet) { 122 channel.channel <- packet 123 } 124 } 125 } 126 } 127 } 128 } 129 130 // GetPKIid returns this instance's PKI id 131 func (mock *commMock) GetPKIid() common.PKIidType { 132 return common.PKIidType(mock.id) 133 } 134 135 // Send sends a message to remote peers 136 func (mock *commMock) Send(msg *proto.SignedGossipMessage, peers ...*comm.RemotePeer) { 137 for _, peer := range peers { 138 logger.Debug("Sending message to peer ", peer.Endpoint, "from ", mock.id) 139 mock.members[peer.Endpoint].socket <- &packetMock{ 140 src: mock.members[mock.id], 141 dst: mock.members[peer.Endpoint], 142 msg: msg, 143 } 144 } 145 } 146 147 // Probe probes a remote node and returns nil if its responsive, 148 // and an error if it's not. 149 func (mock *commMock) Probe(peer *comm.RemotePeer) error { 150 return nil 151 } 152 153 // Handshake authenticates a remote peer and returns 154 // (its identity, nil) on success and (nil, error) 155 func (mock *commMock) Handshake(peer *comm.RemotePeer) (api.PeerIdentityType, error) { 156 return nil, nil 157 } 158 159 // Accept returns a dedicated read-only channel for messages sent by other nodes that match a certain predicate. 160 // Each message from the channel can be used to send a reply back to the sender 161 func (mock *commMock) Accept(accept common.MessageAcceptor) <-chan proto.ReceivedMessage { 162 ch := make(chan proto.ReceivedMessage) 163 mock.acceptors = append(mock.acceptors, &channelMock{accept, ch}) 164 return ch 165 } 166 167 // PresumedDead returns a read-only channel for node endpoints that are suspected to be offline 168 func (mock *commMock) PresumedDead() <-chan common.PKIidType { 169 return mock.deadChannel 170 } 171 172 // CloseConn closes a connection to a certain endpoint 173 func (mock *commMock) CloseConn(peer *comm.RemotePeer) { 174 // NOOP 175 } 176 177 // Stop stops the module 178 func (mock *commMock) Stop() { 179 logger.Debug("Stopping communication module, closing all accepting channels.") 180 for _, accept := range mock.acceptors { 181 close(accept.channel) 182 } 183 logger.Debug("[XXX]: Sending done signal to close the module.") 184 mock.done <- struct{}{} 185 }