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