1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20 package org.apache.hadoop.hbase.regionserver.handler;
21
22 import static org.junit.Assert.assertEquals;
23 import static org.junit.Assert.assertNotNull;
24
25 import java.io.IOException;
26
27 import org.apache.commons.logging.Log;
28 import org.apache.commons.logging.LogFactory;
29 import org.apache.hadoop.conf.Configuration;
30 import org.apache.hadoop.hbase.HBaseTestingUtility;
31 import org.apache.hadoop.hbase.HConstants;
32 import org.apache.hadoop.hbase.HRegionInfo;
33 import org.apache.hadoop.hbase.HTableDescriptor;
34 import org.apache.hadoop.hbase.MediumTests;
35 import org.apache.hadoop.hbase.MiniHBaseCluster;
36 import org.apache.hadoop.hbase.Server;
37 import org.apache.hadoop.hbase.executor.EventHandler.EventType;
38 import org.apache.hadoop.hbase.executor.RegionTransitionData;
39 import org.apache.hadoop.hbase.regionserver.HRegion;
40 import org.apache.hadoop.hbase.regionserver.HRegionServer;
41 import org.apache.hadoop.hbase.regionserver.RegionAlreadyInTransitionException;
42 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
43 import org.apache.hadoop.hbase.util.Bytes;
44 import org.apache.hadoop.hbase.util.MockRegionServerServices;
45 import org.apache.hadoop.hbase.util.MockServer;
46 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
47 import org.apache.hadoop.hbase.zookeeper.ZKUtil;
48 import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
49 import org.apache.zookeeper.KeeperException;
50 import org.apache.zookeeper.KeeperException.NodeExistsException;
51 import org.junit.AfterClass;
52 import org.junit.Before;
53 import org.junit.BeforeClass;
54 import org.junit.Test;
55 import org.junit.experimental.categories.Category;
56
57
58
59
60 @Category(MediumTests.class)
61 public class TestOpenRegionHandler {
62 static final Log LOG = LogFactory.getLog(TestOpenRegionHandler.class);
63 private final static HBaseTestingUtility HTU = new HBaseTestingUtility();
64 private static HTableDescriptor TEST_HTD;
65 private HRegionInfo TEST_HRI;
66
67 private int testIndex = 0;
68
69 @BeforeClass public static void before() throws Exception {
70 Configuration c = HTU.getConfiguration();
71 c.setClass(HConstants.REGION_SERVER_IMPL, TestOpenRegionHandlerRegionServer.class,
72 HRegionServer.class);
73 HTU.startMiniCluster();
74 TEST_HTD = new HTableDescriptor("TestOpenRegionHandler.java");
75 }
76
77 @AfterClass public static void after() throws IOException {
78 TEST_HTD = null;
79 try {
80 HTU.shutdownMiniCluster();
81 } catch (Exception e) {
82 throw new IOException(e);
83 }
84 }
85
86
87
88
89
90
91 @Before
92 public void setupHRI() {
93 TEST_HRI = new HRegionInfo(TEST_HTD.getName(),
94 Bytes.toBytes(testIndex),
95 Bytes.toBytes(testIndex + 1));
96 testIndex++;
97 }
98
99
100
101
102
103
104
105
106
107 @Test public void testYankingRegionFromUnderIt()
108 throws IOException, NodeExistsException, KeeperException {
109 final Server server = new MockServer(HTU);
110 final RegionServerServices rss = new MockRegionServerServices();
111
112 HTableDescriptor htd = TEST_HTD;
113 final HRegionInfo hri = TEST_HRI;
114 HRegion region =
115 HRegion.createHRegion(hri, HTU.getDataTestDir(), HTU
116 .getConfiguration(), htd);
117 assertNotNull(region);
118 try {
119 OpenRegionHandler handler = new OpenRegionHandler(server, rss, hri, htd) {
120 HRegion openRegion() {
121
122 HRegion region = super.openRegion();
123
124
125
126 ZooKeeperWatcher zkw = this.server.getZooKeeper();
127 String node = ZKAssign.getNodeName(zkw, hri.getEncodedName());
128 try {
129 ZKUtil.deleteNodeFailSilent(zkw, node);
130 } catch (KeeperException e) {
131 throw new RuntimeException("Ugh failed delete of " + node, e);
132 }
133 return region;
134 }
135 };
136
137
138 handler.process();
139 ZKAssign.createNodeOffline(server.getZooKeeper(), hri, server.getServerName());
140
141
142 handler.process();
143 } finally {
144 HRegion.closeHRegion(region);
145 }
146 }
147
148 @Test
149 public void testFailedOpenRegion() throws Exception {
150 Server server = new MockServer(HTU);
151 RegionServerServices rsServices = new MockRegionServerServices();
152
153
154 ZKAssign.createNodeOffline(server.getZooKeeper(), TEST_HRI, server.getServerName());
155 ZKAssign.transitionNodeOpening(server.getZooKeeper(), TEST_HRI, server.getServerName());
156
157
158 OpenRegionHandler handler =
159 new OpenRegionHandler(server, rsServices, TEST_HRI, TEST_HTD) {
160 @Override
161 HRegion openRegion() {
162
163 return null;
164 }
165 };
166 handler.process();
167
168
169 RegionTransitionData data =
170 ZKAssign.getData(server.getZooKeeper(), TEST_HRI.getEncodedName());
171 assertEquals(EventType.RS_ZK_REGION_FAILED_OPEN, data.getEventType());
172 }
173
174 @Test
175 public void testFailedUpdateMeta() throws Exception {
176 Server server = new MockServer(HTU);
177 RegionServerServices rsServices = new MockRegionServerServices();
178
179
180 ZKAssign.createNodeOffline(server.getZooKeeper(), TEST_HRI, server.getServerName());
181 ZKAssign.transitionNodeOpening(server.getZooKeeper(), TEST_HRI, server.getServerName());
182
183 OpenRegionHandler handler =
184 new OpenRegionHandler(server, rsServices, TEST_HRI, TEST_HTD) {
185 @Override
186 boolean updateMeta(final HRegion r) {
187
188 return false;
189 }
190 };
191 handler.process();
192
193
194 RegionTransitionData data =
195 ZKAssign.getData(server.getZooKeeper(), TEST_HRI.getEncodedName());
196 assertEquals(EventType.RS_ZK_REGION_FAILED_OPEN, data.getEventType());
197 }
198
199 public static class TestOpenRegionHandlerRegionServer extends HRegionServer {
200 public TestOpenRegionHandlerRegionServer(Configuration conf)
201 throws IOException, InterruptedException {
202 super(conf);
203 }
204 @Override
205 public void addRegionsInTransition(HRegionInfo region,
206 String currentAction) throws RegionAlreadyInTransitionException {
207 super.addRegionsInTransition(region, currentAction);
208 }
209 }
210
211 @Test
212 public void testTransitionToFailedOpenEvenIfCleanupFails() throws Exception {
213 MiniHBaseCluster cluster = HTU.getHBaseCluster();
214 HRegionServer server =
215 cluster.getLiveRegionServerThreads().get(0).getRegionServer();
216
217 ZKAssign.createNodeOffline(server.getZooKeeper(), TEST_HRI, server.getServerName());
218 ZKAssign.transitionNodeOpening(server.getZooKeeper(), TEST_HRI, server.getServerName());
219
220 OpenRegionHandler handler = new OpenRegionHandler(server, server, TEST_HRI, TEST_HTD) {
221 @Override
222 boolean updateMeta(HRegion r) {
223 return false;
224 };
225
226 @Override
227 void cleanupFailedOpen(HRegion region) throws IOException {
228 throw new IOException("FileSystem got closed.");
229 }
230 };
231 ((TestOpenRegionHandlerRegionServer)server).addRegionsInTransition(TEST_HRI, "OPEN");
232 try {
233 handler.process();
234 } catch (Exception e) {
235
236 }
237 RegionTransitionData data =
238 ZKAssign.getData(server.getZooKeeper(), TEST_HRI.getEncodedName());
239 assertEquals(EventType.RS_ZK_REGION_FAILED_OPEN, data.getEventType());
240 }
241
242
243 @org.junit.Rule
244 public org.apache.hadoop.hbase.ResourceCheckerJUnitRule cu =
245 new org.apache.hadoop.hbase.ResourceCheckerJUnitRule();
246 }
247