github.com/hechain20/hechain@v0.0.0-20220316014945-b544036ba106/gossip/comm/mock/mock_comm.go (about)

     1  /*
     2  Copyright hechain. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package mock
     8  
     9  import (
    10  	"time"
    11  
    12  	"github.com/hechain20/hechain/gossip/api"
    13  	"github.com/hechain20/hechain/gossip/comm"
    14  	"github.com/hechain20/hechain/gossip/common"
    15  	"github.com/hechain20/hechain/gossip/protoext"
    16  	"github.com/hechain20/hechain/gossip/util"
    17  	proto "github.com/hyperledger/fabric-protos-go/gossip"
    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  // GetSourceEnvelope Returns the Envelope the ReceivedMessage was
    94  // constructed with
    95  func (packet *packetMock) GetSourceEnvelope() *proto.Envelope {
    96  	return nil
    97  }
    98  
    99  // GetGossipMessage returns the underlying GossipMessage
   100  func (packet *packetMock) GetGossipMessage() *protoext.SignedGossipMessage {
   101  	return packet.msg.(*protoext.SignedGossipMessage)
   102  }
   103  
   104  // GetConnectionInfo returns information about the remote peer
   105  // that sent the message
   106  func (packet *packetMock) GetConnectionInfo() *protoext.ConnectionInfo {
   107  	return nil
   108  }
   109  
   110  func (mock *commMock) start() {
   111  	logger.Debug("Starting communication mock module...")
   112  	for {
   113  		select {
   114  		case <-mock.done:
   115  			{
   116  				// Got final signal, exiting...
   117  				logger.Debug("Exiting...")
   118  				return
   119  			}
   120  		case msg := <-mock.members[mock.id].socket:
   121  			{
   122  				logger.Debug("Got new message", msg)
   123  				packet := msg.(*packetMock)
   124  				for _, channel := range mock.acceptors {
   125  					// if message acceptor agrees to get
   126  					// new message forward it to the received
   127  					// messages channel
   128  					if channel.accept(packet) {
   129  						channel.channel <- packet
   130  					}
   131  				}
   132  			}
   133  		}
   134  	}
   135  }
   136  
   137  func (mock *commMock) IdentitySwitch() <-chan common.PKIidType {
   138  	panic("implement me")
   139  }
   140  
   141  // GetPKIid returns this instance's PKI id
   142  func (mock *commMock) GetPKIid() common.PKIidType {
   143  	return common.PKIidType(mock.id)
   144  }
   145  
   146  // Send sends a message to remote peers asynchronously
   147  func (mock *commMock) Send(msg *protoext.SignedGossipMessage, peers ...*comm.RemotePeer) {
   148  	for _, peer := range peers {
   149  		logger.Debug("Sending message to peer ", peer.Endpoint, "from ", mock.id)
   150  		mock.members[peer.Endpoint].socket <- &packetMock{
   151  			src: mock.members[mock.id],
   152  			dst: mock.members[peer.Endpoint],
   153  			msg: msg,
   154  		}
   155  	}
   156  }
   157  
   158  func (mock *commMock) SendWithAck(_ *protoext.SignedGossipMessage, _ time.Duration, _ int, _ ...*comm.RemotePeer) comm.AggregatedSendResult {
   159  	panic("not implemented")
   160  }
   161  
   162  // Probe probes a remote node and returns nil if its responsive,
   163  // and an error if it's not.
   164  func (mock *commMock) Probe(peer *comm.RemotePeer) error {
   165  	return nil
   166  }
   167  
   168  // Handshake authenticates a remote peer and returns
   169  // (its identity, nil) on success and (nil, error)
   170  func (mock *commMock) Handshake(peer *comm.RemotePeer) (api.PeerIdentityType, error) {
   171  	return nil, nil
   172  }
   173  
   174  // Accept returns a dedicated read-only channel for messages sent by other nodes that match a certain predicate.
   175  // Each message from the channel can be used to send a reply back to the sender
   176  func (mock *commMock) Accept(accept common.MessageAcceptor) <-chan protoext.ReceivedMessage {
   177  	ch := make(chan protoext.ReceivedMessage)
   178  	mock.acceptors = append(mock.acceptors, &channelMock{accept, ch})
   179  	return ch
   180  }
   181  
   182  // PresumedDead returns a read-only channel for node endpoints that are suspected to be offline
   183  func (mock *commMock) PresumedDead() <-chan common.PKIidType {
   184  	return mock.deadChannel
   185  }
   186  
   187  // CloseConn closes a connection to a certain endpoint
   188  func (mock *commMock) CloseConn(peer *comm.RemotePeer) {
   189  	// NOOP
   190  }
   191  
   192  // Stop stops the module
   193  func (mock *commMock) Stop() {
   194  	logger.Debug("Stopping communication module, closing all accepting channels.")
   195  	for _, accept := range mock.acceptors {
   196  		close(accept.channel)
   197  	}
   198  	logger.Debug("[XXX]: Sending done signal to close the module.")
   199  	mock.done <- struct{}{}
   200  }