github.com/adnan-c/fabric_e2e_couchdb@v0.6.1-preview.0.20170228180935-21ce6b23cf91/gossip/comm/mock/mock_comm.go (about) 1 /* 2 Copyright IBM Corp. 2016 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 mock 18 19 import ( 20 "github.com/hyperledger/fabric/gossip/comm" 21 "github.com/hyperledger/fabric/gossip/common" 22 "github.com/hyperledger/fabric/gossip/util" 23 proto "github.com/hyperledger/fabric/protos/gossip" 24 ) 25 26 // Mock which aims to simulate socket 27 type socketMock struct { 28 // socket endpoint 29 endpoint string 30 31 // To simulate simple tcp socket 32 socket chan interface{} 33 } 34 35 // Mock of primitive tcp packet structure 36 type packetMock struct { 37 // Sender channel message sent from 38 src *socketMock 39 40 // Destination channel sent to 41 dst *socketMock 42 43 msg interface{} 44 } 45 46 type channelMock struct { 47 accept common.MessageAcceptor 48 49 channel chan proto.ReceivedMessage 50 } 51 52 type commMock struct { 53 id string 54 55 members map[string]*socketMock 56 57 acceptors []*channelMock 58 59 deadChannel chan common.PKIidType 60 61 done chan struct{} 62 } 63 64 var logger = util.GetLogger(util.LoggingMockModule, "") 65 66 // NewCommMock creates mocked communication object 67 func NewCommMock(id string, members map[string]*socketMock) comm.Comm { 68 res := &commMock{ 69 id: id, 70 71 members: members, 72 73 acceptors: make([]*channelMock, 0), 74 75 done: make(chan struct{}), 76 77 deadChannel: make(chan common.PKIidType), 78 } 79 // Start communication service 80 go res.start() 81 82 return res 83 } 84 85 // Respond sends a GossipMessage to the origin from which this ReceivedMessage was sent from 86 func (packet *packetMock) Respond(msg *proto.GossipMessage) { 87 packet.src.socket <- &packetMock{ 88 src: packet.dst, 89 dst: packet.src, 90 msg: msg.NoopSign(), 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() *proto.SignedGossipMessage { 102 return packet.msg.(*proto.SignedGossipMessage) 103 } 104 105 // GetPKIID returns the PKI-ID of the remote peer 106 // that sent the message 107 func (packet *packetMock) GetPKIID() common.PKIidType { 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 // GetPKIid returns this instance's PKI id 139 func (mock *commMock) GetPKIid() common.PKIidType { 140 return common.PKIidType(mock.id) 141 } 142 143 // Send sends a message to remote peers 144 func (mock *commMock) Send(msg *proto.SignedGossipMessage, peers ...*comm.RemotePeer) { 145 for _, peer := range peers { 146 logger.Debug("Sending message to peer ", peer.Endpoint, "from ", mock.id) 147 mock.members[peer.Endpoint].socket <- &packetMock{ 148 src: mock.members[mock.id], 149 dst: mock.members[peer.Endpoint], 150 msg: msg, 151 } 152 } 153 } 154 155 // Probe probes a remote node and returns nil if its responsive 156 func (mock *commMock) Probe(peer *comm.RemotePeer) error { 157 return nil 158 } 159 160 // Accept returns a dedicated read-only channel for messages sent by other nodes that match a certain predicate. 161 // Each message from the channel can be used to send a reply back to the sender 162 func (mock *commMock) Accept(accept common.MessageAcceptor) <-chan proto.ReceivedMessage { 163 ch := make(chan proto.ReceivedMessage) 164 mock.acceptors = append(mock.acceptors, &channelMock{accept, ch}) 165 return ch 166 } 167 168 // PresumedDead returns a read-only channel for node endpoints that are suspected to be offline 169 func (mock *commMock) PresumedDead() <-chan common.PKIidType { 170 return mock.deadChannel 171 } 172 173 // CloseConn closes a connection to a certain endpoint 174 func (mock *commMock) CloseConn(peer *comm.RemotePeer) { 175 // NOOP 176 } 177 178 // Stop stops the module 179 func (mock *commMock) Stop() { 180 logger.Debug("Stopping communication module, closing all accepting channels.") 181 for _, accept := range mock.acceptors { 182 close(accept.channel) 183 } 184 logger.Debug("[XXX]: Sending done signal to close the module.") 185 mock.done <- struct{}{} 186 } 187 188 // BlackListPKIid prohibits the module communicating with the given PKIid 189 func (mock *commMock) BlackListPKIid(PKIid common.PKIidType) { 190 // NOOP 191 }