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  }