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