Skip to content

Commit 4940b1f

Browse files
Dongmingdenyeart
authored andcommitted
[FAB-15982] gossip IT test with no leader election
This CR is to add gossip tests: [FAB-15982] a leader peer goes down then comes back should catch up all blocks with no leader election [FAB-15984] a non-leader peer, that joins an active channel, should have all blocks either with or without leader election Signed-off-by: Dongming <dongming@ibm.com> Change-Id: Ieee47d7dd582255012c3bba26d8f9fa9d60a4cea
1 parent 7b3fafc commit 4940b1f

File tree

1 file changed

+107
-77
lines changed

1 file changed

+107
-77
lines changed

integration/gossip/gossip_test.go

Lines changed: 107 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ var _ = Describe("Gossip Test", func() {
6363
os.RemoveAll(testDir)
6464
})
6565

66-
PDescribe("State transfer test", func() {
66+
PDescribe("Gossip state transfer test", func() {
6767
var (
6868
ordererProcess ifrit.Process
6969
peerProcesses = map[string]ifrit.Process{}
@@ -74,6 +74,32 @@ var _ = Describe("Gossip Test", func() {
7474
network = nwo.New(nwo.BasicSolo(), testDir, client, StartPort(), components)
7575

7676
network.GenerateConfigTree()
77+
// modify peer config
78+
// Org1: leader election
79+
// Org2: no leader election
80+
// peer0: follower
81+
// peer1: leader
82+
for _, peer := range network.Peers {
83+
if peer.Organization == "Org1" {
84+
core := network.ReadPeerConfig(peer)
85+
if peer.Name == "peer1" {
86+
core.Peer.Gossip.Bootstrap = "127.0.0.1:21004"
87+
network.WritePeerConfig(peer, core)
88+
}
89+
90+
}
91+
if peer.Organization == "Org2" {
92+
core := network.ReadPeerConfig(peer)
93+
core.Peer.Gossip.UseLeaderElection = false
94+
if peer.Name == "peer1" {
95+
core.Peer.Gossip.OrgLeader = true
96+
} else {
97+
core.Peer.Gossip.OrgLeader = false
98+
}
99+
100+
network.WritePeerConfig(peer, core)
101+
}
102+
}
77103
network.Bootstrap()
78104
})
79105

@@ -89,101 +115,61 @@ var _ = Describe("Gossip Test", func() {
89115
}
90116
})
91117

92-
It("solo network with 2 orgs, 2 peers each, should sync from the peer if no orderer available", func() {
118+
It("syncs blocks from the peer if no orderer is available, using solo network with 2 orgs, 2 peers each", func() {
93119
orderer := network.Orderer("orderer")
94120
ordererRunner := network.OrdererRunner(orderer)
95121
ordererProcess = ifrit.Invoke(ordererRunner)
96122

97123
peer0Org1, peer1Org1 := network.Peer("Org1", "peer0"), network.Peer("Org1", "peer1")
98124
peer0Org2, peer1Org2 := network.Peer("Org2", "peer0"), network.Peer("Org2", "peer1")
99125

100-
for _, peer := range []*nwo.Peer{peer0Org1, peer1Org1, peer0Org2, peer1Org2} {
101-
runner := network.PeerRunner(peer)
102-
peerProcesses[peer.ID()] = ifrit.Invoke(runner)
103-
peerRunners[peer.ID()] = runner
104-
}
126+
By("bring up all four peers")
127+
peersToBringUp := []*nwo.Peer{peer0Org1, peer1Org1, peer0Org2, peer1Org2}
128+
startPeers(network, peersToBringUp, peerProcesses, peerRunners, false)
105129

106130
channelName := "testchannel"
107131
network.CreateChannel(channelName, orderer, peer0Org1)
132+
By("join all peers to channel")
108133
network.JoinChannel(channelName, orderer, peer0Org1, peer1Org1, peer0Org2, peer1Org2)
109134

110-
nwo.DeployChaincodeLegacy(network, channelName, orderer, chaincode, peer0Org1)
111135
network.UpdateChannelAnchors(orderer, channelName)
112136

113-
for _, peer := range []*nwo.Peer{peer0Org1, peer1Org1, peer0Org2, peer1Org2} {
114-
Eventually(func() int {
115-
return nwo.GetLedgerHeight(network, peer, channelName)
116-
}, network.EventuallyTimeout).Should(BeNumerically(">=", 2))
117-
}
118-
119-
By("stop peers except peer0Org1 to make sure they cannot get blocks from orderer")
120-
for id, proc := range peerProcesses {
121-
if id == peer0Org1.ID() {
122-
continue
123-
}
124-
proc.Signal(syscall.SIGTERM)
125-
Eventually(proc.Wait(), network.EventuallyTimeout).Should(Receive())
126-
delete(peerProcesses, id)
127-
}
128-
129-
By("create transactions")
130-
runTransactions(network, orderer, peer0Org1, "mycc", channelName)
131-
132-
peer0LedgerHeight := nwo.GetLedgerHeight(network, peer0Org1, channelName)
133-
134-
By("turning down ordering service")
135-
ordererProcess.Signal(syscall.SIGTERM)
136-
Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive())
137-
ordererProcess = nil
138-
139-
By("restart the three peers that were stopped")
140-
peerList := []*nwo.Peer{peer1Org1, peer0Org2, peer1Org2}
141-
peersRestart(network, orderer, peerList, peerProcesses, peerRunners)
142-
143-
By("Make sure peers are synced up")
144-
assertPeersLedgerHeight(network, orderer, peerList, peer0LedgerHeight, channelName)
145-
146-
By("start the orderer")
147-
orderer = network.Orderer("orderer")
148-
ordererRunner = network.OrdererRunner(orderer)
149-
ordererProcess = ifrit.Invoke(ordererRunner)
150-
151-
By("install chaincode")
152-
nwo.InstallChaincodeLegacy(network, chaincode, peer1Org1)
153-
154-
By("stop leader, peer0Org1, to make sure it cannot get blocks from orderer")
155-
id := peer0Org1.ID()
156-
proc := peerProcesses[id]
157-
proc.Signal(syscall.SIGTERM)
158-
Eventually(proc.Wait(), network.EventuallyTimeout).Should(Receive())
137+
// base peer will be used for chaincode interactions
138+
basePeerForTransactions := peer0Org1
139+
nwo.DeployChaincodeLegacy(network, channelName, orderer, chaincode, basePeerForTransactions)
159140

160-
expectedMsg := "Stopped being a leader"
161-
Eventually(peerRunners[id].Err(), network.EventuallyTimeout).Should(gbytes.Say(expectedMsg))
141+
By("STATE TRANSFER TEST 1: newly joined peers should receive blocks from the peers that are already up")
162142

163-
delete(peerProcesses, id)
143+
// Note, a better test would be to bring orderer down before joining the two peers.
144+
// However, network.JoinChannel() requires orderer to be up so that genesis block can be fetched from orderer before joining peers.
145+
// Therefore, for now we've joined all four peers and stop the two peers that should be synced up.
146+
peersToStop := []*nwo.Peer{peer1Org1, peer1Org2}
147+
stopPeers(network, peersToStop, peerProcesses)
164148

165-
By("create transactions")
166-
runTransactions(network, orderer, peer1Org1, "mycc", channelName)
149+
peersToSyncUp := []*nwo.Peer{peer1Org1, peer1Org2}
150+
sendTransactionsAndSyncUpPeers(network, orderer, basePeerForTransactions, peersToSyncUp, channelName, &ordererProcess, ordererRunner, peerProcesses, peerRunners)
167151

168-
peer1LedgerHeight := nwo.GetLedgerHeight(network, peer1Org1, channelName)
152+
By("STATE TRANSFER TEST 2: restarted peers should receive blocks from the peers that are already up")
153+
basePeerForTransactions = peer1Org1
154+
nwo.InstallChaincodeLegacy(network, chaincode, basePeerForTransactions)
169155

170-
By("turning down ordering service")
171-
ordererProcess.Signal(syscall.SIGTERM)
172-
Eventually(ordererProcess.Wait(), network.EventuallyTimeout).Should(Receive())
173-
ordererProcess = nil
156+
By("stop peer0Org1 (currently elected leader in Org1) and peer1Org2 (static leader in Org2)")
157+
peersToStop = []*nwo.Peer{peer0Org1, peer1Org2}
158+
stopPeers(network, peersToStop, peerProcesses)
174159

175-
By("restart peer0Org1")
176-
peerList = []*nwo.Peer{peer0Org1}
177-
peersRestart(network, orderer, peerList, peerProcesses, peerRunners)
160+
peersToSyncUp = []*nwo.Peer{peer0Org1, peer1Org2}
161+
// Note that with the static leader in Org2 down, the static follower peer0Org2 will also get blocks via state transfer
162+
// This effectively tests leader election as well, since the newly elected leader in Org1 (peer1Org1) will be the only peer
163+
// that receives blocks from orderer and will therefore serve as the provider of blocks to all other peers.
164+
sendTransactionsAndSyncUpPeers(network, orderer, basePeerForTransactions, peersToSyncUp, channelName, &ordererProcess, ordererRunner, peerProcesses, peerRunners)
178165

179-
By("Make sure peer0Org1 is synced up")
180-
assertPeersLedgerHeight(network, orderer, peerList, peer1LedgerHeight, channelName)
181166
})
167+
182168
})
183169
})
184170

185171
func runTransactions(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, chaincodeName string, channelID string) {
186-
for i := 0; i < 10; i++ {
172+
for i := 0; i < 5; i++ {
187173
sess, err := n.PeerUserSession(peer, "User1", commands.ChaincodeInvoke{
188174
ChannelID: channelID,
189175
Orderer: n.OrdererAddress(orderer, nwo.ListenPort),
@@ -200,20 +186,64 @@ func runTransactions(n *nwo.Network, orderer *nwo.Orderer, peer *nwo.Peer, chain
200186
}
201187
}
202188

203-
func peersRestart(n *nwo.Network, orderer *nwo.Orderer, peerList []*nwo.Peer, peerProc map[string]ifrit.Process, peerRun map[string]*ginkgomon.Runner) {
204-
for _, peer := range peerList {
205-
runner := n.PeerRunner(peer, fmt.Sprint("CORE_PEER_GOSSIP_STATE_CHECKINTERVAL=200ms"),
206-
fmt.Sprint("FABRIC_LOGGING_SPEC=info:gossip.state=debug"),
207-
)
189+
func startPeers(network *nwo.Network, peersToStart []*nwo.Peer, peerProc map[string]ifrit.Process, peerRun map[string]*ginkgomon.Runner, forceStateTransfer bool) {
190+
191+
env := []string{fmt.Sprint("FABRIC_LOGGING_SPEC=info:gossip.state=debug")}
192+
193+
// Setting CORE_PEER_GOSSIP_STATE_CHECKINTERVAL to 200ms (from default of 10s) will ensure that state transfer happens quickly,
194+
// before blocks are gossipped through normal mechanisms
195+
if forceStateTransfer {
196+
env = append(env, fmt.Sprint("CORE_PEER_GOSSIP_STATE_CHECKINTERVAL=200ms"))
197+
}
198+
199+
for _, peer := range peersToStart {
200+
runner := network.PeerRunner(peer, env...)
208201
peerProc[peer.ID()] = ifrit.Invoke(runner)
209202
peerRun[peer.ID()] = runner
210203
}
211204
}
212205

213-
func assertPeersLedgerHeight(n *nwo.Network, orderer *nwo.Orderer, peerList []*nwo.Peer, expectedVal int, channelID string) {
214-
for _, peer := range peerList {
206+
func stopPeers(network *nwo.Network, peersToStop []*nwo.Peer, peerProcesses map[string]ifrit.Process) {
207+
for _, peer := range peersToStop {
208+
id := peer.ID()
209+
proc := peerProcesses[id]
210+
proc.Signal(syscall.SIGTERM)
211+
Eventually(proc.Wait(), network.EventuallyTimeout).Should(Receive())
212+
delete(peerProcesses, id)
213+
}
214+
}
215+
216+
func assertPeersLedgerHeight(n *nwo.Network, orderer *nwo.Orderer, peersToSyncUp []*nwo.Peer, expectedVal int, channelID string) {
217+
for _, peer := range peersToSyncUp {
215218
Eventually(func() int {
216219
return nwo.GetLedgerHeight(n, peer, channelID)
217220
}, n.EventuallyTimeout).Should(Equal(expectedVal))
218221
}
219222
}
223+
224+
// send transactions, stop orderering server, then start peers to ensure they received blcoks via state transfer
225+
func sendTransactionsAndSyncUpPeers(network *nwo.Network, orderer *nwo.Orderer, basePeer *nwo.Peer, peersToSyncUp []*nwo.Peer, channelName string,
226+
ordererProcess *ifrit.Process, ordererRunner *ginkgomon.Runner,
227+
peerProcesses map[string]ifrit.Process, peerRunners map[string]*ginkgomon.Runner) {
228+
229+
By("create transactions")
230+
runTransactions(network, orderer, basePeer, "mycc", channelName)
231+
basePeerLedgerHeight := nwo.GetLedgerHeight(network, basePeer, channelName)
232+
233+
By("stop orderer")
234+
(*ordererProcess).Signal(syscall.SIGTERM)
235+
Eventually((*ordererProcess).Wait(), network.EventuallyTimeout).Should(Receive())
236+
*ordererProcess = nil
237+
238+
By("start the peers contained in the peersToSyncUp list")
239+
startPeers(network, peersToSyncUp, peerProcesses, peerRunners, true)
240+
241+
By("ensure the peers are synced up")
242+
assertPeersLedgerHeight(network, orderer, peersToSyncUp, basePeerLedgerHeight, channelName)
243+
244+
By("restart orderer")
245+
orderer = network.Orderer("orderer")
246+
ordererRunner = network.OrdererRunner(orderer)
247+
*ordererProcess = ifrit.Invoke(ordererRunner)
248+
249+
}

0 commit comments

Comments
 (0)