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.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.startMiniZKCluster();
66 }
67
68 @AfterClass public static void after() throws IOException {
69 HTU.shutdownMiniZKCluster();
70 }
71
72
73
74
75
76
77 @Before
78 public void setupHRI() {
79 TEST_HRI = new HRegionInfo(TEST_HTD.getTableName(),
80 Bytes.toBytes(testIndex),
81 Bytes.toBytes(testIndex + 1));
82 testIndex++;
83 }
84
85
86
87
88
89
90
91
92 @Test public void testFailedFlushAborts()
93 throws IOException, NodeExistsException, KeeperException {
94 final Server server = new MockServer(HTU, false);
95 final RegionServerServices rss = HTU.createMockRegionServerService();
96 HTableDescriptor htd = TEST_HTD;
97 final HRegionInfo hri =
98 new HRegionInfo(htd.getTableName(), HConstants.EMPTY_END_ROW,
99 HConstants.EMPTY_END_ROW);
100 HRegion region = HTU.createLocalHRegion(hri, htd);
101 try {
102 assertNotNull(region);
103
104 HRegion spy = Mockito.spy(region);
105 final boolean abort = false;
106 Mockito.when(spy.close(abort)).
107 thenThrow(new RuntimeException("Mocked failed close!"));
108
109
110 rss.addToOnlineRegions(spy);
111
112 assertFalse(server.isStopped());
113 CloseRegionHandler handler =
114 new CloseRegionHandler(server, rss, hri, false, false, -1);
115 boolean throwable = false;
116 try {
117 handler.process();
118 } catch (Throwable t) {
119 throwable = true;
120 } finally {
121 assertTrue(throwable);
122
123 assertTrue(server.isStopped());
124 }
125 } finally {
126 HRegion.closeHRegion(region);
127 }
128 }
129
130
131
132
133
134
135
136
137 @Test public void testZKClosingNodeVersionMismatch()
138 throws IOException, NodeExistsException, KeeperException, DeserializationException {
139 final Server server = new MockServer(HTU);
140 final RegionServerServices rss = HTU.createMockRegionServerService();
141
142 HTableDescriptor htd = TEST_HTD;
143 final HRegionInfo hri = TEST_HRI;
144
145
146 OpenRegion(server, rss, htd, hri);
147
148
149
150 int versionOfClosingNode = ZKAssign.createNodeClosing(server.getZooKeeper(),
151 hri, server.getServerName());
152
153
154
155
156 CloseRegionHandler handler =
157 new CloseRegionHandler(server, rss, hri, false, true,
158 versionOfClosingNode+1);
159 handler.process();
160
161
162 RegionTransition rt =
163 RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
164 assertTrue(rt.getEventType().equals(EventType.M_ZK_REGION_CLOSING ));
165 }
166
167
168
169
170
171
172
173
174 @Test public void testCloseRegion()
175 throws IOException, NodeExistsException, KeeperException, DeserializationException {
176 final Server server = new MockServer(HTU);
177 final RegionServerServices rss = HTU.createMockRegionServerService();
178
179 HTableDescriptor htd = TEST_HTD;
180 HRegionInfo hri = TEST_HRI;
181
182
183 OpenRegion(server, rss, htd, hri);
184
185
186
187 int versionOfClosingNode = ZKAssign.createNodeClosing(server.getZooKeeper(),
188 hri, server.getServerName());
189
190
191
192
193 CloseRegionHandler handler =
194 new CloseRegionHandler(server, rss, hri, false, true,
195 versionOfClosingNode);
196 handler.process();
197
198 RegionTransition rt = RegionTransition.parseFrom(
199 ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
200 assertTrue(rt.getEventType().equals(EventType.RS_ZK_REGION_CLOSED));
201 }
202
203 private void OpenRegion(Server server, RegionServerServices rss,
204 HTableDescriptor htd, HRegionInfo hri)
205 throws IOException, NodeExistsException, KeeperException, DeserializationException {
206
207 ZKAssign.createNodeOffline(server.getZooKeeper(), hri, server.getServerName());
208 OpenRegionHandler openHandler = new OpenRegionHandler(server, rss, hri, htd);
209 rss.getRegionsInTransitionInRS().put(hri.getEncodedNameAsBytes(), Boolean.TRUE);
210 openHandler.process();
211
212 RegionTransition.parseFrom(ZKAssign.getData(server.getZooKeeper(), hri.getEncodedName()));
213
214 ZKAssign.deleteNode(server.getZooKeeper(), hri.getEncodedName(),
215 EventType.RS_ZK_REGION_OPENED, server.getServerName());
216 }
217
218 }
219