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 6dd4db1ecb8 HBASE-29780: Addendum to HBASE-29715: Add an additional 
test case that uses the filesystem (#7702)
6dd4db1ecb8 is described below

commit 6dd4db1ecb87b369e88231f911d30daea3a2c4ae
Author: Kevin Geiszler <[email protected]>
AuthorDate: Wed Feb 4 09:41:07 2026 -0800

    HBASE-29780: Addendum to HBASE-29715: Add an additional test case that uses 
the filesystem (#7702)
    
    Change-Id: I776f956c830a7f4671cfae265269a21fa61d0bdf
---
 .../hadoop/hbase/util/FSTableDescriptors.java      |  10 +-
 .../hadoop/hbase/master/TestMasterMetrics.java     | 125 ++++++++++++++++++---
 2 files changed, 116 insertions(+), 19 deletions(-)

diff --git 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
index 30525d7129e..e38ce97b026 100644
--- 
a/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
+++ 
b/hbase-server/src/main/java/org/apache/hadoop/hbase/util/FSTableDescriptors.java
@@ -236,7 +236,7 @@ public class FSTableDescriptors implements TableDescriptors 
{
         cachehits++;
         return cachedtdm;
       }
-      // we do not need to go to fs any more
+      // we do not need to go to the fs anymore
       if (fsvisited) {
         return null;
       }
@@ -669,8 +669,8 @@ public class FSTableDescriptors implements TableDescriptors 
{
    * @param htd           description of the table to write
    * @param forceCreation if <tt>true</tt>,then even if previous table 
descriptor is present it will
    *                      be overwritten
-   * @return <tt>true</tt> if the we successfully created the file, 
<tt>false</tt> if the file
-   *         already exists and we weren't forcing the descriptor creation.
+   * @return <tt>true</tt> if we successfully created the file, <tt>false</tt> 
if the file already
+   *         exists, and we weren't forcing the descriptor creation.
    * @throws IOException if a filesystem error occurs
    */
   public boolean createTableDescriptorForTableDirectory(Path tableDir, 
TableDescriptor htd,
@@ -689,8 +689,8 @@ public class FSTableDescriptors implements TableDescriptors 
{
    * @param htd           description of the table to write
    * @param forceCreation if <tt>true</tt>,then even if previous table 
descriptor is present it will
    *                      be overwritten
-   * @return <tt>true</tt> if the we successfully created the file, 
<tt>false</tt> if the file
-   *         already exists and we weren't forcing the descriptor creation.
+   * @return <tt>true</tt> if we successfully created the file, <tt>false</tt> 
if the file already
+   *         exists, and we weren't forcing the descriptor creation.
    * @throws IOException if a filesystem error occurs
    */
   public static boolean createTableDescriptorForTableDirectory(FileSystem fs, 
Path tableDir,
diff --git 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java
 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java
index 0f2d1a17634..409550f5fd5 100644
--- 
a/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java
+++ 
b/hbase-server/src/test/java/org/apache/hadoop/hbase/master/TestMasterMetrics.java
@@ -17,10 +17,12 @@
  */
 package org.apache.hadoop.hbase.master;
 
+import static org.junit.Assert.assertEquals;
 import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertTrue;
 
 import java.io.IOException;
+import java.io.InterruptedIOException;
 import java.io.UncheckedIOException;
 import java.util.ArrayList;
 import java.util.EnumSet;
@@ -28,6 +30,8 @@ import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.FileSystem;
+import org.apache.hadoop.fs.Path;
 import org.apache.hadoop.hbase.ClusterMetrics;
 import org.apache.hadoop.hbase.CompatibilityFactory;
 import org.apache.hadoop.hbase.HBaseClassTestRule;
@@ -47,6 +51,7 @@ import org.apache.hadoop.hbase.test.MetricsAssertHelper;
 import org.apache.hadoop.hbase.testclassification.MasterTests;
 import org.apache.hadoop.hbase.testclassification.MediumTests;
 import org.apache.hadoop.hbase.util.EnvironmentEdgeManager;
+import org.apache.hadoop.hbase.util.FSTableDescriptors;
 import org.apache.zookeeper.KeeperException;
 import org.junit.AfterClass;
 import org.junit.BeforeClass;
@@ -75,6 +80,7 @@ public class TestMasterMetrics {
   private static final Logger LOG = 
LoggerFactory.getLogger(TestMasterMetrics.class);
   private static final MetricsAssertHelper metricsHelper =
     CompatibilityFactory.getInstance(MetricsAssertHelper.class);
+  private static final String COLUMN_FAMILY = "cf";
 
   private static SingleProcessHBaseCluster cluster;
   private static HMaster master;
@@ -202,22 +208,20 @@ public class TestMasterMetrics {
   }
 
   @Test
-  public void testDefaultMasterProcMetrics() throws Exception {
+  public void testDefaultMasterProcMetrics() {
     MetricsMasterProcSource masterSource = 
master.getMasterMetrics().getMetricsProcSource();
     metricsHelper.assertGauge("numMasterWALs", master.getNumWALFiles(), 
masterSource);
   }
 
+  // Verifies a foreign meta table does not show up in the table regions state
   @Test
-  public void testClusterMetricsMetaTableSkipping() throws Exception {
+  public void testClusterMetricsSkippingForeignMetaTable() throws Exception {
     TableName replicaMetaTable = TableName.valueOf("hbase", "meta_replica");
     TableDescriptor replicaMetaDescriptor = 
TableDescriptorBuilder.newBuilder(replicaMetaTable)
       .setColumnFamily(ColumnFamilyDescriptorBuilder.of("info")).build();
     master.getTableDescriptors().update(replicaMetaDescriptor, true);
     try {
-      ClusterMetrics metrics = master.getClusterMetricsWithoutCoprocessor(
-        EnumSet.of(ClusterMetrics.Option.TABLE_TO_REGIONS_COUNT));
-      Map<TableName, RegionStatesCount> tableRegionStatesCount =
-        metrics.getTableRegionStatesCount();
+      Map<TableName, RegionStatesCount> tableRegionStatesCount = 
getTableRegionStatesCount();
 
       assertFalse("Foreign meta table should not be present",
         tableRegionStatesCount.containsKey(replicaMetaTable));
@@ -229,8 +233,10 @@ public class TestMasterMetrics {
     }
   }
 
+  // This test adds foreign file descriptors to the cluster's table descriptor 
cache. It then
+  // verifies the foreign tables do not show up in the table regions state.
   @Test
-  public void testClusterMetricsForeignTableSkipping() throws Exception {
+  public void testClusterMetricsSkippingCachedForeignTables() throws Exception 
{
     List<TableName> allTables = new ArrayList<>();
 
     // These tables, including the cluster's meta table, should not be foreign 
to the cluster.
@@ -246,10 +252,13 @@ public class TestMasterMetrics {
     // Create these "familiar" tables so their state can be found
     
TEST_UTIL.getAdmin().createNamespace(NamespaceDescriptor.create("familiarNamespace").build());
     for (TableName familiarTable : familiarTables) {
-      TEST_UTIL.createTable(familiarTable, "cf");
+      TEST_UTIL.createTable(familiarTable, COLUMN_FAMILY);
       allTables.add(familiarTable);
     }
 
+    // hbase:meta is a familiar table that was created automatically
+    familiarTables.add(TableName.META_TABLE_NAME);
+
     // These tables should be foreign to the cluster.
     // The cluster should not be able to find their state.
     allTables.add(TableName.valueOf("hbase", "meta_replica"));
@@ -266,7 +275,7 @@ public class TestMasterMetrics {
     TableDescriptor foreignTableDescriptor;
     for (TableName tableName : allTables) {
       foreignTableDescriptor = TableDescriptorBuilder.newBuilder(tableName)
-        .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build();
+        
.setColumnFamily(ColumnFamilyDescriptorBuilder.of(COLUMN_FAMILY)).build();
       master.getTableDescriptors().update(foreignTableDescriptor, true);
     }
 
@@ -274,10 +283,7 @@ public class TestMasterMetrics {
     // The other tables' state should not exist.
     for (TableName tableName : allTables) {
       try {
-        ClusterMetrics metrics = master.getClusterMetricsWithoutCoprocessor(
-          EnumSet.of(ClusterMetrics.Option.TABLE_TO_REGIONS_COUNT));
-        Map<TableName, RegionStatesCount> tableRegionStatesCount =
-          metrics.getTableRegionStatesCount();
+        Map<TableName, RegionStatesCount> tableRegionStatesCount = 
getTableRegionStatesCount();
 
         if (
           tableName.equals(TableName.META_TABLE_NAME)
@@ -290,8 +296,99 @@ public class TestMasterMetrics {
             tableRegionStatesCount.containsKey(tableName));
         }
       } finally {
-        master.getTableDescriptors().remove(tableName);
+        if (!TableName.META_TABLE_NAME.equals(tableName) && 
familiarTables.contains(tableName)) {
+          LOG.debug("Deleting table: {}", tableName);
+          TEST_UTIL.deleteTable(tableName);
+        } else if (!familiarTables.contains(tableName)) {
+          LOG.debug("Removing table descriptor for foreign table: {}", 
tableName);
+          master.getTableDescriptors().remove(tableName);
+        }
       }
     }
   }
+
+  // This test creates foreign file descriptors on the filesystem in addition 
to updating the
+  // table descriptor cache. It then verifies the foreign tables do not show 
up in the
+  // table regions state.
+  @Test
+  public void testClusterMetricsSkippingForeignTablesOnFileSystem() throws 
IOException {
+    List<TableName> familiarTables = new ArrayList<>();
+    List<TableName> foreignTables = new ArrayList<>();
+    FileSystem fs = TEST_UTIL.getTestFileSystem();
+    Path testDir = TEST_UTIL.getDataTestDirOnTestFS();
+    LOG.info("The test dir is: {}", testDir);
+
+    // Create tables whose state are familiar to this cluster
+    familiarTables.add(TableName.valueOf("testTable1"));
+    familiarTables.add(TableName.valueOf("testTable2"));
+    
TEST_UTIL.getAdmin().createNamespace(NamespaceDescriptor.create("myNamespace").build());
+    familiarTables.add(TableName.valueOf("myNamespace", 
"tableWithNamespace1"));
+    for (TableName tableName : familiarTables) {
+      TEST_UTIL.createTable(tableName, COLUMN_FAMILY);
+    }
+
+    // hbase:meta is a familiar table that was created automatically
+    familiarTables.add(TableName.META_TABLE_NAME);
+
+    // There should now be 4 tables, including hbase:meta
+    Map<String, TableDescriptor> tableDescriptorMap = 
master.getTableDescriptors().getAll();
+    assertEquals(4, tableDescriptorMap.size());
+    for (TableName tableName : familiarTables) {
+      assertTrue("Expected table descriptor map to contain table: " + 
tableName, tableDescriptorMap
+        .containsKey(tableName.getNamespaceAsString() + ":" + 
tableName.getQualifierAsString()));
+    }
+
+    createTableDescriptorOnFileSystem("hbase", "meta_replica", foreignTables);
+    createTableDescriptorOnFileSystem("default", "foreignTable1", 
foreignTables);
+    createTableDescriptorOnFileSystem("customForeignNs", 
"customForeignNsTable1", foreignTables);
+
+    // Verify the table descriptors were created on the filesystem
+    for (TableName tableName : foreignTables) {
+      Path tableDescPath = new Path(testDir,
+        "data" + Path.SEPARATOR + tableName.getNamespaceAsString() + 
Path.SEPARATOR
+          + tableName.getQualifierAsString() + Path.SEPARATOR + 
FSTableDescriptors.TABLEINFO_DIR);
+      assertTrue("Expected table descriptor directory to exist: " + 
tableDescPath,
+        fs.exists(tableDescPath));
+    }
+
+    Map<TableName, RegionStatesCount> tableRegionStatesCount = 
getTableRegionStatesCount();
+
+    // The foreign tables should not be in the table state
+    assertEquals(4, tableRegionStatesCount.size());
+    for (TableName tableName : familiarTables) {
+      assertTrue("Expected table regions state count to contain: " + tableName,
+        tableRegionStatesCount.containsKey(tableName));
+      // Delete unneeded tables
+      if (!TableName.META_TABLE_NAME.equals(tableName)) {
+        LOG.debug("Deleting table: {}", tableName);
+        TEST_UTIL.deleteTable(tableName);
+      }
+    }
+    for (TableName tableName : foreignTables) {
+      assertFalse("Expected table regions state count to NOT contain: " + 
tableName,
+        tableRegionStatesCount.containsKey(tableName));
+      // Remove unneeded table descriptors
+      LOG.debug("Removing table descriptor for foreign table: {}", tableName);
+      master.getTableDescriptors().remove(tableName);
+    }
+  }
+
+  private Map<TableName, RegionStatesCount> getTableRegionStatesCount()
+    throws InterruptedIOException {
+    ClusterMetrics metrics = master.getClusterMetricsWithoutCoprocessor(
+      EnumSet.of(ClusterMetrics.Option.TABLE_TO_REGIONS_COUNT));
+    return metrics.getTableRegionStatesCount();
+  }
+
+  private void createTableDescriptorOnFileSystem(String namespace, String 
qualifier,
+    List<TableName> tableNameList) throws IOException {
+    // Create a table descriptor on the filesystem that uses the provided 
namespace
+    TableName tableName = TableName.valueOf(namespace, qualifier);
+    TableDescriptor tableDescriptor = 
TableDescriptorBuilder.newBuilder(tableName)
+      
.setColumnFamily(ColumnFamilyDescriptorBuilder.of(COLUMN_FAMILY)).build();
+    // Create the table descriptor on the filesystem and update the file 
descriptor cache
+    master.getTableDescriptors().update(tableDescriptor, false);
+
+    tableNameList.add(tableName);
+  }
 }

Reply via email to