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.client; 019 020import static org.apache.hadoop.hbase.TableName.META_TABLE_NAME; 021import static org.junit.Assert.assertEquals; 022import static org.junit.Assert.assertFalse; 023import static org.junit.Assert.assertTrue; 024import static org.junit.Assert.fail; 025import java.util.ArrayList; 026import java.util.HashMap; 027import java.util.Iterator; 028import java.util.List; 029import java.util.Map; 030import java.util.Optional; 031import java.util.concurrent.CompletionException; 032import org.apache.hadoop.hbase.AsyncMetaTableAccessor; 033import org.apache.hadoop.hbase.HBaseClassTestRule; 034import org.apache.hadoop.hbase.HConstants; 035import org.apache.hadoop.hbase.HRegionLocation; 036import org.apache.hadoop.hbase.ServerName; 037import org.apache.hadoop.hbase.TableExistsException; 038import org.apache.hadoop.hbase.TableName; 039import org.apache.hadoop.hbase.TableNotFoundException; 040import org.apache.hadoop.hbase.master.LoadBalancer; 041import org.apache.hadoop.hbase.testclassification.ClientTests; 042import org.apache.hadoop.hbase.testclassification.LargeTests; 043import org.apache.hadoop.hbase.util.Bytes; 044import org.junit.ClassRule; 045import org.junit.Test; 046import org.junit.experimental.categories.Category; 047import org.junit.runner.RunWith; 048import org.junit.runners.Parameterized; 049 050/** 051 * Class to test asynchronous table admin operations. 052 * @see TestAsyncTableAdminApi2 This test and it used to be joined it was taking longer than our 053 * ten minute timeout so they were split. 054 * @see TestAsyncTableAdminApi3 Another split out from this class so each runs under ten minutes. 055 */ 056@RunWith(Parameterized.class) 057@Category({ LargeTests.class, ClientTests.class }) 058public class TestAsyncTableAdminApi extends TestAsyncAdminBase { 059 060 @ClassRule 061 public static final HBaseClassTestRule CLASS_RULE = 062 HBaseClassTestRule.forClass(TestAsyncTableAdminApi.class); 063 064 @Test 065 public void testCreateTable() throws Exception { 066 List<TableDescriptor> tables = admin.listTableDescriptors().get(); 067 int numTables = tables.size(); 068 createTableWithDefaultConf(tableName); 069 tables = admin.listTableDescriptors().get(); 070 assertEquals(numTables + 1, tables.size()); 071 assertTrue("Table must be enabled.", TEST_UTIL.getHBaseCluster().getMaster() 072 .getTableStateManager().isTableState(tableName, TableState.State.ENABLED)); 073 assertEquals(TableState.State.ENABLED, getStateFromMeta(tableName)); 074 } 075 076 static TableState.State getStateFromMeta(TableName table) throws Exception { 077 Optional<TableState> state = AsyncMetaTableAccessor 078 .getTableState(ASYNC_CONN.getTable(TableName.META_TABLE_NAME), table).get(); 079 assertTrue(state.isPresent()); 080 return state.get().getState(); 081 } 082 083 @Test 084 public void testCreateTableNumberOfRegions() throws Exception { 085 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME); 086 087 createTableWithDefaultConf(tableName); 088 List<HRegionLocation> regionLocations = AsyncMetaTableAccessor 089 .getTableHRegionLocations(metaTable, tableName).get(); 090 assertEquals("Table should have only 1 region", 1, regionLocations.size()); 091 092 final TableName tableName2 = TableName.valueOf(tableName.getNameAsString() + "_2"); 093 createTableWithDefaultConf(tableName2, new byte[][] { new byte[] { 42 } }); 094 regionLocations = AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, tableName2).get(); 095 assertEquals("Table should have only 2 region", 2, regionLocations.size()); 096 097 final TableName tableName3 = TableName.valueOf(tableName.getNameAsString() + "_3"); 098 TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName3); 099 builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)); 100 admin.createTable(builder.build(), Bytes.toBytes("a"), Bytes.toBytes("z"), 3).join(); 101 regionLocations = AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, tableName3).get(); 102 assertEquals("Table should have only 3 region", 3, regionLocations.size()); 103 104 final TableName tableName4 = TableName.valueOf(tableName.getNameAsString() + "_4"); 105 builder = TableDescriptorBuilder.newBuilder(tableName4); 106 builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)); 107 try { 108 admin.createTable(builder.build(), "a".getBytes(), "z".getBytes(), 2).join(); 109 fail("Should not be able to create a table with only 2 regions using this API."); 110 } catch (CompletionException e) { 111 assertTrue(e.getCause() instanceof IllegalArgumentException); 112 } 113 114 final TableName tableName5 = TableName.valueOf(tableName.getNameAsString() + "_5"); 115 builder = TableDescriptorBuilder.newBuilder(tableName5); 116 builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)); 117 admin.createTable(builder.build(), new byte[] { 1 }, new byte[] { 127 }, 16).join(); 118 regionLocations = AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, tableName5).get(); 119 assertEquals("Table should have 16 region", 16, regionLocations.size()); 120 } 121 122 @Test 123 public void testCreateTableWithRegions() throws Exception { 124 byte[][] splitKeys = { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, new byte[] { 3, 3, 3 }, 125 new byte[] { 4, 4, 4 }, new byte[] { 5, 5, 5 }, new byte[] { 6, 6, 6 }, 126 new byte[] { 7, 7, 7 }, new byte[] { 8, 8, 8 }, new byte[] { 9, 9, 9 }, }; 127 int expectedRegions = splitKeys.length + 1; 128 boolean tablesOnMaster = LoadBalancer.isTablesOnMaster(TEST_UTIL.getConfiguration()); 129 createTableWithDefaultConf(tableName, splitKeys); 130 131 boolean tableAvailable = admin.isTableAvailable(tableName, splitKeys).get(); 132 assertTrue("Table should be created with splitKyes + 1 rows in META", tableAvailable); 133 134 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME); 135 List<HRegionLocation> regions = AsyncMetaTableAccessor 136 .getTableHRegionLocations(metaTable, tableName).get(); 137 Iterator<HRegionLocation> hris = regions.iterator(); 138 139 assertEquals( 140 "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(), 141 expectedRegions, regions.size()); 142 System.err.println("Found " + regions.size() + " regions"); 143 144 RegionInfo hri; 145 hris = regions.iterator(); 146 hri = hris.next().getRegion(); 147 assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0); 148 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[0])); 149 hri = hris.next().getRegion(); 150 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[0])); 151 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[1])); 152 hri = hris.next().getRegion(); 153 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[1])); 154 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[2])); 155 hri = hris.next().getRegion(); 156 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[2])); 157 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[3])); 158 hri = hris.next().getRegion(); 159 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[3])); 160 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[4])); 161 hri = hris.next().getRegion(); 162 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[4])); 163 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[5])); 164 hri = hris.next().getRegion(); 165 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[5])); 166 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[6])); 167 hri = hris.next().getRegion(); 168 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[6])); 169 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[7])); 170 hri = hris.next().getRegion(); 171 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[7])); 172 assertTrue(Bytes.equals(hri.getEndKey(), splitKeys[8])); 173 hri = hris.next().getRegion(); 174 assertTrue(Bytes.equals(hri.getStartKey(), splitKeys[8])); 175 assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0); 176 if (tablesOnMaster) { 177 verifyRoundRobinDistribution(regions, expectedRegions); 178 } 179 180 // Now test using start/end with a number of regions 181 182 // Use 80 bit numbers to make sure we aren't limited 183 byte[] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 }; 184 byte[] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 }; 185 186 // Splitting into 10 regions, we expect (null,1) ... (9, null) 187 // with (1,2) (2,3) (3,4) (4,5) (5,6) (6,7) (7,8) (8,9) in the middle 188 expectedRegions = 10; 189 final TableName tableName2 = TableName.valueOf(tableName.getNameAsString() + "_2"); 190 TableDescriptorBuilder builder = TableDescriptorBuilder.newBuilder(tableName2); 191 builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)); 192 admin.createTable(builder.build(), startKey, endKey, expectedRegions).join(); 193 194 regions = AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, tableName2).get(); 195 assertEquals( 196 "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(), 197 expectedRegions, regions.size()); 198 System.err.println("Found " + regions.size() + " regions"); 199 200 hris = regions.iterator(); 201 hri = hris.next().getRegion(); 202 assertTrue(hri.getStartKey() == null || hri.getStartKey().length == 0); 203 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 })); 204 hri = hris.next().getRegion(); 205 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 })); 206 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 })); 207 hri = hris.next().getRegion(); 208 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 2, 2, 2, 2, 2, 2, 2, 2, 2, 2 })); 209 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 })); 210 hri = hris.next().getRegion(); 211 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 3, 3, 3, 3, 3, 3, 3, 3, 3, 3 })); 212 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 })); 213 hri = hris.next().getRegion(); 214 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 4, 4, 4, 4, 4, 4, 4, 4, 4, 4 })); 215 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 })); 216 hri = hris.next().getRegion(); 217 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 5, 5, 5, 5, 5, 5, 5, 5, 5, 5 })); 218 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 })); 219 hri = hris.next().getRegion(); 220 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 6, 6, 6, 6, 6, 6, 6, 6, 6, 6 })); 221 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 })); 222 hri = hris.next().getRegion(); 223 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 7, 7, 7, 7, 7, 7, 7, 7, 7, 7 })); 224 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 })); 225 hri = hris.next().getRegion(); 226 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 8, 8, 8, 8, 8, 8, 8, 8, 8, 8 })); 227 assertTrue(Bytes.equals(hri.getEndKey(), new byte[] { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 })); 228 hri = hris.next().getRegion(); 229 assertTrue(Bytes.equals(hri.getStartKey(), new byte[] { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 })); 230 assertTrue(hri.getEndKey() == null || hri.getEndKey().length == 0); 231 if (tablesOnMaster) { 232 // This don't work if master is not carrying regions. FIX. TODO. 233 verifyRoundRobinDistribution(regions, expectedRegions); 234 } 235 236 // Try once more with something that divides into something infinite 237 startKey = new byte[] { 0, 0, 0, 0, 0, 0 }; 238 endKey = new byte[] { 1, 0, 0, 0, 0, 0 }; 239 240 expectedRegions = 5; 241 final TableName tableName3 = TableName.valueOf(tableName.getNameAsString() + "_3"); 242 builder = TableDescriptorBuilder.newBuilder(tableName3); 243 builder.setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY)); 244 admin.createTable(builder.build(), startKey, endKey, expectedRegions).join(); 245 246 regions = AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, tableName3) 247 .get(); 248 assertEquals( 249 "Tried to create " + expectedRegions + " regions " + "but only found " + regions.size(), 250 expectedRegions, regions.size()); 251 System.err.println("Found " + regions.size() + " regions"); 252 if (tablesOnMaster) { 253 // This don't work if master is not carrying regions. FIX. TODO. 254 verifyRoundRobinDistribution(regions, expectedRegions); 255 } 256 257 // Try an invalid case where there are duplicate split keys 258 splitKeys = new byte[][] { new byte[] { 1, 1, 1 }, new byte[] { 2, 2, 2 }, 259 new byte[] { 3, 3, 3 }, new byte[] { 2, 2, 2 } }; 260 final TableName tableName4 = TableName.valueOf(tableName.getNameAsString() + "_4"); 261 try { 262 createTableWithDefaultConf(tableName4, splitKeys); 263 fail("Should not be able to create this table because of " + "duplicate split keys"); 264 } catch (CompletionException e) { 265 assertTrue(e.getCause() instanceof IllegalArgumentException); 266 } 267 } 268 269 private void verifyRoundRobinDistribution(List<HRegionLocation> regions, int expectedRegions) { 270 int numRS = TEST_UTIL.getMiniHBaseCluster().getNumLiveRegionServers(); 271 272 Map<ServerName, List<RegionInfo>> server2Regions = new HashMap<>(); 273 regions.stream().forEach((loc) -> { 274 ServerName server = loc.getServerName(); 275 server2Regions.computeIfAbsent(server, (s) -> new ArrayList<>()).add(loc.getRegion()); 276 }); 277 if (numRS >= 2) { 278 // Ignore the master region server, 279 // which contains less regions by intention. 280 numRS--; 281 } 282 float average = (float) expectedRegions / numRS; 283 int min = (int) Math.floor(average); 284 int max = (int) Math.ceil(average); 285 server2Regions.values().forEach((regionList) -> { 286 assertTrue(regionList.size() == min || regionList.size() == max); 287 }); 288 } 289 290 @Test 291 public void testCreateTableWithOnlyEmptyStartRow() throws Exception { 292 byte[][] splitKeys = new byte[1][]; 293 splitKeys[0] = HConstants.EMPTY_BYTE_ARRAY; 294 try { 295 createTableWithDefaultConf(tableName, splitKeys); 296 fail("Test case should fail as empty split key is passed."); 297 } catch (CompletionException e) { 298 assertTrue(e.getCause() instanceof IllegalArgumentException); 299 } 300 } 301 302 @Test 303 public void testCreateTableWithEmptyRowInTheSplitKeys() throws Exception { 304 byte[][] splitKeys = new byte[3][]; 305 splitKeys[0] = "region1".getBytes(); 306 splitKeys[1] = HConstants.EMPTY_BYTE_ARRAY; 307 splitKeys[2] = "region2".getBytes(); 308 try { 309 createTableWithDefaultConf(tableName, splitKeys); 310 fail("Test case should fail as empty split key is passed."); 311 } catch (CompletionException e) { 312 assertTrue(e.getCause() instanceof IllegalArgumentException); 313 } 314 } 315 316 @Test 317 public void testDeleteTable() throws Exception { 318 createTableWithDefaultConf(tableName); 319 assertTrue(admin.tableExists(tableName).get()); 320 TEST_UTIL.getAdmin().disableTable(tableName); 321 admin.deleteTable(tableName).join(); 322 assertFalse(admin.tableExists(tableName).get()); 323 } 324 325 @Test 326 public void testTruncateTable() throws Exception { 327 testTruncateTable(tableName, false); 328 } 329 330 @Test 331 public void testTruncateTablePreservingSplits() throws Exception { 332 testTruncateTable(tableName, true); 333 } 334 335 private void testTruncateTable(final TableName tableName, boolean preserveSplits) 336 throws Exception { 337 byte[][] splitKeys = new byte[2][]; 338 splitKeys[0] = Bytes.toBytes(4); 339 splitKeys[1] = Bytes.toBytes(8); 340 341 // Create & Fill the table 342 createTableWithDefaultConf(tableName, splitKeys); 343 AsyncTable<?> table = ASYNC_CONN.getTable(tableName); 344 int expectedRows = 10; 345 for (int i = 0; i < expectedRows; i++) { 346 byte[] data = Bytes.toBytes(String.valueOf(i)); 347 Put put = new Put(data); 348 put.addColumn(FAMILY, null, data); 349 table.put(put).join(); 350 } 351 assertEquals(10, table.scanAll(new Scan()).get().size()); 352 assertEquals(3, TEST_UTIL.getHBaseCluster().getRegions(tableName).size()); 353 354 // Truncate & Verify 355 admin.disableTable(tableName).join(); 356 admin.truncateTable(tableName, preserveSplits).join(); 357 assertEquals(0, table.scanAll(new Scan()).get().size()); 358 if (preserveSplits) { 359 assertEquals(3, TEST_UTIL.getHBaseCluster().getRegions(tableName).size()); 360 } else { 361 assertEquals(1, TEST_UTIL.getHBaseCluster().getRegions(tableName).size()); 362 } 363 } 364 365 @Test 366 public void testCloneTableSchema() throws Exception { 367 final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new"); 368 testCloneTableSchema(tableName, newTableName, false); 369 } 370 371 @Test 372 public void testCloneTableSchemaPreservingSplits() throws Exception { 373 final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new"); 374 testCloneTableSchema(tableName, newTableName, true); 375 } 376 377 private void testCloneTableSchema(final TableName tableName, 378 final TableName newTableName, boolean preserveSplits) throws Exception { 379 byte[][] splitKeys = new byte[2][]; 380 splitKeys[0] = Bytes.toBytes(4); 381 splitKeys[1] = Bytes.toBytes(8); 382 int NUM_FAMILYS = 2; 383 int NUM_REGIONS = 3; 384 int BLOCK_SIZE = 1024; 385 int TTL = 86400; 386 boolean BLOCK_CACHE = false; 387 388 // Create the table 389 TableDescriptor tableDesc = TableDescriptorBuilder 390 .newBuilder(tableName) 391 .setColumnFamily(ColumnFamilyDescriptorBuilder.of(FAMILY_0)) 392 .setColumnFamily(ColumnFamilyDescriptorBuilder 393 .newBuilder(FAMILY_1) 394 .setBlocksize(BLOCK_SIZE) 395 .setBlockCacheEnabled(BLOCK_CACHE) 396 .setTimeToLive(TTL) 397 .build()).build(); 398 admin.createTable(tableDesc, splitKeys).join(); 399 400 assertEquals(NUM_REGIONS, TEST_UTIL.getHBaseCluster().getRegions(tableName).size()); 401 assertTrue("Table should be created with splitKyes + 1 rows in META", 402 admin.isTableAvailable(tableName, splitKeys).get()); 403 404 // Clone & Verify 405 admin.cloneTableSchema(tableName, newTableName, preserveSplits).join(); 406 TableDescriptor newTableDesc = admin.getDescriptor(newTableName).get(); 407 408 assertEquals(NUM_FAMILYS, newTableDesc.getColumnFamilyCount()); 409 assertEquals(BLOCK_SIZE, newTableDesc.getColumnFamily(FAMILY_1).getBlocksize()); 410 assertEquals(BLOCK_CACHE, newTableDesc.getColumnFamily(FAMILY_1).isBlockCacheEnabled()); 411 assertEquals(TTL, newTableDesc.getColumnFamily(FAMILY_1).getTimeToLive()); 412 TEST_UTIL.verifyTableDescriptorIgnoreTableName(tableDesc, newTableDesc); 413 414 if (preserveSplits) { 415 assertEquals(NUM_REGIONS, TEST_UTIL.getHBaseCluster().getRegions(newTableName).size()); 416 assertTrue("New table should be created with splitKyes + 1 rows in META", 417 admin.isTableAvailable(newTableName, splitKeys).get()); 418 } else { 419 assertEquals(1, TEST_UTIL.getHBaseCluster().getRegions(newTableName).size()); 420 } 421 } 422 423 @Test 424 public void testCloneTableSchemaWithNonExistentSourceTable() throws Exception { 425 final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new"); 426 // test for non-existent source table 427 try { 428 admin.cloneTableSchema(tableName, newTableName, false).join(); 429 fail("Should have failed when source table doesn't exist."); 430 } catch (CompletionException e) { 431 assertTrue(e.getCause() instanceof TableNotFoundException); 432 } 433 } 434 435 @Test 436 public void testCloneTableSchemaWithExistentDestinationTable() throws Exception { 437 final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new"); 438 byte[] FAMILY_0 = Bytes.toBytes("cf0"); 439 TEST_UTIL.createTable(tableName, FAMILY_0); 440 TEST_UTIL.createTable(newTableName, FAMILY_0); 441 // test for existent destination table 442 try { 443 admin.cloneTableSchema(tableName, newTableName, false).join(); 444 fail("Should have failed when destination table exists."); 445 } catch (CompletionException e) { 446 assertTrue(e.getCause() instanceof TableExistsException); 447 } 448 } 449 450 @Test 451 public void testIsTableAvailableWithInexistantTable() throws Exception { 452 final TableName newTableName = TableName.valueOf(tableName.getNameAsString() + "_new"); 453 // test for inexistant table 454 assertFalse(admin.isTableAvailable(newTableName).get()); 455 } 456}