Skip to content

Commit e7b3c7a

Browse files
[FAB-2576] Fix LE and gossip integration test
While using real gossip as communication middleware for leader election it become impossible to point to what peer will become leader after previous leader shutdown. So test was changed to check only amount of leaders, but not what peer is a leader. Change-Id: Iac745a3e6a7e3ba66702dc4a73ca82e074d64dd0 Signed-off-by: Gennady Laventman <[email protected]>
1 parent 94505fc commit e7b3c7a

File tree

1 file changed

+82
-53
lines changed

1 file changed

+82
-53
lines changed

gossip/service/gossip_service_test.go

+82-53
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ import (
3939
"github.com/hyperledger/fabric/msp/mgmt/testtools"
4040
"github.com/hyperledger/fabric/peer/gossip/mcs"
4141
"github.com/hyperledger/fabric/protos/common"
42+
"github.com/op/go-logging"
4243
"github.com/spf13/viper"
4344
"github.com/stretchr/testify/assert"
4445
"google.golang.org/grpc"
@@ -105,7 +106,7 @@ func TestLeaderElectionWithDeliverClient(t *testing.T) {
105106
}
106107
addPeersToChannel(t, n, 10000, channelName, gossips, peerIndexes)
107108

108-
waitForFullMembership(t, gossips, n, time.Second*30, time.Second*2)
109+
waitForFullMembership(t, gossips, n, time.Second*20, time.Second*2)
109110

110111
services := make([]*electionService, n)
111112

@@ -119,20 +120,26 @@ func TestLeaderElectionWithDeliverClient(t *testing.T) {
119120
deliverServiceFactory.service.running[channelName] = false
120121

121122
gossips[i].InitializeChannel(channelName, &mockLedgerInfo{0}, []string{"localhost:5005"})
123+
gossips[i].(*gossipServiceImpl).chains[channelName].Stop()
122124
service, exist := gossips[i].(*gossipServiceImpl).leaderElection[channelName]
123125
assert.True(t, exist, "Leader election service should be created for peer %d and channel %s", i, channelName)
124126
services[i] = &electionService{nil, false, 0}
125127
services[i].LeaderElectionService = service
126128
}
127129

128-
assert.True(t, waitForLeaderElection(t, services, 0, time.Second*30, time.Second*2), "One leader (peer 0) should be selected")
129-
130-
assert.True(t, gossips[0].(*gossipServiceImpl).deliveryService.(*mockDeliverService).running[channelName], "Delivery service should be started in peer %d", 0)
130+
// Is single leader was elected.
131+
assert.True(t, waitForLeaderElection(t, services, time.Second*30, time.Second*2), "One leader should be selected")
131132

132-
for i := 1; i < n; i++ {
133-
assert.False(t, gossips[i].(*gossipServiceImpl).deliveryService.(*mockDeliverService).running[channelName], "Delivery service should not be started in peer %d", i)
133+
startsNum := 0
134+
for i := 0; i < n; i++ {
135+
// Is mockDeliverService.StartDeliverForChannel in current peer for the specific channel was invoked
136+
if gossips[i].(*gossipServiceImpl).deliveryService.(*mockDeliverService).running[channelName] {
137+
startsNum++
138+
}
134139
}
135140

141+
assert.Equal(t, 1, startsNum, "Only for one peer delivery client should start")
142+
136143
stopPeers(gossips)
137144
}
138145

@@ -170,6 +177,7 @@ func TestWithStaticDeliverClientLeader(t *testing.T) {
170177
gossips[i].(*gossipServiceImpl).deliveryFactory = deliverServiceFactory
171178
deliverServiceFactory.service.running[channelName] = false
172179
gossips[i].InitializeChannel(channelName, &mockLedgerInfo{0}, []string{"localhost:5005"})
180+
gossips[i].(*gossipServiceImpl).chains[channelName].Stop()
173181
}
174182

175183
for i := 0; i < n; i++ {
@@ -218,6 +226,7 @@ func TestWithStaticDeliverClientNotLeader(t *testing.T) {
218226
gossips[i].(*gossipServiceImpl).deliveryFactory = deliverServiceFactory
219227
deliverServiceFactory.service.running[channelName] = false
220228
gossips[i].InitializeChannel(channelName, &mockLedgerInfo{0}, []string{"localhost:5005"})
229+
gossips[i].(*gossipServiceImpl).chains[channelName].Stop()
221230
}
222231

223232
for i := 0; i < n; i++ {
@@ -302,15 +311,14 @@ func (li *mockLedgerInfo) Commit(block *common.Block) error {
302311

303312
// Gets blocks with sequence numbers provided in the slice
304313
func (li *mockLedgerInfo) GetBlocks(blockSeqs []uint64) []*common.Block {
305-
return nil
314+
return make([]*common.Block, 0)
306315
}
307316

308317
// Closes committing service
309318
func (li *mockLedgerInfo) Close() {
310319
}
311320

312321
func TestLeaderElectionWithRealGossip(t *testing.T) {
313-
t.Skip()
314322

315323
// Spawn 10 gossip instances with single channel and inside same organization
316324
// Run leader election on top of each gossip instance and check that only one leader chosen
@@ -319,6 +327,9 @@ func TestLeaderElectionWithRealGossip(t *testing.T) {
319327
// Check correct leader still exist for first channel and new correct leader chosen in second channel
320328
// Stop gossip instances of leader peers for both channels and see that new leader chosen for both
321329

330+
logging.SetLevel(logging.DEBUG, util.LoggingElectionModule)
331+
logging.SetLevel(logging.DEBUG, util.LoggingServiceModule)
332+
322333
// Creating gossip service instances for peers
323334
n := 10
324335
gossips := startPeers(t, n, 10000)
@@ -335,7 +346,7 @@ func TestLeaderElectionWithRealGossip(t *testing.T) {
335346

336347
logger.Warning("Starting leader election services")
337348

338-
//Stariting leader election services
349+
//Starting leader election services
339350
services := make([]*electionService, n)
340351

341352
for i := 0; i < n; i++ {
@@ -345,13 +356,17 @@ func TestLeaderElectionWithRealGossip(t *testing.T) {
345356

346357
logger.Warning("Waiting for leader election")
347358

348-
assert.True(t, waitForLeaderElection(t, services, 0, time.Second*30, time.Second*2), "One leader (peer 0) should be selected")
349-
assert.True(t, services[0].callbackInvokeRes, "Callback func for peer 0 should be called (chanA)")
359+
assert.True(t, waitForLeaderElection(t, services, time.Second*30, time.Second*2), "One leader should be selected")
350360

351-
for i := 1; i < n; i++ {
352-
assert.False(t, services[i].callbackInvokeRes, "Callback func for peer %d should not be called (chanA)", i)
353-
assert.False(t, services[i].IsLeader(), "Peer %d should not be leader in chanA", i)
361+
startsNum := 0
362+
for i := 0; i < n; i++ {
363+
// Is callback function was invoked by this leader election service instance
364+
if services[i].callbackInvokeRes {
365+
startsNum++
366+
}
354367
}
368+
//Only leader should invoke callback function, so it is double check that only one leader exists
369+
assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanA")
355370

356371
// Adding some peers to new channel and creating leader election services for peers in new channel
357372
// Expecting peer 1 (first in list of election services) to become leader of second channel
@@ -365,39 +380,52 @@ func TestLeaderElectionWithRealGossip(t *testing.T) {
365380
secondChannelServices[idx].LeaderElectionService = gossips[i].(*gossipServiceImpl).newLeaderElectionComponent(gossipCommon.ChainID(secondChannelName), secondChannelServices[idx].callback)
366381
}
367382

368-
assert.True(t, waitForLeaderElection(t, secondChannelServices, 0, time.Second*30, time.Second*2), "One leader (peer 1) should be selected")
369-
assert.True(t, waitForLeaderElection(t, services, 0, time.Second*30, time.Second*2), "One leader (peer 0) should be selected")
383+
assert.True(t, waitForLeaderElection(t, secondChannelServices, time.Second*30, time.Second*2), "One leader should be selected for chanB")
384+
assert.True(t, waitForLeaderElection(t, services, time.Second*30, time.Second*2), "One leader should be selected for chanA")
370385

371-
assert.True(t, services[0].callbackInvokeRes, "Callback func for peer 0 should be called (chanA)")
372-
for i := 1; i < n; i++ {
373-
assert.False(t, services[i].callbackInvokeRes, "Callback func for peer %d should not be called (chanA)", i)
374-
assert.False(t, services[i].IsLeader(), "Peer %d should not be leader in chanA", i)
386+
startsNum = 0
387+
for i := 0; i < n; i++ {
388+
if services[i].callbackInvokeRes {
389+
startsNum++
390+
}
375391
}
392+
assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanA")
376393

377-
assert.True(t, secondChannelServices[0].callbackInvokeRes, "Callback func for peer 1 should be called (chanB)")
378-
for i := 1; i < len(secondChannelServices); i++ {
379-
assert.False(t, secondChannelServices[i].callbackInvokeRes, "Callback func for peer %d should not be called (chanB)", secondChannelPeerIndexes[i])
380-
assert.False(t, secondChannelServices[i].IsLeader(), "Peer %d should not be leader in chanB", i)
394+
startsNum = 0
395+
for i := 0; i < len(secondChannelServices); i++ {
396+
if secondChannelServices[i].callbackInvokeRes {
397+
startsNum++
398+
}
381399
}
400+
assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called - chanB")
382401

383402
//Stopping 2 gossip instances(peer 0 and peer 1), should init re-election
384403
//Now peer 2 become leader for first channel and peer 3 for second channel
404+
405+
logger.Warning("Killing 2 peers, initiation new leader election")
406+
385407
stopPeers(gossips[:2])
386408

387-
assert.True(t, waitForLeaderElection(t, secondChannelServices[1:], 0, time.Second*30, time.Second*2), "One leader (peer 2) should be selected")
388-
assert.True(t, waitForLeaderElection(t, services[2:], 0, time.Second*30, time.Second*2), "One leader (peer 3) should be selected")
409+
waitForFullMembership(t, gossips[2:], n-2, time.Second*30, time.Second*2)
410+
411+
assert.True(t, waitForLeaderElection(t, services[2:], time.Second*30, time.Second*2), "One leader should be selected after re-election - chanA")
412+
assert.True(t, waitForLeaderElection(t, secondChannelServices[1:], time.Second*30, time.Second*2), "One leader should be selected after re-election - chanB")
389413

390-
assert.True(t, services[2].callbackInvokeRes, "Callback func for peer 2 should be called (chanA)")
391-
for i := 3; i < n; i++ {
392-
assert.False(t, services[i].callbackInvokeRes, "Callback func for peer %d should not be called (chanA)", i)
393-
assert.False(t, services[i].IsLeader(), "Peer %d should not be leader in chanA", i)
414+
startsNum = 0
415+
for i := 2; i < n; i++ {
416+
if services[i].callbackInvokeRes {
417+
startsNum++
418+
}
394419
}
420+
assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called after re-election - chanA")
395421

396-
assert.True(t, secondChannelServices[1].callbackInvokeRes, "Callback func for peer 3 should be called (chanB)")
397-
for i := 2; i < len(secondChannelServices); i++ {
398-
assert.False(t, secondChannelServices[i].callbackInvokeRes, "Callback func for peer %d should not be called (chanB)", secondChannelPeerIndexes[i])
399-
assert.False(t, secondChannelServices[i].IsLeader(), "Peer %d should not be leader in chanB", i)
422+
startsNum = 0
423+
for i := 1; i < len(secondChannelServices); i++ {
424+
if secondChannelServices[i].callbackInvokeRes {
425+
startsNum++
426+
}
400427
}
428+
assert.Equal(t, 1, startsNum, "Only for one peer callback function should be called after re-election - chanB")
401429

402430
stopServices(secondChannelServices)
403431
stopServices(services)
@@ -452,36 +480,37 @@ func waitForFullMembership(t *testing.T, gossips []GossipService, peersNum int,
452480
return false
453481
}
454482

455-
func waitForMultipleLeadersElection(t *testing.T, services []*electionService, leadersNum int, leaderIndexes []int, timeout time.Duration, testPollInterval time.Duration) bool {
483+
func waitForMultipleLeadersElection(t *testing.T, services []*electionService, leadersNum int, timeout time.Duration, testPollInterval time.Duration) bool {
484+
logger.Warning("Waiting for", leadersNum, "leaders")
456485
end := time.Now().Add(timeout)
486+
correctNumberOfLeadersFound := false
487+
leaders := 0
457488
for time.Now().Before(end) {
458-
leaders := 0
459-
incorrectLeaders := false
460-
for i, s := range services {
489+
leaders = 0
490+
for _, s := range services {
461491
if s.IsLeader() {
462-
expectedLeader := false
463-
for _, index := range leaderIndexes {
464-
if i == index {
465-
leaders++
466-
expectedLeader = true
467-
}
468-
}
469-
if !expectedLeader {
470-
logger.Warning("Incorrect peer", i, "become leader")
471-
incorrectLeaders = true
472-
}
492+
leaders++
473493
}
474494
}
475-
if leaders == leadersNum && !incorrectLeaders {
476-
return true
495+
if leaders == leadersNum {
496+
if correctNumberOfLeadersFound {
497+
return true
498+
}
499+
correctNumberOfLeadersFound = true
500+
} else {
501+
correctNumberOfLeadersFound = false
477502
}
478503
time.Sleep(testPollInterval)
479504
}
505+
logger.Warning("Incorrect number of leaders", leaders)
506+
for i, s := range services {
507+
logger.Warning("Peer at index", i, "is leader", s.IsLeader())
508+
}
480509
return false
481510
}
482511

483-
func waitForLeaderElection(t *testing.T, services []*electionService, leaderIndex int, timeout time.Duration, testPollInterval time.Duration) bool {
484-
return waitForMultipleLeadersElection(t, services, 1, []int{leaderIndex}, timeout, testPollInterval)
512+
func waitForLeaderElection(t *testing.T, services []*electionService, timeout time.Duration, testPollInterval time.Duration) bool {
513+
return waitForMultipleLeadersElection(t, services, 1, timeout, testPollInterval)
485514
}
486515

487516
func waitUntilOrFailBlocking(t *testing.T, f func(), timeout time.Duration) {

0 commit comments

Comments
 (0)