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