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  }