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