HBASE-23949 refactor loadBalancer implements for rsgroup balance by table to achieve...
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / client / TestAsyncRegionAdminApi2.java
blob7ea6b94cf82d54b2cfffbad40c2794c423413942
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.apache.hadoop.hbase.TableName.META_TABLE_NAME;
21 import static org.hamcrest.CoreMatchers.instanceOf;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertFalse;
24 import static org.junit.Assert.assertThat;
25 import static org.junit.Assert.assertTrue;
26 import static org.junit.Assert.fail;
28 import java.util.ArrayList;
29 import java.util.Collections;
30 import java.util.List;
31 import java.util.concurrent.ExecutionException;
32 import java.util.stream.Collectors;
33 import org.apache.hadoop.hbase.AsyncMetaTableAccessor;
34 import org.apache.hadoop.hbase.HBaseClassTestRule;
35 import org.apache.hadoop.hbase.HConstants;
36 import org.apache.hadoop.hbase.HRegionLocation;
37 import org.apache.hadoop.hbase.TableName;
38 import org.apache.hadoop.hbase.testclassification.ClientTests;
39 import org.apache.hadoop.hbase.testclassification.LargeTests;
40 import org.apache.hadoop.hbase.util.Bytes;
41 import org.apache.hadoop.hbase.util.Threads;
42 import org.junit.ClassRule;
43 import org.junit.Ignore;
44 import org.junit.Test;
45 import org.junit.experimental.categories.Category;
46 import org.junit.runner.RunWith;
47 import org.junit.runners.Parameterized;
49 /**
50 * Class to test asynchronous region admin operations.
51 * @see TestAsyncRegionAdminApi This test and it used to be joined it was taking longer than our
52 * ten minute timeout so they were split.
54 @RunWith(Parameterized.class)
55 @Category({ LargeTests.class, ClientTests.class })
56 public class TestAsyncRegionAdminApi2 extends TestAsyncAdminBase {
58 @ClassRule
59 public static final HBaseClassTestRule CLASS_RULE =
60 HBaseClassTestRule.forClass(TestAsyncRegionAdminApi2.class);
62 @Test
63 public void testGetRegionLocation() throws Exception {
64 RawAsyncHBaseAdmin rawAdmin = (RawAsyncHBaseAdmin) ASYNC_CONN.getAdmin();
65 TEST_UTIL.createMultiRegionTable(tableName, HConstants.CATALOG_FAMILY);
66 AsyncTableRegionLocator locator = ASYNC_CONN.getRegionLocator(tableName);
67 HRegionLocation regionLocation = locator.getRegionLocation(Bytes.toBytes("mmm")).get();
68 RegionInfo region = regionLocation.getRegion();
69 byte[] regionName = regionLocation.getRegion().getRegionName();
70 HRegionLocation location = rawAdmin.getRegionLocation(regionName).get();
71 assertTrue(Bytes.equals(regionName, location.getRegion().getRegionName()));
72 location = rawAdmin.getRegionLocation(region.getEncodedNameAsBytes()).get();
73 assertTrue(Bytes.equals(regionName, location.getRegion().getRegionName()));
76 @Test
77 public void testSplitSwitch() throws Exception {
78 createTableWithDefaultConf(tableName);
79 byte[][] families = {FAMILY};
80 final int rows = 10000;
81 TestAsyncRegionAdminApi.loadData(tableName, families, rows);
83 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME);
84 List<HRegionLocation> regionLocations =
85 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, tableName).get();
86 int originalCount = regionLocations.size();
88 initSplitMergeSwitch();
89 assertTrue(admin.splitSwitch(false).get());
90 try {
91 admin.split(tableName, Bytes.toBytes(rows / 2)).join();
92 } catch (Exception e) {
93 //Expected
95 int count = admin.getRegions(tableName).get().size();
96 assertTrue(originalCount == count);
98 assertFalse(admin.splitSwitch(true).get());
99 admin.split(tableName).join();
100 while ((count = admin.getRegions(tableName).get().size()) == originalCount) {
101 Threads.sleep(100);
103 assertTrue(originalCount < count);
106 @Test
107 @Ignore
108 // It was ignored in TestSplitOrMergeStatus, too
109 public void testMergeSwitch() throws Exception {
110 createTableWithDefaultConf(tableName);
111 byte[][] families = {FAMILY};
112 TestAsyncRegionAdminApi.loadData(tableName, families, 1000);
114 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME);
115 List<HRegionLocation> regionLocations =
116 AsyncMetaTableAccessor.getTableHRegionLocations(metaTable, tableName).get();
117 int originalCount = regionLocations.size();
119 initSplitMergeSwitch();
120 admin.split(tableName).join();
121 int postSplitCount = originalCount;
122 while ((postSplitCount = admin.getRegions(tableName).get().size()) == originalCount) {
123 Threads.sleep(100);
125 assertTrue("originalCount=" + originalCount + ", postSplitCount=" + postSplitCount,
126 originalCount != postSplitCount);
128 // Merge switch is off so merge should NOT succeed.
129 assertTrue(admin.mergeSwitch(false).get());
130 List<RegionInfo> regions = admin.getRegions(tableName).get();
131 assertTrue(regions.size() > 1);
132 admin.mergeRegions(regions.get(0).getRegionName(), regions.get(1).getRegionName(), true).join();
133 int count = admin.getRegions(tableName).get().size();
134 assertTrue("postSplitCount=" + postSplitCount + ", count=" + count, postSplitCount == count);
136 // Merge switch is on so merge should succeed.
137 assertFalse(admin.mergeSwitch(true).get());
138 admin.mergeRegions(regions.get(0).getRegionName(), regions.get(1).getRegionName(), true).join();
139 count = admin.getRegions(tableName).get().size();
140 assertTrue((postSplitCount / 2) == count);
143 private void initSplitMergeSwitch() throws Exception {
144 if (!admin.isSplitEnabled().get()) {
145 admin.splitSwitch(true).get();
147 if (!admin.isMergeEnabled().get()) {
148 admin.mergeSwitch(true).get();
150 assertTrue(admin.isSplitEnabled().get());
151 assertTrue(admin.isMergeEnabled().get());
154 @Test
155 public void testMergeRegions() throws Exception {
156 byte[][] splitRows = new byte[][]{Bytes.toBytes("3"), Bytes.toBytes("6")};
157 createTableWithDefaultConf(tableName, splitRows);
159 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME);
160 List<HRegionLocation> regionLocations = AsyncMetaTableAccessor
161 .getTableHRegionLocations(metaTable, tableName).get();
162 RegionInfo regionA;
163 RegionInfo regionB;
165 // merge with full name
166 assertEquals(3, regionLocations.size());
167 regionA = regionLocations.get(0).getRegion();
168 regionB = regionLocations.get(1).getRegion();
169 admin.mergeRegions(regionA.getRegionName(), regionB.getRegionName(), false).get();
171 regionLocations = AsyncMetaTableAccessor
172 .getTableHRegionLocations(metaTable, tableName).get();
173 assertEquals(2, regionLocations.size());
174 // merge with encoded name
175 regionA = regionLocations.get(0).getRegion();
176 regionB = regionLocations.get(1).getRegion();
177 admin.mergeRegions(regionA.getRegionName(), regionB.getRegionName(), false).get();
179 regionLocations = AsyncMetaTableAccessor
180 .getTableHRegionLocations(metaTable, tableName).get();
181 assertEquals(1, regionLocations.size());
184 @Test
185 public void testMergeRegionsInvalidRegionCount() throws Exception {
186 byte[][] splitRows = new byte[][] { Bytes.toBytes("3"), Bytes.toBytes("6") };
187 createTableWithDefaultConf(tableName, splitRows);
188 List<RegionInfo> regions = admin.getRegions(tableName).join();
189 // 0
190 try {
191 admin.mergeRegions(Collections.emptyList(), false).get();
192 fail();
193 } catch (ExecutionException e) {
194 // expected
195 assertThat(e.getCause(), instanceOf(IllegalArgumentException.class));
197 // 1
198 try {
199 admin.mergeRegions(regions.stream().limit(1).map(RegionInfo::getEncodedNameAsBytes)
200 .collect(Collectors.toList()), false).get();
201 fail();
202 } catch (ExecutionException e) {
203 // expected
204 assertThat(e.getCause(), instanceOf(IllegalArgumentException.class));
208 @Test
209 public void testSplitTable() throws Exception {
210 initSplitMergeSwitch();
211 splitTest(TableName.valueOf("testSplitTable"), 3000, false, null);
212 splitTest(TableName.valueOf("testSplitTableWithSplitPoint"), 3000, false, Bytes.toBytes("3"));
213 splitTest(TableName.valueOf("testSplitTableRegion"), 3000, true, null);
214 splitTest(TableName.valueOf("testSplitTableRegionWithSplitPoint2"), 3000, true, Bytes.toBytes("3"));
217 private void
218 splitTest(TableName tableName, int rowCount, boolean isSplitRegion, byte[] splitPoint)
219 throws Exception {
220 // create table
221 createTableWithDefaultConf(tableName);
223 AsyncTable<AdvancedScanResultConsumer> metaTable = ASYNC_CONN.getTable(META_TABLE_NAME);
224 List<HRegionLocation> regionLocations = AsyncMetaTableAccessor
225 .getTableHRegionLocations(metaTable, tableName).get();
226 assertEquals(1, regionLocations.size());
228 AsyncTable<?> table = ASYNC_CONN.getTable(tableName);
229 List<Put> puts = new ArrayList<>();
230 for (int i = 0; i < rowCount; i++) {
231 Put put = new Put(Bytes.toBytes(i));
232 put.addColumn(FAMILY, null, Bytes.toBytes("value" + i));
233 puts.add(put);
235 table.putAll(puts).join();
237 if (isSplitRegion) {
238 if (splitPoint == null) {
239 admin.splitRegion(regionLocations.get(0).getRegion().getRegionName()).get();
240 } else {
241 admin.splitRegion(regionLocations.get(0).getRegion().getRegionName(), splitPoint).get();
243 } else {
244 if (splitPoint == null) {
245 admin.split(tableName).get();
246 } else {
247 admin.split(tableName, splitPoint).get();
251 int count = 0;
252 for (int i = 0; i < 45; i++) {
253 try {
254 regionLocations = AsyncMetaTableAccessor
255 .getTableHRegionLocations(metaTable, tableName).get();
256 count = regionLocations.size();
257 if (count >= 2) {
258 break;
260 Thread.sleep(1000L);
261 } catch (Exception e) {
262 LOG.error(e.toString(), e);
265 assertEquals(2, count);