001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.util; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertFalse; 022import static org.junit.jupiter.api.Assertions.assertNotEquals; 023import static org.junit.jupiter.api.Assertions.assertNotNull; 024import static org.junit.jupiter.api.Assertions.assertNull; 025import static org.junit.jupiter.api.Assertions.assertThrows; 026import static org.junit.jupiter.api.Assertions.assertTrue; 027import static org.junit.jupiter.api.Assertions.fail; 028 029import java.io.IOException; 030import java.util.Arrays; 031import java.util.Comparator; 032import java.util.Map; 033import org.apache.hadoop.fs.FSDataOutputStream; 034import org.apache.hadoop.fs.FileStatus; 035import org.apache.hadoop.fs.FileSystem; 036import org.apache.hadoop.fs.Path; 037import org.apache.hadoop.hbase.HBaseCommonTestingUtil; 038import org.apache.hadoop.hbase.HConstants; 039import org.apache.hadoop.hbase.TableDescriptors; 040import org.apache.hadoop.hbase.TableName; 041import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 042import org.apache.hadoop.hbase.client.TableDescriptor; 043import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 044import org.apache.hadoop.hbase.regionserver.BloomType; 045import org.apache.hadoop.hbase.testclassification.MediumTests; 046import org.apache.hadoop.hbase.testclassification.MiscTests; 047import org.junit.jupiter.api.AfterAll; 048import org.junit.jupiter.api.BeforeEach; 049import org.junit.jupiter.api.Tag; 050import org.junit.jupiter.api.Test; 051import org.junit.jupiter.api.TestInfo; 052import org.slf4j.Logger; 053import org.slf4j.LoggerFactory; 054 055/** 056 * Tests for {@link FSTableDescriptors}. 057 */ 058// Do not support to be executed in he same JVM as other tests 059@Tag(MiscTests.TAG) 060@Tag(MediumTests.TAG) 061public class TestFSTableDescriptors { 062 063 private static final HBaseCommonTestingUtil UTIL = new HBaseCommonTestingUtil(); 064 private static final Logger LOG = LoggerFactory.getLogger(TestFSTableDescriptors.class); 065 066 private Path testDir; 067 068 @BeforeEach 069 public void setUp(TestInfo testInfo) { 070 testDir = UTIL.getDataTestDir(testInfo.getTestMethod().get().getName()); 071 } 072 073 @AfterAll 074 public static void tearDownAfterClass() { 075 UTIL.cleanupTestDir(); 076 } 077 078 @Test 079 public void testRegexAgainstOldStyleTableInfo() { 080 Path p = new Path(testDir, FSTableDescriptors.TABLEINFO_FILE_PREFIX); 081 int i = FSTableDescriptors.getTableInfoSequenceIdAndFileLength(p).sequenceId; 082 assertEquals(0, i); 083 // Assert it won't eat garbage -- that it fails 084 Path p2 = new Path(testDir, "abc"); 085 assertThrows(IllegalArgumentException.class, 086 () -> FSTableDescriptors.getTableInfoSequenceIdAndFileLength(p2)); 087 } 088 089 @Test 090 public void testCreateAndUpdate(TestInfo testInfo) throws IOException { 091 TableDescriptor htd = TableDescriptorBuilder 092 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName())).build(); 093 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 094 FSTableDescriptors fstd = new FSTableDescriptors(fs, testDir); 095 assertTrue(fstd.createTableDescriptor(htd)); 096 assertFalse(fstd.createTableDescriptor(htd)); 097 Path tableInfoDir = new Path(CommonFSUtils.getTableDir(testDir, htd.getTableName()), 098 FSTableDescriptors.TABLEINFO_DIR); 099 FileStatus[] statuses = fs.listStatus(tableInfoDir); 100 assertEquals(1, statuses.length, "statuses.length=" + statuses.length); 101 for (int i = 0; i < 10; i++) { 102 fstd.update(htd); 103 } 104 statuses = fs.listStatus(tableInfoDir); 105 assertEquals(1, statuses.length); 106 } 107 108 @Test 109 public void testSequenceIdAdvancesOnTableInfo(TestInfo testInfo) throws IOException { 110 TableDescriptor htd = TableDescriptorBuilder 111 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName())).build(); 112 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 113 FSTableDescriptors fstd = new FSTableDescriptors(fs, testDir); 114 Path previousPath = null; 115 int previousSeqId = -1; 116 for (int i = 0; i < 10; i++) { 117 Path path = fstd.updateTableDescriptor(htd); 118 int seqId = FSTableDescriptors.getTableInfoSequenceIdAndFileLength(path).sequenceId; 119 if (previousPath != null) { 120 // Assert we cleaned up the old file. 121 assertTrue(!fs.exists(previousPath)); 122 assertEquals(previousSeqId + 1, seqId); 123 } 124 previousPath = path; 125 previousSeqId = seqId; 126 } 127 } 128 129 @Test 130 public void testFormatTableInfoSequenceId() { 131 Path p0 = assertWriteAndReadSequenceId(0); 132 // Assert p0 has format we expect. 133 StringBuilder sb = new StringBuilder(); 134 for (int i = 0; i < FSTableDescriptors.WIDTH_OF_SEQUENCE_ID; i++) { 135 sb.append("0"); 136 } 137 assertEquals(FSTableDescriptors.TABLEINFO_FILE_PREFIX + "." + sb.toString() + ".0", 138 p0.getName()); 139 // Check a few more. 140 Path p2 = assertWriteAndReadSequenceId(2); 141 Path p10000 = assertWriteAndReadSequenceId(10000); 142 // Get a .tablinfo that has no sequenceid suffix. 143 Path p = new Path(p0.getParent(), FSTableDescriptors.TABLEINFO_FILE_PREFIX); 144 FileStatus fs = new FileStatus(0, false, 0, 0, 0, p); 145 FileStatus fs0 = new FileStatus(0, false, 0, 0, 0, p0); 146 FileStatus fs2 = new FileStatus(0, false, 0, 0, 0, p2); 147 FileStatus fs10000 = new FileStatus(0, false, 0, 0, 0, p10000); 148 Comparator<FileStatus> comparator = FSTableDescriptors.TABLEINFO_FILESTATUS_COMPARATOR; 149 assertTrue(comparator.compare(fs, fs0) > 0); 150 assertTrue(comparator.compare(fs0, fs2) > 0); 151 assertTrue(comparator.compare(fs2, fs10000) > 0); 152 } 153 154 private Path assertWriteAndReadSequenceId(final int i) { 155 Path p = 156 new Path(testDir, FSTableDescriptors.getTableInfoFileName(i, HConstants.EMPTY_BYTE_ARRAY)); 157 int ii = FSTableDescriptors.getTableInfoSequenceIdAndFileLength(p).sequenceId; 158 assertEquals(i, ii); 159 return p; 160 } 161 162 @Test 163 public void testRemoves(TestInfo testInfo) throws IOException { 164 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 165 // Cleanup old tests if any detrius laying around. 166 TableDescriptors htds = new FSTableDescriptors(fs, testDir); 167 TableDescriptor htd = TableDescriptorBuilder 168 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName())).build(); 169 htds.update(htd); 170 assertNotNull(htds.remove(htd.getTableName())); 171 assertNull(htds.remove(htd.getTableName())); 172 } 173 174 @Test 175 public void testReadingHTDFromFS(TestInfo testInfo) throws IOException { 176 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 177 TableDescriptor htd = TableDescriptorBuilder 178 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName())).build(); 179 FSTableDescriptors fstd = new FSTableDescriptors(fs, testDir); 180 fstd.createTableDescriptor(htd); 181 TableDescriptor td2 = 182 FSTableDescriptors.getTableDescriptorFromFs(fs, testDir, htd.getTableName()); 183 assertTrue(htd.equals(td2)); 184 } 185 186 @Test 187 public void testTableDescriptors(TestInfo testInfo) throws IOException, InterruptedException { 188 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 189 // Cleanup old tests if any debris laying around. 190 FSTableDescriptors htds = new FSTableDescriptors(fs, testDir) { 191 @Override 192 public TableDescriptor get(TableName tablename) { 193 LOG.info(tablename + ", cachehits=" + this.cachehits); 194 return super.get(tablename); 195 } 196 }; 197 final int count = 10; 198 // Write out table infos. 199 for (int i = 0; i < count; i++) { 200 htds.createTableDescriptor(TableDescriptorBuilder 201 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)).build()); 202 } 203 204 for (int i = 0; i < count; i++) { 205 assertTrue(htds.get(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)) != null); 206 } 207 for (int i = 0; i < count; i++) { 208 assertTrue(htds.get(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)) != null); 209 } 210 // Update the table infos 211 for (int i = 0; i < count; i++) { 212 TableDescriptorBuilder builder = TableDescriptorBuilder 213 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)); 214 builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of("" + i)); 215 htds.update(builder.build()); 216 } 217 // Wait a while so mod time we write is for sure different. 218 Thread.sleep(100); 219 for (int i = 0; i < count; i++) { 220 assertTrue(htds.get(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)) != null); 221 } 222 for (int i = 0; i < count; i++) { 223 assertTrue(htds.get(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)) != null); 224 } 225 assertEquals(count * 4, htds.invocations); 226 assertTrue(htds.cachehits >= (count * 2), 227 "expected=" + (count * 2) + ", actual=" + htds.cachehits); 228 } 229 230 @Test 231 public void testTableDescriptorsNoCache(TestInfo testInfo) 232 throws IOException, InterruptedException { 233 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 234 // Cleanup old tests if any debris laying around. 235 FSTableDescriptors htds = new FSTableDescriptorsTest(fs, testDir, false); 236 final int count = 10; 237 // Write out table infos. 238 for (int i = 0; i < count; i++) { 239 htds.createTableDescriptor(TableDescriptorBuilder 240 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)).build()); 241 } 242 243 for (int i = 0; i < 2 * count; i++) { 244 assertNotNull(htds.get(TableName.valueOf(testInfo.getTestMethod().get().getName() + i % 2)), 245 "Expected HTD, got null instead"); 246 } 247 // Update the table infos 248 for (int i = 0; i < count; i++) { 249 TableDescriptorBuilder builder = TableDescriptorBuilder 250 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)); 251 builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of("" + i)); 252 htds.update(builder.build()); 253 } 254 for (int i = 0; i < count; i++) { 255 assertNotNull(htds.get(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)), 256 "Expected HTD, got null instead"); 257 assertTrue(htds.get(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)) 258 .hasColumnFamily(Bytes.toBytes("" + i)), "Column Family " + i + " missing"); 259 } 260 assertEquals(count * 4, htds.invocations); 261 assertEquals(0, htds.cachehits, "expected=0, actual=" + htds.cachehits); 262 } 263 264 @Test 265 public void testGetAll() throws IOException, InterruptedException { 266 final String name = "testGetAll"; 267 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 268 // Cleanup old tests if any debris laying around. 269 FSTableDescriptors htds = new FSTableDescriptorsTest(fs, testDir); 270 final int count = 4; 271 // Write out table infos. 272 for (int i = 0; i < count; i++) { 273 htds.createTableDescriptor( 274 TableDescriptorBuilder.newBuilder(TableName.valueOf(name + i)).build()); 275 } 276 // add hbase:meta 277 htds 278 .createTableDescriptor(TableDescriptorBuilder.newBuilder(TableName.META_TABLE_NAME).build()); 279 assertEquals(count + 1, htds.getAll().size(), 280 "getAll() didn't return all TableDescriptors, expected: " + (count + 1) + " got: " 281 + htds.getAll().size()); 282 } 283 284 @Test 285 public void testParallelGetAll() throws IOException, InterruptedException { 286 final String name = "testParallelGetAll"; 287 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 288 // Enable parallel load table descriptor. 289 FSTableDescriptors htds = new FSTableDescriptorsTest(fs, testDir, true, 20); 290 final int count = 100; 291 // Write out table infos. 292 for (int i = 0; i < count; i++) { 293 htds.createTableDescriptor( 294 TableDescriptorBuilder.newBuilder(TableName.valueOf(name + i)).build()); 295 } 296 // add hbase:meta 297 htds 298 .createTableDescriptor(TableDescriptorBuilder.newBuilder(TableName.META_TABLE_NAME).build()); 299 300 int getTableDescriptorSize = htds.getAll().size(); 301 assertEquals(count + 1, getTableDescriptorSize, 302 "getAll() didn't return all TableDescriptors, expected: " + (count + 1) + " got: " 303 + getTableDescriptorSize); 304 305 // get again to check whether the cache works well 306 getTableDescriptorSize = htds.getAll().size(); 307 assertEquals(count + 1, getTableDescriptorSize, 308 "getAll() didn't return all TableDescriptors with cache, expected: " + (count + 1) + " got: " 309 + getTableDescriptorSize); 310 } 311 312 @Test 313 public void testGetAllOrdering() throws Exception { 314 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 315 FSTableDescriptors tds = new FSTableDescriptorsTest(fs, testDir); 316 317 String[] tableNames = new String[] { "foo", "bar", "foo:bar", "bar:foo" }; 318 for (String tableName : tableNames) { 319 tds.createTableDescriptor( 320 TableDescriptorBuilder.newBuilder(TableName.valueOf(tableName)).build()); 321 } 322 323 Map<String, TableDescriptor> tables = tds.getAll(); 324 // Remove hbase:meta from list. It shows up now since we made it dynamic. The schema 325 // is written into the fs by the FSTableDescriptors constructor now where before it 326 // didn't. 327 tables.remove(TableName.META_TABLE_NAME.getNameAsString()); 328 assertEquals(4, tables.size()); 329 330 String[] tableNamesOrdered = 331 new String[] { "bar:foo", "default:bar", "default:foo", "foo:bar" }; 332 int i = 0; 333 for (Map.Entry<String, TableDescriptor> entry : tables.entrySet()) { 334 assertEquals(tableNamesOrdered[i], entry.getKey()); 335 assertEquals(tableNamesOrdered[i], 336 entry.getValue().getTableName().getNameWithNamespaceInclAsString()); 337 i++; 338 } 339 } 340 341 @Test 342 public void testCacheConsistency(TestInfo testInfo) throws IOException, InterruptedException { 343 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 344 // Cleanup old tests if any debris laying around. 345 FSTableDescriptors chtds = new FSTableDescriptorsTest(fs, testDir); 346 FSTableDescriptors nonchtds = new FSTableDescriptorsTest(fs, testDir, false); 347 348 final int count = 10; 349 // Write out table infos via non-cached FSTableDescriptors 350 for (int i = 0; i < count; i++) { 351 nonchtds.createTableDescriptor(TableDescriptorBuilder 352 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)).build()); 353 } 354 355 // Calls to getAll() won't increase the cache counter, do per table. 356 for (int i = 0; i < count; i++) { 357 assertTrue( 358 chtds.get(TableName.valueOf(testInfo.getTestMethod().get().getName() + i)) != null); 359 } 360 361 assertTrue(nonchtds.getAll().size() == chtds.getAll().size()); 362 363 // add a new entry for random table name. 364 TableName random = TableName.valueOf("random"); 365 TableDescriptor htd = TableDescriptorBuilder.newBuilder(random).build(); 366 nonchtds.createTableDescriptor(htd); 367 368 // random will only increase the cachehit by 1 369 assertEquals(nonchtds.getAll().size(), chtds.getAll().size() + 1); 370 371 for (Map.Entry<String, TableDescriptor> entry : chtds.getAll().entrySet()) { 372 String t = (String) entry.getKey(); 373 TableDescriptor nchtd = entry.getValue(); 374 assertTrue((nchtd.equals(chtds.get(TableName.valueOf(t)))), 375 "expected " + htd.toString() + " got: " + chtds.get(TableName.valueOf(t)).toString()); 376 } 377 // this is by design, for FSTableDescriptor with cache enabled, once we have done a full scan 378 // and load all the table descriptors to cache, we will not go to file system again, as the only 379 // way to update table descriptor is to through us so we can cache it when updating. 380 assertNotNull(nonchtds.get(random)); 381 assertNull(chtds.get(random)); 382 } 383 384 @Test 385 public void testNoSuchTable() throws IOException { 386 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 387 // Cleanup old tests if any detrius laying around. 388 TableDescriptors htds = new FSTableDescriptors(fs, testDir); 389 assertNull(htds.get(TableName.valueOf("NoSuchTable")), 390 "There shouldn't be any HTD for this table"); 391 } 392 393 @Test 394 public void testUpdates(TestInfo testInfo) throws IOException { 395 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 396 // Cleanup old tests if any detrius laying around. 397 TableDescriptors htds = new FSTableDescriptors(fs, testDir); 398 TableDescriptor htd = TableDescriptorBuilder 399 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName())).build(); 400 htds.update(htd); 401 htds.update(htd); 402 htds.update(htd); 403 } 404 405 @Test 406 public void testTableInfoFileStatusComparator() { 407 FileStatus bare = new FileStatus(0, false, 0, 0, -1, 408 new Path("/tmp", FSTableDescriptors.TABLEINFO_FILE_PREFIX)); 409 FileStatus future = new FileStatus(0, false, 0, 0, -1, 410 new Path("/tmp/tablinfo." + EnvironmentEdgeManager.currentTime())); 411 FileStatus farFuture = new FileStatus(0, false, 0, 0, -1, 412 new Path("/tmp/tablinfo." + EnvironmentEdgeManager.currentTime() + 1000)); 413 FileStatus[] alist = { bare, future, farFuture }; 414 FileStatus[] blist = { bare, farFuture, future }; 415 FileStatus[] clist = { farFuture, bare, future }; 416 Comparator<FileStatus> c = FSTableDescriptors.TABLEINFO_FILESTATUS_COMPARATOR; 417 Arrays.sort(alist, c); 418 Arrays.sort(blist, c); 419 Arrays.sort(clist, c); 420 // Now assert all sorted same in way we want. 421 for (int i = 0; i < alist.length; i++) { 422 assertTrue(alist[i].equals(blist[i])); 423 assertTrue(blist[i].equals(clist[i])); 424 assertTrue(clist[i].equals(i == 0 ? farFuture : i == 1 ? future : bare)); 425 } 426 } 427 428 @Test 429 public void testReadingInvalidDirectoryFromFS() throws IOException { 430 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 431 try { 432 new FSTableDescriptors(fs, CommonFSUtils.getRootDir(UTIL.getConfiguration())) 433 .get(TableName.valueOf(HConstants.HBASE_TEMP_DIRECTORY)); 434 fail("Shouldn't be able to read a table descriptor for the archive directory."); 435 } catch (Exception e) { 436 LOG.debug("Correctly got error when reading a table descriptor from the archive directory: " 437 + e.getMessage()); 438 } 439 } 440 441 @Test 442 public void testCreateTableDescriptorUpdatesIfExistsAlready(TestInfo testInfo) 443 throws IOException { 444 TableDescriptor htd = TableDescriptorBuilder 445 .newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName())).build(); 446 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 447 FSTableDescriptors fstd = new FSTableDescriptors(fs, testDir); 448 assertTrue(fstd.createTableDescriptor(htd)); 449 assertFalse(fstd.createTableDescriptor(htd)); 450 htd = TableDescriptorBuilder.newBuilder(htd) 451 .setValue(Bytes.toBytes("mykey"), Bytes.toBytes("myValue")).build(); 452 assertTrue(fstd.createTableDescriptor(htd)); // this will re-create 453 Path tableDir = CommonFSUtils.getTableDir(testDir, htd.getTableName()); 454 assertEquals(htd, FSTableDescriptors.getTableDescriptorFromFs(fs, tableDir)); 455 } 456 457 @Test 458 public void testIgnoreBrokenTableDescriptorFiles(TestInfo testInfo) throws IOException { 459 TableDescriptor htd = 460 TableDescriptorBuilder.newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName())) 461 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf")).build(); 462 TableDescriptor newHtd = 463 TableDescriptorBuilder.newBuilder(TableName.valueOf(testInfo.getTestMethod().get().getName())) 464 .setColumnFamily(ColumnFamilyDescriptorBuilder.of("cf2")).build(); 465 assertNotEquals(newHtd, htd); 466 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 467 FSTableDescriptors fstd = new FSTableDescriptors(fs, testDir, false, false); 468 fstd.update(htd); 469 byte[] bytes = TableDescriptorBuilder.toByteArray(newHtd); 470 Path tableDir = CommonFSUtils.getTableDir(testDir, htd.getTableName()); 471 Path tableInfoDir = new Path(tableDir, FSTableDescriptors.TABLEINFO_DIR); 472 FileStatus[] statuses = fs.listStatus(tableInfoDir); 473 assertEquals(1, statuses.length); 474 int seqId = 475 FSTableDescriptors.getTableInfoSequenceIdAndFileLength(statuses[0].getPath()).sequenceId + 1; 476 Path brokenFile = new Path(tableInfoDir, FSTableDescriptors.getTableInfoFileName(seqId, bytes)); 477 try (FSDataOutputStream out = fs.create(brokenFile)) { 478 out.write(bytes, 0, bytes.length / 2); 479 } 480 assertTrue(fs.exists(brokenFile)); 481 TableDescriptor getTd = fstd.get(htd.getTableName()); 482 assertEquals(htd, getTd); 483 assertFalse(fs.exists(brokenFile)); 484 } 485 486 @Test 487 public void testFSTableDescriptorsSkipsForeignMetaTables() throws Exception { 488 FileSystem fs = FileSystem.get(UTIL.getConfiguration()); 489 String[] metaTables = { "meta_replica1", "meta" }; 490 Path hbaseNamespaceDir = new Path(testDir, HConstants.BASE_NAMESPACE_DIR + "/hbase"); 491 fs.mkdirs(hbaseNamespaceDir); 492 493 for (String metaTable : metaTables) { 494 TableName tableName = TableName.valueOf("hbase", metaTable); 495 Path metaTableDir = new Path(hbaseNamespaceDir, metaTable); 496 fs.mkdirs(metaTableDir); 497 fs.mkdirs(new Path(metaTableDir, FSTableDescriptors.TABLEINFO_DIR)); 498 fs.mkdirs(new Path(metaTableDir, "abcdef0123456789")); 499 500 TableDescriptor tableDescriptor = TableDescriptorBuilder.newBuilder(tableName) 501 .setColumnFamily(ColumnFamilyDescriptorBuilder.newBuilder(HConstants.CATALOG_FAMILY) 502 .setMaxVersions(HConstants.DEFAULT_HBASE_META_VERSIONS).setInMemory(true) 503 .setBlocksize(HConstants.DEFAULT_HBASE_META_BLOCK_SIZE) 504 .setBloomFilterType(BloomType.ROWCOL).build()) 505 .build(); 506 507 Path tableDir = CommonFSUtils.getTableDir(testDir, tableName); 508 FSTableDescriptors.createTableDescriptorForTableDirectory(fs, tableDir, tableDescriptor, 509 false); 510 } 511 FSTableDescriptors tableDescriptors = new FSTableDescriptors(fs, testDir); 512 Map<String, TableDescriptor> allTables = tableDescriptors.getAll(); 513 514 assertFalse(allTables.containsKey("hbase:meta_replica1"), "Should not contain meta_replica1"); 515 assertTrue(allTables.containsKey("hbase:meta"), "Should include the local hbase:meta"); 516 } 517 518 private static class FSTableDescriptorsTest extends FSTableDescriptors { 519 520 public FSTableDescriptorsTest(FileSystem fs, Path rootdir) { 521 this(fs, rootdir, true); 522 } 523 524 public FSTableDescriptorsTest(FileSystem fs, Path rootdir, boolean usecache) { 525 super(fs, rootdir, false, usecache); 526 } 527 528 public FSTableDescriptorsTest(FileSystem fs, Path rootdir, boolean usecache, 529 int tableDescriptorParallelLoadThreads) { 530 super(fs, rootdir, false, usecache, tableDescriptorParallelLoadThreads); 531 } 532 533 @Override 534 public TableDescriptor get(TableName tablename) { 535 LOG.info((super.isUsecache() ? "Cached" : "Non-Cached") + " TableDescriptor.get() on " 536 + tablename + ", cachehits=" + this.cachehits); 537 return super.get(tablename); 538 } 539 } 540}