github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/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 }