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.assertTrue; 022import static org.junit.Assert.fail; 023 024import java.net.BindException; 025import org.apache.commons.lang3.exception.ExceptionUtils; 026import org.apache.hadoop.hbase.testclassification.MediumTests; 027import org.junit.ClassRule; 028import org.junit.Test; 029import org.junit.experimental.categories.Category; 030import org.slf4j.Logger; 031import org.slf4j.LoggerFactory; 032 033@Category(MediumTests.class) 034public class TestClusterPortAssignment { 035 @ClassRule 036 public static final HBaseClassTestRule CLASS_RULE = 037 HBaseClassTestRule.forClass(TestClusterPortAssignment.class); 038 039 private static final HBaseTestingUtil TEST_UTIL = new HBaseTestingUtil(); 040 private static final Logger LOG = LoggerFactory.getLogger(TestClusterPortAssignment.class); 041 042 /** 043 * Check that we can start an HBase cluster specifying a custom set of RPC and infoserver ports. 044 */ 045 @Test(timeout = 300000) 046 public void testClusterPortAssignment() throws Exception { 047 boolean retry = false; 048 do { 049 int masterPort = HBaseTestingUtil.randomFreePort(); 050 int masterInfoPort = HBaseTestingUtil.randomFreePort(); 051 int rsPort = HBaseTestingUtil.randomFreePort(); 052 int rsInfoPort = HBaseTestingUtil.randomFreePort(); 053 TEST_UTIL.getConfiguration().setBoolean(LocalHBaseCluster.ASSIGN_RANDOM_PORTS, false); 054 TEST_UTIL.getConfiguration().setBoolean(HConstants.REGIONSERVER_INFO_PORT_AUTO, false); 055 TEST_UTIL.getConfiguration().setBoolean("fs.hdfs.impl.disable.cache", true); 056 TEST_UTIL.getConfiguration().setInt(HConstants.MASTER_PORT, masterPort); 057 TEST_UTIL.getConfiguration().setInt(HConstants.MASTER_INFO_PORT, masterInfoPort); 058 TEST_UTIL.getConfiguration().setInt(HConstants.REGIONSERVER_PORT, rsPort); 059 TEST_UTIL.getConfiguration().setInt(HConstants.REGIONSERVER_INFO_PORT, rsInfoPort); 060 LOG.info("Ports: {}, {}, {}, {}", masterPort, masterInfoPort, rsPort, rsInfoPort); 061 try { 062 SingleProcessHBaseCluster cluster = TEST_UTIL.startMiniCluster(); 063 assertTrue("Cluster failed to come up", cluster.waitForActiveAndReadyMaster(30000)); 064 retry = false; 065 assertEquals("Master RPC port is incorrect", masterPort, 066 cluster.getMaster().getRpcServer().getListenerAddress().getPort()); 067 assertEquals("Master info port is incorrect", masterInfoPort, 068 cluster.getMaster().getInfoServer().getPort()); 069 assertEquals("RS RPC port is incorrect", rsPort, 070 cluster.getRegionServer(0).getRpcServer().getListenerAddress().getPort()); 071 assertEquals("RS info port is incorrect", rsInfoPort, 072 cluster.getRegionServer(0).getInfoServer().getPort()); 073 } catch (Exception e) { 074 Throwable rootCause = ExceptionUtils.getRootCause(e); 075 if (rootCause instanceof BindException) { 076 LOG.info("Failed bind, need to retry", e); 077 retry = true; 078 } else { 079 LOG.error("Failed to start mini cluster", e); 080 retry = false; 081 fail("Failed to start mini cluster with assigned ports."); 082 } 083 } finally { 084 TEST_UTIL.shutdownMiniCluster(); 085 } 086 } while (retry); 087 } 088}