HBASE-26567 Remove IndexType from ChunkCreator (#3947)
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / regionserver / TestRegionServerNoMaster.java
blobf97aa49f9a24776b205f695c8406894cf01673e2
1 /**
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
10 * http://www.apache.org/licenses/LICENSE-2.0
12 * Unless required by applicable law or agreed to in writing, software
13 * distributed under the License is distributed on an "AS IS" BASIS,
14 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15 * See the License for the specific language governing permissions and
16 * limitations under the License.
18 package org.apache.hadoop.hbase.regionserver;
20 import java.io.IOException;
21 import org.apache.hadoop.hbase.HBaseClassTestRule;
22 import org.apache.hadoop.hbase.HBaseTestingUtil;
23 import org.apache.hadoop.hbase.HConstants;
24 import org.apache.hadoop.hbase.NotServingRegionException;
25 import org.apache.hadoop.hbase.ServerName;
26 import org.apache.hadoop.hbase.TableName;
27 import org.apache.hadoop.hbase.client.Put;
28 import org.apache.hadoop.hbase.client.RegionInfo;
29 import org.apache.hadoop.hbase.client.RegionLocator;
30 import org.apache.hadoop.hbase.client.Table;
31 import org.apache.hadoop.hbase.client.TableDescriptor;
32 import org.apache.hadoop.hbase.master.HMaster;
33 import org.apache.hadoop.hbase.regionserver.handler.OpenRegionHandler;
34 import org.apache.hadoop.hbase.testclassification.MediumTests;
35 import org.apache.hadoop.hbase.testclassification.RegionServerTests;
36 import org.apache.hadoop.hbase.util.Bytes;
37 import org.apache.hadoop.hbase.util.JVMClusterUtil;
38 import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
39 import org.apache.hadoop.hbase.util.Threads;
40 import org.junit.AfterClass;
41 import org.junit.Assert;
42 import org.junit.BeforeClass;
43 import org.junit.ClassRule;
44 import org.junit.Test;
45 import org.junit.experimental.categories.Category;
46 import org.slf4j.Logger;
47 import org.slf4j.LoggerFactory;
49 import org.apache.hadoop.hbase.shaded.protobuf.ProtobufUtil;
50 import org.apache.hadoop.hbase.shaded.protobuf.RequestConverter;
51 import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos;
52 import org.apache.hadoop.hbase.shaded.protobuf.generated.AdminProtos.CloseRegionRequest;
54 /**
55 * Tests on the region server, without the master.
57 @Category({RegionServerTests.class, MediumTests.class})
58 public class TestRegionServerNoMaster {
60 @ClassRule
61 public static final HBaseClassTestRule CLASS_RULE =
62 HBaseClassTestRule.forClass(TestRegionServerNoMaster.class);
64 private static final Logger LOG = LoggerFactory.getLogger(TestRegionServerNoMaster.class);
65 private static final int NB_SERVERS = 1;
66 private static Table table;
67 private static final byte[] row = Bytes.toBytes("ee");
69 private static RegionInfo hri;
71 private static byte[] regionName;
72 private static final HBaseTestingUtil HTU = new HBaseTestingUtil();
75 @BeforeClass
76 public static void before() throws Exception {
77 HTU.startMiniCluster(NB_SERVERS);
78 final TableName tableName = TableName.valueOf(TestRegionServerNoMaster.class.getSimpleName());
80 // Create table then get the single region for our new table.
81 table = HTU.createTable(tableName,HConstants.CATALOG_FAMILY);
82 Put p = new Put(row);
83 p.addColumn(HConstants.CATALOG_FAMILY, row, row);
84 table.put(p);
86 try (RegionLocator locator = HTU.getConnection().getRegionLocator(tableName)) {
87 hri = locator.getRegionLocation(row, false).getRegion();
89 regionName = hri.getRegionName();
91 stopMasterAndCacheMetaLocation(HTU);
94 public static void stopMasterAndCacheMetaLocation(HBaseTestingUtil HTU)
95 throws IOException, InterruptedException {
96 // cache meta location, so we will not go to master to lookup meta region location
97 for (JVMClusterUtil.RegionServerThread t : HTU.getMiniHBaseCluster().getRegionServerThreads()) {
98 try (RegionLocator locator =
99 t.getRegionServer().getConnection().getRegionLocator(TableName.META_TABLE_NAME)) {
100 locator.getAllRegionLocations();
103 try (RegionLocator locator = HTU.getConnection().getRegionLocator(TableName.META_TABLE_NAME)) {
104 locator.getAllRegionLocations();
106 // Stop master
107 HMaster master = HTU.getHBaseCluster().getMaster();
108 Thread masterThread = HTU.getHBaseCluster().getMasterThread();
109 master.stopMaster();
111 LOG.info("Waiting until master thread exits");
112 while (masterThread != null && masterThread.isAlive()) {
113 Threads.sleep(100);
116 HRegionServer.TEST_SKIP_REPORTING_TRANSITION = true;
119 /** Flush the given region in the mini cluster. Since no master, we cannot use HBaseAdmin.flush() */
120 public static void flushRegion(HBaseTestingUtil HTU, RegionInfo regionInfo)
121 throws IOException {
122 for (RegionServerThread rst : HTU.getMiniHBaseCluster().getRegionServerThreads()) {
123 HRegion region = rst.getRegionServer().getRegionByEncodedName(regionInfo.getEncodedName());
124 if (region != null) {
125 region.flush(true);
126 return;
129 throw new IOException("Region to flush cannot be found");
132 @AfterClass
133 public static void afterClass() throws Exception {
134 HRegionServer.TEST_SKIP_REPORTING_TRANSITION = false;
135 if (table != null) {
136 table.close();
138 HTU.shutdownMiniCluster();
141 private static HRegionServer getRS() {
142 return HTU.getHBaseCluster().getLiveRegionServerThreads().get(0).getRegionServer();
146 public static void openRegion(HBaseTestingUtil HTU, HRegionServer rs, RegionInfo hri)
147 throws Exception {
148 AdminProtos.OpenRegionRequest orr =
149 RequestConverter.buildOpenRegionRequest(rs.getServerName(), hri, null);
150 AdminProtos.OpenRegionResponse responseOpen = rs.getRpcServices().openRegion(null, orr);
152 Assert.assertTrue(responseOpen.getOpeningStateCount() == 1);
153 Assert.assertTrue(responseOpen.getOpeningState(0).
154 equals(AdminProtos.OpenRegionResponse.RegionOpeningState.OPENED));
157 checkRegionIsOpened(HTU, rs, hri);
160 public static void checkRegionIsOpened(HBaseTestingUtil HTU, HRegionServer rs,
161 RegionInfo hri) throws Exception {
162 while (!rs.getRegionsInTransitionInRS().isEmpty()) {
163 Thread.sleep(1);
166 Assert.assertTrue(rs.getRegion(hri.getRegionName()).isAvailable());
169 public static void closeRegion(HBaseTestingUtil HTU, HRegionServer rs, RegionInfo hri)
170 throws Exception {
171 AdminProtos.CloseRegionRequest crr = ProtobufUtil.buildCloseRegionRequest(
172 rs.getServerName(), hri.getRegionName());
173 AdminProtos.CloseRegionResponse responseClose = rs.getRpcServices().closeRegion(null, crr);
174 Assert.assertTrue(responseClose.getClosed());
175 checkRegionIsClosed(HTU, rs, hri);
178 public static void checkRegionIsClosed(HBaseTestingUtil HTU, HRegionServer rs,
179 RegionInfo hri) throws Exception {
180 while (!rs.getRegionsInTransitionInRS().isEmpty()) {
181 Thread.sleep(1);
184 try {
185 Assert.assertFalse(rs.getRegion(hri.getRegionName()).isAvailable());
186 } catch (NotServingRegionException expected) {
187 // That's how it work: if the region is closed we have an exception.
192 * Close the region without using ZK
194 private void closeRegionNoZK() throws Exception {
195 // no transition in ZK
196 AdminProtos.CloseRegionRequest crr =
197 ProtobufUtil.buildCloseRegionRequest(getRS().getServerName(), regionName);
198 AdminProtos.CloseRegionResponse responseClose = getRS().getRpcServices().closeRegion(null, crr);
199 Assert.assertTrue(responseClose.getClosed());
201 // now waiting & checking. After a while, the transition should be done and the region closed
202 checkRegionIsClosed(HTU, getRS(), hri);
206 @Test
207 public void testCloseByRegionServer() throws Exception {
208 closeRegionNoZK();
209 openRegion(HTU, getRS(), hri);
212 @Test
213 public void testMultipleCloseFromMaster() throws Exception {
214 for (int i = 0; i < 10; i++) {
215 AdminProtos.CloseRegionRequest crr =
216 ProtobufUtil.buildCloseRegionRequest(getRS().getServerName(), regionName, null);
217 try {
218 AdminProtos.CloseRegionResponse responseClose =
219 getRS().getRpcServices().closeRegion(null, crr);
220 Assert.assertTrue("request " + i + " failed",
221 responseClose.getClosed() || responseClose.hasClosed());
222 } catch (org.apache.hbase.thirdparty.com.google.protobuf.ServiceException se) {
223 Assert.assertTrue("The next queries may throw an exception.", i > 0);
227 checkRegionIsClosed(HTU, getRS(), hri);
229 openRegion(HTU, getRS(), hri);
233 * Test that if we do a close while opening it stops the opening.
235 @Test
236 public void testCancelOpeningWithoutZK() throws Exception {
237 // We close
238 closeRegionNoZK();
239 checkRegionIsClosed(HTU, getRS(), hri);
241 // Let do the initial steps, without having a handler
242 getRS().getRegionsInTransitionInRS().put(hri.getEncodedNameAsBytes(), Boolean.TRUE);
244 // That's a close without ZK.
245 AdminProtos.CloseRegionRequest crr =
246 ProtobufUtil.buildCloseRegionRequest(getRS().getServerName(), regionName);
247 try {
248 getRS().getRpcServices().closeRegion(null, crr);
249 Assert.assertTrue(false);
250 } catch (org.apache.hbase.thirdparty.com.google.protobuf.ServiceException expected) {
253 // The state in RIT should have changed to close
254 Assert.assertEquals(Boolean.FALSE, getRS().getRegionsInTransitionInRS().get(
255 hri.getEncodedNameAsBytes()));
257 // Let's start the open handler
258 TableDescriptor htd = getRS().getTableDescriptors().get(hri.getTable());
260 getRS().getExecutorService().submit(new OpenRegionHandler(getRS(), getRS(), hri, htd, -1));
262 // The open handler should have removed the region from RIT but kept the region closed
263 checkRegionIsClosed(HTU, getRS(), hri);
265 openRegion(HTU, getRS(), hri);
269 * Tests an on-the-fly RPC that was scheduled for the earlier RS on the same port
270 * for openRegion. The region server should reject this RPC. (HBASE-9721)
272 @Test
273 public void testOpenCloseRegionRPCIntendedForPreviousServer() throws Exception {
274 Assert.assertTrue(getRS().getRegion(regionName).isAvailable());
276 ServerName sn = getRS().getServerName();
277 ServerName earlierServerName = ServerName.valueOf(sn.getHostname(), sn.getPort(), 1);
279 try {
280 CloseRegionRequest request = ProtobufUtil.buildCloseRegionRequest(earlierServerName, regionName);
281 getRS().getRSRpcServices().closeRegion(null, request);
282 Assert.fail("The closeRegion should have been rejected");
283 } catch (org.apache.hbase.thirdparty.com.google.protobuf.ServiceException se) {
284 Assert.assertTrue(se.getCause() instanceof IOException);
285 Assert.assertTrue(se.getCause().getMessage().contains("This RPC was intended for a different server"));
288 //actual close
289 closeRegionNoZK();
290 try {
291 AdminProtos.OpenRegionRequest orr = RequestConverter.buildOpenRegionRequest(
292 earlierServerName, hri, null);
293 getRS().getRSRpcServices().openRegion(null, orr);
294 Assert.fail("The openRegion should have been rejected");
295 } catch (org.apache.hbase.thirdparty.com.google.protobuf.ServiceException se) {
296 Assert.assertTrue(se.getCause() instanceof IOException);
297 Assert.assertTrue(se.getCause().getMessage().contains("This RPC was intended for a different server"));
298 } finally {
299 openRegion(HTU, getRS(), hri);