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