HBASE-24033 Add ut for loading the corrupt recovered hfiles (#1322)
[hbase.git] / hbase-server / src / test / java / org / apache / hadoop / hbase / TestHBaseTestingUtility.java
blob993af2187237c071ed044f73928b51d6c88de10b
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;
20 import static org.junit.Assert.assertEquals;
21 import static org.junit.Assert.assertFalse;
22 import static org.junit.Assert.assertNotEquals;
23 import static org.junit.Assert.assertTrue;
24 import static org.mockito.ArgumentMatchers.anyInt;
25 import static org.mockito.Mockito.mock;
26 import static org.mockito.Mockito.when;
27 import java.io.File;
28 import java.util.List;
29 import java.util.Random;
30 import org.apache.hadoop.conf.Configuration;
31 import org.apache.hadoop.fs.FileSystem;
32 import org.apache.hadoop.fs.FileUtil;
33 import org.apache.hadoop.fs.Path;
34 import org.apache.hadoop.hbase.client.Get;
35 import org.apache.hadoop.hbase.client.Put;
36 import org.apache.hadoop.hbase.client.Result;
37 import org.apache.hadoop.hbase.client.Table;
38 import org.apache.hadoop.hbase.http.ssl.KeyStoreTestUtil;
39 import org.apache.hadoop.hbase.testclassification.LargeTests;
40 import org.apache.hadoop.hbase.testclassification.MiscTests;
41 import org.apache.hadoop.hbase.util.Bytes;
42 import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
43 import org.apache.hadoop.hdfs.MiniDFSCluster;
44 import org.apache.hadoop.security.ssl.SSLFactory;
45 import org.junit.ClassRule;
46 import org.junit.Rule;
47 import org.junit.Test;
48 import org.junit.experimental.categories.Category;
49 import org.junit.rules.TestName;
50 import org.mockito.Mockito;
51 import org.mockito.invocation.InvocationOnMock;
52 import org.mockito.stubbing.Answer;
53 import org.slf4j.Logger;
54 import org.slf4j.LoggerFactory;
56 /**
57 * Test our testing utility class
59 @Category({MiscTests.class, LargeTests.class})
60 public class TestHBaseTestingUtility {
61 private static final int NUMTABLES = 1;
62 private static final int NUMROWS = 100;
63 private static final int NUMREGIONS = 10;
65 @ClassRule
66 public static final HBaseClassTestRule CLASS_RULE =
67 HBaseClassTestRule.forClass(TestHBaseTestingUtility.class);
69 private static final Logger LOG = LoggerFactory.getLogger(TestHBaseTestingUtility.class);
71 @Rule
72 public TestName name = new TestName();
74 /**
75 * Basic sanity test that spins up multiple HDFS and HBase clusters that share
76 * the same ZK ensemble. We then create the same table in both and make sure
77 * that what we insert in one place doesn't end up in the other.
78 * @throws Exception on error
80 @Test
81 public void testMultiClusters() throws Exception {
82 // Create three clusters
84 // Cluster 1.
85 HBaseTestingUtility htu1 = new HBaseTestingUtility();
86 // Set a different zk path for each cluster
87 htu1.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/1");
88 htu1.startMiniZKCluster();
90 // Cluster 2
91 HBaseTestingUtility htu2 = new HBaseTestingUtility();
92 htu2.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/2");
93 htu2.getConfiguration().set(HConstants.ZOOKEEPER_CLIENT_PORT,
94 htu1.getConfiguration().get(HConstants.ZOOKEEPER_CLIENT_PORT, "-1"));
95 htu2.setZkCluster(htu1.getZkCluster());
97 // Cluster 3; seed it with the conf from htu1 so we pickup the 'right'
98 // zk cluster config; it is set back into the config. as part of the
99 // start of minizkcluster.
100 HBaseTestingUtility htu3 = new HBaseTestingUtility();
101 htu3.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/3");
102 htu3.getConfiguration().set(HConstants.ZOOKEEPER_CLIENT_PORT,
103 htu1.getConfiguration().get(HConstants.ZOOKEEPER_CLIENT_PORT, "-1"));
104 htu3.setZkCluster(htu1.getZkCluster());
106 try {
107 htu1.startMiniCluster();
108 htu2.startMiniCluster();
109 htu3.startMiniCluster();
111 final TableName tableName = TableName.valueOf(name.getMethodName());
112 final byte[] FAM_NAME = Bytes.toBytes("fam");
113 final byte[] ROW = Bytes.toBytes("row");
114 final byte[] QUAL_NAME = Bytes.toBytes("qual");
115 final byte[] VALUE = Bytes.toBytes("value");
117 Table table1 = htu1.createTable(tableName, FAM_NAME);
118 Table table2 = htu2.createTable(tableName, FAM_NAME);
120 Put put = new Put(ROW);
121 put.addColumn(FAM_NAME, QUAL_NAME, VALUE);
122 table1.put(put);
124 Get get = new Get(ROW);
125 get.addColumn(FAM_NAME, QUAL_NAME);
126 Result res = table1.get(get);
127 assertEquals(1, res.size());
129 res = table2.get(get);
130 assertEquals(0, res.size());
132 table1.close();
133 table2.close();
135 } finally {
136 htu3.shutdownMiniCluster();
137 htu2.shutdownMiniCluster();
138 htu1.shutdownMiniCluster();
142 @Test public void testMiniCluster() throws Exception {
143 HBaseTestingUtility hbt = new HBaseTestingUtility();
145 MiniHBaseCluster cluster = hbt.startMiniCluster();
146 try {
147 assertEquals(1, cluster.getLiveRegionServerThreads().size());
148 } finally {
149 hbt.shutdownMiniCluster();
153 @Test
154 public void testMiniClusterBindToWildcard() throws Exception {
155 HBaseTestingUtility hbt = new HBaseTestingUtility();
156 hbt.getConfiguration().set("hbase.regionserver.ipc.address", "0.0.0.0");
157 MiniHBaseCluster cluster = hbt.startMiniCluster();
158 try {
159 assertEquals(1, cluster.getLiveRegionServerThreads().size());
160 } finally {
161 hbt.shutdownMiniCluster();
165 @Test
166 public void testMiniClusterWithSSLOn() throws Exception {
167 final String BASEDIR = System.getProperty("test.build.dir",
168 "target/test-dir") + "/" + TestHBaseTestingUtility.class.getSimpleName();
169 String sslConfDir = KeyStoreTestUtil.getClasspathDir(TestHBaseTestingUtility.class);
170 String keystoresDir = new File(BASEDIR).getAbsolutePath();
172 HBaseTestingUtility hbt = new HBaseTestingUtility();
173 File base = new File(BASEDIR);
174 FileUtil.fullyDelete(base);
175 base.mkdirs();
177 KeyStoreTestUtil.setupSSLConfig(keystoresDir, sslConfDir, hbt.getConfiguration(), false);
179 hbt.getConfiguration().set("hbase.ssl.enabled", "true");
180 hbt.getConfiguration().addResource(hbt.getConfiguration().get(SSLFactory.SSL_CLIENT_CONF_KEY));
181 hbt.getConfiguration().addResource(hbt.getConfiguration().get(SSLFactory.SSL_SERVER_CONF_KEY));
183 MiniHBaseCluster cluster = hbt.startMiniCluster();
184 try {
185 assertEquals(1, cluster.getLiveRegionServerThreads().size());
186 } finally {
187 hbt.shutdownMiniCluster();
192 * Test that we can start and stop multiple time a cluster
193 * with the same HBaseTestingUtility.
195 @Test public void testMultipleStartStop() throws Exception{
196 HBaseTestingUtility htu1 = new HBaseTestingUtility();
197 Path foo = new Path("foo");
199 htu1.startMiniCluster();
200 htu1.getDFSCluster().getFileSystem().create(foo);
201 assertTrue(htu1.getDFSCluster().getFileSystem().exists(foo));
202 htu1.shutdownMiniCluster();
204 htu1.startMiniCluster();
205 assertFalse(htu1.getDFSCluster().getFileSystem().exists(foo));
206 htu1.getDFSCluster().getFileSystem().create(foo);
207 assertTrue(htu1.getDFSCluster().getFileSystem().exists(foo));
208 htu1.shutdownMiniCluster();
211 @Test
212 public void testMiniZooKeeperWithOneServer() throws Exception {
213 HBaseTestingUtility hbt = new HBaseTestingUtility();
214 MiniZooKeeperCluster cluster1 = hbt.startMiniZKCluster();
215 try {
216 assertEquals(0, cluster1.getBackupZooKeeperServerNum());
217 assertTrue((cluster1.killCurrentActiveZooKeeperServer() == -1));
218 } finally {
219 hbt.shutdownMiniZKCluster();
223 @Test
224 public void testMiniZooKeeperWithMultipleServers() throws Exception {
225 HBaseTestingUtility hbt = new HBaseTestingUtility();
226 // set up zookeeper cluster with 5 zk servers
227 MiniZooKeeperCluster cluster2 = hbt.startMiniZKCluster(5);
228 int defaultClientPort = 21818;
229 cluster2.setDefaultClientPort(defaultClientPort);
230 try {
231 assertEquals(4, cluster2.getBackupZooKeeperServerNum());
233 // killing the current active zk server
234 int currentActivePort = cluster2.killCurrentActiveZooKeeperServer();
235 assertTrue(currentActivePort >= defaultClientPort);
236 // Check if the client port is returning a proper value
237 assertTrue(cluster2.getClientPort() == currentActivePort);
239 // kill another active zk server
240 currentActivePort = cluster2.killCurrentActiveZooKeeperServer();
241 assertTrue(currentActivePort >= defaultClientPort);
242 assertTrue(cluster2.getClientPort() == currentActivePort);
243 assertEquals(2, cluster2.getBackupZooKeeperServerNum());
244 assertEquals(3, cluster2.getZooKeeperServerNum());
246 // killing the backup zk servers
247 cluster2.killOneBackupZooKeeperServer();
248 cluster2.killOneBackupZooKeeperServer();
249 assertEquals(0, cluster2.getBackupZooKeeperServerNum());
250 assertEquals(1, cluster2.getZooKeeperServerNum());
252 // killing the last zk server
253 currentActivePort = cluster2.killCurrentActiveZooKeeperServer();
254 assertTrue(currentActivePort == -1);
255 assertTrue(cluster2.getClientPort() == currentActivePort);
256 // this should do nothing.
257 cluster2.killOneBackupZooKeeperServer();
258 assertEquals(-1, cluster2.getBackupZooKeeperServerNum());
259 assertEquals(0, cluster2.getZooKeeperServerNum());
260 } finally {
261 hbt.shutdownMiniZKCluster();
265 @Test
266 public void testMiniZooKeeperWithMultipleClientPorts() throws Exception {
267 int defaultClientPort = 8888;
268 int i, j;
269 HBaseTestingUtility hbt = new HBaseTestingUtility();
271 // Test 1 - set up zookeeper cluster with same number of ZK servers and specified client ports
272 int [] clientPortList1 = {1111, 1112, 1113};
273 MiniZooKeeperCluster cluster1 = hbt.startMiniZKCluster(clientPortList1.length, clientPortList1);
274 try {
275 List<Integer> clientPortListInCluster = cluster1.getClientPortList();
277 for (i = 0; i < clientPortListInCluster.size(); i++) {
278 // cannot assert the specific port due to the port conflict in which situation
279 // it always chooses a bigger port by +1. The below is the same.
280 assertTrue(clientPortListInCluster.get(i).intValue() >= clientPortList1[i]);
282 } finally {
283 hbt.shutdownMiniZKCluster();
286 // Test 2 - set up zookeeper cluster with more ZK servers than specified client ports
287 hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort);
288 int [] clientPortList2 = {2222, 2223};
289 MiniZooKeeperCluster cluster2 =
290 hbt.startMiniZKCluster(clientPortList2.length + 2, clientPortList2);
292 try {
293 List<Integer> clientPortListInCluster = cluster2.getClientPortList();
295 for (i = 0, j = 0; i < clientPortListInCluster.size(); i++) {
296 if (i < clientPortList2.length) {
297 assertTrue(clientPortListInCluster.get(i).intValue() >= clientPortList2[i]);
298 } else {
299 // servers with no specified client port will use defaultClientPort or some other ports
300 // based on defaultClientPort
301 assertTrue(clientPortListInCluster.get(i).intValue() >= defaultClientPort + j);
302 j++;
305 } finally {
306 hbt.shutdownMiniZKCluster();
309 // Test 3 - set up zookeeper cluster with invalid client ports
310 hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort);
311 int [] clientPortList3 = {3333, -3334, 3335, 0};
312 MiniZooKeeperCluster cluster3 =
313 hbt.startMiniZKCluster(clientPortList3.length + 1, clientPortList3);
315 try {
316 List<Integer> clientPortListInCluster = cluster3.getClientPortList();
318 for (i = 0, j = 0; i < clientPortListInCluster.size(); i++) {
319 // Servers will only use valid client ports; if ports are not specified or invalid,
320 // the default port or a port based on default port will be used.
321 if (i < clientPortList3.length && clientPortList3[i] > 0) {
322 assertTrue(clientPortListInCluster.get(i).intValue() >= clientPortList3[i]);
323 } else {
324 assertTrue(clientPortListInCluster.get(i).intValue() >= defaultClientPort + j);
325 j++;
328 } finally {
329 hbt.shutdownMiniZKCluster();
332 // Test 4 - set up zookeeper cluster with default port and some other ports used
333 // This test tests that the defaultClientPort and defaultClientPort+2 are used, so
334 // the algorithm should choice defaultClientPort+1 and defaultClientPort+3 to fill
335 // out the ports for servers without ports specified.
336 hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort);
337 int [] clientPortList4 = {-4444, defaultClientPort+2, 4446, defaultClientPort};
338 MiniZooKeeperCluster cluster4 =
339 hbt.startMiniZKCluster(clientPortList4.length + 1, clientPortList4);
341 try {
342 List<Integer> clientPortListInCluster = cluster4.getClientPortList();
344 for (i = 0, j = 1; i < clientPortListInCluster.size(); i++) {
345 // Servers will only use valid client ports; if ports are not specified or invalid,
346 // the default port or a port based on default port will be used.
347 if (i < clientPortList4.length && clientPortList4[i] > 0) {
348 assertTrue(clientPortListInCluster.get(i).intValue() >= clientPortList4[i]);
349 } else {
350 assertTrue(clientPortListInCluster.get(i).intValue() >= defaultClientPort + j);
351 j +=2;
354 } finally {
355 hbt.shutdownMiniZKCluster();
358 // Test 5 - set up zookeeper cluster with same ports specified - fail is expected.
359 int [] clientPortList5 = {5555, 5556, 5556};
361 try {
362 MiniZooKeeperCluster cluster5 =
363 hbt.startMiniZKCluster(clientPortList5.length, clientPortList5);
364 assertTrue(cluster5.getClientPort() == -1); // expected failure
365 } catch (Exception e) {
366 // exception is acceptable
367 } finally {
368 hbt.shutdownMiniZKCluster();
372 @Test public void testMiniDFSCluster() throws Exception {
373 HBaseTestingUtility hbt = new HBaseTestingUtility();
374 MiniDFSCluster cluster = hbt.startMiniDFSCluster(null);
375 FileSystem dfs = cluster.getFileSystem();
376 Path dir = new Path("dir");
377 Path qualifiedDir = dfs.makeQualified(dir);
378 LOG.info("dir=" + dir + ", qualifiedDir=" + qualifiedDir);
379 assertFalse(dfs.exists(qualifiedDir));
380 assertTrue(dfs.mkdirs(qualifiedDir));
381 assertTrue(dfs.delete(qualifiedDir, true));
382 hbt.shutdownMiniCluster();
385 @Test public void testSetupClusterTestBuildDir() throws Exception {
386 HBaseTestingUtility hbt = new HBaseTestingUtility();
387 Path testdir = hbt.getClusterTestDir();
388 LOG.info("uuid-subdir=" + testdir);
389 FileSystem fs = hbt.getTestFileSystem();
391 assertFalse(fs.exists(testdir));
393 hbt.startMiniDFSCluster(null);
394 assertTrue(fs.exists(testdir));
396 hbt.shutdownMiniCluster();
397 assertFalse(fs.exists(testdir));
400 @Test public void testTestDir() throws Exception {
401 HBaseTestingUtility hbt = new HBaseTestingUtility();
402 Path testdir = hbt.getDataTestDir();
403 LOG.info("testdir=" + testdir);
404 FileSystem fs = hbt.getTestFileSystem();
405 assertTrue(!fs.exists(testdir));
406 assertTrue(fs.mkdirs(testdir));
407 assertTrue(hbt.cleanupTestDir());
410 @Test public void testResolvePortConflict() throws Exception {
411 // raises port conflict between 1st call and 2nd call of randomPort() by mocking Random object
412 Random random = mock(Random.class);
413 when(random.nextInt(anyInt()))
414 .thenAnswer(new Answer<Integer>() {
415 int[] numbers = { 1, 1, 2 };
416 int count = 0;
418 @Override
419 public Integer answer(InvocationOnMock invocation) {
420 int ret = numbers[count];
421 count++;
422 return ret;
426 HBaseTestingUtility.PortAllocator.AvailablePortChecker portChecker =
427 mock(HBaseTestingUtility.PortAllocator.AvailablePortChecker.class);
428 when(portChecker.available(anyInt())).thenReturn(true);
430 HBaseTestingUtility.PortAllocator portAllocator =
431 new HBaseTestingUtility.PortAllocator(random, portChecker);
433 int port1 = portAllocator.randomFreePort();
434 int port2 = portAllocator.randomFreePort();
435 assertNotEquals(port1, port2);
436 Mockito.verify(random, Mockito.times(3)).nextInt(anyInt());
439 @Test
440 public void testOverridingOfDefaultPorts() throws Exception {
442 // confirm that default port properties being overridden to random
443 Configuration defaultConfig = HBaseConfiguration.create();
444 defaultConfig.setInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT);
445 defaultConfig.setInt(HConstants.REGIONSERVER_INFO_PORT,
446 HConstants.DEFAULT_REGIONSERVER_INFOPORT);
447 HBaseTestingUtility htu = new HBaseTestingUtility(defaultConfig);
448 try {
449 MiniHBaseCluster defaultCluster = htu.startMiniCluster();
450 final String masterHostPort =
451 defaultCluster.getMaster().getServerName().getAddress().toString();
452 assertNotEquals(HConstants.DEFAULT_MASTER_INFOPORT,
453 defaultCluster.getConfiguration().getInt(HConstants.MASTER_INFO_PORT, 0));
454 assertNotEquals(HConstants.DEFAULT_REGIONSERVER_INFOPORT,
455 defaultCluster.getConfiguration().getInt(HConstants.REGIONSERVER_INFO_PORT, 0));
456 assertEquals(masterHostPort,
457 defaultCluster.getConfiguration().get(HConstants.MASTER_ADDRS_KEY));
458 } finally {
459 htu.shutdownMiniCluster();
462 // confirm that nonDefault (custom) port settings are NOT overridden
463 Configuration altConfig = HBaseConfiguration.create();
464 final int nonDefaultMasterInfoPort = 3333;
465 final int nonDefaultRegionServerPort = 4444;
466 altConfig.setInt(HConstants.MASTER_INFO_PORT, nonDefaultMasterInfoPort);
467 altConfig.setInt(HConstants.REGIONSERVER_INFO_PORT, nonDefaultRegionServerPort);
468 htu = new HBaseTestingUtility(altConfig);
469 try {
470 MiniHBaseCluster customCluster = htu.startMiniCluster();
471 final String masterHostPort =
472 customCluster.getMaster().getServerName().getAddress().toString();
473 assertEquals(nonDefaultMasterInfoPort,
474 customCluster.getConfiguration().getInt(HConstants.MASTER_INFO_PORT, 0));
475 assertEquals(nonDefaultRegionServerPort,
476 customCluster.getConfiguration().getInt(HConstants.REGIONSERVER_INFO_PORT, 0));
477 assertEquals(masterHostPort,
478 customCluster.getConfiguration().get(HConstants.MASTER_ADDRS_KEY));
479 } finally {
480 htu.shutdownMiniCluster();
484 // This test demonstrates how long killHBTU takes vs. shutdownHBTU takes
485 // for realistic results, adjust NUMROWS, NUMTABLES to much larger number.
486 @Test
487 public void testKillMiniHBaseCluster() throws Exception {
489 HBaseTestingUtility htu = new HBaseTestingUtility();
490 htu.startMiniZKCluster();
492 try {
493 htu.startMiniHBaseCluster();
495 TableName tableName;
496 byte[] FAM_NAME;
498 for(int i = 0; i < NUMTABLES; i++) {
499 tableName = TableName.valueOf(name.getMethodName() + i);
500 FAM_NAME = Bytes.toBytes("fam" + i);
502 try (Table table = htu.createMultiRegionTable(tableName, FAM_NAME, NUMREGIONS)) {
503 htu.loadRandomRows(table, FAM_NAME, 100, NUMROWS);
506 } finally {
507 htu.killMiniHBaseCluster();
508 htu.shutdownMiniZKCluster();