@@ -157,7 +157,7 @@ public void testOpenLedgers() throws Exception {
157157 List <LedgerHandle > listOfLedgerHandle = createLedgersAndAddEntries (1 , 5 );
158158 LedgerHandle lh = listOfLedgerHandle .get (0 );
159159 int ledgerReplicaIndex = 0 ;
160- BookieId replicaToKillAddr = lh . getLedgerMetadata (). getAllEnsembles (). get ( 0L ). get ( 0 );
160+ BookieId replicaToKillAddr = pickReplicaNotAuditor ( lh );
161161
162162 final String urLedgerZNode = getUrLedgerZNode (lh );
163163 ledgerReplicaIndex = getReplicaIndexInLedger (lh , replicaToKillAddr );
@@ -211,7 +211,7 @@ public void testClosedLedgers() throws Exception {
211211 closeLedgers (listOfLedgerHandle );
212212 LedgerHandle lhandle = listOfLedgerHandle .get (0 );
213213 int ledgerReplicaIndex = 0 ;
214- BookieId replicaToKillAddr = lhandle . getLedgerMetadata (). getAllEnsembles (). get ( 0L ). get ( 0 );
214+ BookieId replicaToKillAddr = pickReplicaNotAuditor ( lhandle );
215215
216216 CountDownLatch latch = new CountDownLatch (listOfLedgerHandle .size ());
217217 for (LedgerHandle lh : listOfLedgerHandle ) {
@@ -277,8 +277,7 @@ public void testStopWhileReplicationInProgress() throws Exception {
277277 List <LedgerHandle > listOfLedgerHandle = createLedgersAndAddEntries (
278278 numberOfLedgers , 5 );
279279 closeLedgers (listOfLedgerHandle );
280- LedgerHandle handle = listOfLedgerHandle .get (0 );
281- BookieId replicaToKillAddr = handle .getLedgerMetadata ().getAllEnsembles ().get (0L ).get (0 );
280+ BookieId replicaToKillAddr = pickReplicaNotAuditor (listOfLedgerHandle .get (0 ));
282281 LOG .info ("Killing Bookie:" + replicaToKillAddr );
283282
284283 // Each ledger, there will be two events : create urLedger and after
@@ -362,13 +361,7 @@ public void testNoSuchLedgerExists() throws Exception {
362361 assertNull ("UrLedger already exists!" ,
363362 watchUrLedgerNode (getUrLedgerZNode (lh ), latch ));
364363 }
365- BookieId replicaToKillAddr = listOfLedgerHandle .get (0 )
366- .getLedgerMetadata ().getAllEnsembles ()
367- .get (0L ).get (0 );
368- killBookie (replicaToKillAddr );
369- replicaToKillAddr = listOfLedgerHandle .get (0 )
370- .getLedgerMetadata ().getAllEnsembles ()
371- .get (0L ).get (0 );
364+ BookieId replicaToKillAddr = pickReplicaNotAuditor (listOfLedgerHandle .get (0 ));
372365 killBookie (replicaToKillAddr );
373366 // waiting to publish urLedger znode by Auditor
374367 assertTrue ("Ledgers should be marked as underreplicated" ,
@@ -405,13 +398,34 @@ public void testNoSuchLedgerExists() throws Exception {
405398 public void testEmptyLedgerLosesQuorumEventually () throws Exception {
406399 LOG .info ("Start testEmptyLedgerLosesQuorumEventually" );
407400 LedgerHandle lh = bkc .createLedger (3 , 2 , 2 , DigestType .CRC32 , PASSWD );
401+ List <BookieId > ensembleBookies = lh .getLedgerMetadata ().getAllEnsembles ().get (0L );
402+
403+ // Pin the Auditor onto ensemble[0] by stopping AutoRecovery on the bookies
404+ // the test will kill (ensemble[1] and ensemble[2]). Otherwise the slow ZK
405+ // leader-failover path blows past the 20s assertion timeouts in CI.
406+ for (int i = 1 ; i <= 2 ; i ++) {
407+ BookieId killTarget = ensembleBookies .get (i );
408+ for (ServerTester t : servers ) {
409+ if (t .getServer ().getBookieId ().equals (killTarget )) {
410+ t .stopAutoRecovery ();
411+ }
412+ }
413+ }
414+ BookieId safeBookie = ensembleBookies .get (0 );
415+ long deadline = System .nanoTime () + TimeUnit .SECONDS .toNanos (30 );
416+ while (!safeBookie .equals (getAuditorBookieId ())) {
417+ if (System .nanoTime () > deadline ) {
418+ throw new IllegalStateException ("Auditor did not settle on ensemble[0]: " + safeBookie );
419+ }
420+ Thread .sleep (200 );
421+ }
422+
408423 CountDownLatch latch = new CountDownLatch (1 );
409424 String urZNode = getUrLedgerZNode (lh );
410425 watchUrLedgerNode (urZNode , latch );
411426
412- BookieId replicaToKill = lh .getLedgerMetadata ().getAllEnsembles ().get (0L ).get (2 );
413- LOG .info ("Killing last bookie, {}, in ensemble {}" , replicaToKill ,
414- lh .getLedgerMetadata ().getAllEnsembles ().get (0L ));
427+ BookieId replicaToKill = ensembleBookies .get (2 );
428+ LOG .info ("Killing last bookie, {}, in ensemble {}" , replicaToKill , ensembleBookies );
415429 killBookie (replicaToKill );
416430 startNewBookie ();
417431
@@ -618,6 +632,29 @@ private int getReplicaIndexInLedger(LedgerHandle lh, BookieId replicaToKill) {
618632 return ledgerReplicaIndex ;
619633 }
620634
635+ private BookieId getAuditorBookieId () throws Exception {
636+ Auditor auditor = getAuditor (10 , TimeUnit .SECONDS );
637+ for (ServerTester t : servers ) {
638+ if (t .getAuditor () == auditor ) {
639+ return t .getServer ().getBookieId ();
640+ }
641+ }
642+ throw new IllegalStateException ("Auditor not found in cluster" );
643+ }
644+
645+ // Killing the Auditor leader triggers a slow ZK leader-failover path that
646+ // routinely exceeds these tests' latch timeouts in CI; pick a non-Auditor
647+ // bookie from the ensemble instead.
648+ private BookieId pickReplicaNotAuditor (LedgerHandle lh ) throws Exception {
649+ BookieId auditorId = getAuditorBookieId ();
650+ for (BookieId addr : lh .getLedgerMetadata ().getAllEnsembles ().get (0L )) {
651+ if (!addr .equals (auditorId )) {
652+ return addr ;
653+ }
654+ }
655+ throw new IllegalStateException ("All ensemble bookies are the Auditor" );
656+ }
657+
621658 private void verifyLedgerEnsembleMetadataAfterReplication (
622659 BookieServer newBookieServer , LedgerHandle lh ,
623660 int ledgerReplicaIndex ) throws Exception {
0 commit comments