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