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  }