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
.assertNotNull
;
23 import static org
.junit
.Assert
.assertThrows
;
24 import static org
.junit
.Assert
.assertTrue
;
25 import static org
.junit
.Assert
.fail
;
27 import java
.io
.IOException
;
28 import java
.util
.ArrayList
;
29 import java
.util
.List
;
30 import java
.util
.concurrent
.ExecutionException
;
31 import java
.util
.concurrent
.TimeUnit
;
32 import java
.util
.concurrent
.atomic
.AtomicInteger
;
33 import org
.apache
.hadoop
.hbase
.HBaseClassTestRule
;
34 import org
.apache
.hadoop
.hbase
.HConstants
;
35 import org
.apache
.hadoop
.hbase
.HRegionLocation
;
36 import org
.apache
.hadoop
.hbase
.MetaTableAccessor
;
37 import org
.apache
.hadoop
.hbase
.ServerName
;
38 import org
.apache
.hadoop
.hbase
.TableName
;
39 import org
.apache
.hadoop
.hbase
.TableNotFoundException
;
40 import org
.apache
.hadoop
.hbase
.exceptions
.MergeRegionException
;
41 import org
.apache
.hadoop
.hbase
.master
.HMaster
;
42 import org
.apache
.hadoop
.hbase
.master
.janitor
.CatalogJanitor
;
43 import org
.apache
.hadoop
.hbase
.regionserver
.DisabledRegionSplitPolicy
;
44 import org
.apache
.hadoop
.hbase
.regionserver
.HRegion
;
45 import org
.apache
.hadoop
.hbase
.regionserver
.HStore
;
46 import org
.apache
.hadoop
.hbase
.regionserver
.HStoreFile
;
47 import org
.apache
.hadoop
.hbase
.testclassification
.ClientTests
;
48 import org
.apache
.hadoop
.hbase
.testclassification
.LargeTests
;
49 import org
.apache
.hadoop
.hbase
.util
.Bytes
;
50 import org
.apache
.hadoop
.hbase
.util
.CommonFSUtils
;
51 import org
.apache
.hadoop
.hbase
.util
.FutureUtils
;
52 import org
.apache
.hadoop
.hbase
.util
.Pair
;
53 import org
.apache
.hadoop
.hbase
.util
.Threads
;
54 import org
.junit
.ClassRule
;
55 import org
.junit
.Test
;
56 import org
.junit
.experimental
.categories
.Category
;
57 import org
.slf4j
.Logger
;
58 import org
.slf4j
.LoggerFactory
;
60 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.RequestConverter
;
61 import org
.apache
.hadoop
.hbase
.shaded
.protobuf
.generated
.MasterProtos
.MergeTableRegionsRequest
;
64 * Class to test HBaseAdmin. Spins up the minicluster once at test start and then takes it down
65 * afterward. Add any testing of HBaseAdmin functionality here.
67 @Category({ LargeTests
.class, ClientTests
.class })
68 public class TestAdmin1
extends TestAdminBase
{
71 public static final HBaseClassTestRule CLASS_RULE
= HBaseClassTestRule
.forClass(TestAdmin1
.class);
73 private static final Logger LOG
= LoggerFactory
.getLogger(TestAdmin1
.class);
76 public void testSplitFlushCompactUnknownTable() throws InterruptedException
{
77 final TableName unknowntable
= TableName
.valueOf(name
.getMethodName());
78 Exception exception
= null;
80 ADMIN
.compact(unknowntable
);
81 } catch (IOException e
) {
84 assertTrue(exception
instanceof TableNotFoundException
);
88 ADMIN
.flush(unknowntable
);
89 } catch (IOException e
) {
92 assertTrue(exception
instanceof TableNotFoundException
);
96 ADMIN
.split(unknowntable
);
97 } catch (IOException e
) {
100 assertTrue(exception
instanceof TableNotFoundException
);
104 public void testCompactATableWithSuperLongTableName() throws Exception
{
105 TableName tableName
= TableName
.valueOf(name
.getMethodName());
106 TableDescriptor htd
= TableDescriptorBuilder
.newBuilder(tableName
)
107 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("fam1")).build();
109 ADMIN
.createTable(htd
);
110 assertThrows(IllegalArgumentException
.class,
111 () -> ADMIN
.majorCompactRegion(tableName
.getName()));
113 assertThrows(IllegalArgumentException
.class,
114 () -> ADMIN
.majorCompactRegion(Bytes
.toBytes("abcd")));
116 ADMIN
.disableTable(tableName
);
117 ADMIN
.deleteTable(tableName
);
122 public void testCompactionTimestamps() throws Exception
{
123 TableName tableName
= TableName
.valueOf(name
.getMethodName());
124 TableDescriptor htd
= TableDescriptorBuilder
.newBuilder(tableName
)
125 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("fam1")).build();
126 ADMIN
.createTable(htd
);
127 Table table
= TEST_UTIL
.getConnection().getTable(htd
.getTableName());
128 long ts
= ADMIN
.getLastMajorCompactionTimestamp(tableName
);
130 Put p
= new Put(Bytes
.toBytes("row1"));
131 p
.addColumn(Bytes
.toBytes("fam1"), Bytes
.toBytes("fam1"), Bytes
.toBytes("fam1"));
133 ts
= ADMIN
.getLastMajorCompactionTimestamp(tableName
);
134 // no files written -> no data
137 ADMIN
.flush(tableName
);
138 ts
= ADMIN
.getLastMajorCompactionTimestamp(tableName
);
139 // still 0, we flushed a file, but no major compaction happened
143 try (RegionLocator l
= TEST_UTIL
.getConnection().getRegionLocator(tableName
)) {
144 regionName
= l
.getAllRegionLocations().get(0).getRegion().getRegionName();
146 long ts1
= ADMIN
.getLastMajorCompactionTimestampForRegion(regionName
);
147 assertEquals(ts
, ts1
);
148 p
= new Put(Bytes
.toBytes("row2"));
149 p
.addColumn(Bytes
.toBytes("fam1"), Bytes
.toBytes("fam1"), Bytes
.toBytes("fam1"));
151 ADMIN
.flush(tableName
);
152 ts
= ADMIN
.getLastMajorCompactionTimestamp(tableName
);
153 // make sure the region API returns the same value, as the old file is still around
154 assertEquals(ts1
, ts
);
156 TEST_UTIL
.compact(tableName
, true);
158 // forces a wait for the compaction
159 ADMIN
.flush(tableName
);
160 ts
= ADMIN
.getLastMajorCompactionTimestamp(tableName
);
161 // after a compaction our earliest timestamp will have progressed forward
162 assertTrue(ts
> ts1
);
164 // region api still the same
165 ts1
= ADMIN
.getLastMajorCompactionTimestampForRegion(regionName
);
166 assertEquals(ts
, ts1
);
168 ADMIN
.flush(tableName
);
169 ts
= ADMIN
.getLastMajorCompactionTimestamp(tableName
);
170 assertEquals(ts
, ts1
);
174 @Test(expected
= IllegalArgumentException
.class)
175 public void testColumnValidName() {
176 ColumnFamilyDescriptorBuilder
.of("\\test\\abc");
180 public void testTableExist() throws IOException
{
181 final TableName table
= TableName
.valueOf(name
.getMethodName());
183 exist
= ADMIN
.tableExists(table
);
184 assertEquals(false, exist
);
185 TEST_UTIL
.createTable(table
, HConstants
.CATALOG_FAMILY
);
186 exist
= ADMIN
.tableExists(table
);
187 assertEquals(true, exist
);
191 * Tests forcing split from client and having scanners successfully ride over split.
194 public void testForceSplit() throws Exception
{
195 byte[][] familyNames
= new byte[][] { Bytes
.toBytes("cf") };
196 int[] rowCounts
= new int[] { 6000 };
197 int numVersions
= ColumnFamilyDescriptorBuilder
.DEFAULT_MAX_VERSIONS
;
199 splitTest(null, familyNames
, rowCounts
, numVersions
, blockSize
, true);
201 byte[] splitKey
= Bytes
.toBytes(3500);
202 splitTest(splitKey
, familyNames
, rowCounts
, numVersions
, blockSize
, true);
203 // test regionSplitSync
204 splitTest(splitKey
, familyNames
, rowCounts
, numVersions
, blockSize
, false);
208 * Multi-family scenario. Tests forcing split from client and having scanners successfully ride
212 public void testForceSplitMultiFamily() throws Exception
{
213 int numVersions
= ColumnFamilyDescriptorBuilder
.DEFAULT_MAX_VERSIONS
;
215 // use small HFile block size so that we can have lots of blocks in HFile
216 // Otherwise, if there is only one block,
217 // HFileBlockIndex.midKey()'s value == startKey
219 byte[][] familyNames
= new byte[][] { Bytes
.toBytes("cf1"), Bytes
.toBytes("cf2") };
221 // one of the column families isn't splittable
222 int[] rowCounts
= new int[] { 6000, 1 };
223 splitTest(null, familyNames
, rowCounts
, numVersions
, blockSize
, true);
225 rowCounts
= new int[] { 1, 6000 };
226 splitTest(null, familyNames
, rowCounts
, numVersions
, blockSize
, true);
228 // one column family has much smaller data than the other
229 // the split key should be based on the largest column family
230 rowCounts
= new int[] { 6000, 300 };
231 splitTest(null, familyNames
, rowCounts
, numVersions
, blockSize
, true);
233 rowCounts
= new int[] { 300, 6000 };
234 splitTest(null, familyNames
, rowCounts
, numVersions
, blockSize
, true);
237 private int count(ResultScanner scanner
) throws IOException
{
239 while (scanner
.next() != null) {
245 private void splitTest(byte[] splitPoint
, byte[][] familyNames
, int[] rowCounts
, int numVersions
,
246 int blockSize
, boolean async
) throws Exception
{
247 TableName tableName
= TableName
.valueOf("testForceSplit");
248 StringBuilder sb
= new StringBuilder();
249 // Add tail to String so can see better in logs where a test is running.
250 for (int i
= 0; i
< rowCounts
.length
; i
++) {
251 sb
.append("_").append(Integer
.toString(rowCounts
[i
]));
253 assertFalse(ADMIN
.tableExists(tableName
));
254 try (final Table table
= TEST_UTIL
.createTable(tableName
, familyNames
, numVersions
, blockSize
);
255 final RegionLocator locator
= TEST_UTIL
.getConnection().getRegionLocator(tableName
)) {
258 byte[] q
= new byte[0];
260 // insert rows into column families. The number of rows that have values
261 // in a specific column family is decided by rowCounts[familyIndex]
262 for (int index
= 0; index
< familyNames
.length
; index
++) {
263 ArrayList
<Put
> puts
= new ArrayList
<>(rowCounts
[index
]);
264 for (int i
= 0; i
< rowCounts
[index
]; i
++) {
265 byte[] k
= Bytes
.toBytes(i
);
266 Put put
= new Put(k
);
267 put
.addColumn(familyNames
[index
], q
, k
);
272 if (rowCount
< rowCounts
[index
]) {
273 rowCount
= rowCounts
[index
];
277 // get the initial layout (should just be one region)
278 List
<HRegionLocation
> m
= locator
.getAllRegionLocations();
279 LOG
.info("Initial regions (" + m
.size() + "): " + m
);
280 assertTrue(m
.size() == 1);
283 Scan scan
= new Scan();
285 try (ResultScanner scanner
= table
.getScanner(scan
)) {
286 rows
= count(scanner
);
288 assertEquals(rowCount
, rows
);
290 // Have an outstanding scan going on to make sure we can scan over splits.
292 try (ResultScanner scanner
= table
.getScanner(scan
)) {
293 // Scan first row so we are into first region before split happens.
298 if (splitPoint
!= null) {
299 ADMIN
.split(tableName
, splitPoint
);
301 ADMIN
.split(tableName
);
303 final AtomicInteger count
= new AtomicInteger(0);
304 Thread t
= new Thread("CheckForSplit") {
307 for (int i
= 0; i
< 45; i
++) {
310 } catch (InterruptedException e
) {
314 List
<HRegionLocation
> regions
= null;
316 regions
= locator
.getAllRegionLocations();
317 } catch (IOException e
) {
318 LOG
.warn("get location failed", e
);
320 if (regions
== null) {
323 count
.set(regions
.size());
324 if (count
.get() >= 2) {
325 LOG
.info("Found: " + regions
);
328 LOG
.debug("Cycle waiting on split");
330 LOG
.debug("CheckForSplit thread exited, current region count: " + count
.get());
333 t
.setPriority(Thread
.NORM_PRIORITY
- 2);
337 // Sync split region, no need to create a thread to check
338 ADMIN
.splitRegionAsync(m
.get(0).getRegion().getRegionName(), splitPoint
).get();
341 rows
= 1 + count(scanner
); // We counted one row above.
343 assertEquals(rowCount
, rows
);
345 List
<HRegionLocation
> regions
= null;
347 regions
= locator
.getAllRegionLocations();
348 } catch (IOException e
) {
351 assertEquals(2, regions
.size());
352 if (splitPoint
!= null) {
353 // make sure the split point matches our explicit configuration
354 assertEquals(Bytes
.toString(splitPoint
),
355 Bytes
.toString(regions
.get(0).getRegion().getEndKey()));
356 assertEquals(Bytes
.toString(splitPoint
),
357 Bytes
.toString(regions
.get(1).getRegion().getStartKey()));
358 LOG
.debug("Properly split on " + Bytes
.toString(splitPoint
));
360 if (familyNames
.length
> 1) {
361 int splitKey
= Bytes
.toInt(regions
.get(0).getRegion().getEndKey());
362 // check if splitKey is based on the largest column family
363 // in terms of it store size
364 int deltaForLargestFamily
= Math
.abs(rowCount
/ 2 - splitKey
);
365 LOG
.debug("SplitKey=" + splitKey
+ "&deltaForLargestFamily=" + deltaForLargestFamily
+
366 ", r=" + regions
.get(0).getRegion());
367 for (int index
= 0; index
< familyNames
.length
; index
++) {
368 int delta
= Math
.abs(rowCounts
[index
] / 2 - splitKey
);
369 if (delta
< deltaForLargestFamily
) {
370 assertTrue("Delta " + delta
+ " for family " + index
+ " should be at least " +
371 "deltaForLargestFamily " + deltaForLargestFamily
, false);
376 TEST_UTIL
.deleteTable(tableName
);
381 public void testSplitAndMergeWithReplicaTable() throws Exception
{
382 // The test tries to directly split replica regions and directly merge replica regions. These
383 // are not allowed. The test validates that. Then the test does a valid split/merge of allowed
385 // Set up a table with 3 regions and replication set to 3
386 TableName tableName
= TableName
.valueOf(name
.getMethodName());
387 byte[] cf
= Bytes
.toBytes("f");
388 TableDescriptor desc
= TableDescriptorBuilder
.newBuilder(tableName
).setRegionReplication(3)
389 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of(cf
)).build();
390 byte[][] splitRows
= new byte[2][];
391 splitRows
[0] = new byte[] { (byte) '4' };
392 splitRows
[1] = new byte[] { (byte) '7' };
393 TEST_UTIL
.getAdmin().createTable(desc
, splitRows
);
394 List
<HRegion
> oldRegions
;
396 oldRegions
= TEST_UTIL
.getHBaseCluster().getRegions(tableName
);
398 } while (oldRegions
.size() != 9); // 3 regions * 3 replicas
399 // write some data to the table
400 Table ht
= TEST_UTIL
.getConnection().getTable(tableName
);
401 List
<Put
> puts
= new ArrayList
<>();
402 byte[] qualifier
= Bytes
.toBytes("c");
403 Put put
= new Put(new byte[] { (byte) '1' });
404 put
.addColumn(cf
, qualifier
, Bytes
.toBytes("100"));
406 put
= new Put(new byte[] { (byte) '6' });
407 put
.addColumn(cf
, qualifier
, Bytes
.toBytes("100"));
409 put
= new Put(new byte[] { (byte) '8' });
410 put
.addColumn(cf
, qualifier
, Bytes
.toBytes("100"));
414 List
<Pair
<RegionInfo
, ServerName
>> regions
=
415 MetaTableAccessor
.getTableRegionsAndLocations(TEST_UTIL
.getConnection(), tableName
);
416 boolean gotException
= false;
417 // the element at index 1 would be a replica (since the metareader gives us ordered
418 // regions). Try splitting that region via the split API . Should fail
421 TEST_UTIL
.getAdmin().splitRegionAsync(regions
.get(1).getFirst().getRegionName()));
422 } catch (IllegalArgumentException ex
) {
425 assertTrue(gotException
);
426 gotException
= false;
427 // the element at index 1 would be a replica (since the metareader gives us ordered
428 // regions). Try splitting that region via a different split API (the difference is
429 // this API goes direct to the regionserver skipping any checks in the admin). Should fail
431 FutureUtils
.get(TEST_UTIL
.getAdmin().splitRegionAsync(
432 regions
.get(1).getFirst().getEncodedNameAsBytes(), new byte[] { (byte) '1' }));
433 } catch (IllegalArgumentException ex
) {
436 assertTrue(gotException
);
438 gotException
= false;
439 // testing Sync split operation
441 FutureUtils
.get(TEST_UTIL
.getAdmin()
442 .splitRegionAsync(regions
.get(1).getFirst().getRegionName(), new byte[] { (byte) '1' }));
443 } catch (IllegalArgumentException ex
) {
446 assertTrue(gotException
);
448 gotException
= false;
449 // Try merging a replica with another. Should fail.
451 FutureUtils
.get(TEST_UTIL
.getAdmin().mergeRegionsAsync(
452 regions
.get(1).getFirst().getEncodedNameAsBytes(),
453 regions
.get(2).getFirst().getEncodedNameAsBytes(),
455 } catch (IllegalArgumentException m
) {
458 assertTrue(gotException
);
459 // Try going to the master directly (that will skip the check in admin)
461 byte[][] nameofRegionsToMerge
= new byte[2][];
462 nameofRegionsToMerge
[0] = regions
.get(1).getFirst().getEncodedNameAsBytes();
463 nameofRegionsToMerge
[1] = regions
.get(2).getFirst().getEncodedNameAsBytes();
464 MergeTableRegionsRequest request
= RequestConverter
.buildMergeTableRegionsRequest(
465 nameofRegionsToMerge
, true, HConstants
.NO_NONCE
, HConstants
.NO_NONCE
);
466 TEST_UTIL
.getMiniHBaseCluster().getMaster().getMasterRpcServices().mergeTableRegions(null,
468 } catch (org
.apache
.hbase
.thirdparty
.com
.google
.protobuf
.ServiceException m
) {
469 Throwable t
= m
.getCause();
471 if (t
instanceof MergeRegionException
) {
478 assertTrue(gotException
);
481 @Test(expected
= IllegalArgumentException
.class)
482 public void testInvalidColumnDescriptor() throws IOException
{
483 ColumnFamilyDescriptorBuilder
.of("/cfamily/name");
487 * Test DFS replication for column families, where one CF has default replication(3) and the other
491 public void testHFileReplication() throws Exception
{
492 final TableName tableName
= TableName
.valueOf(this.name
.getMethodName());
494 String fn
= "defaultRep";
495 TableDescriptor htd
= TableDescriptorBuilder
.newBuilder(tableName
)
496 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of(fn
))
497 .setColumnFamily(ColumnFamilyDescriptorBuilder
.newBuilder(Bytes
.toBytes(fn1
))
498 .setDFSReplication((short) 1).build())
500 Table table
= TEST_UTIL
.createTable(htd
, null);
501 TEST_UTIL
.waitTableAvailable(tableName
);
502 Put p
= new Put(Bytes
.toBytes("defaultRep_rk"));
503 byte[] q1
= Bytes
.toBytes("q1");
504 byte[] v1
= Bytes
.toBytes("v1");
505 p
.addColumn(Bytes
.toBytes(fn
), q1
, v1
);
506 List
<Put
> puts
= new ArrayList
<>(2);
508 p
= new Put(Bytes
.toBytes("rep1_rk"));
509 p
.addColumn(Bytes
.toBytes(fn1
), q1
, v1
);
513 ADMIN
.flush(tableName
);
515 List
<HRegion
> regions
= TEST_UTIL
.getMiniHBaseCluster().getRegions(tableName
);
516 for (HRegion r
: regions
) {
517 HStore store
= r
.getStore(Bytes
.toBytes(fn
));
518 for (HStoreFile sf
: store
.getStorefiles()) {
519 assertTrue(sf
.toString().contains(fn
));
520 assertTrue("Column family " + fn
+ " should have 3 copies",
521 CommonFSUtils
.getDefaultReplication(TEST_UTIL
.getTestFileSystem(),
522 sf
.getPath()) == (sf
.getFileInfo().getFileStatus().getReplication()));
525 store
= r
.getStore(Bytes
.toBytes(fn1
));
526 for (HStoreFile sf
: store
.getStorefiles()) {
527 assertTrue(sf
.toString().contains(fn1
));
528 assertTrue("Column family " + fn1
+ " should have only 1 copy",
529 1 == sf
.getFileInfo().getFileStatus().getReplication());
533 if (ADMIN
.isTableEnabled(tableName
)) {
534 ADMIN
.disableTable(tableName
);
535 ADMIN
.deleteTable(tableName
);
541 public void testMergeRegions() throws Exception
{
542 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
543 TableDescriptor td
= TableDescriptorBuilder
.newBuilder(tableName
)
544 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("d")).build();
545 byte[][] splitRows
= new byte[2][];
546 splitRows
[0] = new byte[] { (byte) '3' };
547 splitRows
[1] = new byte[] { (byte) '6' };
549 TEST_UTIL
.createTable(td
, splitRows
);
550 TEST_UTIL
.waitTableAvailable(tableName
);
552 List
<RegionInfo
> tableRegions
;
556 RegionInfo mergedChildRegion
= null;
558 // merge with full name
559 tableRegions
= ADMIN
.getRegions(tableName
);
560 assertEquals(3, ADMIN
.getRegions(tableName
).size());
561 regionA
= tableRegions
.get(0);
562 regionB
= tableRegions
.get(1);
563 regionC
= tableRegions
.get(2);
564 // TODO convert this to version that is synchronous (See HBASE-16668)
565 ADMIN
.mergeRegionsAsync(regionA
.getRegionName(), regionB
.getRegionName(),
566 false).get(60, TimeUnit
.SECONDS
);
568 tableRegions
= ADMIN
.getRegions(tableName
);
570 assertEquals(2, tableRegions
.size());
571 for (RegionInfo ri
: tableRegions
) {
572 if (regionC
.compareTo(ri
) != 0) {
573 mergedChildRegion
= ri
;
578 assertNotNull(mergedChildRegion
);
579 // Need to wait GC for merged child region is done.
580 HMaster services
= TEST_UTIL
.getHBaseCluster().getMaster();
581 CatalogJanitor cj
= services
.getCatalogJanitor();
582 assertTrue(cj
.scan() > 0);
583 // Wait until all procedures settled down
584 while (!services
.getMasterProcedureExecutor().getActiveProcIds().isEmpty()) {
588 // TODO convert this to version that is synchronous (See HBASE-16668)
589 ADMIN
.mergeRegionsAsync(regionC
.getEncodedNameAsBytes(),
590 mergedChildRegion
.getEncodedNameAsBytes(), false)
591 .get(60, TimeUnit
.SECONDS
);
593 assertEquals(1, ADMIN
.getRegions(tableName
).size());
595 ADMIN
.disableTable(tableName
);
596 ADMIN
.deleteTable(tableName
);
601 public void testMergeRegionsInvalidRegionCount()
602 throws IOException
, InterruptedException
, ExecutionException
{
603 TableName tableName
= TableName
.valueOf(name
.getMethodName());
604 TableDescriptor td
= TableDescriptorBuilder
.newBuilder(tableName
)
605 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("d")).build();
606 byte[][] splitRows
= new byte[2][];
607 splitRows
[0] = new byte[] { (byte) '3' };
608 splitRows
[1] = new byte[] { (byte) '6' };
610 TEST_UTIL
.createTable(td
, splitRows
);
611 TEST_UTIL
.waitTableAvailable(tableName
);
613 List
<RegionInfo
> tableRegions
= ADMIN
.getRegions(tableName
);
616 FutureUtils
.get(ADMIN
.mergeRegionsAsync(new byte[0][0], false));
618 } catch (IllegalArgumentException e
) {
623 FutureUtils
.get(ADMIN
624 .mergeRegionsAsync(new byte[][] { tableRegions
.get(0).getEncodedNameAsBytes() }, false));
626 } catch (IllegalArgumentException e
) {
630 ADMIN
.disableTable(tableName
);
631 ADMIN
.deleteTable(tableName
);
636 public void testSplitShouldNotHappenIfSplitIsDisabledForTable() throws Exception
{
637 final TableName tableName
= TableName
.valueOf(name
.getMethodName());
638 TableDescriptor htd
= TableDescriptorBuilder
.newBuilder(tableName
)
639 .setRegionSplitPolicyClassName(DisabledRegionSplitPolicy
.class.getName())
640 .setColumnFamily(ColumnFamilyDescriptorBuilder
.of("f")).build();
641 Table table
= TEST_UTIL
.createTable(htd
, null);
642 for (int i
= 0; i
< 10; i
++) {
643 Put p
= new Put(Bytes
.toBytes("row" + i
));
644 byte[] q1
= Bytes
.toBytes("q1");
645 byte[] v1
= Bytes
.toBytes("v1");
646 p
.addColumn(Bytes
.toBytes("f"), q1
, v1
);
649 ADMIN
.flush(tableName
);
651 ADMIN
.split(tableName
, Bytes
.toBytes("row5"));
652 Threads
.sleep(10000);
653 } catch (Exception e
) {
656 // Split should not happen.
657 List
<RegionInfo
> allRegions
=
658 MetaTableAccessor
.getTableRegions(ADMIN
.getConnection(), tableName
, true);
659 assertEquals(1, allRegions
.size());