github.com/ewagmig/fabric@v2.1.1+incompatible/gossip/service/join_test.go (about)

     1  /*
     2  Copyright IBM Corp. All Rights Reserved.
     3  
     4  SPDX-License-Identifier: Apache-2.0
     5  */
     6  
     7  package service
     8  
     9  import (
    10  	"sync"
    11  	"testing"
    12  	"time"
    13  
    14  	proto "github.com/hyperledger/fabric-protos-go/gossip"
    15  	"github.com/hyperledger/fabric-protos-go/peer"
    16  	"github.com/hyperledger/fabric/common/channelconfig"
    17  	"github.com/hyperledger/fabric/gossip/api"
    18  	"github.com/hyperledger/fabric/gossip/comm"
    19  	"github.com/hyperledger/fabric/gossip/common"
    20  	"github.com/hyperledger/fabric/gossip/discovery"
    21  	"github.com/hyperledger/fabric/gossip/filter"
    22  	"github.com/hyperledger/fabric/gossip/gossip"
    23  	"github.com/hyperledger/fabric/gossip/protoext"
    24  	"github.com/hyperledger/fabric/gossip/util"
    25  	"github.com/hyperledger/fabric/msp"
    26  	"github.com/stretchr/testify/assert"
    27  	"github.com/stretchr/testify/mock"
    28  )
    29  
    30  type secAdvMock struct {
    31  }
    32  
    33  func init() {
    34  	util.SetupTestLogging()
    35  }
    36  
    37  func (s *secAdvMock) OrgByPeerIdentity(identity api.PeerIdentityType) api.OrgIdentityType {
    38  	return api.OrgIdentityType(identity)
    39  }
    40  
    41  type gossipMock struct {
    42  	mock.Mock
    43  }
    44  
    45  func (g *gossipMock) SelfChannelInfo(common.ChannelID) *protoext.SignedGossipMessage {
    46  	panic("implement me")
    47  }
    48  
    49  func (g *gossipMock) SelfMembershipInfo() discovery.NetworkMember {
    50  	panic("implement me")
    51  }
    52  
    53  func (*gossipMock) PeerFilter(channel common.ChannelID, messagePredicate api.SubChannelSelectionCriteria) (filter.RoutingFilter, error) {
    54  	panic("implement me")
    55  }
    56  
    57  func (*gossipMock) SuspectPeers(s api.PeerSuspector) {
    58  	panic("implement me")
    59  }
    60  
    61  func (*gossipMock) Send(msg *proto.GossipMessage, peers ...*comm.RemotePeer) {
    62  	panic("implement me")
    63  }
    64  
    65  func (*gossipMock) Peers() []discovery.NetworkMember {
    66  	panic("implement me")
    67  }
    68  
    69  func (*gossipMock) PeersOfChannel(common.ChannelID) []discovery.NetworkMember {
    70  	panic("implement me")
    71  }
    72  
    73  func (*gossipMock) UpdateMetadata(metadata []byte) {
    74  	panic("implement me")
    75  }
    76  
    77  // UpdateLedgerHeight updates the ledger height the peer
    78  // publishes to other peers in the channel
    79  func (*gossipMock) UpdateLedgerHeight(height uint64, channelID common.ChannelID) {
    80  	panic("implement me")
    81  }
    82  
    83  // UpdateChaincodes updates the chaincodes the peer publishes
    84  // to other peers in the channel
    85  func (*gossipMock) UpdateChaincodes(chaincode []*proto.Chaincode, channelID common.ChannelID) {
    86  	panic("implement me")
    87  }
    88  
    89  func (*gossipMock) Gossip(msg *proto.GossipMessage) {
    90  	panic("implement me")
    91  }
    92  
    93  func (*gossipMock) Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan protoext.ReceivedMessage) {
    94  	panic("implement me")
    95  }
    96  
    97  func (g *gossipMock) JoinChan(joinMsg api.JoinChannelMessage, channelID common.ChannelID) {
    98  	g.Called(joinMsg, channelID)
    99  }
   100  
   101  func (g *gossipMock) LeaveChan(channelID common.ChannelID) {
   102  	panic("implement me")
   103  }
   104  
   105  func (g *gossipMock) IdentityInfo() api.PeerIdentitySet {
   106  	panic("implement me")
   107  }
   108  
   109  func (*gossipMock) IsInMyOrg(member discovery.NetworkMember) bool {
   110  	panic("implement me")
   111  }
   112  
   113  func (*gossipMock) Stop() {
   114  	panic("implement me")
   115  }
   116  
   117  func (*gossipMock) SendByCriteria(*protoext.SignedGossipMessage, gossip.SendCriteria) error {
   118  	panic("implement me")
   119  }
   120  
   121  type appOrgMock struct {
   122  	id string
   123  }
   124  
   125  func (*appOrgMock) Name() string {
   126  	panic("implement me")
   127  }
   128  
   129  func (*appOrgMock) MSP() msp.MSP {
   130  	panic("generate this fake instead")
   131  }
   132  
   133  func (ao *appOrgMock) MSPID() string {
   134  	return ao.id
   135  }
   136  
   137  func (ao *appOrgMock) AnchorPeers() []*peer.AnchorPeer {
   138  	return []*peer.AnchorPeer{}
   139  }
   140  
   141  type configMock struct {
   142  	orgs2AppOrgs map[string]channelconfig.ApplicationOrg
   143  }
   144  
   145  func (c *configMock) OrdererAddresses() []string {
   146  	return []string{"localhost:7050"}
   147  }
   148  
   149  func (*configMock) ChannelID() string {
   150  	return "A"
   151  }
   152  
   153  func (c *configMock) Organizations() map[string]channelconfig.ApplicationOrg {
   154  	return c.orgs2AppOrgs
   155  }
   156  
   157  func (*configMock) Sequence() uint64 {
   158  	return 0
   159  }
   160  
   161  func TestJoinChannelConfig(t *testing.T) {
   162  	// Scenarios: The channel we're joining has a single org - Org0
   163  	// but our org ID is actually Org0MSP in the negative path
   164  	// and Org0 in the positive path
   165  
   166  	failChan := make(chan struct{}, 1)
   167  	g1SvcMock := &gossipMock{}
   168  	g1SvcMock.On("JoinChan", mock.Anything, mock.Anything).Run(func(_ mock.Arguments) {
   169  		failChan <- struct{}{}
   170  	})
   171  	g1 := &GossipService{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("OrgMSP0"), gossipSvc: g1SvcMock}
   172  	g1.updateAnchors(&configMock{
   173  		orgs2AppOrgs: map[string]channelconfig.ApplicationOrg{
   174  			"Org0": &appOrgMock{id: "Org0"},
   175  		},
   176  	})
   177  	select {
   178  	case <-time.After(time.Second):
   179  	case <-failChan:
   180  		assert.Fail(t, "Joined a badly configured channel")
   181  	}
   182  
   183  	succChan := make(chan struct{}, 1)
   184  	g2SvcMock := &gossipMock{}
   185  	g2SvcMock.On("JoinChan", mock.Anything, mock.Anything).Run(func(_ mock.Arguments) {
   186  		succChan <- struct{}{}
   187  	})
   188  	g2 := &GossipService{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("Org0"), gossipSvc: g2SvcMock}
   189  	g2.updateAnchors(&configMock{
   190  		orgs2AppOrgs: map[string]channelconfig.ApplicationOrg{
   191  			"Org0": &appOrgMock{id: "Org0"},
   192  		},
   193  	})
   194  	select {
   195  	case <-time.After(time.Second):
   196  		assert.Fail(t, "Didn't join a channel (should have done so within the time period)")
   197  	case <-succChan:
   198  
   199  	}
   200  }
   201  
   202  func TestJoinChannelNoAnchorPeers(t *testing.T) {
   203  	// Scenario: The channel we're joining has 2 orgs but no anchor peers
   204  	// The test ensures that JoinChan is called with a JoinChannelMessage with Members
   205  	// that consist of the organizations of the configuration given.
   206  
   207  	var joinChanCalled sync.WaitGroup
   208  	joinChanCalled.Add(1)
   209  	gMock := &gossipMock{}
   210  	gMock.On("JoinChan", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
   211  		defer joinChanCalled.Done()
   212  		jcm := args.Get(0).(api.JoinChannelMessage)
   213  		channel := args.Get(1).(common.ChannelID)
   214  		assert.Len(t, jcm.Members(), 2)
   215  		assert.Contains(t, jcm.Members(), api.OrgIdentityType("Org0"))
   216  		assert.Contains(t, jcm.Members(), api.OrgIdentityType("Org1"))
   217  		assert.Equal(t, "A", string(channel))
   218  	})
   219  
   220  	g := &GossipService{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("Org0"), gossipSvc: gMock}
   221  
   222  	appOrg0 := &appOrgMock{id: "Org0"}
   223  	appOrg1 := &appOrgMock{id: "Org1"}
   224  
   225  	// Make sure the ApplicationOrgs really have no anchor peers
   226  	assert.Empty(t, appOrg0.AnchorPeers())
   227  	assert.Empty(t, appOrg1.AnchorPeers())
   228  
   229  	g.updateAnchors(&configMock{
   230  		orgs2AppOrgs: map[string]channelconfig.ApplicationOrg{
   231  			"Org0": appOrg0,
   232  			"Org1": appOrg1,
   233  		},
   234  	})
   235  	joinChanCalled.Wait()
   236  }