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);
}
}