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
;
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
{
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
;
94 public TestName name
= new TestName();
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();
109 public static void tearDownAfterClass() throws Exception
{
110 TEST_UTIL
.shutdownMiniCluster();
114 public void tearDown() throws Exception
{
115 for (TableDescriptor htd
: ADMIN
.listTableDescriptors()) {
116 TEST_UTIL
.deleteTable(htd
.getTableName());
121 public void testCreateBadTables() throws IOException
{
124 ADMIN
.createTable(new HTableDescriptor(TableName
.META_TABLE_NAME
));
125 } catch(TableExistsException e
) {
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
));
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
)) {
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
++) {
158 for (int i
= 0; i
< count
; i
++) {
159 while(threads
[i
].isAlive()) {
162 } catch (InterruptedException e
) {
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'.
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();
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
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);
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
);
212 TEST_UTIL
.getConfiguration().setInt(HConstants
.HBASE_RPC_TIMEOUT_KEY
, oldTimeout
);
217 * Test read only tables
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
);
233 * Test that user table names can contain '-' and '.' so long as they do not
234 * start with same. HBASE-771
237 public void testTableNames() throws IOException
{
238 byte[][] illegalNames
= new byte[][] {
239 Bytes
.toBytes("-bad"),
240 Bytes
.toBytes(".bad")
242 for (byte[] illegalName
: illegalNames
) {
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
) {
251 byte[] legalName
= Bytes
.toBytes("g-oo.d");
253 new HTableDescriptor(TableName
.valueOf(legalName
));
254 } catch (IllegalArgumentException e
) {
255 throw new IOException("Legal user table name: '" +
256 Bytes
.toString(legalName
) + "' caused IllegalArgumentException: " +
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
);
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")));
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()) {
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
)) {
323 isInList
= ProtobufUtil
.getOnlineRegions(
324 rs
.getRSRpcServices()).contains(info
);
327 assertFalse("The region should not be present in online regions list.",
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
)) {
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
));
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")) {
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
)) {
379 isInList
= ProtobufUtil
.getOnlineRegions(
380 rs
.getRSRpcServices()).contains(info
);
383 assertFalse("The region should not be present in online regions list.",
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");
394 admin
.createTable(htd
, null);
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");
407 ADMIN
.createTable(htd
, null);
412 * @throws IOException
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());
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
));
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) {
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");
465 for (HRegion r
: regionServer
.getOnlineRegionsLocalContext()) {
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
,
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
,
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
500 TEST_UTIL
.getConfiguration().setInt(HConstants
.THREAD_WAKE_FREQUENCY
,
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
);
534 // After every 32 writes sleep to let the log roller run
537 } catch (InterruptedException e
) {
548 * Check that we have an exception if the cluster is not there.
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();
560 HBaseAdmin
.available(conf
);
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");
572 public void testDisableCatalogTable() throws Exception
{
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"));
584 TEST_UTIL
.getHBaseAdmin().createTable(htd
);
588 public void testIsEnabledOrDisabledOnUnknownTable() throws Exception
{
590 ADMIN
.isTableEnabled(TableName
.valueOf(name
.getMethodName()));
591 fail("Test should fail if isTableEnabled called on unknown table.");
592 } catch (IOException e
) {
596 ADMIN
.isTableDisabled(TableName
.valueOf(name
.getMethodName()));
597 fail("Test should fail if isTableDisabled called on unknown table.");
598 } catch (IOException e
) {
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()));
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());
646 public void testRegionNormalizer() throws Exception
{
647 boolean initialState
= ADMIN
.isNormalizerEnabled();
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());
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
);
677 public void testGetProcedures() throws Exception
{
678 String procList
= ADMIN
.getProcedures();
679 assertTrue(procList
.startsWith("["));
683 public void testGetLocks() throws Exception
{
684 String lockList
= ADMIN
.getLocks();
685 assertTrue(lockList
.startsWith("["));
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.
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
);
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);
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
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
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"),
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
++) {
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());
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
>() {
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)
808 ADMIN
.modifyTable(tableDesc
);
809 assertEquals(11111111, ADMIN
.getDescriptor(tableName
).getMaxFileSize());
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
>() {
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)
840 ADMIN
.modifyTable(tableDesc
);
841 assertEquals(11111111, ADMIN
.getDescriptor(tableName
).getMaxFileSize());