github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/gossip/service/join_test.go (about)

     1  /*
     2  Copyright IBM Corp. 2017 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 service
    18  
    19  import (
    20  	"sync"
    21  	"testing"
    22  	"time"
    23  
    24  	"github.com/hyperledger/fabric/common/config"
    25  	"github.com/hyperledger/fabric/gossip/api"
    26  	"github.com/hyperledger/fabric/gossip/comm"
    27  	"github.com/hyperledger/fabric/gossip/common"
    28  	"github.com/hyperledger/fabric/gossip/discovery"
    29  	"github.com/hyperledger/fabric/gossip/util"
    30  	proto "github.com/hyperledger/fabric/protos/gossip"
    31  	"github.com/hyperledger/fabric/protos/peer"
    32  	"github.com/stretchr/testify/assert"
    33  	"github.com/stretchr/testify/mock"
    34  )
    35  
    36  type secAdvMock struct {
    37  }
    38  
    39  func init() {
    40  	util.SetupTestLogging()
    41  }
    42  
    43  func (s *secAdvMock) OrgByPeerIdentity(identity api.PeerIdentityType) api.OrgIdentityType {
    44  	return api.OrgIdentityType(identity)
    45  }
    46  
    47  type gossipMock struct {
    48  	mock.Mock
    49  }
    50  
    51  func (*gossipMock) SuspectPeers(s api.PeerSuspector) {
    52  	panic("implement me")
    53  }
    54  
    55  func (*gossipMock) Send(msg *proto.GossipMessage, peers ...*comm.RemotePeer) {
    56  	panic("implement me")
    57  }
    58  
    59  func (*gossipMock) Peers() []discovery.NetworkMember {
    60  	panic("implement me")
    61  }
    62  
    63  func (*gossipMock) PeersOfChannel(common.ChainID) []discovery.NetworkMember {
    64  	panic("implement me")
    65  }
    66  
    67  func (*gossipMock) UpdateMetadata(metadata []byte) {
    68  	panic("implement me")
    69  }
    70  
    71  func (*gossipMock) UpdateChannelMetadata(metadata []byte, chainID common.ChainID) {
    72  	panic("implement me")
    73  }
    74  
    75  func (*gossipMock) Gossip(msg *proto.GossipMessage) {
    76  	panic("implement me")
    77  }
    78  
    79  func (*gossipMock) Accept(acceptor common.MessageAcceptor, passThrough bool) (<-chan *proto.GossipMessage, <-chan proto.ReceivedMessage) {
    80  	panic("implement me")
    81  }
    82  
    83  func (g *gossipMock) JoinChan(joinMsg api.JoinChannelMessage, chainID common.ChainID) {
    84  	g.Called(joinMsg, chainID)
    85  }
    86  
    87  func (*gossipMock) Stop() {
    88  	panic("implement me")
    89  }
    90  
    91  type appOrgMock struct {
    92  	id string
    93  }
    94  
    95  func (*appOrgMock) Name() string {
    96  	panic("implement me")
    97  }
    98  
    99  func (ao *appOrgMock) MSPID() string {
   100  	return ao.id
   101  }
   102  
   103  func (ao *appOrgMock) AnchorPeers() []*peer.AnchorPeer {
   104  	return []*peer.AnchorPeer{}
   105  }
   106  
   107  type configMock struct {
   108  	orgs2AppOrgs map[string]config.ApplicationOrg
   109  }
   110  
   111  func (*configMock) ChainID() string {
   112  	return "A"
   113  }
   114  
   115  func (c *configMock) Organizations() map[string]config.ApplicationOrg {
   116  	return c.orgs2AppOrgs
   117  }
   118  
   119  func (*configMock) Sequence() uint64 {
   120  	return 0
   121  }
   122  
   123  func TestJoinChannelConfig(t *testing.T) {
   124  	// Scenarios: The channel we're joining has a single org - Org0
   125  	// but our org ID is actually Org0MSP in the negative path
   126  	// and Org0 in the positive path
   127  
   128  	failChan := make(chan struct{}, 1)
   129  	g1SvcMock := &gossipMock{}
   130  	g1SvcMock.On("JoinChan", mock.Anything, mock.Anything).Run(func(_ mock.Arguments) {
   131  		failChan <- struct{}{}
   132  	})
   133  	g1 := &gossipServiceImpl{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("OrgMSP0"), gossipSvc: g1SvcMock}
   134  	g1.configUpdated(&configMock{
   135  		orgs2AppOrgs: map[string]config.ApplicationOrg{
   136  			"Org0": &appOrgMock{id: "Org0"},
   137  		},
   138  	})
   139  	select {
   140  	case <-time.After(time.Second):
   141  	case <-failChan:
   142  		assert.Fail(t, "Joined a badly configured channel")
   143  	}
   144  
   145  	succChan := make(chan struct{}, 1)
   146  	g2SvcMock := &gossipMock{}
   147  	g2SvcMock.On("JoinChan", mock.Anything, mock.Anything).Run(func(_ mock.Arguments) {
   148  		succChan <- struct{}{}
   149  	})
   150  	g2 := &gossipServiceImpl{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("Org0"), gossipSvc: g2SvcMock}
   151  	g2.configUpdated(&configMock{
   152  		orgs2AppOrgs: map[string]config.ApplicationOrg{
   153  			"Org0": &appOrgMock{id: "Org0"},
   154  		},
   155  	})
   156  	select {
   157  	case <-time.After(time.Second):
   158  		assert.Fail(t, "Didn't join a channel (should have done so within the time period)")
   159  	case <-succChan:
   160  
   161  	}
   162  }
   163  
   164  func TestJoinChannelNoAnchorPeers(t *testing.T) {
   165  	// Scenario: The channel we're joining has 2 orgs but no anchor peers
   166  	// The test ensures that JoinChan is called with a JoinChannelMessage with Members
   167  	// that consist of the organizations of the configuration given.
   168  
   169  	var joinChanCalled sync.WaitGroup
   170  	joinChanCalled.Add(1)
   171  	gMock := &gossipMock{}
   172  	gMock.On("JoinChan", mock.Anything, mock.Anything).Run(func(args mock.Arguments) {
   173  		defer joinChanCalled.Done()
   174  		jcm := args.Get(0).(api.JoinChannelMessage)
   175  		channel := args.Get(1).(common.ChainID)
   176  		assert.Len(t, jcm.Members(), 2)
   177  		assert.Contains(t, jcm.Members(), api.OrgIdentityType("Org0"))
   178  		assert.Contains(t, jcm.Members(), api.OrgIdentityType("Org1"))
   179  		assert.Equal(t, "A", string(channel))
   180  	})
   181  
   182  	g := &gossipServiceImpl{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("Org0"), gossipSvc: gMock}
   183  
   184  	appOrg0 := &appOrgMock{id: "Org0"}
   185  	appOrg1 := &appOrgMock{id: "Org1"}
   186  
   187  	// Make sure the ApplicationOrgs really have no anchor peers
   188  	assert.Empty(t, appOrg0.AnchorPeers())
   189  	assert.Empty(t, appOrg1.AnchorPeers())
   190  
   191  	g.configUpdated(&configMock{
   192  		orgs2AppOrgs: map[string]config.ApplicationOrg{
   193  			"Org0": appOrg0,
   194  			"Org1": appOrg1,
   195  		},
   196  	})
   197  	joinChanCalled.Wait()
   198  }