1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19 package org.apache.hadoop.hbase.master;
20
21 import static org.junit.Assert.assertArrayEquals;
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.junit.Assert.fail;
25
26 import java.io.IOException;
27 import java.util.List;
28
29 import org.apache.commons.logging.Log;
30 import org.apache.commons.logging.LogFactory;
31 import org.apache.hadoop.hbase.HBaseIOException;
32 import org.apache.hadoop.hbase.HBaseTestingUtility;
33 import org.apache.hadoop.hbase.HColumnDescriptor;
34 import org.apache.hadoop.hbase.HConstants;
35 import org.apache.hadoop.hbase.HRegionInfo;
36 import org.apache.hadoop.hbase.HTableDescriptor;
37 import org.apache.hadoop.hbase.testclassification.MediumTests;
38 import org.apache.hadoop.hbase.MetaTableAccessor;
39 import org.apache.hadoop.hbase.MiniHBaseCluster;
40 import org.apache.hadoop.hbase.PleaseHoldException;
41 import org.apache.hadoop.hbase.ServerName;
42 import org.apache.hadoop.hbase.TableName;
43 import org.apache.hadoop.hbase.UnknownRegionException;
44 import org.apache.hadoop.hbase.client.Admin;
45 import org.apache.hadoop.hbase.client.HTable;
46 import org.apache.hadoop.hbase.protobuf.generated.ZooKeeperProtos;
47 import org.apache.hadoop.hbase.util.Bytes;
48 import org.apache.hadoop.hbase.util.Pair;
49 import org.apache.hadoop.util.StringUtils;
50 import org.apache.zookeeper.KeeperException;
51 import org.junit.AfterClass;
52 import org.junit.Assert;
53 import org.junit.BeforeClass;
54 import org.junit.Test;
55 import org.junit.experimental.categories.Category;
56
57 import com.google.common.base.Joiner;
58
59 @Category(MediumTests.class)
60 public class TestMaster {
61 private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
62 private static final Log LOG = LogFactory.getLog(TestMaster.class);
63 private static final TableName TABLENAME =
64 TableName.valueOf("TestMaster");
65 private static final byte[] FAMILYNAME = Bytes.toBytes("fam");
66 private static Admin admin;
67
68 @BeforeClass
69 public static void beforeAllTests() throws Exception {
70
71 TEST_UTIL.getConfiguration().setInt(HConstants.HBASE_CLIENT_RETRIES_NUMBER, 3);
72
73 TEST_UTIL.getConfiguration().
74 setLong(HConstants.HBASE_MASTER_WAITING_META_ASSIGNMENT_TIMEOUT, 1);
75
76
77
78
79 TEST_UTIL.getConfiguration().set("hbase.min.version.move.system.tables", "0.0.0");
80
81 TEST_UTIL.startMiniCluster(2);
82 admin = TEST_UTIL.getHBaseAdmin();
83 TEST_UTIL.getHBaseCluster().getMaster().assignmentManager.initializeHandlerTrackers();
84 }
85
86 @AfterClass
87 public static void afterAllTests() throws Exception {
88 TEST_UTIL.shutdownMiniCluster();
89 }
90
91 @Test
92 public void testMasterOpsWhileSplitting() throws Exception {
93 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
94 HMaster m = cluster.getMaster();
95
96 try (HTable ht = TEST_UTIL.createTable(TABLENAME, FAMILYNAME)) {
97 assertTrue(m.assignmentManager.getTableStateManager().isTableState(TABLENAME,
98 ZooKeeperProtos.Table.State.ENABLED));
99 TEST_UTIL.loadTable(ht, FAMILYNAME, false);
100 }
101
102 List<Pair<HRegionInfo, ServerName>> tableRegions = MetaTableAccessor.getTableRegionsAndLocations(
103 m.getZooKeeper(),
104 m.getConnection(), TABLENAME);
105 LOG.info("Regions after load: " + Joiner.on(',').join(tableRegions));
106 assertEquals(1, tableRegions.size());
107 assertArrayEquals(HConstants.EMPTY_START_ROW,
108 tableRegions.get(0).getFirst().getStartKey());
109 assertArrayEquals(HConstants.EMPTY_END_ROW,
110 tableRegions.get(0).getFirst().getEndKey());
111
112
113 LOG.info("Splitting table");
114 TEST_UTIL.getHBaseAdmin().split(TABLENAME);
115 LOG.info("Waiting for split result to be about to open");
116 RegionStates regionStates = m.assignmentManager.getRegionStates();
117 while (regionStates.getRegionsOfTable(TABLENAME).size() <= 1) {
118 Thread.sleep(100);
119 }
120 LOG.info("Making sure we can call getTableRegions while opening");
121 tableRegions = MetaTableAccessor.getTableRegionsAndLocations(m.getZooKeeper(),
122 m.getConnection(),
123 TABLENAME, false);
124
125 LOG.info("Regions: " + Joiner.on(',').join(tableRegions));
126
127 assertEquals(3, tableRegions.size());
128 LOG.info("Making sure we can call getTableRegionClosest while opening");
129 Pair<HRegionInfo, ServerName> pair =
130 m.getTableRegionForRow(TABLENAME, Bytes.toBytes("cde"));
131 LOG.info("Result is: " + pair);
132 Pair<HRegionInfo, ServerName> tableRegionFromName =
133 MetaTableAccessor.getRegion(m.getConnection(),
134 pair.getFirst().getRegionName());
135 assertEquals(tableRegionFromName.getFirst(), pair.getFirst());
136 }
137
138 @Test
139 public void testMoveRegionWhenNotInitialized() {
140 MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
141 HMaster m = cluster.getMaster();
142 try {
143 m.setInitialized(false);
144 HRegionInfo meta = HRegionInfo.FIRST_META_REGIONINFO;
145 m.move(meta.getEncodedNameAsBytes(), null);
146 fail("Region should not be moved since master is not initialized");
147 } catch (IOException ioe) {
148 assertTrue(ioe instanceof PleaseHoldException);
149 } finally {
150 m.setInitialized(true);
151 }
152 }
153
154 @Test
155 public void testMoveThrowsUnknownRegionException() throws IOException {
156 TableName tableName =
157 TableName.valueOf("testMoveThrowsUnknownRegionException");
158 HTableDescriptor htd = new HTableDescriptor(tableName);
159 HColumnDescriptor hcd = new HColumnDescriptor("value");
160 htd.addFamily(hcd);
161
162 admin.createTable(htd, null);
163 try {
164 HRegionInfo hri = new HRegionInfo(
165 tableName, Bytes.toBytes("A"), Bytes.toBytes("Z"));
166 admin.move(hri.getEncodedNameAsBytes(), null);
167 fail("Region should not be moved since it is fake");
168 } catch (IOException ioe) {
169 assertTrue(ioe instanceof UnknownRegionException);
170 } finally {
171 TEST_UTIL.deleteTable(tableName);
172 }
173 }
174
175 @Test
176 public void testMoveThrowsPleaseHoldException() throws IOException {
177 TableName tableName = TableName.valueOf("testMoveThrowsPleaseHoldException");
178 HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster();
179 HTableDescriptor htd = new HTableDescriptor(tableName);
180 HColumnDescriptor hcd = new HColumnDescriptor("value");
181 htd.addFamily(hcd);
182
183 admin.createTable(htd, null);
184 try {
185 List<HRegionInfo> tableRegions = admin.getTableRegions(tableName);
186
187 master.setInitialized(false);
188 admin.move(tableRegions.get(0).getEncodedNameAsBytes(), null);
189 fail("Region should not be moved since master is not initialized");
190 } catch (IOException ioe) {
191 assertTrue(StringUtils.stringifyException(ioe).contains("PleaseHoldException"));
192 } finally {
193 master.setInitialized(true);
194 TEST_UTIL.deleteTable(tableName);
195 }
196 }
197
198 @Test (timeout = 300000)
199 public void testMoveRegionWhenMetaRegionInTransition()
200 throws IOException, InterruptedException, KeeperException {
201 TableName tableName = TableName.valueOf("testMoveRegionWhenMetaRegionInTransition");
202 HMaster master = TEST_UTIL.getMiniHBaseCluster().getMaster();
203 HTableDescriptor htd = new HTableDescriptor(tableName);
204 HColumnDescriptor hcd = new HColumnDescriptor("value");
205 RegionStates regionStates = master.getAssignmentManager().getRegionStates();
206 htd.addFamily(hcd);
207
208 admin.createTable(htd, null);
209 try {
210 HRegionInfo hri = admin.getTableRegions(tableName).get(0);
211
212 HRegionInfo metaRegion = admin.getTableRegions(TableName.META_TABLE_NAME).get(0);
213
214 ServerName rs0 = TEST_UTIL.getHBaseCluster().getRegionServer(0).getServerName();
215 ServerName rs1 = TEST_UTIL.getHBaseCluster().getRegionServer(1).getServerName();
216
217 admin.move(hri.getEncodedNameAsBytes(), rs0.getServerName().getBytes());
218 while (regionStates.isRegionInTransition(hri)) {
219
220 Thread.sleep(1000);
221 }
222
223 master.assignmentManager.unassign(metaRegion);
224
225 try{
226 master.move(hri.getEncodedNameAsBytes(), rs1.getServerName().getBytes());
227 Assert.fail("Admin move should not be successful here.");
228 } catch (HBaseIOException e) {
229 assertTrue(e.getMessage().contains("Fail-fast"));
230 }
231
232 Thread.sleep(HConstants.HBASE_MASTER_WAITING_META_ASSIGNMENT_TIMEOUT_DEFAULT);
233
234 TEST_UTIL.assertRegionOnServer(hri, rs0, 5000);
235
236
237 admin.assign(metaRegion.getEncodedNameAsBytes());
238 while (regionStates.isMetaRegionInTransition()) {
239 Thread.sleep(1000);
240 }
241
242
243 admin.move(hri.getEncodedNameAsBytes(), rs1.getServerName().getBytes());
244
245 Thread.sleep(HConstants.HBASE_MASTER_WAITING_META_ASSIGNMENT_TIMEOUT_DEFAULT);
246
247 TEST_UTIL.assertRegionOnServer(hri, rs1, 5000);
248 } finally {
249 TEST_UTIL.deleteTable(tableName);
250 }
251 }
252
253 @Test
254 public void testInstallShutdownHook() {
255
256 assertTrue(TEST_UTIL.getMiniHBaseCluster().getMaster().isShutdownHookInstalled());
257 }
258 }
259