kadirozde commented on code in PR #2310:
URL: https://github.com/apache/phoenix/pull/2310#discussion_r2599942117
##########
phoenix-core/src/it/java/org/apache/phoenix/jdbc/PhoenixHAAdminToolIT.java:
##########
@@ -60,264 +73,893 @@ public class PhoenixHAAdminToolIT {
private static final ByteArrayOutputStream STDOUT_CAPTURE = new
ByteArrayOutputStream();
private String haGroupName;
- private ClusterRoleRecord recordV1, recordV2; // two versions of record
for the same HA group
- private PhoenixHAAdminTool admin; // the HA admin to test; it's against
cluster1.
+ private PhoenixHAAdminTool adminTool;
@Rule
public final TestName testName = new TestName();
+ @Rule
+ public final TestWatcher testWatcher = new TestWatcher() {
+ @Override
+ protected void failed(Throwable e, Description description) {
+ // Print captured stdout if test failed and there's content
+ String capturedOutput = STDOUT_CAPTURE.toString();
+ if (!capturedOutput.isEmpty()) {
+ System.err.println("\n=============== CAPTURED STDOUT (Test
Failed) ===============");
+ System.err.println(capturedOutput);
+
System.err.println("=============================================================\n");
+ }
+ }
+ };
+
@BeforeClass
public static void setUpBeforeClass() throws Exception {
CLUSTERS.start();
}
@AfterClass
public static void tearDownAfterClass() throws Exception {
- getCurator1().close();
- getCurator2().close();
CLUSTERS.close();
}
@Before
public void setup() throws Exception {
- admin = new PhoenixHAAdminTool();
- admin.setConf(CLUSTERS.getHBaseCluster1().getConfiguration());
- haGroupName = testName.getMethodName();
- recordV1 = new ClusterRoleRecord(
- haGroupName, HighAvailabilityPolicy.FAILOVER,
- CLUSTERS.getMasterAddress1(), ClusterRole.ACTIVE,
- CLUSTERS.getMasterAddress2(), ClusterRole.STANDBY,
- 1);
- String jsonFileName =
ClusterRoleRecordTest.createJsonFileWithRecords(recordV1);
- int ret = admin.run(new String[]{"-m", jsonFileName});
- if(ret != RET_SUCCESS) {
- throw new RuntimeException("Failed to create initial records");
+ // Clean up all HA group records from both clusters before starting
test
+ try {
+ String zkUrl1 = CLUSTERS.getZkUrl1();
+ String zkUrl2 = CLUSTERS.getZkUrl2();
+
+ // Clean up cluster 1
+ try (PhoenixHAAdmin haAdmin1 = new PhoenixHAAdmin(
+ CLUSTERS.getHBaseCluster1().getConfiguration(),
+ ZK_CONSISTENT_HA_GROUP_RECORD_NAMESPACE)) {
+
+ List<String> haGroupNames =
HAGroupStoreClient.getHAGroupNames(zkUrl1);
+ for (String name : haGroupNames) {
+ try {
+ // Delete from ZK
+ haAdmin1.deleteHAGroupStoreRecordInZooKeeper(name);
+ // Delete from system table
+
HAGroupStoreTestUtil.deleteHAGroupRecordInSystemTable(name, zkUrl1);
+ } catch (Exception e) {
+ LOG.warn("Failed to cleanup HA group: " + name, e);
+ }
+ }
+ }
+
+ // Clean up cluster 2
+ try (PhoenixHAAdmin haAdmin2 = new PhoenixHAAdmin(
+ CLUSTERS.getHBaseCluster2().getConfiguration(),
+ ZK_CONSISTENT_HA_GROUP_RECORD_NAMESPACE)) {
+
+ List<String> haGroupNames =
HAGroupStoreClient.getHAGroupNames(zkUrl2);
+ for (String name : haGroupNames) {
+ try {
+ // Delete from ZK
+ haAdmin2.deleteHAGroupStoreRecordInZooKeeper(name);
+ // Delete from system table
+
HAGroupStoreTestUtil.deleteHAGroupRecordInSystemTable(name, zkUrl2);
+ } catch (Exception e) {
+ LOG.warn("Failed to cleanup HA group from cluster 2: "
+ name, e);
+ }
+ }
+ }
+
+ } catch (Exception e) {
+ LOG.warn("Error during cleanup", e);
+ // Don't fail the test due to cleanup errors
}
- // the V2 record is for the same HA group; it is created but not
populated yet
- recordV2 = new ClusterRoleRecord(
- haGroupName, HighAvailabilityPolicy.FAILOVER,
- CLUSTERS.getMasterAddress1(), ClusterRole.STANDBY,
- CLUSTERS.getMasterAddress2(), ClusterRole.ACTIVE,
- 2);
+
+ adminTool = new PhoenixHAAdminTool();
+ adminTool.setConf(CLUSTERS.getHBaseCluster1().getConfiguration());
+
+ haGroupName = testName.getMethodName();
+
+ // Insert multiple HAGroupStoreRecords into the SYSTEM.HA_GROUP table
with completely unique names
+ // Using distinct names without common prefixes to avoid validation
issues
+
+ // Group 1 - Active cluster group
+ HAGroupStoreTestUtil.upsertHAGroupRecordInSystemTable(
+ "prod_cluster_alpha",
+ CLUSTERS.getZkUrl1(),
+ CLUSTERS.getZkUrl2(),
+ CLUSTERS.getMasterAddress1(),
+ CLUSTERS.getMasterAddress2(),
+ ClusterRoleRecord.ClusterRole.ACTIVE,
+ ClusterRoleRecord.ClusterRole.STANDBY,
+ null);
+
+ // Group 2 - Standby cluster group
+ HAGroupStoreTestUtil.upsertHAGroupRecordInSystemTable(
+ "disaster_recovery_beta",
+ CLUSTERS.getZkUrl1(),
+ CLUSTERS.getZkUrl2(),
+ CLUSTERS.getMasterAddress1(),
+ CLUSTERS.getMasterAddress2(),
+ ClusterRoleRecord.ClusterRole.STANDBY,
+ ClusterRoleRecord.ClusterRole.ACTIVE,
+ null);
+
+ // Group 3 - Test-specific group (uses test method name for uniqueness
across test runs)
+ HAGroupStoreTestUtil.upsertHAGroupRecordInSystemTable(
+ haGroupName,
+ CLUSTERS.getZkUrl1(),
+ CLUSTERS.getZkUrl2(),
+ CLUSTERS.getMasterAddress1(),
+ CLUSTERS.getMasterAddress2(),
+ ClusterRoleRecord.ClusterRole.ACTIVE,
+ ClusterRoleRecord.ClusterRole.STANDBY,
+ null);
+
+ // Clear stdout capture
+ STDOUT_CAPTURE.reset();
}
@After
- public void after() {
+ public void after() throws Exception {
// reset STDOUT in case it was captured for testing
System.setOut(STDOUT);
+
+ // Clean up all HA group records from both clusters after each test
+ try {
+ String zkUrl1 = CLUSTERS.getZkUrl1();
+ String zkUrl2 = CLUSTERS.getZkUrl2();
+
+ // Clean up cluster 1
+ try (PhoenixHAAdmin haAdmin1 = new PhoenixHAAdmin(
+ CLUSTERS.getHBaseCluster1().getConfiguration(),
+ ZK_CONSISTENT_HA_GROUP_RECORD_NAMESPACE)) {
+
+ // Delete all ZNodes in the namespace
+
haAdmin1.getCurator().delete().quietly().deletingChildrenIfNeeded()
+ .forPath(toPath(""));
+ LOG.info("Cleaned up all ZK records from cluster 1");
+
+ // Delete all records from System Table
+
HAGroupStoreTestUtil.deleteAllHAGroupRecordsInSystemTable(zkUrl1);
+ LOG.info("Cleaned up all system table records from cluster 1");
+ } catch (Exception e) {
+ LOG.warn("Failed to cleanup cluster 1", e);
+ }
+
+ // Clean up cluster 2
+ try (PhoenixHAAdmin haAdmin2 = new PhoenixHAAdmin(
+ CLUSTERS.getHBaseCluster2().getConfiguration(),
+ ZK_CONSISTENT_HA_GROUP_RECORD_NAMESPACE)) {
+
+ // Delete all ZNodes in the namespace
+
haAdmin2.getCurator().delete().quietly().deletingChildrenIfNeeded()
+ .forPath(toPath(""));
+ LOG.info("Cleaned up all ZK records from cluster 2");
+
+ // Delete all records from System Table
+
HAGroupStoreTestUtil.deleteAllHAGroupRecordsInSystemTable(zkUrl2);
+ LOG.info("Cleaned up all system table records from cluster 2");
+ } catch (Exception e) {
+ LOG.warn("Failed to cleanup cluster 2", e);
+ }
+
+ } catch (Exception e) {
+ LOG.warn("Error during @After cleanup", e);
+ // Don't fail the test due to cleanup errors
+ }
}
/**
- * Test that the initial cluster role record on ZK is populated to clients
correctly.
+ * Test that the list command shows HA groups correctly.
*/
-// @Test(timeout = 180000)
- public void testCreateDataOnZookeeper() throws Exception {
- doVerifyClusterRole(recordV1);
+ @Test(timeout = 180000)
+ public void testListCommand() throws Exception {
+ System.setOut(new PrintStream(STDOUT_CAPTURE));
+
+ int ret = ToolRunner.run(adminTool, new String[]{"list"});
+
+ assertEquals(RET_SUCCESS, ret);
+
+ String output = STDOUT_CAPTURE.toString();
+ LOG.info("Got stdout from list command: \n++++++++\n{}++++++++\n",
output);
+
+ // Verify the output contains all three HA group names with unique
names
+ assertOutputContainsHAGroupNames(output,
+ "prod_cluster_alpha",
+ "disaster_recovery_beta",
+ haGroupName);
+
+ // Verify the output contains all expected fields
+ assertOutputContainsHAGroupFields(output);
+
+ // Verify total count is shown
+ assertTrue("Output should show total count",
+ output.contains("Total:"));
}
/**
- * Test that sync the same cluster role record work since it is no-op.
+ * Test that the get command shows a single HA group correctly.
*/
-// @Test(timeout = 180000)
- public void testUpdateSameDataOnZookeeper() throws Exception {
- String jsonFileName =
ClusterRoleRecordTest.createJsonFileWithRecords(recordV1);
- int ret = admin.run(new String[]{"-m", jsonFileName});
+ @Test(timeout = 180000)
+ public void testGetCommand() throws Exception {
+ System.setOut(new PrintStream(STDOUT_CAPTURE));
+
+ // Test getting a specific group with a unique name
+ int ret = ToolRunner.run(adminTool, new String[]{"get", "-g",
"prod_cluster_alpha"});
+
assertEquals(RET_SUCCESS, ret);
- doVerifyClusterRole(recordV1);
+
+ String output = STDOUT_CAPTURE.toString();
+ LOG.info("Got stdout from get command: \n++++++++\n{}++++++++\n",
output);
+
+ // Verify the output contains the requested HA group name
+ assertTrue("Output should contain the requested HA group name",
+ output.contains("prod_cluster_alpha"));
+
+ // Verify the output contains all expected fields
+ assertOutputContainsHAGroupFields(output);
+
+ // Verify it does NOT contain other HA groups (since it's a get, not
list)
+ assertTrue("Output should not contain disaster_recovery_beta",
+ !output.contains("disaster_recovery_beta"));
+
+ // Only check for test method name if it's different from the
requested group
+ if (!haGroupName.equals("prod_cluster_alpha")) {
+ assertTrue("Output should not contain test method name group",
+ !output.contains(haGroupName));
+ }
}
/**
- * Test that the updated cluster role is populated to clients correctly.
+ * Helper method to query system table and get HA group record details.
+ *
+ * @param haGroupName the HA group name to query
+ * @param zkUrl the ZooKeeper URL to connect to
+ * @return SystemTableRecord containing the record details, or null if not
found
*/
-// @Test(timeout = 180000)
- public void testUpdateDataOnZookeeper() throws Exception {
- String jsonFileName =
ClusterRoleRecordTest.createJsonFileWithRecords(recordV2);
- int ret = admin.run(new String[]{"-m", jsonFileName});
- assertEquals(RET_SUCCESS, ret);
- // Eventually HA group should have see this updated cluster role
record from ZK
- doVerifyClusterRole(recordV2);
+ private SystemTableRecord querySystemTable(String haGroupName, String
zkUrl) throws Exception {
+ String queryString = String.format("SELECT * FROM %s WHERE %s = '%s'",
+ SYSTEM_HA_GROUP_NAME, HA_GROUP_NAME, haGroupName);
+ try (PhoenixConnection conn = (PhoenixConnection)
DriverManager.getConnection(
+ JDBC_PROTOCOL_ZK + JDBC_PROTOCOL_SEPARATOR + zkUrl);
+ Statement stmt = conn.createStatement();
+ ResultSet rs = stmt.executeQuery(queryString)) {
+ if (rs.next()) {
+ return new SystemTableRecord(
+ rs.getString(HA_GROUP_NAME),
+ rs.getString(ZK_URL_1),
+ rs.getString(ZK_URL_2),
+ rs.getString(CLUSTER_URL_1),
+ rs.getString(CLUSTER_URL_2),
+ rs.getString(CLUSTER_ROLE_1),
+ rs.getString(CLUSTER_ROLE_2),
+ rs.getString(POLICY),
+ rs.getLong(VERSION)
+ );
+ }
+ }
+ return null;
}
/**
- * Test that the HA admin can support multiple cluster role records for
different groups.
+ * Helper class to hold system table record data for verification.
*/
-// @Test(timeout = 180000)
- public void testCreateOrUpdateDataOnZookeeperForMultipleHAGroups() throws
Exception {
- // Note it is for a different HA group, while recordV2 is for the same
HA group as recordV1
- String haGroupName2 = haGroupName + 2;
- ClusterRoleRecord record2 = new ClusterRoleRecord(
- haGroupName2, HighAvailabilityPolicy.FAILOVER,
- CLUSTERS.getMasterAddress1(), ClusterRole.ACTIVE,
- CLUSTERS.getMasterAddress2(), ClusterRole.STANDBY,
- 1);
- // For haGroupName it's update and for haGroupName2 it's create.
- String jsonFileName =
ClusterRoleRecordTest.createJsonFileWithRecords(recordV2, record2);
- int ret = admin.run(new String[]{"-m", jsonFileName});
- assertEquals(RET_SUCCESS, ret);
- doVerifyClusterRole(recordV2);
- doVerifyClusterRole(record2);
- }
+ private static class SystemTableRecord {
+ final String zkUrl1;
+ final String zkUrl2;
+ final String clusterUrl1;
+ final String clusterUrl2;
+ final String policy;
+ final long version;
-// @Test(timeout = 180000)
- public void testListAllClusterRoleRecordsOnZookeeper() throws Exception {
- System.setOut(new PrintStream(STDOUT_CAPTURE));
- int ret = admin.run(new String[]{"-l"});
- assertEquals(RET_SUCCESS, ret);
- assertStdoutShouldHaveHaGroup(recordV1);
+ SystemTableRecord(String haGroupName, String zkUrl1, String zkUrl2,
+ String clusterUrl1, String clusterUrl2,
+ String clusterRole1, String clusterRole2,
+ String policy, long version) {
+ // Note: haGroupName, clusterRole1, and clusterRole2 are
intentionally not stored
+ // as they are not currently needed for verification
+ this.zkUrl1 = zkUrl1;
+ this.zkUrl2 = zkUrl2;
+ this.clusterUrl1 = clusterUrl1;
+ this.clusterUrl2 = clusterUrl2;
+ this.policy = policy;
+ this.version = version;
+ }
}
- private void assertStdoutShouldHaveHaGroup(ClusterRoleRecord record) {
- LOG.info("Got stdout: \n++++++++\n{}++++++++\n",
STDOUT_CAPTURE.toString());
-
assertTrue(STDOUT_CAPTURE.toString().contains(record.getHaGroupName()));
+ /**
+ * Helper method to assert output contains all expected HA group names.
+ */
+ private void assertOutputContainsHAGroupNames(String output, String...
groupNames) {
+ for (String groupName : groupNames) {
+ assertTrue("Output should contain HA group name: " + groupName,
+ output.contains(groupName));
+ }
}
/**
- * Test that --repair command options works.
+ * Helper method to assert output contains all expected HAGroupStoreRecord
fields.
*/
-// @Test(timeout = 180000)
- public void testRepair() throws Exception {
- // no-op since both ZK nodes are the same initially after setup()
- int ret = admin.run(new String[]{"--repair"});
- assertEquals(RET_SUCCESS, ret);
+ private void assertOutputContainsHAGroupFields(String output) {
+ // Verify state information
+ assertTrue("Output should contain state information",
+ output.contains("ACTIVE_IN_SYNC") || output.contains("State")
||
+ output.contains("STANDBY"));
- // Update ZK1 with newer version
- String zpath = ZKPaths.PATH_SEPARATOR + haGroupName;
- PhoenixHAAdminToolIT.this.getCurator1().setData().forPath(zpath,
ClusterRoleRecord.toJson(recordV2));
- doVerifyClusterRole(getCurator1(), recordV2);
- doVerifyClusterRole(PhoenixHAAdminToolIT.this.getCurator2(),
recordV1); // ZK2 still has old version
- ret = admin.run(new String[]{"--repair"}); // admin is created using
cluster1 configuration
- assertEquals(RET_SUCCESS, ret);
- doVerifyClusterRole(getCurator1(), recordV2);
- doVerifyClusterRole(getCurator2(), recordV2);
-
- ClusterRoleRecord recordV3 = new ClusterRoleRecord(
- haGroupName, HighAvailabilityPolicy.FAILOVER,
- CLUSTERS.getMasterAddress2(), ClusterRole.ACTIVE,
- CLUSTERS.getMasterAddress2(), ClusterRole.STANDBY,
- 3);
- getCurator2().setData().forPath(zpath,
ClusterRoleRecord.toJson(recordV3));
- doVerifyClusterRole(getCurator1(), recordV2);
- doVerifyClusterRole(getCurator2(), recordV3); // ZK2 has newer version
- ret = admin.run(new String[]{"--repair"}); // admin is created using
cluster1 configuration
- assertEquals(RET_SUCCESS, ret);
- doVerifyClusterRole(getCurator1(), recordV3);
- doVerifyClusterRole(getCurator2(), recordV3);
+ // Verify policy information
+ assertTrue("Output should contain policy information",
+ output.contains("FAILOVER") || output.contains("Policy"));
+
+ // Verify cluster role information
+ assertTrue("Output should contain cluster role information",
+ output.contains("ACTIVE") || output.contains("STANDBY") ||
+ output.contains("Cluster Role"));
+
+ // Verify protocol version
+ assertTrue("Output should contain protocol version",
+ output.contains("1.0") || output.contains("Protocol Version"));
+
+ // Verify admin version
+ assertTrue("Output should contain admin version",
+ output.contains("Admin Version") ||
output.contains("adminCRRVersion"));
}
/**
- * Test that --repair should report inconsistent records.
+ * Test that the get-cluster-role-record command shows cluster role
information correctly.
+ * This test sets up both local cluster data (via System table) and peer
cluster data (via ZK).
*/
-// @Test(timeout = 180000)
- public void testRepairGotInconsistentRecords() throws Exception {
- // Set ZK1 node with different HA policy and cluster roles but the
same version v1
- String zpath = ZKPaths.PATH_SEPARATOR + haGroupName;
- try {
- ClusterRoleRecord recordDifferent = new ClusterRoleRecord(
- haGroupName, HighAvailabilityPolicy.PARALLEL,
- CLUSTERS.getZkUrl1(), ClusterRole.STANDBY,
- CLUSTERS.getZkUrl2(), ClusterRole.STANDBY,
- 1);
- getCurator1().setData().forPath(zpath,
ClusterRoleRecord.toJson(recordDifferent));
- doVerifyClusterRole(getCurator1(), recordDifferent);
-
- System.setOut(new PrintStream(STDOUT_CAPTURE)); // capture stdout
- int ret = ToolRunner.run(admin, new String[] { "--repair" });
- assertEquals(RET_REPAIR_FOUND_INCONSISTENCIES, ret);
- assertStdoutShouldHaveHaGroup(recordV1); // should be reported back
- } finally {
- // reset for this HA group so that other tests will not see
inconsistent records.
- getCurator1().setData().forPath(zpath,
ClusterRoleRecord.toJson(recordV1));
+ @Test(timeout = 180000)
+ public void testGetClusterRoleRecordCommand() throws Exception {
+ System.setOut(new PrintStream(STDOUT_CAPTURE));
+
+ // Create peer ZK record using PhoenixHAAdmin
+ try (PhoenixHAAdmin peerHaAdmin = new PhoenixHAAdmin(
+ CLUSTERS.getHBaseCluster2().getConfiguration(),
+ ZK_CONSISTENT_HA_GROUP_RECORD_NAMESPACE)) {
+
+ // Create a HAGroupStoreRecord in the peer cluster with STANDBY
state
+ HAGroupStoreRecord peerRecord = new HAGroupStoreRecord(
+ HAGroupStoreRecord.DEFAULT_PROTOCOL_VERSION,
+ haGroupName,
+ HAGroupStoreRecord.HAGroupState.STANDBY,
+ 0L,
+ HighAvailabilityPolicy.FAILOVER.toString(),
+ CLUSTERS.getZkUrl1(),
+ CLUSTERS.getMasterAddress2(),
+ CLUSTERS.getMasterAddress1(),
+ 1L);
+
+ peerHaAdmin.createHAGroupStoreRecordInZooKeeper(peerRecord);
+
+ // Wait for ZK event propagation
+ Thread.sleep(5000);
+
+ // Now execute the get-cluster-role-record command
+ int ret = ToolRunner.run(adminTool, new
String[]{"get-cluster-role-record", "-g", haGroupName});
+
+ assertEquals(RET_SUCCESS, ret);
+
+ String output = STDOUT_CAPTURE.toString();
+ LOG.info("Got stdout from get-cluster-role-record command:
\n++++++++\n{}++++++++\n", output);
+
+ // Verify the output contains cluster role record information
+ assertTrue("Output should contain HA group name",
+ output.contains(haGroupName));
+
+ // Verify policy is shown
+ assertTrue("Output should contain policy (FAILOVER)",
+ output.contains("FAILOVER"));
+
+ // Verify cluster 1 and cluster 2 information is present
+ assertTrue("Output should contain Cluster 1 URL",
+ output.contains("Cluster 1 URL"));
+ assertTrue("Output should contain Cluster 1 Role",
+ output.contains("Cluster 1 Role"));
+ assertTrue("Output should contain Cluster 2 URL",
+ output.contains("Cluster 2 URL"));
+ assertTrue("Output should contain Cluster 2 Role",
+ output.contains("Cluster 2 Role"));
+
+ // CRITICAL: Verify roles are NOT swapped by checking via
ClusterRoleRecord.getRole(url)
+ // The ClusterRoleRecord may have url1/url2 in any order, so we
need to query by URL
+ HAGroupStoreManager manager = new
HAGroupStoreManager(adminTool.getConf());
+ ClusterRoleRecord clusterRoleRecord =
manager.getClusterRoleRecord(haGroupName);
+
+ // Local cluster (zkUrl1) should be ACTIVE
+ ClusterRoleRecord.ClusterRole localRole =
clusterRoleRecord.getRole(CLUSTERS.getMasterAddress1());
+ assertEquals("Local cluster (zkUrl1) should have ACTIVE role",
+ ClusterRoleRecord.ClusterRole.ACTIVE, localRole);
+
+ // Peer cluster (zkUrl2) should be STANDBY
+ ClusterRoleRecord.ClusterRole peerRole =
clusterRoleRecord.getRole(CLUSTERS.getMasterAddress2());
+ assertEquals("Peer cluster (zkUrl2) should have STANDBY role",
+ ClusterRoleRecord.ClusterRole.STANDBY, peerRole);
+
+ // Verify the output text shows both URLs (regardless of order)
+ assertTrue("Output should contain local masterAddress1",
+ output.contains(CLUSTERS.getMasterAddress1()));
+ assertTrue("Output should contain peer masterAddress2",
+ output.contains(CLUSTERS.getMasterAddress2()));
+
+ // Verify output contains both role types
+ assertTrue("Output should contain ACTIVE role",
+ output.contains("ACTIVE"));
+ assertTrue("Output should contain STANDBY role",
+ output.contains("STANDBY"));
+
+ // Verify version information
+ assertTrue("Output should contain Version",
+ output.contains("Version"));
+
+ // Clean up: delete the peer ZK record
+ peerHaAdmin.deleteHAGroupStoreRecordInZooKeeper(haGroupName);
}
}
/**
- * Test that updating two ZK clusters should fail if the first cluster is
not healthy.
- *
- * The first cluster is the new STANDBY and previously it was ACTIVE. So
it should be updated
- * first. If it is down, the update will fail and skip updating second
cluster.
+ * Test that the initiate-failover command triggers failover correctly.
+ * This test verifies the complete failover flow with automatic state
transitions.
*/
-// @Test(timeout = 180000)
- public void testUpdateDataOnZookeeperShouldFailWhenActiveZkClusterDown()
throws Exception {
+ @Test(timeout = 180000)
+ public void testInitiateFailoverCommand() throws Exception {
+ // Use a specific HA group name for this test
+ String failoverHaGroupName = "testInitiateFailover_" +
System.currentTimeMillis();
+
+ String zkUrl1 = CLUSTERS.getZkUrl1();
+ String zkUrl2 = CLUSTERS.getZkUrl2();
+
+ // Set up system tables for both clusters
+
HAGroupStoreTestUtil.upsertHAGroupRecordInSystemTable(failoverHaGroupName,
zkUrl1, zkUrl2,
+ CLUSTERS.getMasterAddress1(), CLUSTERS.getMasterAddress2(),
+ ClusterRoleRecord.ClusterRole.ACTIVE,
ClusterRoleRecord.ClusterRole.STANDBY, null);
+
HAGroupStoreTestUtil.upsertHAGroupRecordInSystemTable(failoverHaGroupName,
zkUrl1, zkUrl2,
+ CLUSTERS.getMasterAddress1(), CLUSTERS.getMasterAddress2(),
+ ClusterRoleRecord.ClusterRole.ACTIVE,
ClusterRoleRecord.ClusterRole.STANDBY, zkUrl2);
+
+ // Create HAGroupStoreManager instances for both clusters
+ // This will automatically setup failover management and create ZNodes
from system table
+ HAGroupStoreManager cluster1HAManager = new
HAGroupStoreManager(CLUSTERS.getHBaseCluster1().getConfiguration());
+ HAGroupStoreManager cluster2HAManager = new
HAGroupStoreManager(CLUSTERS.getHBaseCluster2().getConfiguration());
+
+ // Initialize HAGroupStoreClient and move to ACTIVE_IN_SYNC state
+ cluster1HAManager.getHAGroupStoreRecord(failoverHaGroupName);
+ cluster2HAManager.getHAGroupStoreRecord(failoverHaGroupName);
+
+ // Wait for ZK session timeout to allow transition from
ACTIVE_NOT_IN_SYNC to ACTIVE_IN_SYNC
+ Thread.sleep(20 * 1000);
+ cluster1HAManager.setHAGroupStatusToSync(failoverHaGroupName);
+ Thread.sleep(5000);
+
+ // Set up listener to simulate reader completing replay and becoming
ACTIVE
+ HAGroupStateListener listener = (haGroupName1, fromState, toState,
modifiedTime,
Review Comment:
Why do we need a listener here for completing replay? Should not the log
reader of the standby cluster do this automatically?
--
This is an automated message from the Apache Git Service.
To respond to the message, please log on to GitHub and use the
URL above to go to the specific comment.
To unsubscribe, e-mail: [email protected]
For queries about this service, please contact Infrastructure at:
[email protected]