HBASE-22002 Remove the deprecated methods in Admin interface
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / client / TestAdmin2.java
blobb92875057bb6dac7757f27d34ff9d02e99ee0767
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.client;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertTrue;
23 import static org.junit.Assert.fail;
25 import java.io.IOException;
26 import java.util.ArrayList;
27 import java.util.EnumSet;
28 import java.util.HashMap;
29 import java.util.List;
30 import java.util.Random;
31 import java.util.concurrent.atomic.AtomicInteger;
32 import java.util.stream.Collectors;
33 import org.apache.hadoop.conf.Configuration;
34 import org.apache.hadoop.hbase.ClusterMetrics.Option;
35 import org.apache.hadoop.hbase.HBaseClassTestRule;
36 import org.apache.hadoop.hbase.HBaseTestingUtility;
37 import org.apache.hadoop.hbase.HColumnDescriptor;
38 import org.apache.hadoop.hbase.HConstants;
39 import org.apache.hadoop.hbase.HRegionLocation;
40 import org.apache.hadoop.hbase.HTableDescriptor;
41 import org.apache.hadoop.hbase.MiniHBaseCluster;
42 import org.apache.hadoop.hbase.ServerName;
43 import org.apache.hadoop.hbase.TableExistsException;
44 import org.apache.hadoop.hbase.TableName;
45 import org.apache.hadoop.hbase.TableNotDisabledException;
46 import org.apache.hadoop.hbase.TableNotEnabledException;
47 import org.apache.hadoop.hbase.TableNotFoundException;
48 import org.apache.hadoop.hbase.UnknownRegionException;
49 import org.apache.hadoop.hbase.Waiter.Predicate;
50 import org.apache.hadoop.hbase.ZooKeeperConnectionException;
51 import org.apache.hadoop.hbase.constraint.ConstraintException;
52 import org.apache.hadoop.hbase.ipc.HBaseRpcController;
53 import org.apache.hadoop.hbase.master.HMaster;
54 import org.apache.hadoop.hbase.master.assignment.AssignmentManager;
55 import org.apache.hadoop.hbase.regionserver.HRegion;
56 import org.apache.hadoop.hbase.regionserver.HRegionServer;
57 import org.apache.hadoop.hbase.regionserver.HStore;
58 import org.apache.hadoop.hbase.testclassification.ClientTests;
59 import org.apache.hadoop.hbase.testclassification.LargeTests;
60 import org.apache.hadoop.hbase.util.Bytes;
61 import org.apache.hadoop.hbase.util.Pair;
62 import org.apache.hadoop.hbase.wal.AbstractFSWALProvider;
63 import org.junit.After;
64 import org.junit.AfterClass;
65 import org.junit.Assert;
66 import org.junit.BeforeClass;
67 import org.junit.ClassRule;
68 import org.junit.Rule;
69 import org.junit.Test;
70 import org.junit.experimental.categories.Category;
71 import org.junit.rules.TestName;
72 import org.slf4j.Logger;
73 import org.slf4j.LoggerFactory;
75 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
77 /**
78 * Class to test HBaseAdmin.
79 * Spins up the minicluster once at test start and then takes it down afterward.
80 * Add any testing of HBaseAdmin functionality here.
82 @Category({LargeTests.class, ClientTests.class})
83 public class TestAdmin2 {
85 @ClassRule
86 public static final HBaseClassTestRule CLASS_RULE =
87 HBaseClassTestRule.forClass(TestAdmin2.class);
89 private static final Logger LOG = LoggerFactory.getLogger(TestAdmin2.class);
90 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
91 private static Admin ADMIN;
93 @Rule
94 public TestName name = new TestName();
96 @BeforeClass
97 public static void setUpBeforeClass() throws Exception {
98 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.msginterval", 100);
99 TEST_UTIL.getConfiguration().setInt("hbase.client.pause", 250);
100 TEST_UTIL.getConfiguration().setInt("hbase.client.retries.number", 6);
101 TEST_UTIL.getConfiguration().setInt(HConstants.REGION_SERVER_HIGH_PRIORITY_HANDLER_COUNT, 30);
102 TEST_UTIL.getConfiguration().setInt(HConstants.REGION_SERVER_HANDLER_COUNT, 30);
103 TEST_UTIL.getConfiguration().setBoolean("hbase.master.enabletable.roundrobin", true);
104 TEST_UTIL.startMiniCluster(3);
105 ADMIN = TEST_UTIL.getAdmin();
108 @AfterClass
109 public static void tearDownAfterClass() throws Exception {
110 TEST_UTIL.shutdownMiniCluster();
113 @After
114 public void tearDown() throws Exception {
115 for (TableDescriptor htd : ADMIN.listTableDescriptors()) {
116 TEST_UTIL.deleteTable(htd.getTableName());
120 @Test
121 public void testCreateBadTables() throws IOException {
122 String msg = null;
123 try {
124 ADMIN.createTable(new HTableDescriptor(TableName.META_TABLE_NAME));
125 } catch(TableExistsException e) {
126 msg = e.toString();
128 assertTrue("Unexcepted exception message " + msg, msg != null &&
129 msg.startsWith(TableExistsException.class.getName()) &&
130 msg.contains(TableName.META_TABLE_NAME.getNameAsString()));
132 // Now try and do concurrent creation with a bunch of threads.
133 final HTableDescriptor threadDesc = new HTableDescriptor(TableName.valueOf(name.getMethodName()));
134 threadDesc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
135 int count = 10;
136 Thread [] threads = new Thread [count];
137 final AtomicInteger successes = new AtomicInteger(0);
138 final AtomicInteger failures = new AtomicInteger(0);
139 final Admin localAdmin = ADMIN;
140 for (int i = 0; i < count; i++) {
141 threads[i] = new Thread(Integer.toString(i)) {
142 @Override
143 public void run() {
144 try {
145 localAdmin.createTable(threadDesc);
146 successes.incrementAndGet();
147 } catch (TableExistsException e) {
148 failures.incrementAndGet();
149 } catch (IOException e) {
150 throw new RuntimeException("Failed threaded create" + getName(), e);
155 for (int i = 0; i < count; i++) {
156 threads[i].start();
158 for (int i = 0; i < count; i++) {
159 while(threads[i].isAlive()) {
160 try {
161 Thread.sleep(100);
162 } catch (InterruptedException e) {
163 // continue
167 // All threads are now dead. Count up how many tables were created and
168 // how many failed w/ appropriate exception.
169 assertEquals(1, successes.get());
170 assertEquals(count - 1, failures.get());
174 * Test for hadoop-1581 'HBASE: Unopenable tablename bug'.
175 * @throws Exception
177 @Test
178 public void testTableNameClash() throws Exception {
179 final String name = this.name.getMethodName();
180 HTableDescriptor htd1 = new HTableDescriptor(TableName.valueOf(name + "SOMEUPPERCASE"));
181 HTableDescriptor htd2 = new HTableDescriptor(TableName.valueOf(name));
182 htd1.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
183 htd2.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
184 ADMIN.createTable(htd1);
185 ADMIN.createTable(htd2);
186 // Before fix, below would fail throwing a NoServerForRegionException.
187 TEST_UTIL.getConnection().getTable(htd2.getTableName()).close();
190 /***
191 * HMaster.createTable used to be kind of synchronous call
192 * Thus creating of table with lots of regions can cause RPC timeout
193 * After the fix to make createTable truly async, RPC timeout shouldn't be an
194 * issue anymore
196 @Test
197 public void testCreateTableRPCTimeOut() throws Exception {
198 final String name = this.name.getMethodName();
199 int oldTimeout = TEST_UTIL.getConfiguration().
200 getInt(HConstants.HBASE_RPC_TIMEOUT_KEY, HConstants.DEFAULT_HBASE_RPC_TIMEOUT);
201 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, 1500);
202 try {
203 int expectedRegions = 100;
204 // Use 80 bit numbers to make sure we aren't limited
205 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
206 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
207 Admin hbaseadmin = TEST_UTIL.getHBaseAdmin();
208 HTableDescriptor htd = new HTableDescriptor(TableName.valueOf(name));
209 htd.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
210 hbaseadmin.createTable(htd, startKey, endKey, expectedRegions);
211 } finally {
212 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_RPC_TIMEOUT_KEY, oldTimeout);
217 * Test read only tables
218 * @throws Exception
220 @Test
221 public void testReadOnlyTable() throws Exception {
222 final TableName name = TableName.valueOf(this.name.getMethodName());
223 Table table = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
224 byte[] value = Bytes.toBytes("somedata");
225 // This used to use an empty row... That must have been a bug
226 Put put = new Put(value);
227 put.addColumn(HConstants.CATALOG_FAMILY, HConstants.CATALOG_FAMILY, value);
228 table.put(put);
229 table.close();
233 * Test that user table names can contain '-' and '.' so long as they do not
234 * start with same. HBASE-771
236 @Test
237 public void testTableNames() throws IOException {
238 byte[][] illegalNames = new byte[][] {
239 Bytes.toBytes("-bad"),
240 Bytes.toBytes(".bad")
242 for (byte[] illegalName : illegalNames) {
243 try {
244 new HTableDescriptor(TableName.valueOf(illegalName));
245 throw new IOException("Did not detect '" +
246 Bytes.toString(illegalName) + "' as an illegal user table name");
247 } catch (IllegalArgumentException e) {
248 // expected
251 byte[] legalName = Bytes.toBytes("g-oo.d");
252 try {
253 new HTableDescriptor(TableName.valueOf(legalName));
254 } catch (IllegalArgumentException e) {
255 throw new IOException("Legal user table name: '" +
256 Bytes.toString(legalName) + "' caused IllegalArgumentException: " +
257 e.getMessage());
262 * For HADOOP-2579
264 @Test (expected=TableExistsException.class)
265 public void testTableExistsExceptionWithATable() throws IOException {
266 final TableName name = TableName.valueOf(this.name.getMethodName());
267 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
268 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY);
272 * Can't disable a table if the table isn't in enabled state
274 @Test (expected=TableNotEnabledException.class)
275 public void testTableNotEnabledExceptionWithATable() throws IOException {
276 final TableName name = TableName.valueOf(this.name.getMethodName());
277 TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY).close();
278 ADMIN.disableTable(name);
279 ADMIN.disableTable(name);
283 * Can't enable a table if the table isn't in disabled state
285 @Test (expected=TableNotDisabledException.class)
286 public void testTableNotDisabledExceptionWithATable() throws IOException {
287 final TableName name = TableName.valueOf(this.name.getMethodName());
288 try (Table t = TEST_UTIL.createTable(name, HConstants.CATALOG_FAMILY)) {
289 ADMIN.enableTable(name);
294 * For HADOOP-2579
296 @Test(expected = TableNotFoundException.class)
297 public void testTableNotFoundExceptionWithoutAnyTables() throws IOException {
298 TableName tableName = TableName.valueOf("testTableNotFoundExceptionWithoutAnyTables");
299 try (Table ht = TEST_UTIL.getConnection().getTable(tableName)) {
300 ht.get(new Get(Bytes.toBytes("e")));
304 @Test
305 public void testShouldUnassignTheRegion() throws Exception {
306 final TableName tableName = TableName.valueOf(name.getMethodName());
307 createTableWithDefaultConf(tableName);
309 RegionInfo info = null;
310 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(tableName);
311 List<RegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
312 for (RegionInfo regionInfo : onlineRegions) {
313 if (!regionInfo.getTable().isSystemTable()) {
314 info = regionInfo;
315 ADMIN.unassign(regionInfo.getRegionName(), true);
318 boolean isInList = ProtobufUtil.getOnlineRegions(
319 rs.getRSRpcServices()).contains(info);
320 long timeout = System.currentTimeMillis() + 10000;
321 while ((System.currentTimeMillis() < timeout) && (isInList)) {
322 Thread.sleep(100);
323 isInList = ProtobufUtil.getOnlineRegions(
324 rs.getRSRpcServices()).contains(info);
327 assertFalse("The region should not be present in online regions list.",
328 isInList);
331 @Test
332 public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception {
333 final String name = this.name.getMethodName();
334 byte[] tableName = Bytes.toBytes(name);
335 createTableWithDefaultConf(tableName);
337 RegionInfo info = null;
338 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(TableName.valueOf(tableName));
339 List<RegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
340 for (RegionInfo regionInfo : onlineRegions) {
341 if (!regionInfo.isMetaRegion()) {
342 if (regionInfo.getRegionNameAsString().contains(name)) {
343 info = regionInfo;
344 try {
345 ADMIN.unassign(Bytes.toBytes("sample"), true);
346 } catch (UnknownRegionException nsre) {
347 // expected, ignore it
352 onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
353 assertTrue("The region should be present in online regions list.",
354 onlineRegions.contains(info));
357 @Test
358 public void testCloseRegionThatFetchesTheHRIFromMeta() throws Exception {
359 final TableName tableName = TableName.valueOf(name.getMethodName());
360 createTableWithDefaultConf(tableName);
362 RegionInfo info = null;
363 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(tableName);
364 List<RegionInfo> onlineRegions = ProtobufUtil.getOnlineRegions(rs.getRSRpcServices());
365 for (RegionInfo regionInfo : onlineRegions) {
366 if (!regionInfo.isMetaRegion()) {
367 if (regionInfo.getRegionNameAsString().contains("TestHBACloseRegion2")) {
368 info = regionInfo;
369 ADMIN.unassign(regionInfo.getRegionName(), true);
374 boolean isInList = ProtobufUtil.getOnlineRegions(
375 rs.getRSRpcServices()).contains(info);
376 long timeout = System.currentTimeMillis() + 10000;
377 while ((System.currentTimeMillis() < timeout) && (isInList)) {
378 Thread.sleep(100);
379 isInList = ProtobufUtil.getOnlineRegions(
380 rs.getRSRpcServices()).contains(info);
383 assertFalse("The region should not be present in online regions list.",
384 isInList);
387 private HBaseAdmin createTable(TableName tableName) throws IOException {
388 HBaseAdmin admin = TEST_UTIL.getHBaseAdmin();
390 HTableDescriptor htd = new HTableDescriptor(tableName);
391 HColumnDescriptor hcd = new HColumnDescriptor("value");
393 htd.addFamily(hcd);
394 admin.createTable(htd, null);
395 return admin;
398 private void createTableWithDefaultConf(byte[] TABLENAME) throws IOException {
399 createTableWithDefaultConf(TableName.valueOf(TABLENAME));
402 private void createTableWithDefaultConf(TableName TABLENAME) throws IOException {
403 HTableDescriptor htd = new HTableDescriptor(TABLENAME);
404 HColumnDescriptor hcd = new HColumnDescriptor("value");
405 htd.addFamily(hcd);
407 ADMIN.createTable(htd, null);
411 * For HBASE-2556
412 * @throws IOException
414 @Test
415 public void testGetTableRegions() throws IOException {
416 final TableName tableName = TableName.valueOf(name.getMethodName());
418 int expectedRegions = 10;
420 // Use 80 bit numbers to make sure we aren't limited
421 byte [] startKey = { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
422 byte [] endKey = { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
425 HTableDescriptor desc = new HTableDescriptor(tableName);
426 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
427 ADMIN.createTable(desc, startKey, endKey, expectedRegions);
429 List<RegionInfo> RegionInfos = ADMIN.getRegions(tableName);
431 assertEquals("Tried to create " + expectedRegions + " regions " +
432 "but only found " + RegionInfos.size(),
433 expectedRegions, RegionInfos.size());
436 @Test
437 public void testMoveToPreviouslyAssignedRS() throws IOException, InterruptedException {
438 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
439 HMaster master = cluster.getMaster();
440 final TableName tableName = TableName.valueOf(name.getMethodName());
441 Admin localAdmin = createTable(tableName);
442 List<RegionInfo> tableRegions = localAdmin.getRegions(tableName);
443 RegionInfo hri = tableRegions.get(0);
444 AssignmentManager am = master.getAssignmentManager();
445 ServerName server = am.getRegionStates().getRegionServerOfRegion(hri);
446 localAdmin.move(hri.getEncodedNameAsBytes(), Bytes.toBytes(server.getServerName()));
447 assertEquals("Current region server and region server before move should be same.", server,
448 am.getRegionStates().getRegionServerOfRegion(hri));
451 @Test
452 public void testWALRollWriting() throws Exception {
453 setUpforLogRolling();
454 String className = this.getClass().getName();
455 StringBuilder v = new StringBuilder(className);
456 while (v.length() < 1000) {
457 v.append(className);
459 byte[] value = Bytes.toBytes(v.toString());
460 HRegionServer regionServer = startAndWriteData(TableName.valueOf(name.getMethodName()), value);
461 LOG.info("after writing there are "
462 + AbstractFSWALProvider.getNumRolledLogFiles(regionServer.getWAL(null)) + " log files");
464 // flush all regions
465 for (HRegion r : regionServer.getOnlineRegionsLocalContext()) {
466 r.flush(true);
468 ADMIN.rollWALWriter(regionServer.getServerName());
469 int count = AbstractFSWALProvider.getNumRolledLogFiles(regionServer.getWAL(null));
470 LOG.info("after flushing all regions and rolling logs there are " +
471 count + " log files");
472 assertTrue(("actual count: " + count), count <= 2);
475 private void setUpforLogRolling() {
476 // Force a region split after every 768KB
477 TEST_UTIL.getConfiguration().setLong(HConstants.HREGION_MAX_FILESIZE,
478 768L * 1024L);
480 // We roll the log after every 32 writes
481 TEST_UTIL.getConfiguration().setInt("hbase.regionserver.maxlogentries", 32);
483 TEST_UTIL.getConfiguration().setInt(
484 "hbase.regionserver.logroll.errors.tolerated", 2);
485 TEST_UTIL.getConfiguration().setInt("hbase.rpc.timeout", 10 * 1000);
487 // For less frequently updated regions flush after every 2 flushes
488 TEST_UTIL.getConfiguration().setInt(
489 "hbase.hregion.memstore.optionalflushcount", 2);
491 // We flush the cache after every 8192 bytes
492 TEST_UTIL.getConfiguration().setInt(HConstants.HREGION_MEMSTORE_FLUSH_SIZE,
493 8192);
495 // Increase the amount of time between client retries
496 TEST_UTIL.getConfiguration().setLong("hbase.client.pause", 10 * 1000);
498 // Reduce thread wake frequency so that other threads can get
499 // a chance to run.
500 TEST_UTIL.getConfiguration().setInt(HConstants.THREAD_WAKE_FREQUENCY,
501 2 * 1000);
503 /**** configuration for testLogRollOnDatanodeDeath ****/
504 // lower the namenode & datanode heartbeat so the namenode
505 // quickly detects datanode failures
506 TEST_UTIL.getConfiguration().setInt("dfs.namenode.heartbeat.recheck-interval", 5000);
507 TEST_UTIL.getConfiguration().setInt("dfs.heartbeat.interval", 1);
508 // the namenode might still try to choose the recently-dead datanode
509 // for a pipeline, so try to a new pipeline multiple times
510 TEST_UTIL.getConfiguration().setInt("dfs.client.block.write.retries", 30);
511 TEST_UTIL.getConfiguration().setInt(
512 "hbase.regionserver.hlog.tolerable.lowreplication", 2);
513 TEST_UTIL.getConfiguration().setInt(
514 "hbase.regionserver.hlog.lowreplication.rolllimit", 3);
517 private HRegionServer startAndWriteData(TableName tableName, byte[] value)
518 throws IOException, InterruptedException {
519 // When the hbase:meta table can be opened, the region servers are running
520 TEST_UTIL.getConnection().getTable(TableName.META_TABLE_NAME).close();
522 // Create the test table and open it
523 HTableDescriptor desc = new HTableDescriptor(tableName);
524 desc.addFamily(new HColumnDescriptor(HConstants.CATALOG_FAMILY));
525 ADMIN.createTable(desc);
526 Table table = TEST_UTIL.getConnection().getTable(tableName);
528 HRegionServer regionServer = TEST_UTIL.getRSForFirstRegionInTable(tableName);
529 for (int i = 1; i <= 256; i++) { // 256 writes should cause 8 log rolls
530 Put put = new Put(Bytes.toBytes("row" + String.format("%1$04d", i)));
531 put.addColumn(HConstants.CATALOG_FAMILY, null, value);
532 table.put(put);
533 if (i % 32 == 0) {
534 // After every 32 writes sleep to let the log roller run
535 try {
536 Thread.sleep(2000);
537 } catch (InterruptedException e) {
538 // continue
543 table.close();
544 return regionServer;
548 * Check that we have an exception if the cluster is not there.
550 @Test
551 public void testCheckHBaseAvailableWithoutCluster() {
552 Configuration conf = new Configuration(TEST_UTIL.getConfiguration());
554 // Change the ZK address to go to something not used.
555 conf.setInt(HConstants.ZOOKEEPER_CLIENT_PORT,
556 conf.getInt(HConstants.ZOOKEEPER_CLIENT_PORT, 9999)+10);
558 long start = System.currentTimeMillis();
559 try {
560 HBaseAdmin.available(conf);
561 assertTrue(false);
562 } catch (ZooKeeperConnectionException ignored) {
563 } catch (IOException ignored) {
565 long end = System.currentTimeMillis();
567 LOG.info("It took "+(end-start)+" ms to find out that" +
568 " HBase was not available");
571 @Test
572 public void testDisableCatalogTable() throws Exception {
573 try {
574 ADMIN.disableTable(TableName.META_TABLE_NAME);
575 fail("Expected to throw ConstraintException");
576 } catch (ConstraintException e) {
578 // Before the fix for HBASE-6146, the below table creation was failing as the hbase:meta table
579 // actually getting disabled by the disableTable() call.
580 HTableDescriptor htd =
581 new HTableDescriptor(TableName.valueOf(Bytes.toBytes(name.getMethodName())));
582 HColumnDescriptor hcd = new HColumnDescriptor(Bytes.toBytes("cf1"));
583 htd.addFamily(hcd);
584 TEST_UTIL.getHBaseAdmin().createTable(htd);
587 @Test
588 public void testIsEnabledOrDisabledOnUnknownTable() throws Exception {
589 try {
590 ADMIN.isTableEnabled(TableName.valueOf(name.getMethodName()));
591 fail("Test should fail if isTableEnabled called on unknown table.");
592 } catch (IOException e) {
595 try {
596 ADMIN.isTableDisabled(TableName.valueOf(name.getMethodName()));
597 fail("Test should fail if isTableDisabled called on unknown table.");
598 } catch (IOException e) {
602 @Test
603 public void testGetRegion() throws Exception {
604 // We use actual HBaseAdmin instance instead of going via Admin interface in
605 // here because makes use of an internal HBA method (TODO: Fix.).
606 HBaseAdmin rawAdmin = TEST_UTIL.getHBaseAdmin();
608 final TableName tableName = TableName.valueOf(name.getMethodName());
609 LOG.info("Started " + tableName);
610 Table t = TEST_UTIL.createMultiRegionTable(tableName, HConstants.CATALOG_FAMILY);
612 try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(tableName)) {
613 HRegionLocation regionLocation = locator.getRegionLocation(Bytes.toBytes("mmm"));
614 RegionInfo region = regionLocation.getRegionInfo();
615 byte[] regionName = region.getRegionName();
616 Pair<RegionInfo, ServerName> pair = rawAdmin.getRegion(regionName);
617 assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
618 pair = rawAdmin.getRegion(region.getEncodedNameAsBytes());
619 assertTrue(Bytes.equals(regionName, pair.getFirst().getRegionName()));
623 @Test
624 public void testBalancer() throws Exception {
625 boolean initialState = ADMIN.isBalancerEnabled();
627 // Start the balancer, wait for it.
628 boolean prevState = ADMIN.balancerSwitch(!initialState, true);
630 // The previous state should be the original state we observed
631 assertEquals(initialState, prevState);
633 // Current state should be opposite of the original
634 assertEquals(!initialState, ADMIN.isBalancerEnabled());
636 // Reset it back to what it was
637 prevState = ADMIN.balancerSwitch(initialState, true);
639 // The previous state should be the opposite of the initial state
640 assertEquals(!initialState, prevState);
641 // Current state should be the original state again
642 assertEquals(initialState, ADMIN.isBalancerEnabled());
645 @Test
646 public void testRegionNormalizer() throws Exception {
647 boolean initialState = ADMIN.isNormalizerEnabled();
649 // flip state
650 boolean prevState = ADMIN.normalizerSwitch(!initialState);
652 // The previous state should be the original state we observed
653 assertEquals(initialState, prevState);
655 // Current state should be opposite of the original
656 assertEquals(!initialState, ADMIN.isNormalizerEnabled());
658 // Reset it back to what it was
659 prevState = ADMIN.normalizerSwitch(initialState);
661 // The previous state should be the opposite of the initial state
662 assertEquals(!initialState, prevState);
663 // Current state should be the original state again
664 assertEquals(initialState, ADMIN.isNormalizerEnabled());
667 @Test
668 public void testAbortProcedureFail() throws Exception {
669 Random randomGenerator = new Random();
670 long procId = randomGenerator.nextLong();
672 boolean abortResult = ADMIN.abortProcedure(procId, true);
673 assertFalse(abortResult);
676 @Test
677 public void testGetProcedures() throws Exception {
678 String procList = ADMIN.getProcedures();
679 assertTrue(procList.startsWith("["));
682 @Test
683 public void testGetLocks() throws Exception {
684 String lockList = ADMIN.getLocks();
685 assertTrue(lockList.startsWith("["));
688 @Test
689 public void testDecommissionRegionServers() throws Exception {
690 List<ServerName> decommissionedRegionServers = ADMIN.listDecommissionedRegionServers();
691 assertTrue(decommissionedRegionServers.isEmpty());
693 final TableName tableName = TableName.valueOf(name.getMethodName());
694 TEST_UTIL.createMultiRegionTable(tableName, Bytes.toBytes("f"), 6);
696 ArrayList<ServerName> clusterRegionServers =
697 new ArrayList<>(ADMIN.getClusterMetrics(EnumSet.of(Option.LIVE_SERVERS))
698 .getLiveServerMetrics().keySet());
700 assertEquals(3, clusterRegionServers.size());
702 HashMap<ServerName, List<RegionInfo>> serversToDecommssion = new HashMap<>();
703 // Get a server that has meta online. We will decommission two of the servers,
704 // leaving one online.
705 int i;
706 for (i = 0; i < clusterRegionServers.size(); i++) {
707 List<RegionInfo> regionsOnServer = ADMIN.getRegions(clusterRegionServers.get(i));
708 if (ADMIN.getRegions(clusterRegionServers.get(i)).stream().anyMatch(p -> p.isMetaRegion())) {
709 serversToDecommssion.put(clusterRegionServers.get(i), regionsOnServer);
710 break;
714 clusterRegionServers.remove(i);
715 // Get another server to decommission.
716 serversToDecommssion.put(clusterRegionServers.get(0),
717 ADMIN.getRegions(clusterRegionServers.get(0)));
719 ServerName remainingServer = clusterRegionServers.get(1);
721 // Decommission
722 ADMIN.decommissionRegionServers(new ArrayList<ServerName>(serversToDecommssion.keySet()), true);
723 assertEquals(2, ADMIN.listDecommissionedRegionServers().size());
725 // Verify the regions have been off the decommissioned servers, all on the one
726 // remaining server.
727 for (ServerName server : serversToDecommssion.keySet()) {
728 for (RegionInfo region : serversToDecommssion.get(server)) {
729 TEST_UTIL.assertRegionOnServer(region, remainingServer, 10000);
733 // Recommission and load the regions.
734 for (ServerName server : serversToDecommssion.keySet()) {
735 List<byte[]> encodedRegionNames = serversToDecommssion.get(server).stream()
736 .map(region -> region.getEncodedNameAsBytes()).collect(Collectors.toList());
737 ADMIN.recommissionRegionServer(server, encodedRegionNames);
739 assertTrue(ADMIN.listDecommissionedRegionServers().isEmpty());
740 // Verify the regions have been moved to the recommissioned servers
741 for (ServerName server : serversToDecommssion.keySet()) {
742 for (RegionInfo region : serversToDecommssion.get(server)) {
743 TEST_UTIL.assertRegionOnServer(region, server, 10000);
749 * TestCase for HBASE-21355
751 @Test
752 public void testGetRegionInfo() throws Exception {
753 final TableName tableName = TableName.valueOf(name.getMethodName());
754 Table table = TEST_UTIL.createTable(tableName, Bytes.toBytes("f"));
755 for (int i = 0; i < 100; i++) {
756 table.put(new Put(Bytes.toBytes(i)).addColumn(Bytes.toBytes("f"), Bytes.toBytes("q"),
757 Bytes.toBytes(i)));
759 ADMIN.flush(tableName);
761 HRegionServer rs = TEST_UTIL.getRSForFirstRegionInTable(table.getName());
762 List<HRegion> regions = rs.getRegions(tableName);
763 Assert.assertEquals(1, regions.size());
765 HRegion region = regions.get(0);
766 byte[] regionName = region.getRegionInfo().getRegionName();
767 HStore store = region.getStore(Bytes.toBytes("f"));
768 long expectedStoreFilesSize = store.getStorefilesSize();
769 Assert.assertNotNull(store);
770 Assert.assertEquals(expectedStoreFilesSize, store.getSize());
772 ClusterConnection conn = ((ClusterConnection) ADMIN.getConnection());
773 HBaseRpcController controller = conn.getRpcControllerFactory().newController();
774 for (int i = 0; i < 10; i++) {
775 RegionInfo ri =
776 ProtobufUtil.getRegionInfo(controller, conn.getAdmin(rs.getServerName()), regionName);
777 Assert.assertEquals(region.getRegionInfo(), ri);
779 // Make sure that the store size is still the actual file system's store size.
780 Assert.assertEquals(expectedStoreFilesSize, store.getSize());
784 @Test
785 public void testTableSplitFollowedByModify() throws Exception {
786 final TableName tableName = TableName.valueOf(name.getMethodName());
787 TEST_UTIL.createTable(tableName, Bytes.toBytes("f"));
789 // get the original table region count
790 List<RegionInfo> regions = ADMIN.getRegions(tableName);
791 int originalCount = regions.size();
792 assertEquals(1, originalCount);
794 // split the table and wait until region count increases
795 ADMIN.split(tableName, Bytes.toBytes(3));
796 TEST_UTIL.waitFor(30000, new Predicate<Exception>() {
798 @Override
799 public boolean evaluate() throws Exception {
800 return ADMIN.getRegions(tableName).size() > originalCount;
804 // do some table modification
805 TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(ADMIN.getDescriptor(tableName))
806 .setMaxFileSize(11111111)
807 .build();
808 ADMIN.modifyTable(tableDesc);
809 assertEquals(11111111, ADMIN.getDescriptor(tableName).getMaxFileSize());
812 @Test
813 public void testTableMergeFollowedByModify() throws Exception {
814 final TableName tableName = TableName.valueOf(name.getMethodName());
815 TEST_UTIL.createTable(tableName, new byte[][] { Bytes.toBytes("f") },
816 new byte[][] { Bytes.toBytes(3) });
818 // assert we have at least 2 regions in the table
819 List<RegionInfo> regions = ADMIN.getRegions(tableName);
820 int originalCount = regions.size();
821 assertTrue(originalCount >= 2);
823 byte[] nameOfRegionA = regions.get(0).getEncodedNameAsBytes();
824 byte[] nameOfRegionB = regions.get(1).getEncodedNameAsBytes();
826 // merge the table regions and wait until region count decreases
827 ADMIN.mergeRegionsAsync(nameOfRegionA, nameOfRegionB, true);
828 TEST_UTIL.waitFor(30000, new Predicate<Exception>() {
830 @Override
831 public boolean evaluate() throws Exception {
832 return ADMIN.getRegions(tableName).size() < originalCount;
836 // do some table modification
837 TableDescriptor tableDesc = TableDescriptorBuilder.newBuilder(ADMIN.getDescriptor(tableName))
838 .setMaxFileSize(11111111)
839 .build();
840 ADMIN.modifyTable(tableDesc);
841 assertEquals(11111111, ADMIN.getDescriptor(tableName).getMaxFileSize());