github.com/darrenli6/fabric-sdk-example@v0.0.0-20220109053535-94b13b56df8c/gossip/service/integration_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 "fmt" 11 "sync" 12 "testing" 13 "time" 14 15 "github.com/hyperledger/fabric/core/deliverservice" 16 "github.com/hyperledger/fabric/core/deliverservice/blocksprovider" 17 "github.com/hyperledger/fabric/gossip/api" 18 "github.com/hyperledger/fabric/gossip/election" 19 "github.com/hyperledger/fabric/gossip/identity" 20 "github.com/hyperledger/fabric/gossip/state" 21 "github.com/spf13/viper" 22 "github.com/stretchr/testify/assert" 23 ) 24 25 type embeddingDeliveryService struct { 26 deliverclient.DeliverService 27 startSignal sync.WaitGroup 28 stopSignal sync.WaitGroup 29 } 30 31 func newEmbeddingDeliveryService(ds deliverclient.DeliverService) *embeddingDeliveryService { 32 eds := &embeddingDeliveryService{ 33 DeliverService: ds, 34 } 35 eds.startSignal.Add(1) 36 eds.stopSignal.Add(1) 37 return eds 38 } 39 40 func (eds *embeddingDeliveryService) waitForDeliveryServiceActivation() { 41 eds.startSignal.Wait() 42 } 43 44 func (eds *embeddingDeliveryService) waitForDeliveryServiceTermination() { 45 eds.stopSignal.Wait() 46 } 47 48 func (eds *embeddingDeliveryService) StartDeliverForChannel(chainID string, ledgerInfo blocksprovider.LedgerInfo, finalizer func()) error { 49 eds.startSignal.Done() 50 return eds.DeliverService.StartDeliverForChannel(chainID, ledgerInfo, finalizer) 51 } 52 53 func (eds *embeddingDeliveryService) StopDeliverForChannel(chainID string) error { 54 eds.stopSignal.Done() 55 return eds.DeliverService.StopDeliverForChannel(chainID) 56 } 57 58 func (eds *embeddingDeliveryService) Stop() { 59 eds.DeliverService.Stop() 60 } 61 62 type embeddingDeliveryServiceFactory struct { 63 DeliveryServiceFactory 64 } 65 66 func (edsf *embeddingDeliveryServiceFactory) Service(g GossipService, endpoints []string, mcs api.MessageCryptoService) (deliverclient.DeliverService, error) { 67 ds, _ := edsf.DeliveryServiceFactory.Service(g, endpoints, mcs) 68 return newEmbeddingDeliveryService(ds), nil 69 } 70 71 func TestLeaderYield(t *testing.T) { 72 // Scenario: Spawn 2 peers and wait for the first one to be the leader 73 // There isn't any orderer present so the leader peer won't be able to 74 // connect to the orderer, and should relinquish its leadership after a while. 75 // Make sure the other peer declares itself as the leader soon after. 76 deliverclient.SetReconnectTotalTimeThreshold(time.Second * 5) 77 viper.Set("peer.gossip.useLeaderElection", true) 78 viper.Set("peer.gossip.orgLeader", false) 79 n := 2 80 portPrefix := 30000 81 gossips := startPeers(t, n, portPrefix) 82 defer stopPeers(gossips) 83 channelName := "channelA" 84 peerIndexes := []int{0, 1} 85 // Add peers to the channel 86 addPeersToChannel(t, n, portPrefix, channelName, gossips, peerIndexes) 87 // Prime the membership view of the peers 88 waitForFullMembership(t, gossips, n, time.Second*30, time.Second*2) 89 mcs := &naiveCryptoService{} 90 // Helper function that creates a gossipService instance 91 newGossipService := func(i int) *gossipServiceImpl { 92 peerIdentity := api.PeerIdentityType(fmt.Sprintf("localhost:%d", portPrefix+i)) 93 gs := &gossipServiceImpl{ 94 mcs: mcs, 95 gossipSvc: gossips[i], 96 chains: make(map[string]state.GossipStateProvider), 97 leaderElection: make(map[string]election.LeaderElectionService), 98 deliveryFactory: &embeddingDeliveryServiceFactory{&deliveryFactoryImpl{}}, 99 idMapper: identity.NewIdentityMapper(mcs, peerIdentity), 100 peerIdentity: peerIdentity, 101 secAdv: &secAdvMock{}, 102 } 103 gossipServiceInstance = gs 104 gs.InitializeChannel(channelName, &mockLedgerInfo{1}, []string{"localhost:7050"}) 105 return gs 106 } 107 108 p0 := newGossipService(0) 109 p1 := newGossipService(1) 110 111 // Returns index of the leader or -1 if no leader elected 112 getLeader := func() int { 113 if p0.leaderElection[channelName].IsLeader() { 114 // Ensure p1 isn't a leader at the same time 115 assert.False(t, p1.leaderElection[channelName].IsLeader()) 116 return 0 117 } 118 if p1.leaderElection[channelName].IsLeader() { 119 return 1 120 } 121 return -1 122 } 123 124 ds0 := p0.deliveryService.(*embeddingDeliveryService) 125 ds1 := p1.deliveryService.(*embeddingDeliveryService) 126 127 // Wait for p0 to connect to the ordering service 128 ds0.waitForDeliveryServiceActivation() 129 t.Log("p0 started its delivery service") 130 // Ensure it's a leader 131 assert.Equal(t, 0, getLeader()) 132 // Wait for p0 to lose its leadership 133 ds0.waitForDeliveryServiceTermination() 134 t.Log("p0 stopped its delivery service") 135 // Ensure there is no leader 136 assert.Equal(t, -1, getLeader()) 137 // Wait for p1 to take over 138 ds1.waitForDeliveryServiceActivation() 139 t.Log("p1 started its delivery service") 140 // Ensure it's a leader now 141 assert.Equal(t, 1, getLeader()) 142 p0.chains[channelName].Stop() 143 p1.chains[channelName].Stop() 144 p0.deliveryService.Stop() 145 p1.deliveryService.Stop() 146 }