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
;
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
;
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;
66 public static final HBaseClassTestRule CLASS_RULE
=
67 HBaseClassTestRule
.forClass(TestHBaseTestingUtility
.class);
69 private static final Logger LOG
= LoggerFactory
.getLogger(TestHBaseTestingUtility
.class);
72 public TestName name
= new TestName();
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
81 public void testMultiClusters() throws Exception
{
82 // Create three clusters
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();
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());
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
);
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());
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();
147 assertEquals(1, cluster
.getLiveRegionServerThreads().size());
149 hbt
.shutdownMiniCluster();
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();
159 assertEquals(1, cluster
.getLiveRegionServerThreads().size());
161 hbt
.shutdownMiniCluster();
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
);
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();
185 assertEquals(1, cluster
.getLiveRegionServerThreads().size());
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();
212 public void testMiniZooKeeperWithOneServer() throws Exception
{
213 HBaseTestingUtility hbt
= new HBaseTestingUtility();
214 MiniZooKeeperCluster cluster1
= hbt
.startMiniZKCluster();
216 assertEquals(0, cluster1
.getBackupZooKeeperServerNum());
217 assertTrue((cluster1
.killCurrentActiveZooKeeperServer() == -1));
219 hbt
.shutdownMiniZKCluster();
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
);
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());
261 hbt
.shutdownMiniZKCluster();
266 public void testMiniZooKeeperWithMultipleClientPorts() throws Exception
{
267 int defaultClientPort
= 8888;
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
);
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
]);
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
);
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
]);
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
);
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
);
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
]);
324 assertTrue(clientPortListInCluster
.get(i
).intValue() >= defaultClientPort
+ j
);
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
);
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
]);
350 assertTrue(clientPortListInCluster
.get(i
).intValue() >= defaultClientPort
+ j
);
355 hbt
.shutdownMiniZKCluster();
358 // Test 5 - set up zookeeper cluster with same ports specified - fail is expected.
359 int [] clientPortList5
= {5555, 5556, 5556};
362 MiniZooKeeperCluster cluster5
=
363 hbt
.startMiniZKCluster(clientPortList5
.length
, clientPortList5
);
364 assertTrue(cluster5
.getClientPort() == -1); // expected failure
365 } catch (Exception e
) {
366 // exception is acceptable
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 };
419 public Integer
answer(InvocationOnMock invocation
) {
420 int ret
= numbers
[count
];
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());
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
);
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
));
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
);
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
));
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.
487 public void testKillMiniHBaseCluster() throws Exception
{
489 HBaseTestingUtility htu
= new HBaseTestingUtility();
490 htu
.startMiniZKCluster();
493 htu
.startMiniHBaseCluster();
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
);
507 htu
.killMiniHBaseCluster();
508 htu
.shutdownMiniZKCluster();