/* Copyright IBM Corp All Rights Reserved. SPDX-License-Identifier: Apache-2.0 */ package raft import ( "fmt" "strconv" "sync" "time" "github.com/onsi/ginkgo/v2" "github.com/onsi/gomega" "github.com/onsi/gomega/gbytes" "github.com/tedsuo/ifrit/ginkgomon_v2" ) func FindLeader(ordererRunners []*ginkgomon_v2.Runner) int { var wg sync.WaitGroup wg.Add(len(ordererRunners)) findLeader := func(runner *ginkgomon_v2.Runner) int { gomega.Eventually(runner.Err(), time.Minute, time.Second).Should(gbytes.Say("Raft leader changed: [0-9] -> ")) idBuff := make([]byte, 1) _, err := runner.Err().Read(idBuff) gomega.Expect(err).NotTo(gomega.HaveOccurred()) newLeader, err := strconv.ParseInt(string(idBuff), 10, 32) gomega.Expect(err).To(gomega.BeNil()) return int(newLeader) } leaders := make(chan int, len(ordererRunners)) for _, runner := range ordererRunners { go func(runner *ginkgomon_v2.Runner) { defer ginkgo.GinkgoRecover() defer wg.Done() for { leader := findLeader(runner) if leader != 0 { leaders <- leader break } } }(runner) } wg.Wait() close(leaders) firstLeader := <-leaders for leader := range leaders { if firstLeader != leader { ginkgo.Fail(fmt.Sprintf("First leader is %d but saw %d also as a leader", firstLeader, leader)) } } return firstLeader }