This is an automated email from the ASF dual-hosted git repository. andor pushed a commit to branch HBASE-29081 in repository https://gitbox.apache.org/repos/asf/hbase.git
The following commit(s) were added to refs/heads/HBASE-29081 by this push: new cc74ebcaf39 HBASE-29597 Supply meta table name for replica to the tests in TestMe… (#7325) cc74ebcaf39 is described below commit cc74ebcaf398abb84ee67022d11c4e37779d37e7 Author: Abhishek Kothalikar <99398985+kabhish...@users.noreply.github.com> AuthorDate: Fri Sep 19 22:26:27 2025 +0530 HBASE-29597 Supply meta table name for replica to the tests in TestMe… (#7325) * HBASE-29597 Supply meta table name for replica to the tests in TestMetaTableForReplica class * HBASE-29597 Supply meta table name for replica to the tests in TestMetaTableForReplica class --- .../hadoop/hbase/TestMetaTableForReplica.java | 76 ++++++++++++++++++++-- 1 file changed, 69 insertions(+), 7 deletions(-) diff --git a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableForReplica.java b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableForReplica.java index d4e3d2c8ce0..7c937eb5c05 100644 --- a/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableForReplica.java +++ b/hbase-server/src/test/java/org/apache/hadoop/hbase/TestMetaTableForReplica.java @@ -18,11 +18,15 @@ package org.apache.hadoop.hbase; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotEquals; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertTrue; import java.io.IOException; +import java.lang.invoke.MethodHandles; +import java.lang.reflect.Field; +import java.lang.reflect.Modifier; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.hbase.client.Connection; import org.apache.hadoop.hbase.client.ConnectionFactory; @@ -55,6 +59,8 @@ public class TestMetaTableForReplica { private static final Logger LOG = LoggerFactory.getLogger(TestMetaTableForReplica.class); private static final HBaseTestingUtil UTIL = new HBaseTestingUtil(); private static Connection connection; + private static Field metaTableName; + private static Object originalMetaTableName; @Rule public TestName name = new TestName(); @@ -66,9 +72,11 @@ public class TestMetaTableForReplica { c.setInt("hbase.ipc.client.connect.max.retries", 1); c.setInt(HConstants.ZK_SESSION_TIMEOUT, 1000); // Start cluster having non-default hbase meta table name - c.setStrings(HConstants.HBASE_META_TABLE_SUFFIX, "test"); UTIL.startMiniCluster(3); connection = ConnectionFactory.createConnection(c); + // Save the original value of META_TABLE_NAME before any test runs.x + metaTableName = TableName.class.getDeclaredField("META_TABLE_NAME"); + originalMetaTableName = metaTableName.get(null); } @AfterClass @@ -84,18 +92,23 @@ public class TestMetaTableForReplica { } @Test - public void testNameOfMetaForReplica() { + public void testMetaTableNameForReplicaWithoutSuffix() throws IOException { + testNameOfMetaForReplica(); + testGetNonExistentRegionFromMetaFromReplica(); + testGetExistentRegionFromMetaFromReplica(); + } + + private void testNameOfMetaForReplica() { // Check the correctness of the meta table for replica String metaTableName = TableName.META_TABLE_NAME.getNameWithNamespaceInclAsString(); assertNotNull(metaTableName); - // Check if name of the meta table for replica is not same as default table + // Check if name of the meta table for replica is same as the default meta table assertEquals(0, TableName.META_TABLE_NAME.compareTo(TableName.getDefaultNameOfMetaForReplica())); } - @Test - public void testGetNonExistentRegionFromMetaFromReplica() throws IOException { + private void testGetNonExistentRegionFromMetaFromReplica() throws IOException { final String name = this.name.getMethodName(); LOG.info("Started " + name); Pair<RegionInfo, ServerName> pair = @@ -104,11 +117,60 @@ public class TestMetaTableForReplica { LOG.info("Finished " + name); } - @Test - public void testGetExistentRegionFromMetaFromReplica() throws IOException { + private void testGetExistentRegionFromMetaFromReplica() throws IOException { final TableName tableName = TableName.valueOf(name.getMethodName()); LOG.info("Started " + tableName); UTIL.createTable(tableName, HConstants.CATALOG_FAMILY); assertEquals(1, MetaTableAccessor.getTableRegions(connection, tableName).size()); } + + @Test + public void testMetaTableNameForReplicaWithSuffix() throws Exception { + // This test actively changes the META_TABLE_NAME to a non-default value and verifies it. + Configuration conf = HBaseConfiguration.create(); + String suffix = "replica1"; + conf.set(HConstants.HBASE_META_TABLE_SUFFIX, suffix); + + // Re-initialize the static final META_TABLE_NAME for the testing to a non-default value. + TableName expectedMetaTableName = TableName.initializeHbaseMetaTableName(conf); + setStaticFinalField(metaTableName, expectedMetaTableName); + + TableName currentMetaName = TableName.META_TABLE_NAME; + TableName defaultMetaName = TableName.getDefaultNameOfMetaForReplica(); + + // The current meta table name is not the default one. + assertNotEquals("META_TABLE_NAME should not be the default. ", defaultMetaName, + currentMetaName); + + // The current meta table name has the configured suffix. + assertEquals("META_TABLE_NAME should have the configured suffix", expectedMetaTableName, + currentMetaName); + + // restore default value of META_TABLE_NAME + setDefaultMetaTableName(); + } + + private static void setDefaultMetaTableName() throws Exception { + if (originalMetaTableName != null) { + setStaticFinalField(metaTableName, originalMetaTableName); + } + } + + /** + * A helper method to modify a static final field using reflection. This is necessary for testing + * code that reads a configuration only once during class loading. + * @param field The field to modify. + * @param newValue The new value to set. + * @throws Exception if reflection fails. + */ + private static void setStaticFinalField(Field field, Object newValue) throws Exception { + field.setAccessible(true); + // Using MethodHandles to get a trusted lookup with the necessary permissions to modify it. + // NOTE: For this to work, the JVM running the test must be started with arguments like: + // --add-opens=java.base/java.lang.reflect=ALL-UNNAMED + var lookup = MethodHandles.privateLookupIn(Field.class, MethodHandles.lookup()); + var handle = lookup.findVarHandle(Field.class, "modifiers", int.class); + handle.set(field, field.getModifiers() & ~Modifier.FINAL); + field.set(null, newValue); + } }