001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertFalse; 022import static org.junit.jupiter.api.Assertions.assertNotEquals; 023import static org.junit.jupiter.api.Assertions.assertTrue; 024 025import java.io.File; 026import java.util.List; 027import org.apache.hadoop.conf.Configuration; 028import org.apache.hadoop.fs.FileSystem; 029import org.apache.hadoop.fs.FileUtil; 030import org.apache.hadoop.fs.Path; 031import org.apache.hadoop.hbase.client.Get; 032import org.apache.hadoop.hbase.client.Put; 033import org.apache.hadoop.hbase.client.Result; 034import org.apache.hadoop.hbase.client.Table; 035import org.apache.hadoop.hbase.http.ssl.KeyStoreTestUtil; 036import org.apache.hadoop.hbase.testclassification.LargeTests; 037import org.apache.hadoop.hbase.testclassification.MiscTests; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster; 040import org.apache.hadoop.hdfs.MiniDFSCluster; 041import org.apache.hadoop.security.ssl.SSLFactory; 042import org.junit.jupiter.api.Tag; 043import org.junit.jupiter.api.Test; 044import org.junit.jupiter.api.TestInfo; 045import org.slf4j.Logger; 046import org.slf4j.LoggerFactory; 047 048/** 049 * Test our testing utility class 050 */ 051@Tag(MiscTests.TAG) 052@Tag(LargeTests.TAG) 053public class TestHBaseTestingUtil { 054 055 private static final Logger LOG = LoggerFactory.getLogger(TestHBaseTestingUtil.class); 056 057 private static final int NUMTABLES = 1; 058 private static final int NUMROWS = 100; 059 private static final int NUMREGIONS = 10; 060 061 /** 062 * Basic sanity test that spins up multiple HDFS and HBase clusters that share the same ZK 063 * ensemble. We then create the same table in both and make sure that what we insert in one place 064 * doesn't end up in the other. 065 * @throws Exception on error 066 */ 067 @Test 068 public void testMultiClusters(TestInfo testInfo) throws Exception { 069 // Create three clusters 070 071 // Cluster 1. 072 HBaseTestingUtil htu1 = new HBaseTestingUtil(); 073 // Set a different zk path for each cluster 074 htu1.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/1"); 075 htu1.startMiniZKCluster(); 076 077 // Cluster 2 078 HBaseTestingUtil htu2 = new HBaseTestingUtil(); 079 htu2.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/2"); 080 htu2.getConfiguration().set(HConstants.ZOOKEEPER_CLIENT_PORT, 081 htu1.getConfiguration().get(HConstants.ZOOKEEPER_CLIENT_PORT, "-1")); 082 htu2.setZkCluster(htu1.getZkCluster()); 083 084 // Cluster 3; seed it with the conf from htu1 so we pickup the 'right' 085 // zk cluster config; it is set back into the config. as part of the 086 // start of minizkcluster. 087 HBaseTestingUtil htu3 = new HBaseTestingUtil(); 088 htu3.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/3"); 089 htu3.getConfiguration().set(HConstants.ZOOKEEPER_CLIENT_PORT, 090 htu1.getConfiguration().get(HConstants.ZOOKEEPER_CLIENT_PORT, "-1")); 091 htu3.setZkCluster(htu1.getZkCluster()); 092 093 try { 094 htu1.startMiniCluster(); 095 htu2.startMiniCluster(); 096 htu3.startMiniCluster(); 097 098 final TableName tableName = TableName.valueOf(testInfo.getTestMethod().get().getName()); 099 final byte[] FAM_NAME = Bytes.toBytes("fam"); 100 final byte[] ROW = Bytes.toBytes("row"); 101 final byte[] QUAL_NAME = Bytes.toBytes("qual"); 102 final byte[] VALUE = Bytes.toBytes("value"); 103 104 Table table1 = htu1.createTable(tableName, FAM_NAME); 105 Table table2 = htu2.createTable(tableName, FAM_NAME); 106 107 Put put = new Put(ROW); 108 put.addColumn(FAM_NAME, QUAL_NAME, VALUE); 109 table1.put(put); 110 111 Get get = new Get(ROW); 112 get.addColumn(FAM_NAME, QUAL_NAME); 113 Result res = table1.get(get); 114 assertEquals(1, res.size()); 115 116 res = table2.get(get); 117 assertEquals(0, res.size()); 118 119 table1.close(); 120 table2.close(); 121 122 } finally { 123 htu3.shutdownMiniCluster(); 124 htu2.shutdownMiniCluster(); 125 htu1.shutdownMiniCluster(); 126 } 127 } 128 129 @Test 130 public void testMiniCluster() throws Exception { 131 HBaseTestingUtil hbt = new HBaseTestingUtil(); 132 133 SingleProcessHBaseCluster cluster = hbt.startMiniCluster(); 134 try { 135 assertEquals(1, cluster.getLiveRegionServerThreads().size()); 136 } finally { 137 hbt.shutdownMiniCluster(); 138 } 139 } 140 141 @Test 142 public void testMiniClusterBindToWildcard() throws Exception { 143 HBaseTestingUtil hbt = new HBaseTestingUtil(); 144 hbt.getConfiguration().set("hbase.regionserver.ipc.address", "0.0.0.0"); 145 SingleProcessHBaseCluster cluster = hbt.startMiniCluster(); 146 try { 147 assertEquals(1, cluster.getLiveRegionServerThreads().size()); 148 } finally { 149 hbt.shutdownMiniCluster(); 150 } 151 } 152 153 @Test 154 public void testMiniClusterWithSSLOn() throws Exception { 155 final String BASEDIR = System.getProperty("test.build.dir", "target/test-dir") + "/" 156 + TestHBaseTestingUtil.class.getSimpleName(); 157 String sslConfDir = KeyStoreTestUtil.getClasspathDir(TestHBaseTestingUtil.class); 158 String keystoresDir = new File(BASEDIR).getAbsolutePath(); 159 160 HBaseTestingUtil hbt = new HBaseTestingUtil(); 161 File base = new File(BASEDIR); 162 FileUtil.fullyDelete(base); 163 base.mkdirs(); 164 165 KeyStoreTestUtil.setupSSLConfig(keystoresDir, sslConfDir, hbt.getConfiguration(), false); 166 167 hbt.getConfiguration().set("hbase.ssl.enabled", "true"); 168 hbt.getConfiguration().addResource(hbt.getConfiguration().get(SSLFactory.SSL_CLIENT_CONF_KEY)); 169 hbt.getConfiguration().addResource(hbt.getConfiguration().get(SSLFactory.SSL_SERVER_CONF_KEY)); 170 171 SingleProcessHBaseCluster cluster = hbt.startMiniCluster(); 172 try { 173 assertEquals(1, cluster.getLiveRegionServerThreads().size()); 174 } finally { 175 hbt.shutdownMiniCluster(); 176 } 177 } 178 179 /** 180 * Test that we can start and stop multiple time a cluster with the same HBaseTestingUtility. 181 */ 182 @Test 183 public void testMultipleStartStop() throws Exception { 184 HBaseTestingUtil htu1 = new HBaseTestingUtil(); 185 Path foo = new Path("foo"); 186 187 htu1.startMiniCluster(); 188 htu1.getDFSCluster().getFileSystem().create(foo); 189 assertTrue(htu1.getDFSCluster().getFileSystem().exists(foo)); 190 htu1.shutdownMiniCluster(); 191 192 htu1.startMiniCluster(); 193 assertFalse(htu1.getDFSCluster().getFileSystem().exists(foo)); 194 htu1.getDFSCluster().getFileSystem().create(foo); 195 assertTrue(htu1.getDFSCluster().getFileSystem().exists(foo)); 196 htu1.shutdownMiniCluster(); 197 } 198 199 @Test 200 public void testMiniZooKeeperWithOneServer() throws Exception { 201 HBaseTestingUtil hbt = new HBaseTestingUtil(); 202 MiniZooKeeperCluster cluster1 = hbt.startMiniZKCluster(); 203 try { 204 assertEquals(0, cluster1.getBackupZooKeeperServerNum()); 205 assertTrue((cluster1.killCurrentActiveZooKeeperServer() == -1)); 206 } finally { 207 hbt.shutdownMiniZKCluster(); 208 } 209 } 210 211 @Test 212 public void testMiniZooKeeperWithMultipleServers() throws Exception { 213 HBaseTestingUtil hbt = new HBaseTestingUtil(); 214 // set up zookeeper cluster with 5 zk servers 215 MiniZooKeeperCluster cluster2 = hbt.startMiniZKCluster(5); 216 int defaultClientPort = 21818; 217 cluster2.setDefaultClientPort(defaultClientPort); 218 try { 219 assertEquals(4, cluster2.getBackupZooKeeperServerNum()); 220 221 // killing the current active zk server 222 int currentActivePort = cluster2.killCurrentActiveZooKeeperServer(); 223 assertTrue(currentActivePort >= defaultClientPort); 224 // Check if the client port is returning a proper value 225 assertTrue(cluster2.getClientPort() == currentActivePort); 226 227 // kill another active zk server 228 currentActivePort = cluster2.killCurrentActiveZooKeeperServer(); 229 assertTrue(currentActivePort >= defaultClientPort); 230 assertTrue(cluster2.getClientPort() == currentActivePort); 231 assertEquals(2, cluster2.getBackupZooKeeperServerNum()); 232 assertEquals(3, cluster2.getZooKeeperServerNum()); 233 234 // killing the backup zk servers 235 cluster2.killOneBackupZooKeeperServer(); 236 cluster2.killOneBackupZooKeeperServer(); 237 assertEquals(0, cluster2.getBackupZooKeeperServerNum()); 238 assertEquals(1, cluster2.getZooKeeperServerNum()); 239 240 // killing the last zk server 241 currentActivePort = cluster2.killCurrentActiveZooKeeperServer(); 242 assertTrue(currentActivePort == -1); 243 assertTrue(cluster2.getClientPort() == currentActivePort); 244 // this should do nothing. 245 cluster2.killOneBackupZooKeeperServer(); 246 assertEquals(-1, cluster2.getBackupZooKeeperServerNum()); 247 assertEquals(0, cluster2.getZooKeeperServerNum()); 248 } finally { 249 hbt.shutdownMiniZKCluster(); 250 } 251 } 252 253 @Test 254 public void testMiniZooKeeperWithMultipleClientPorts() throws Exception { 255 int defaultClientPort = 8888; 256 int i, j; 257 HBaseTestingUtil hbt = new HBaseTestingUtil(); 258 259 // Test 1 - set up zookeeper cluster with same number of ZK servers and specified client ports 260 int[] clientPortList1 = { 1111, 1112, 1113 }; 261 MiniZooKeeperCluster cluster1 = hbt.startMiniZKCluster(clientPortList1.length, clientPortList1); 262 try { 263 List<Integer> clientPortListInCluster = cluster1.getClientPortList(); 264 265 for (i = 0; i < clientPortListInCluster.size(); i++) { 266 // cannot assert the specific port due to the port conflict in which situation 267 // it always chooses a bigger port by +1. The below is the same. 268 assertTrue(clientPortListInCluster.get(i).intValue() >= clientPortList1[i]); 269 } 270 } finally { 271 hbt.shutdownMiniZKCluster(); 272 } 273 274 // Test 2 - set up zookeeper cluster with more ZK servers than specified client ports 275 hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort); 276 int[] clientPortList2 = { 2222, 2223 }; 277 MiniZooKeeperCluster cluster2 = 278 hbt.startMiniZKCluster(clientPortList2.length + 2, clientPortList2); 279 280 try { 281 List<Integer> clientPortListInCluster = cluster2.getClientPortList(); 282 283 for (i = 0, j = 0; i < clientPortListInCluster.size(); i++) { 284 if (i < clientPortList2.length) { 285 assertTrue(clientPortListInCluster.get(i).intValue() >= clientPortList2[i]); 286 } else { 287 // servers with no specified client port will use defaultClientPort or some other ports 288 // based on defaultClientPort 289 assertTrue(clientPortListInCluster.get(i).intValue() >= defaultClientPort + j); 290 j++; 291 } 292 } 293 } finally { 294 hbt.shutdownMiniZKCluster(); 295 } 296 297 // Test 3 - set up zookeeper cluster with invalid client ports 298 hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort); 299 int[] clientPortList3 = { 3333, -3334, 3335, 0 }; 300 MiniZooKeeperCluster cluster3 = 301 hbt.startMiniZKCluster(clientPortList3.length + 1, clientPortList3); 302 303 try { 304 List<Integer> clientPortListInCluster = cluster3.getClientPortList(); 305 306 for (i = 0, j = 0; i < clientPortListInCluster.size(); i++) { 307 // Servers will only use valid client ports; if ports are not specified or invalid, 308 // the default port or a port based on default port will be used. 309 if (i < clientPortList3.length && clientPortList3[i] > 0) { 310 assertTrue(clientPortListInCluster.get(i).intValue() >= clientPortList3[i]); 311 } else { 312 assertTrue(clientPortListInCluster.get(i).intValue() >= defaultClientPort + j); 313 j++; 314 } 315 } 316 } finally { 317 hbt.shutdownMiniZKCluster(); 318 } 319 320 // Test 4 - set up zookeeper cluster with default port and some other ports used 321 // This test tests that the defaultClientPort and defaultClientPort+2 are used, so 322 // the algorithm should choice defaultClientPort+1 and defaultClientPort+3 to fill 323 // out the ports for servers without ports specified. 324 hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort); 325 int[] clientPortList4 = { -4444, defaultClientPort + 2, 4446, defaultClientPort }; 326 MiniZooKeeperCluster cluster4 = 327 hbt.startMiniZKCluster(clientPortList4.length + 1, clientPortList4); 328 329 try { 330 List<Integer> clientPortListInCluster = cluster4.getClientPortList(); 331 332 for (i = 0, j = 1; i < clientPortListInCluster.size(); i++) { 333 // Servers will only use valid client ports; if ports are not specified or invalid, 334 // the default port or a port based on default port will be used. 335 if (i < clientPortList4.length && clientPortList4[i] > 0) { 336 assertTrue(clientPortListInCluster.get(i).intValue() >= clientPortList4[i]); 337 } else { 338 assertTrue(clientPortListInCluster.get(i).intValue() >= defaultClientPort + j); 339 j += 2; 340 } 341 } 342 } finally { 343 hbt.shutdownMiniZKCluster(); 344 } 345 346 // Test 5 - set up zookeeper cluster with same ports specified - fail is expected. 347 int[] clientPortList5 = { 5555, 5556, 5556 }; 348 349 try { 350 MiniZooKeeperCluster cluster5 = 351 hbt.startMiniZKCluster(clientPortList5.length, clientPortList5); 352 assertTrue(cluster5.getClientPort() == -1); // expected failure 353 } catch (Exception e) { 354 // exception is acceptable 355 } finally { 356 hbt.shutdownMiniZKCluster(); 357 } 358 } 359 360 @Test 361 public void testMiniDFSCluster() throws Exception { 362 HBaseTestingUtil hbt = new HBaseTestingUtil(); 363 MiniDFSCluster cluster = hbt.startMiniDFSCluster(null); 364 FileSystem dfs = cluster.getFileSystem(); 365 Path dir = new Path("dir"); 366 Path qualifiedDir = dfs.makeQualified(dir); 367 LOG.info("dir=" + dir + ", qualifiedDir=" + qualifiedDir); 368 assertFalse(dfs.exists(qualifiedDir)); 369 assertTrue(dfs.mkdirs(qualifiedDir)); 370 assertTrue(dfs.delete(qualifiedDir, true)); 371 hbt.shutdownMiniCluster(); 372 } 373 374 @Test 375 public void testSetupClusterTestBuildDir() throws Exception { 376 HBaseTestingUtil hbt = new HBaseTestingUtil(); 377 Path testdir = hbt.getClusterTestDir(); 378 LOG.info("uuid-subdir=" + testdir); 379 FileSystem fs = hbt.getTestFileSystem(); 380 381 assertFalse(fs.exists(testdir)); 382 383 hbt.startMiniDFSCluster(null); 384 assertTrue(fs.exists(testdir)); 385 386 hbt.shutdownMiniCluster(); 387 assertFalse(fs.exists(testdir)); 388 } 389 390 @Test 391 public void testTestDir() throws Exception { 392 HBaseTestingUtil hbt = new HBaseTestingUtil(); 393 Path testdir = hbt.getDataTestDir(); 394 LOG.info("testdir=" + testdir); 395 FileSystem fs = hbt.getTestFileSystem(); 396 assertTrue(!fs.exists(testdir)); 397 assertTrue(fs.mkdirs(testdir)); 398 assertTrue(hbt.cleanupTestDir()); 399 } 400 401 @Test 402 public void testOverridingOfDefaultPorts() throws Exception { 403 // confirm that default port properties being overridden to random 404 Configuration defaultConfig = HBaseConfiguration.create(); 405 defaultConfig.setInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT); 406 defaultConfig.setInt(HConstants.REGIONSERVER_INFO_PORT, 407 HConstants.DEFAULT_REGIONSERVER_INFOPORT); 408 HBaseTestingUtil htu = new HBaseTestingUtil(defaultConfig); 409 try { 410 SingleProcessHBaseCluster defaultCluster = htu.startMiniCluster(); 411 final String masterHostPort = 412 defaultCluster.getMaster().getServerName().getAddress().toString(); 413 assertNotEquals(HConstants.DEFAULT_MASTER_INFOPORT, 414 defaultCluster.getConfiguration().getInt(HConstants.MASTER_INFO_PORT, 0)); 415 assertNotEquals(HConstants.DEFAULT_REGIONSERVER_INFOPORT, 416 defaultCluster.getConfiguration().getInt(HConstants.REGIONSERVER_INFO_PORT, 0)); 417 assertEquals(masterHostPort, 418 defaultCluster.getConfiguration().get(HConstants.MASTER_ADDRS_KEY)); 419 } finally { 420 htu.shutdownMiniCluster(); 421 } 422 423 // confirm that nonDefault (custom) port settings are NOT overridden 424 Configuration altConfig = HBaseConfiguration.create(); 425 final int nonDefaultMasterInfoPort = 3333; 426 final int nonDefaultRegionServerPort = 4444; 427 altConfig.setInt(HConstants.MASTER_INFO_PORT, nonDefaultMasterInfoPort); 428 altConfig.setInt(HConstants.REGIONSERVER_INFO_PORT, nonDefaultRegionServerPort); 429 htu = new HBaseTestingUtil(altConfig); 430 try { 431 SingleProcessHBaseCluster customCluster = htu.startMiniCluster(); 432 final String masterHostPort = 433 customCluster.getMaster().getServerName().getAddress().toString(); 434 assertEquals(nonDefaultMasterInfoPort, 435 customCluster.getConfiguration().getInt(HConstants.MASTER_INFO_PORT, 0)); 436 assertEquals(nonDefaultRegionServerPort, 437 customCluster.getConfiguration().getInt(HConstants.REGIONSERVER_INFO_PORT, 0)); 438 assertEquals(masterHostPort, 439 customCluster.getConfiguration().get(HConstants.MASTER_ADDRS_KEY)); 440 } finally { 441 htu.shutdownMiniCluster(); 442 } 443 } 444 445 // This test demonstrates how long killHBTU takes vs. shutdownHBTU takes 446 // for realistic results, adjust NUMROWS, NUMTABLES to much larger number. 447 @Test 448 public void testKillMiniHBaseCluster(TestInfo testInfo) throws Exception { 449 HBaseTestingUtil htu = new HBaseTestingUtil(); 450 htu.startMiniZKCluster(); 451 452 try { 453 htu.startMiniHBaseCluster(); 454 455 TableName tableName; 456 byte[] FAM_NAME; 457 458 for (int i = 0; i < NUMTABLES; i++) { 459 tableName = TableName.valueOf(testInfo.getTestMethod().get().getName() + i); 460 FAM_NAME = Bytes.toBytes("fam" + i); 461 462 try (Table table = htu.createMultiRegionTable(tableName, FAM_NAME, NUMREGIONS)) { 463 htu.loadRandomRows(table, FAM_NAME, 100, NUMROWS); 464 } 465 } 466 } finally { 467 htu.killMiniHBaseCluster(); 468 htu.shutdownMiniZKCluster(); 469 } 470 } 471}