github.com/osdi23p228/fabric@v0.0.0-20221218062954-77808885f5db/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/osdi23p228/fabric/common/channelconfig" 17 "github.com/osdi23p228/fabric/gossip/api" 18 "github.com/osdi23p228/fabric/gossip/comm" 19 "github.com/osdi23p228/fabric/gossip/common" 20 "github.com/osdi23p228/fabric/gossip/discovery" 21 "github.com/osdi23p228/fabric/gossip/filter" 22 "github.com/osdi23p228/fabric/gossip/gossip" 23 "github.com/osdi23p228/fabric/gossip/protoext" 24 "github.com/osdi23p228/fabric/gossip/util" 25 "github.com/osdi23p228/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 anchorPeerTracker := &anchorPeerTracker{allEndpoints: map[string]map[string]struct{}{}} 172 g1 := &GossipService{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("OrgMSP0"), gossipSvc: g1SvcMock, anchorPeerTracker: anchorPeerTracker} 173 g1.updateAnchors(&configMock{ 174 orgs2AppOrgs: map[string]channelconfig.ApplicationOrg{ 175 "Org0": &appOrgMock{id: "Org0"}, 176 }, 177 }) 178 select { 179 case <-time.After(time.Second): 180 case <-failChan: 181 assert.Fail(t, "Joined a badly configured channel") 182 } 183 184 succChan := make(chan struct{}, 1) 185 g2SvcMock := &gossipMock{} 186 g2SvcMock.On("JoinChan", mock.Anything, mock.Anything).Run(func(_ mock.Arguments) { 187 succChan <- struct{}{} 188 }) 189 g2 := &GossipService{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("Org0"), gossipSvc: g2SvcMock, anchorPeerTracker: anchorPeerTracker} 190 g2.updateAnchors(&configMock{ 191 orgs2AppOrgs: map[string]channelconfig.ApplicationOrg{ 192 "Org0": &appOrgMock{id: "Org0"}, 193 }, 194 }) 195 select { 196 case <-time.After(time.Second): 197 assert.Fail(t, "Didn't join a channel (should have done so within the time period)") 198 case <-succChan: 199 200 } 201 } 202 203 func TestJoinChannelNoAnchorPeers(t *testing.T) { 204 // Scenario: The channel we're joining has 2 orgs but no anchor peers 205 // The test ensures that JoinChan is called with a JoinChannelMessage with Members 206 // that consist of the organizations of the configuration given. 207 208 var joinChanCalled sync.WaitGroup 209 joinChanCalled.Add(1) 210 gMock := &gossipMock{} 211 gMock.On("JoinChan", mock.Anything, mock.Anything).Run(func(args mock.Arguments) { 212 defer joinChanCalled.Done() 213 jcm := args.Get(0).(api.JoinChannelMessage) 214 channel := args.Get(1).(common.ChannelID) 215 assert.Len(t, jcm.Members(), 2) 216 assert.Contains(t, jcm.Members(), api.OrgIdentityType("Org0")) 217 assert.Contains(t, jcm.Members(), api.OrgIdentityType("Org1")) 218 assert.Equal(t, "A", string(channel)) 219 }) 220 221 anchorPeerTracker := &anchorPeerTracker{allEndpoints: map[string]map[string]struct{}{}} 222 g := &GossipService{secAdv: &secAdvMock{}, peerIdentity: api.PeerIdentityType("Org0"), gossipSvc: gMock, anchorPeerTracker: anchorPeerTracker} 223 224 appOrg0 := &appOrgMock{id: "Org0"} 225 appOrg1 := &appOrgMock{id: "Org1"} 226 227 // Make sure the ApplicationOrgs really have no anchor peers 228 assert.Empty(t, appOrg0.AnchorPeers()) 229 assert.Empty(t, appOrg1.AnchorPeers()) 230 231 g.updateAnchors(&configMock{ 232 orgs2AppOrgs: map[string]channelconfig.ApplicationOrg{ 233 "Org0": appOrg0, 234 "Org1": appOrg1, 235 }, 236 }) 237 joinChanCalled.Wait() 238 }