This is an automated email from the ASF dual-hosted git repository.

Apache9 pushed a commit to branch branch-3
in repository https://gitbox.apache.org/repos/asf/hbase.git


The following commit(s) were added to refs/heads/branch-3 by this push:
     new 055b7d970c3 HBASE-30249 Make TestSyncReplicationStandbyKillMaster 
stable (#8393)
055b7d970c3 is described below

commit 055b7d970c37bf4a8c53f2a96d32db8ce34eab89
Author: Duo Zhang <[email protected]>
AuthorDate: Mon Jun 22 23:43:20 2026 +0800

    HBASE-30249 Make TestSyncReplicationStandbyKillMaster stable (#8393)
    
    Signed-off-by: Xiao Liu <[email protected]>
    (cherry picked from commit c726596ae6d8ce0abe09f92a0cd631725c5d58a8)
---
 .../TestSyncReplicationStandbyKillMaster.java      | 69 +++++++++++++++-------
 1 file changed, 49 insertions(+), 20 deletions(-)

diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplicationStandbyKillMaster.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplicationStandbyKillMaster.java
index e2a337504c0..5074279b7be 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplicationStandbyKillMaster.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/replication/TestSyncReplicationStandbyKillMaster.java
@@ -17,13 +17,24 @@
  */
 package org.apache.hadoop.hbase.replication;
 
+import static 
org.apache.hadoop.hbase.coprocessor.CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY;
+import static org.awaitility.Awaitility.await;
+import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertFalse;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
+import java.io.IOException;
+import java.time.Duration;
+import java.util.Optional;
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.hbase.coprocessor.MasterCoprocessor;
+import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
+import org.apache.hadoop.hbase.coprocessor.MasterObserver;
+import org.apache.hadoop.hbase.coprocessor.ObserverContext;
 import org.apache.hadoop.hbase.master.MasterFileSystem;
 import org.apache.hadoop.hbase.testclassification.LargeTests;
 import org.apache.hadoop.hbase.testclassification.ReplicationTests;
+import org.junit.jupiter.api.BeforeAll;
 import org.junit.jupiter.api.Tag;
 import org.junit.jupiter.api.Test;
 import org.slf4j.Logger;
@@ -31,14 +42,38 @@ import org.slf4j.LoggerFactory;
 
 @Tag(ReplicationTests.TAG)
 @Tag(LargeTests.TAG)
-public class TestSyncReplicationStandbyKillMaster extends 
SyncReplicationTestBase {
+public class TestSyncReplicationStandbyKillMaster extends 
SyncReplicationTestBaseNoBeforeAll {
 
   private static final Logger LOG =
     LoggerFactory.getLogger(TestSyncReplicationStandbyKillMaster.class);
 
-  private final long SLEEP_TIME = 2000;
+  private static final int COUNT = 1000;
 
-  private final int COUNT = 1000;
+  private static volatile boolean KILL_MASTER = false;
+
+  public static final class TransitCP implements MasterCoprocessor, 
MasterObserver {
+
+    @Override
+    public void preTransitReplicationPeerSyncReplicationState(
+      ObserverContext<MasterCoprocessorEnvironment> ctx, String peerId, 
SyncReplicationState state)
+      throws IOException {
+      if (KILL_MASTER) {
+        KILL_MASTER = false;
+        UTIL2.getMiniHBaseCluster().getMaster().abort("Stop master for test");
+      }
+    }
+
+    @Override
+    public Optional<MasterObserver> getMasterObserver() {
+      return Optional.of(this);
+    }
+  }
+
+  @BeforeAll
+  public static void setUp() throws Exception {
+    UTIL2.getConfiguration().set(MASTER_COPROCESSOR_CONF_KEY, 
TransitCP.class.getName());
+    startClusters();
+  }
 
   @Test
   public void testStandbyKillMaster() throws Exception {
@@ -56,30 +91,24 @@ public class TestSyncReplicationStandbyKillMaster extends 
SyncReplicationTestBas
     write(UTIL1, 0, COUNT);
     UTIL1.shutdownMiniCluster();
 
-    Thread t = new Thread(() -> {
-      try {
-        Thread.sleep(SLEEP_TIME);
-        UTIL2.getMiniHBaseCluster().getMaster().stop("Stop master for test");
-      } catch (Exception e) {
-        LOG.error("Failed to stop master", e);
-      }
-    });
-    t.start();
-
+    KILL_MASTER = true;
     // Transit standby to DA to replay logs
     try {
       UTIL2.getAdmin().transitReplicationPeerSyncReplicationState(PEER_ID,
         SyncReplicationState.DOWNGRADE_ACTIVE);
     } catch (Exception e) {
-      LOG.error("Failed to transit standby cluster to " + 
SyncReplicationState.DOWNGRADE_ACTIVE);
+      // we will kill master in the transit procedure's preCheck method, not 
in the rpc thread, so
+      // we can not know whether we could successfully get the returned proc 
id. If we can get the
+      // proc id, the call should be succeeded and we will not arrive here, 
and the below await
+      // check will pass immediately, if not, we will get this exception and 
then we need to rely on
+      // the below await check to make sure the transition is successfully 
finished.
+      LOG.warn("Failed to transit standby cluster to {}", 
SyncReplicationState.DOWNGRADE_ACTIVE);
     }
 
-    while (
-      UTIL2.getAdmin().getReplicationPeerSyncReplicationState(PEER_ID)
-          != SyncReplicationState.DOWNGRADE_ACTIVE
-    ) {
-      Thread.sleep(SLEEP_TIME);
-    }
+    await().atMost(Duration.ofMinutes(3))
+      .untilAsserted(() -> assertEquals(SyncReplicationState.DOWNGRADE_ACTIVE,
+        UTIL2.getAdmin().getReplicationPeerSyncReplicationState(PEER_ID)));
+
     verify(UTIL2, 0, COUNT);
   }
 }

Reply via email to