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
.hbase
.ClusterMetrics
.Option
;
34 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
35 import org
.apache
.hadoop
.hbase
.HColumnDescriptor
;
36 import org
.apache
.hadoop
.hbase
.HConstants
;
37 import org
.apache
.hadoop
.hbase
.HTableDescriptor
;
38 import org
.apache
.hadoop
.hbase
.MiniHBaseCluster
;
39 import org
.apache
.hadoop
.hbase
.ServerName
;
40 import org
.apache
.hadoop
.hbase
.TableExistsException
;
41 import org
.apache
.hadoop
.hbase
.TableName
;
42 import org
.apache
.hadoop
.hbase
.TableNotDisabledException
;
43 import org
.apache
.hadoop
.hbase
.TableNotEnabledException
;
44 import org
.apache
.hadoop
.hbase
.TableNotFoundException
;
45 import org
.apache
.hadoop
.hbase
.UnknownRegionException
;
46 import org
.apache
.hadoop
.hbase
.Waiter
.Predicate
;
47 import org
.apache
.hadoop
.hbase
.constraint
.ConstraintException
;
48 import org
.apache
.hadoop
.hbase
.master
.HMaster
;
49 import org
.apache
.hadoop
.hbase
.master
.assignment
.AssignmentManager
;
50 import org
.apache
.hadoop
.hbase
.regionserver
.HRegion
;
51 import org
.apache
.hadoop
.hbase
.regionserver
.HRegionServer
;
52 import org
.apache
.hadoop
.hbase
.regionserver
.HStore
;
53 import org
.apache
.hadoop
.hbase
.testclassification
.ClientTests
;
54 import org
.apache
.hadoop
.hbase
.testclassification
.LargeTests
;
55 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
56 import org
.apache
.hadoop
.hbase
.wal
.AbstractFSWALProvider
;
57 import org
.junit
.Assert
;
58 import org
.junit
.ClassRule
;
59 import org
.junit
.Test
;
60 import org
.junit
.experimental
.categories
.Category
;
61 import org
.slf4j
.Logger
;
62 import org
.slf4j
.LoggerFactory
;
64 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.ProtobufUtil
;
65 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.RequestConverter
;
68 * Class to test HBaseAdmin.
69 * Spins up the minicluster once at test start and then takes it down afterward.
70 * Add any testing of HBaseAdmin functionality here.
72 @Category({LargeTests
.class, ClientTests
.class})
73 public class TestAdmin2
extends TestAdminBase
{
76 public static final HBaseClassTestRule CLASS_RULE
=
77 HBaseClassTestRule
.forClass(TestAdmin2
.class);
79 private static final Logger LOG
= LoggerFactory
.getLogger(TestAdmin2
.class);
82 public void testCreateBadTables() throws IOException
{
85 ADMIN
.createTable(new HTableDescriptor(TableName
.META_TABLE_NAME
));
86 } catch(TableExistsException e
) {
89 assertTrue("Unexcepted exception message " + msg
, msg
!= null &&
90 msg
.startsWith(TableExistsException
.class.getName()) &&
91 msg
.contains(TableName
.META_TABLE_NAME
.getNameAsString()));
93 // Now try and do concurrent creation with a bunch of threads.
94 final HTableDescriptor threadDesc
= new HTableDescriptor(TableName
.valueOf(name
.getMethodName()));
95 threadDesc
.addFamily(new HColumnDescriptor(HConstants
.CATALOG_FAMILY
));
97 Thread
[] threads
= new Thread
[count
];
98 final AtomicInteger successes
= new AtomicInteger(0);
99 final AtomicInteger failures
= new AtomicInteger(0);
100 final Admin localAdmin
= ADMIN
;
101 for (int i
= 0; i
< count
; i
++) {
102 threads
[i
] = new Thread(Integer
.toString(i
)) {
106 localAdmin
.createTable(threadDesc
);
107 successes
.incrementAndGet();
108 } catch (TableExistsException e
) {
109 failures
.incrementAndGet();
110 } catch (IOException e
) {
111 throw new RuntimeException("Failed threaded create" + getName(), e
);
116 for (int i
= 0; i
< count
; i
++) {
119 for (int i
= 0; i
< count
; i
++) {
120 while(threads
[i
].isAlive()) {
123 } catch (InterruptedException e
) {
128 // All threads are now dead. Count up how many tables were created and
129 // how many failed w/ appropriate exception.
130 assertEquals(1, successes
.get());
131 assertEquals(count
- 1, failures
.get());
135 * Test for hadoop-1581 'HBASE: Unopenable tablename bug'.
139 public void testTableNameClash() throws Exception
{
140 final String name
= this.name
.getMethodName();
141 HTableDescriptor htd1
= new HTableDescriptor(TableName
.valueOf(name
+ "SOMEUPPERCASE"));
142 HTableDescriptor htd2
= new HTableDescriptor(TableName
.valueOf(name
));
143 htd1
.addFamily(new HColumnDescriptor(HConstants
.CATALOG_FAMILY
));
144 htd2
.addFamily(new HColumnDescriptor(HConstants
.CATALOG_FAMILY
));
145 ADMIN
.createTable(htd1
);
146 ADMIN
.createTable(htd2
);
147 // Before fix, below would fail throwing a NoServerForRegionException.
148 TEST_UTIL
.getConnection().getTable(htd2
.getTableName()).close();
152 * HMaster.createTable used to be kind of synchronous call
153 * Thus creating of table with lots of regions can cause RPC timeout
154 * After the fix to make createTable truly async, RPC timeout shouldn't be an
158 public void testCreateTableRPCTimeOut() throws Exception
{
159 final String name
= this.name
.getMethodName();
160 int oldTimeout
= TEST_UTIL
.getConfiguration().
161 getInt(HConstants
.HBASE_RPC_TIMEOUT_KEY
, HConstants
.DEFAULT_HBASE_RPC_TIMEOUT
);
162 TEST_UTIL
.getConfiguration().setInt(HConstants
.HBASE_RPC_TIMEOUT_KEY
, 1500);
164 int expectedRegions
= 100;
165 // Use 80 bit numbers to make sure we aren't limited
166 byte [] startKey
= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
167 byte [] endKey
= { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
168 Admin hbaseadmin
= TEST_UTIL
.getAdmin();
169 HTableDescriptor htd
= new HTableDescriptor(TableName
.valueOf(name
));
170 htd
.addFamily(new HColumnDescriptor(HConstants
.CATALOG_FAMILY
));
171 hbaseadmin
.createTable(htd
, startKey
, endKey
, expectedRegions
);
173 TEST_UTIL
.getConfiguration().setInt(HConstants
.HBASE_RPC_TIMEOUT_KEY
, oldTimeout
);
178 * Test read only tables
182 public void testReadOnlyTable() throws Exception
{
183 final TableName name
= TableName
.valueOf(this.name
.getMethodName());
184 Table table
= TEST_UTIL
.createTable(name
, HConstants
.CATALOG_FAMILY
);
185 byte[] value
= Bytes
.toBytes("somedata");
186 // This used to use an empty row... That must have been a bug
187 Put put
= new Put(value
);
188 put
.addColumn(HConstants
.CATALOG_FAMILY
, HConstants
.CATALOG_FAMILY
, value
);
194 * Test that user table names can contain '-' and '.' so long as they do not
195 * start with same. HBASE-771
198 public void testTableNames() throws IOException
{
199 byte[][] illegalNames
= new byte[][] {
200 Bytes
.toBytes("-bad"),
201 Bytes
.toBytes(".bad")
203 for (byte[] illegalName
: illegalNames
) {
205 new HTableDescriptor(TableName
.valueOf(illegalName
));
206 throw new IOException("Did not detect '" +
207 Bytes
.toString(illegalName
) + "' as an illegal user table name");
208 } catch (IllegalArgumentException e
) {
212 byte[] legalName
= Bytes
.toBytes("g-oo.d");
214 new HTableDescriptor(TableName
.valueOf(legalName
));
215 } catch (IllegalArgumentException e
) {
216 throw new IOException("Legal user table name: '" +
217 Bytes
.toString(legalName
) + "' caused IllegalArgumentException: " +
225 @Test (expected
=TableExistsException
.class)
226 public void testTableExistsExceptionWithATable() throws IOException
{
227 final TableName name
= TableName
.valueOf(this.name
.getMethodName());
228 TEST_UTIL
.createTable(name
, HConstants
.CATALOG_FAMILY
).close();
229 TEST_UTIL
.createTable(name
, HConstants
.CATALOG_FAMILY
);
233 * Can't disable a table if the table isn't in enabled state
235 @Test (expected
=TableNotEnabledException
.class)
236 public void testTableNotEnabledExceptionWithATable() throws IOException
{
237 final TableName name
= TableName
.valueOf(this.name
.getMethodName());
238 TEST_UTIL
.createTable(name
, HConstants
.CATALOG_FAMILY
).close();
239 ADMIN
.disableTable(name
);
240 ADMIN
.disableTable(name
);
244 * Can't enable a table if the table isn't in disabled state
246 @Test(expected
= TableNotDisabledException
.class)
247 public void testTableNotDisabledExceptionWithATable() throws IOException
{
248 final TableName name
= TableName
.valueOf(this.name
.getMethodName());
249 try (Table t
= TEST_UTIL
.createTable(name
, HConstants
.CATALOG_FAMILY
)) {
250 ADMIN
.enableTable(name
);
257 @Test(expected
= TableNotFoundException
.class)
258 public void testTableNotFoundExceptionWithoutAnyTables() throws IOException
{
259 TableName tableName
= TableName
.valueOf("testTableNotFoundExceptionWithoutAnyTables");
260 try (Table ht
= TEST_UTIL
.getConnection().getTable(tableName
)) {
261 ht
.get(new Get(Bytes
.toBytes("e")));
266 public void testShouldUnassignTheRegion() throws Exception
{
267 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
268 createTableWithDefaultConf(tableName
);
270 RegionInfo info
= null;
271 HRegionServer rs
= TEST_UTIL
.getRSForFirstRegionInTable(tableName
);
272 List
<RegionInfo
> onlineRegions
= ProtobufUtil
.getOnlineRegions(rs
.getRSRpcServices());
273 for (RegionInfo regionInfo
: onlineRegions
) {
274 if (!regionInfo
.getTable().isSystemTable()) {
276 ADMIN
.unassign(regionInfo
.getRegionName(), true);
279 boolean isInList
= ProtobufUtil
.getOnlineRegions(
280 rs
.getRSRpcServices()).contains(info
);
281 long timeout
= System
.currentTimeMillis() + 10000;
282 while ((System
.currentTimeMillis() < timeout
) && (isInList
)) {
284 isInList
= ProtobufUtil
.getOnlineRegions(
285 rs
.getRSRpcServices()).contains(info
);
288 assertFalse("The region should not be present in online regions list.",
293 public void testCloseRegionIfInvalidRegionNameIsPassed() throws Exception
{
294 final String name
= this.name
.getMethodName();
295 byte[] tableName
= Bytes
.toBytes(name
);
296 createTableWithDefaultConf(tableName
);
298 RegionInfo info
= null;
299 HRegionServer rs
= TEST_UTIL
.getRSForFirstRegionInTable(TableName
.valueOf(tableName
));
300 List
<RegionInfo
> onlineRegions
= ProtobufUtil
.getOnlineRegions(rs
.getRSRpcServices());
301 for (RegionInfo regionInfo
: onlineRegions
) {
302 if (!regionInfo
.isMetaRegion()) {
303 if (regionInfo
.getRegionNameAsString().contains(name
)) {
306 ADMIN
.unassign(Bytes
.toBytes("sample"), true);
307 } catch (UnknownRegionException nsre
) {
308 // expected, ignore it
313 onlineRegions
= ProtobufUtil
.getOnlineRegions(rs
.getRSRpcServices());
314 assertTrue("The region should be present in online regions list.",
315 onlineRegions
.contains(info
));
319 public void testCloseRegionThatFetchesTheHRIFromMeta() throws Exception
{
320 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
321 createTableWithDefaultConf(tableName
);
323 RegionInfo info
= null;
324 HRegionServer rs
= TEST_UTIL
.getRSForFirstRegionInTable(tableName
);
325 List
<RegionInfo
> onlineRegions
= ProtobufUtil
.getOnlineRegions(rs
.getRSRpcServices());
326 for (RegionInfo regionInfo
: onlineRegions
) {
327 if (!regionInfo
.isMetaRegion()) {
328 if (regionInfo
.getRegionNameAsString().contains("TestHBACloseRegion2")) {
330 ADMIN
.unassign(regionInfo
.getRegionName(), true);
335 boolean isInList
= ProtobufUtil
.getOnlineRegions(
336 rs
.getRSRpcServices()).contains(info
);
337 long timeout
= System
.currentTimeMillis() + 10000;
338 while ((System
.currentTimeMillis() < timeout
) && (isInList
)) {
340 isInList
= ProtobufUtil
.getOnlineRegions(
341 rs
.getRSRpcServices()).contains(info
);
344 assertFalse("The region should not be present in online regions list.",
348 private Admin
createTable(TableName tableName
) throws IOException
{
349 Admin admin
= TEST_UTIL
.getAdmin();
351 HTableDescriptor htd
= new HTableDescriptor(tableName
);
352 HColumnDescriptor hcd
= new HColumnDescriptor("value");
355 admin
.createTable(htd
);
359 private void createTableWithDefaultConf(byte[] TABLENAME
) throws IOException
{
360 createTableWithDefaultConf(TableName
.valueOf(TABLENAME
));
363 private void createTableWithDefaultConf(TableName TABLENAME
) throws IOException
{
364 HTableDescriptor htd
= new HTableDescriptor(TABLENAME
);
365 HColumnDescriptor hcd
= new HColumnDescriptor("value");
368 ADMIN
.createTable(htd
);
375 public void testGetTableRegions() throws IOException
{
376 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
378 int expectedRegions
= 10;
380 // Use 80 bit numbers to make sure we aren't limited
381 byte [] startKey
= { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 };
382 byte [] endKey
= { 9, 9, 9, 9, 9, 9, 9, 9, 9, 9 };
385 HTableDescriptor desc
= new HTableDescriptor(tableName
);
386 desc
.addFamily(new HColumnDescriptor(HConstants
.CATALOG_FAMILY
));
387 ADMIN
.createTable(desc
, startKey
, endKey
, expectedRegions
);
389 List
<RegionInfo
> RegionInfos
= ADMIN
.getRegions(tableName
);
391 assertEquals("Tried to create " + expectedRegions
+ " regions " +
392 "but only found " + RegionInfos
.size(),
393 expectedRegions
, RegionInfos
.size());
397 public void testMoveToPreviouslyAssignedRS() throws IOException
, InterruptedException
{
398 MiniHBaseCluster cluster
= TEST_UTIL
.getHBaseCluster();
399 HMaster master
= cluster
.getMaster();
400 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
401 Admin localAdmin
= createTable(tableName
);
402 List
<RegionInfo
> tableRegions
= localAdmin
.getRegions(tableName
);
403 RegionInfo hri
= tableRegions
.get(0);
404 AssignmentManager am
= master
.getAssignmentManager();
405 ServerName server
= am
.getRegionStates().getRegionServerOfRegion(hri
);
406 localAdmin
.move(hri
.getEncodedNameAsBytes(), server
);
407 assertEquals("Current region server and region server before move should be same.", server
,
408 am
.getRegionStates().getRegionServerOfRegion(hri
));
412 public void testWALRollWriting() throws Exception
{
413 setUpforLogRolling();
414 String className
= this.getClass().getName();
415 StringBuilder v
= new StringBuilder(className
);
416 while (v
.length() < 1000) {
419 byte[] value
= Bytes
.toBytes(v
.toString());
420 HRegionServer regionServer
= startAndWriteData(TableName
.valueOf(name
.getMethodName()), value
);
421 LOG
.info("after writing there are "
422 + AbstractFSWALProvider
.getNumRolledLogFiles(regionServer
.getWAL(null)) + " log files");
425 for (HRegion r
: regionServer
.getOnlineRegionsLocalContext()) {
428 ADMIN
.rollWALWriter(regionServer
.getServerName());
429 int count
= AbstractFSWALProvider
.getNumRolledLogFiles(regionServer
.getWAL(null));
430 LOG
.info("after flushing all regions and rolling logs there are " +
431 count
+ " log files");
432 assertTrue(("actual count: " + count
), count
<= 2);
435 private void setUpforLogRolling() {
436 // Force a region split after every 768KB
437 TEST_UTIL
.getConfiguration().setLong(HConstants
.HREGION_MAX_FILESIZE
,
440 // We roll the log after every 32 writes
441 TEST_UTIL
.getConfiguration().setInt("hbase.regionserver.maxlogentries", 32);
443 TEST_UTIL
.getConfiguration().setInt(
444 "hbase.regionserver.logroll.errors.tolerated", 2);
445 TEST_UTIL
.getConfiguration().setInt("hbase.rpc.timeout", 10 * 1000);
447 // For less frequently updated regions flush after every 2 flushes
448 TEST_UTIL
.getConfiguration().setInt(
449 "hbase.hregion.memstore.optionalflushcount", 2);
451 // We flush the cache after every 8192 bytes
452 TEST_UTIL
.getConfiguration().setInt(HConstants
.HREGION_MEMSTORE_FLUSH_SIZE
,
455 // Increase the amount of time between client retries
456 TEST_UTIL
.getConfiguration().setLong("hbase.client.pause", 10 * 1000);
458 // Reduce thread wake frequency so that other threads can get
460 TEST_UTIL
.getConfiguration().setInt(HConstants
.THREAD_WAKE_FREQUENCY
,
463 /**** configuration for testLogRollOnDatanodeDeath ****/
464 // lower the namenode & datanode heartbeat so the namenode
465 // quickly detects datanode failures
466 TEST_UTIL
.getConfiguration().setInt("dfs.namenode.heartbeat.recheck-interval", 5000);
467 TEST_UTIL
.getConfiguration().setInt("dfs.heartbeat.interval", 1);
468 // the namenode might still try to choose the recently-dead datanode
469 // for a pipeline, so try to a new pipeline multiple times
470 TEST_UTIL
.getConfiguration().setInt("dfs.client.block.write.retries", 30);
471 TEST_UTIL
.getConfiguration().setInt(
472 "hbase.regionserver.hlog.tolerable.lowreplication", 2);
473 TEST_UTIL
.getConfiguration().setInt(
474 "hbase.regionserver.hlog.lowreplication.rolllimit", 3);
477 private HRegionServer
startAndWriteData(TableName tableName
, byte[] value
)
478 throws IOException
, InterruptedException
{
479 // When the hbase:meta table can be opened, the region servers are running
480 TEST_UTIL
.getConnection().getTable(TableName
.META_TABLE_NAME
).close();
482 // Create the test table and open it
483 HTableDescriptor desc
= new HTableDescriptor(tableName
);
484 desc
.addFamily(new HColumnDescriptor(HConstants
.CATALOG_FAMILY
));
485 ADMIN
.createTable(desc
);
486 Table table
= TEST_UTIL
.getConnection().getTable(tableName
);
488 HRegionServer regionServer
= TEST_UTIL
.getRSForFirstRegionInTable(tableName
);
489 for (int i
= 1; i
<= 256; i
++) { // 256 writes should cause 8 log rolls
490 Put put
= new Put(Bytes
.toBytes("row" + String
.format("%1$04d", i
)));
491 put
.addColumn(HConstants
.CATALOG_FAMILY
, null, value
);
494 // After every 32 writes sleep to let the log roller run
497 } catch (InterruptedException e
) {
508 public void testDisableCatalogTable() throws Exception
{
510 ADMIN
.disableTable(TableName
.META_TABLE_NAME
);
511 fail("Expected to throw ConstraintException");
512 } catch (ConstraintException e
) {
514 // Before the fix for HBASE-6146, the below table creation was failing as the hbase:meta table
515 // actually getting disabled by the disableTable() call.
516 HTableDescriptor htd
=
517 new HTableDescriptor(TableName
.valueOf(Bytes
.toBytes(name
.getMethodName())));
518 HColumnDescriptor hcd
= new HColumnDescriptor(Bytes
.toBytes("cf1"));
520 TEST_UTIL
.getAdmin().createTable(htd
);
524 public void testIsEnabledOrDisabledOnUnknownTable() throws Exception
{
526 ADMIN
.isTableEnabled(TableName
.valueOf(name
.getMethodName()));
527 fail("Test should fail if isTableEnabled called on unknown table.");
528 } catch (IOException e
) {
532 ADMIN
.isTableDisabled(TableName
.valueOf(name
.getMethodName()));
533 fail("Test should fail if isTableDisabled called on unknown table.");
534 } catch (IOException e
) {
539 public void testBalancer() throws Exception
{
540 boolean initialState
= ADMIN
.isBalancerEnabled();
542 // Start the balancer, wait for it.
543 boolean prevState
= ADMIN
.balancerSwitch(!initialState
, true);
545 // The previous state should be the original state we observed
546 assertEquals(initialState
, prevState
);
548 // Current state should be opposite of the original
549 assertEquals(!initialState
, ADMIN
.isBalancerEnabled());
551 // Reset it back to what it was
552 prevState
= ADMIN
.balancerSwitch(initialState
, true);
554 // The previous state should be the opposite of the initial state
555 assertEquals(!initialState
, prevState
);
556 // Current state should be the original state again
557 assertEquals(initialState
, ADMIN
.isBalancerEnabled());
561 public void testRegionNormalizer() throws Exception
{
562 boolean initialState
= ADMIN
.isNormalizerEnabled();
565 boolean prevState
= ADMIN
.normalizerSwitch(!initialState
);
567 // The previous state should be the original state we observed
568 assertEquals(initialState
, prevState
);
570 // Current state should be opposite of the original
571 assertEquals(!initialState
, ADMIN
.isNormalizerEnabled());
573 // Reset it back to what it was
574 prevState
= ADMIN
.normalizerSwitch(initialState
);
576 // The previous state should be the opposite of the initial state
577 assertEquals(!initialState
, prevState
);
578 // Current state should be the original state again
579 assertEquals(initialState
, ADMIN
.isNormalizerEnabled());
583 public void testAbortProcedureFail() throws Exception
{
584 Random randomGenerator
= new Random();
585 long procId
= randomGenerator
.nextLong();
587 boolean abortResult
= ADMIN
.abortProcedure(procId
, true);
588 assertFalse(abortResult
);
592 public void testGetProcedures() throws Exception
{
593 String procList
= ADMIN
.getProcedures();
594 assertTrue(procList
.startsWith("["));
598 public void testGetLocks() throws Exception
{
599 String lockList
= ADMIN
.getLocks();
600 assertTrue(lockList
.startsWith("["));
604 public void testDecommissionRegionServers() throws Exception
{
605 List
<ServerName
> decommissionedRegionServers
= ADMIN
.listDecommissionedRegionServers();
606 assertTrue(decommissionedRegionServers
.isEmpty());
608 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
609 TEST_UTIL
.createMultiRegionTable(tableName
, Bytes
.toBytes("f"), 6);
611 ArrayList
<ServerName
> clusterRegionServers
=
612 new ArrayList
<>(ADMIN
.getClusterMetrics(EnumSet
.of(Option
.LIVE_SERVERS
))
613 .getLiveServerMetrics().keySet());
615 assertEquals(3, clusterRegionServers
.size());
617 HashMap
<ServerName
, List
<RegionInfo
>> serversToDecommssion
= new HashMap
<>();
618 // Get a server that has meta online. We will decommission two of the servers,
619 // leaving one online.
621 for (i
= 0; i
< clusterRegionServers
.size(); i
++) {
622 List
<RegionInfo
> regionsOnServer
= ADMIN
.getRegions(clusterRegionServers
.get(i
));
623 if (ADMIN
.getRegions(clusterRegionServers
.get(i
)).stream().anyMatch(p
-> p
.isMetaRegion())) {
624 serversToDecommssion
.put(clusterRegionServers
.get(i
), regionsOnServer
);
629 clusterRegionServers
.remove(i
);
630 // Get another server to decommission.
631 serversToDecommssion
.put(clusterRegionServers
.get(0),
632 ADMIN
.getRegions(clusterRegionServers
.get(0)));
634 ServerName remainingServer
= clusterRegionServers
.get(1);
637 ADMIN
.decommissionRegionServers(new ArrayList
<ServerName
>(serversToDecommssion
.keySet()), true);
638 assertEquals(2, ADMIN
.listDecommissionedRegionServers().size());
640 // Verify the regions have been off the decommissioned servers, all on the one
642 for (ServerName server
: serversToDecommssion
.keySet()) {
643 for (RegionInfo region
: serversToDecommssion
.get(server
)) {
644 TEST_UTIL
.assertRegionOnServer(region
, remainingServer
, 10000);
648 // Recommission and load the regions.
649 for (ServerName server
: serversToDecommssion
.keySet()) {
650 List
<byte[]> encodedRegionNames
= serversToDecommssion
.get(server
).stream()
651 .map(region
-> region
.getEncodedNameAsBytes()).collect(Collectors
.toList());
652 ADMIN
.recommissionRegionServer(server
, encodedRegionNames
);
654 assertTrue(ADMIN
.listDecommissionedRegionServers().isEmpty());
655 // Verify the regions have been moved to the recommissioned servers
656 for (ServerName server
: serversToDecommssion
.keySet()) {
657 for (RegionInfo region
: serversToDecommssion
.get(server
)) {
658 TEST_UTIL
.assertRegionOnServer(region
, server
, 10000);
664 * TestCase for HBASE-21355
667 public void testGetRegionInfo() throws Exception
{
668 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
669 Table table
= TEST_UTIL
.createTable(tableName
, Bytes
.toBytes("f"));
670 for (int i
= 0; i
< 100; i
++) {
671 table
.put(new Put(Bytes
.toBytes(i
)).addColumn(Bytes
.toBytes("f"), Bytes
.toBytes("q"),
674 ADMIN
.flush(tableName
);
676 HRegionServer rs
= TEST_UTIL
.getRSForFirstRegionInTable(table
.getName());
677 List
<HRegion
> regions
= rs
.getRegions(tableName
);
678 Assert
.assertEquals(1, regions
.size());
680 HRegion region
= regions
.get(0);
681 byte[] regionName
= region
.getRegionInfo().getRegionName();
682 HStore store
= region
.getStore(Bytes
.toBytes("f"));
683 long expectedStoreFilesSize
= store
.getStorefilesSize();
684 Assert
.assertNotNull(store
);
685 Assert
.assertEquals(expectedStoreFilesSize
, store
.getSize());
686 for (int i
= 0; i
< 10; i
++) {
687 RegionInfo ri
= ProtobufUtil
688 .toRegionInfo(TEST_UTIL
.getAsyncConnection().getRegionServerAdmin(rs
.getServerName())
689 .getRegionInfo(RequestConverter
.buildGetRegionInfoRequest(regionName
)).get()
692 Assert
.assertEquals(region
.getRegionInfo(), ri
);
694 // Make sure that the store size is still the actual file system's store size.
695 Assert
.assertEquals(expectedStoreFilesSize
, store
.getSize());
700 public void testTableSplitFollowedByModify() throws Exception
{
701 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
702 TEST_UTIL
.createTable(tableName
, Bytes
.toBytes("f"));
704 // get the original table region count
705 List
<RegionInfo
> regions
= ADMIN
.getRegions(tableName
);
706 int originalCount
= regions
.size();
707 assertEquals(1, originalCount
);
709 // split the table and wait until region count increases
710 ADMIN
.split(tableName
, Bytes
.toBytes(3));
711 TEST_UTIL
.waitFor(30000, new Predicate
<Exception
>() {
714 public boolean evaluate() throws Exception
{
715 return ADMIN
.getRegions(tableName
).size() > originalCount
;
719 // do some table modification
720 TableDescriptor tableDesc
= TableDescriptorBuilder
.newBuilder(ADMIN
.getDescriptor(tableName
))
721 .setMaxFileSize(11111111)
723 ADMIN
.modifyTable(tableDesc
);
724 assertEquals(11111111, ADMIN
.getDescriptor(tableName
).getMaxFileSize());
728 public void testTableMergeFollowedByModify() throws Exception
{
729 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
730 TEST_UTIL
.createTable(tableName
, new byte[][] { Bytes
.toBytes("f") },
731 new byte[][] { Bytes
.toBytes(3) });
733 // assert we have at least 2 regions in the table
734 List
<RegionInfo
> regions
= ADMIN
.getRegions(tableName
);
735 int originalCount
= regions
.size();
736 assertTrue(originalCount
>= 2);
738 byte[] nameOfRegionA
= regions
.get(0).getEncodedNameAsBytes();
739 byte[] nameOfRegionB
= regions
.get(1).getEncodedNameAsBytes();
741 // merge the table regions and wait until region count decreases
742 ADMIN
.mergeRegionsAsync(nameOfRegionA
, nameOfRegionB
, true);
743 TEST_UTIL
.waitFor(30000, new Predicate
<Exception
>() {
746 public boolean evaluate() throws Exception
{
747 return ADMIN
.getRegions(tableName
).size() < originalCount
;
751 // do some table modification
752 TableDescriptor tableDesc
= TableDescriptorBuilder
.newBuilder(ADMIN
.getDescriptor(tableName
))
753 .setMaxFileSize(11111111)
755 ADMIN
.modifyTable(tableDesc
);
756 assertEquals(11111111, ADMIN
.getDescriptor(tableName
).getMaxFileSize());