1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.client;
19
20 import org.apache.commons.logging.Log;
21 import org.apache.commons.logging.LogFactory;
22 import org.apache.hadoop.hbase.HBaseTestingUtility;
23 import org.apache.hadoop.hbase.HRegionInfo;
24 import org.apache.hadoop.hbase.HRegionLocation;
25 import org.apache.hadoop.hbase.MiniHBaseCluster;
26 import org.apache.hadoop.hbase.TableName;
27 import org.apache.hadoop.hbase.regionserver.HRegion;
28 import org.apache.hadoop.hbase.regionserver.Region;
29 import org.apache.hadoop.hbase.testclassification.MediumTests;
30 import org.apache.hadoop.hbase.util.Bytes;
31 import org.apache.hadoop.hbase.util.JVMClusterUtil;
32 import org.junit.AfterClass;
33 import org.junit.BeforeClass;
34 import org.junit.Test;
35 import org.junit.experimental.categories.Category;
36
37 import java.io.IOException;
38 import java.util.List;
39
40 import static org.junit.Assert.assertEquals;
41 import static org.junit.Assert.assertFalse;
42 import static org.junit.Assert.assertTrue;
43
44 @Category({MediumTests.class})
45 public class TestSplitOrMergeStatus {
46
47 private static final Log LOG = LogFactory.getLog(TestSplitOrMergeStatus.class);
48 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
49 private static byte [] FAMILY = Bytes.toBytes("testFamily");
50
51
52
53
54 @BeforeClass
55 public static void setUpBeforeClass() throws Exception {
56 TEST_UTIL.getConfiguration().setBoolean("hbase.assignment.usezk", false);
57 TEST_UTIL.startMiniCluster(2);
58 }
59
60
61
62
63 @AfterClass
64 public static void tearDownAfterClass() throws Exception {
65 TEST_UTIL.shutdownMiniCluster();
66 }
67
68 @Test
69 public void testSplitSwitch() throws Exception {
70 TableName name = TableName.valueOf("testSplitSwitch");
71 Table t = TEST_UTIL.createTable(name, FAMILY);
72 TEST_UTIL.loadTable(t, FAMILY, false);
73
74 RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(t.getName());
75 int orignalCount = locator.getAllRegionLocations().size();
76
77 Admin admin = TEST_UTIL.getHBaseAdmin();
78 initSwitchStatus(admin);
79 boolean[] results = admin.setSplitOrMergeEnabled(false, false, Admin.MasterSwitchType.SPLIT);
80 assertEquals(results.length, 1);
81 assertTrue(results[0]);
82 admin.split(t.getName());
83 int count = waitOnSplitOrMerge(t).size();
84 assertTrue(orignalCount == count);
85
86 results = admin.setSplitOrMergeEnabled(true, false, Admin.MasterSwitchType.SPLIT);
87 assertEquals(results.length, 1);
88 assertFalse(results[0]);
89 admin.split(t.getName());
90 count = waitOnSplitOrMerge(t).size();
91 assertTrue(orignalCount<count);
92 admin.close();
93 }
94
95
96 @Test
97 public void testMergeSwitch() throws Exception {
98 TableName name = TableName.valueOf("testMergeSwitch");
99 Table t = TEST_UTIL.createTable(name, FAMILY);
100 TEST_UTIL.loadTable(t, FAMILY, false);
101
102 RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(t.getName());
103
104 Admin admin = TEST_UTIL.getHBaseAdmin();
105 initSwitchStatus(admin);
106 admin.split(t.getName());
107 waitOnSplitOrMerge(t);
108
109 waitForMergable(admin, name);
110 int orignalCount = locator.getAllRegionLocations().size();
111 boolean[] results = admin.setSplitOrMergeEnabled(false, false, Admin.MasterSwitchType.MERGE);
112 assertEquals(results.length, 1);
113 assertTrue(results[0]);
114 List<HRegionInfo> regions = admin.getTableRegions(t.getName());
115 assertTrue(regions.size() > 1);
116 admin.mergeRegions(regions.get(0).getEncodedNameAsBytes(),
117 regions.get(1).getEncodedNameAsBytes(), true);
118 int count = waitOnSplitOrMerge(t).size();
119 assertTrue(orignalCount == count);
120
121 waitForMergable(admin, name);
122 results = admin.setSplitOrMergeEnabled(true, false, Admin.MasterSwitchType.MERGE);
123 assertEquals(results.length, 1);
124 assertFalse(results[0]);
125 admin.mergeRegions(regions.get(0).getEncodedNameAsBytes(),
126 regions.get(1).getEncodedNameAsBytes(), true);
127 count = waitOnSplitOrMerge(t).size();
128 assertTrue(orignalCount>count);
129 admin.close();
130 }
131
132 @Test
133 public void testMultiSwitches() throws IOException {
134 Admin admin = TEST_UTIL.getHBaseAdmin();
135 boolean[] switches = admin.setSplitOrMergeEnabled(false, false,
136 Admin.MasterSwitchType.SPLIT, Admin.MasterSwitchType.MERGE);
137 for (boolean s : switches){
138 assertTrue(s);
139 }
140 assertFalse(admin.isSplitOrMergeEnabled(Admin.MasterSwitchType.SPLIT));
141 assertFalse(admin.isSplitOrMergeEnabled(Admin.MasterSwitchType.MERGE));
142 admin.close();
143 }
144
145 private void initSwitchStatus(Admin admin) throws IOException {
146 if (!admin.isSplitOrMergeEnabled(Admin.MasterSwitchType.SPLIT)) {
147 admin.setSplitOrMergeEnabled(true, false, Admin.MasterSwitchType.SPLIT);
148 }
149 if (!admin.isSplitOrMergeEnabled(Admin.MasterSwitchType.MERGE)) {
150 admin.setSplitOrMergeEnabled(true, false, Admin.MasterSwitchType.MERGE);
151 }
152 assertTrue(admin.isSplitOrMergeEnabled(Admin.MasterSwitchType.SPLIT));
153 assertTrue(admin.isSplitOrMergeEnabled(Admin.MasterSwitchType.MERGE));
154 }
155
156 private void waitForMergable(Admin admin, TableName t) throws InterruptedException, IOException {
157
158 MiniHBaseCluster miniCluster = TEST_UTIL.getMiniHBaseCluster();
159 int mergeable = 0;
160 while (mergeable < 2) {
161 Thread.sleep(100);
162 admin.majorCompact(t);
163 mergeable = 0;
164 for (JVMClusterUtil.RegionServerThread regionThread: miniCluster.getRegionServerThreads()) {
165 for (Region region: regionThread.getRegionServer().getOnlineRegions(t)) {
166 mergeable += ((HRegion)region).isMergeable() ? 1 : 0;
167 }
168 }
169 }
170 }
171
172
173
174
175
176
177
178 private List<HRegionLocation> waitOnSplitOrMerge(final Table t)
179 throws IOException {
180 try (RegionLocator locator = TEST_UTIL.getConnection().getRegionLocator(t.getName())) {
181 List<HRegionLocation> regions = locator.getAllRegionLocations();
182 int originalCount = regions.size();
183 for (int i = 0; i < TEST_UTIL.getConfiguration().getInt("hbase.test.retries", 10); i++) {
184 Thread.currentThread();
185 try {
186 Thread.sleep(1000);
187 } catch (InterruptedException e) {
188 e.printStackTrace();
189 }
190 regions = locator.getAllRegionLocations();
191 if (regions.size() != originalCount)
192 break;
193 }
194 return regions;
195 }
196 }
197
198 }