1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18 package org.apache.hadoop.hbase.regionserver.handler;
19
20 import static org.junit.Assert.assertFalse;
21 import static org.junit.Assert.assertNotNull;
22 import static org.junit.Assert.assertTrue;
23
24 import java.io.IOException;
25
26 import org.apache.commons.logging.Log;
27 import org.apache.commons.logging.LogFactory;
28 import org.apache.hadoop.hbase.HBaseTestingUtility;
29 import org.apache.hadoop.hbase.HConstants;
30 import org.apache.hadoop.hbase.HRegionInfo;
31 import org.apache.hadoop.hbase.HTableDescriptor;
32 import org.apache.hadoop.hbase.testclassification.MediumTests;
33 import org.apache.hadoop.hbase.RegionTransition;
34 import org.apache.hadoop.hbase.Server;
35 import org.apache.hadoop.hbase.TableName;
36 import org.apache.hadoop.hbase.exceptions.DeserializationException;
37 import org.apache.hadoop.hbase.executor.EventType;
38 import org.apache.hadoop.hbase.regionserver.HRegion;
39 import org.apache.hadoop.hbase.regionserver.RegionServerServices;
40 import org.apache.hadoop.hbase.util.Bytes;
41 import org.apache.hadoop.hbase.util.MockServer;
42 import org.apache.hadoop.hbase.zookeeper.ZKAssign;
43 import org.apache.zookeeper.KeeperException;
44 import org.apache.zookeeper.KeeperException.NodeExistsException;
45 import org.junit.AfterClass;
46 import org.junit.Before;
47 import org.junit.BeforeClass;
48 import org.junit.Test;
49 import org.junit.experimental.categories.Category;
50 import org.mockito.Mockito;
51
52
53
54
55 @Category(MediumTests.class)
56 public class TestCloseRegionHandler {
57 static final Log LOG = LogFactory.getLog(TestCloseRegionHandler.class);
58 private final static HBaseTestingUtility HTU = HBaseTestingUtility.createLocalHTU();
59 private static final HTableDescriptor TEST_HTD =
60 new HTableDescriptor(TableName.valueOf("TestCloseRegionHandler"));
61 private HRegionInfo TEST_HRI;
62 private int testIndex = 0;
63
64 @BeforeClass public static void before() throws Exception {
65 HTU.getConfiguration().setBoolean("hbase.assignment.usezk", true);
66 HTU.startMiniZKCluster();
67 }
68
69 @AfterClass public static void after() throws IOException {
70 HTU.shutdownMiniZKCluster();
71 }
72
73
74
75
76
77
78 @Before
79 public void setupHRI() {
80 TEST_HRI = new HRegionInfo(TEST_HTD.getTableName(),
81 Bytes.toBytes(testIndex),
82 Bytes.toBytes(testIndex + 1));
83 testIndex++;
84 }
85
86
87
88
89
90
91
92
93 @Test public void testFailedFlushAborts()
94 throws IOException, NodeExistsException, KeeperException {
95 final Server server = new MockServer(HTU, false);
96 final RegionServerServices rss = HTU.createMockRegionServerService();
97 HTableDescriptor htd = TEST_HTD;
98 final HRegionInfo hri =
99 new HRegionInfo(htd.getTableName(), HConstants.EMPTY_END_ROW,
100 HConstants.EMPTY_END_ROW);
101 HRegion region = HTU.createLocalHRegion(hri, htd);
102 try {
103 assertNotNull(region);
104
105 HRegion spy = Mockito.spy(region);
106 final boolean abort = false;
107 Mockito.when(spy.close(abort)).
108 thenThrow(new RuntimeException("Mocked failed close!"));
109
110
111 rss.addToOnlineRegions(spy);
112
113 assertFalse(server.isStopped());
114 CloseRegionHandler handler =
115 new CloseRegionHandler(server, rss, hri, false, false, -1);
116 boolean throwable = false;
117 try {
118 handler.process();
119 } catch (Throwable t) {
120 throwable = true;
121 } finally {
122 assertTrue(throwable);
123
124 assertTrue(server.isStopped());
125 }
126 } finally {
127 HRegion.closeHRegion(region);
128 }
129 }
130
131
132
133
134
135
136
137
138 @Test public void testZKClosingNodeVersionMismatch()
139 throws IOException, NodeExistsException, KeeperException, DeserializationException {
140 final Server server = new MockServer(HTU);
141 final RegionServerServices rss = HTU.createMockRegionServerService();
142
143 HTableDescriptor htd = TEST_HTD;
144 final HRegionInfo hri = TEST_HRI;
145
146
147 OpenRegion(server, rss, htd, hri);
148
149
150
151 int versionOfClosingNode = ZKAssign.createNodeClosing(server.getZooKeeper(),
152 hri, server.getServerName());
153
154
155
156
157 CloseRegionHandler handler =
158 new CloseRegionHandler(server, rss, hri, false, true,
159 versionOfClosingNode+1);
160 handler.process();
161
162
163 RegionTransition rt =
164 RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
165 assertTrue(rt.getEventType().equals(EventType.M_ZK_REGION_CLOSING ));
166 }
167
168
169
170
171
172
173
174
175 @Test public void testCloseRegion()
176 throws IOException, NodeExistsException, KeeperException, DeserializationException {
177 final Server server = new MockServer(HTU);
178 final RegionServerServices rss = HTU.createMockRegionServerService();
179
180 HTableDescriptor htd = TEST_HTD;
181 HRegionInfo hri = TEST_HRI;
182
183
184 OpenRegion(server, rss, htd, hri);
185
186
187
188 int versionOfClosingNode = ZKAssign.createNodeClosing(server.getZooKeeper(),
189 hri, server.getServerName());
190
191
192
193
194 CloseRegionHandler handler =
195 new CloseRegionHandler(server, rss, hri, false, true,
196 versionOfClosingNode);
197 handler.process();
198
199 RegionTransition rt = RegionTransition.parseFrom(
200 ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
201 assertTrue(rt.getEventType().equals(EventType.RS_ZK_REGION_CLOSED));
202 }
203
204 private void OpenRegion(Server server, RegionServerServices rss,
205 HTableDescriptor htd, HRegionInfo hri)
206 throws IOException, NodeExistsException, KeeperException, DeserializationException {
207
208 ZKAssign.createNodeOffline(server.getZooKeeper(), hri, server.getServerName());
209 OpenRegionHandler openHandler = new OpenRegionHandler(server, rss, hri, htd);
210 rss.getRegionsInTransitionInRS().put(hri.getEncodedNameAsBytes(), Boolean.TRUE);
211 openHandler.process();
212
213 RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
214
215 ZKAssign.deleteNode(server.getZooKeeper(), hri.getEncodedName(),
216 EventType.RS_ZK_REGION_OPENED, server.getServerName());
217 }
218
219 }
220