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.master.balancer; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertNotNull; 022import static org.junit.Assert.assertTrue; 023 024import java.util.ArrayList; 025import java.util.List; 026import org.apache.hadoop.hbase.HBaseClassTestRule; 027import org.apache.hadoop.hbase.HBaseTestingUtility; 028import org.apache.hadoop.hbase.HDFSBlocksDistribution; 029import org.apache.hadoop.hbase.MiniHBaseCluster; 030import org.apache.hadoop.hbase.ServerName; 031import org.apache.hadoop.hbase.TableName; 032import org.apache.hadoop.hbase.client.RegionInfo; 033import org.apache.hadoop.hbase.client.Table; 034import org.apache.hadoop.hbase.regionserver.HRegion; 035import org.apache.hadoop.hbase.regionserver.HRegionServer; 036import org.apache.hadoop.hbase.testclassification.MasterTests; 037import org.apache.hadoop.hbase.testclassification.MediumTests; 038import org.apache.hadoop.hbase.util.Bytes; 039import org.junit.AfterClass; 040import org.junit.BeforeClass; 041import org.junit.ClassRule; 042import org.junit.Test; 043import org.junit.experimental.categories.Category; 044 045@Category({MasterTests.class, MediumTests.class}) 046public class TestRegionLocationFinder { 047 048 @ClassRule 049 public static final HBaseClassTestRule CLASS_RULE = 050 HBaseClassTestRule.forClass(TestRegionLocationFinder.class); 051 052 private final static HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility(); 053 private static MiniHBaseCluster cluster; 054 055 private final static TableName tableName = TableName.valueOf("table"); 056 private final static byte[] FAMILY = Bytes.toBytes("cf"); 057 private static Table table; 058 private final static int ServerNum = 5; 059 060 private static RegionLocationFinder finder = new RegionLocationFinder(); 061 062 @BeforeClass 063 public static void setUpBeforeClass() throws Exception { 064 cluster = TEST_UTIL.startMiniCluster(ServerNum); 065 table = TEST_UTIL.createTable(tableName, FAMILY, HBaseTestingUtility.KEYS_FOR_HBA_CREATE_TABLE); 066 TEST_UTIL.waitTableAvailable(tableName, 1000); 067 TEST_UTIL.loadTable(table, FAMILY); 068 069 for (int i = 0; i < ServerNum; i++) { 070 HRegionServer server = cluster.getRegionServer(i); 071 for (HRegion region : server.getRegions(tableName)) { 072 region.flush(true); 073 } 074 } 075 076 finder.setConf(TEST_UTIL.getConfiguration()); 077 finder.setServices(cluster.getMaster()); 078 finder.setClusterMetrics(cluster.getMaster().getClusterMetrics()); 079 } 080 081 @AfterClass 082 public static void tearDownAfterClass() throws Exception { 083 table.close(); 084 TEST_UTIL.deleteTable(tableName); 085 TEST_UTIL.shutdownMiniCluster(); 086 } 087 088 @Test 089 public void testInternalGetTopBlockLocation() throws Exception { 090 for (int i = 0; i < ServerNum; i++) { 091 HRegionServer server = cluster.getRegionServer(i); 092 for (HRegion region : server.getRegions(tableName)) { 093 // get region's hdfs block distribution by region and RegionLocationFinder, 094 // they should have same result 095 HDFSBlocksDistribution blocksDistribution1 = region.getHDFSBlocksDistribution(); 096 HDFSBlocksDistribution blocksDistribution2 = finder.getBlockDistribution(region 097 .getRegionInfo()); 098 assertEquals(blocksDistribution1.getUniqueBlocksTotalWeight(), 099 blocksDistribution2.getUniqueBlocksTotalWeight()); 100 if (blocksDistribution1.getUniqueBlocksTotalWeight() != 0) { 101 assertEquals(blocksDistribution1.getTopHosts().get(0), blocksDistribution2.getTopHosts() 102 .get(0)); 103 } 104 } 105 } 106 } 107 108 @Test 109 public void testMapHostNameToServerName() throws Exception { 110 List<String> topHosts = new ArrayList<>(); 111 for (int i = 0; i < ServerNum; i++) { 112 HRegionServer server = cluster.getRegionServer(i); 113 String serverHost = server.getServerName().getHostname(); 114 if (!topHosts.contains(serverHost)) { 115 topHosts.add(serverHost); 116 } 117 } 118 List<ServerName> servers = finder.mapHostNameToServerName(topHosts); 119 // mini cluster, all rs in one host 120 assertEquals(1, topHosts.size()); 121 for (int i = 0; i < ServerNum; i++) { 122 ServerName server = cluster.getRegionServer(i).getServerName(); 123 assertTrue(servers.contains(server)); 124 } 125 } 126 127 @Test 128 public void testGetTopBlockLocations() throws Exception { 129 for (int i = 0; i < ServerNum; i++) { 130 HRegionServer server = cluster.getRegionServer(i); 131 for (HRegion region : server.getRegions(tableName)) { 132 List<ServerName> servers = finder.getTopBlockLocations(region 133 .getRegionInfo()); 134 // test table may have empty region 135 if (region.getHDFSBlocksDistribution().getUniqueBlocksTotalWeight() == 0) { 136 continue; 137 } 138 List<String> topHosts = region.getHDFSBlocksDistribution().getTopHosts(); 139 // rs and datanode may have different host in local machine test 140 if (!topHosts.contains(server.getServerName().getHostname())) { 141 continue; 142 } 143 for (int j = 0; j < ServerNum; j++) { 144 ServerName serverName = cluster.getRegionServer(j).getServerName(); 145 assertTrue(servers.contains(serverName)); 146 } 147 } 148 } 149 } 150 151 @Test 152 public void testRefreshAndWait() throws Exception { 153 finder.getCache().invalidateAll(); 154 for (int i = 0; i < ServerNum; i++) { 155 HRegionServer server = cluster.getRegionServer(i); 156 List<HRegion> regions = server.getRegions(tableName); 157 if (regions.size() <= 0) { 158 continue; 159 } 160 List<RegionInfo> regionInfos = new ArrayList<>(regions.size()); 161 for (HRegion region : regions) { 162 regionInfos.add(region.getRegionInfo()); 163 } 164 finder.refreshAndWait(regionInfos); 165 for (RegionInfo regionInfo : regionInfos) { 166 assertNotNull(finder.getCache().getIfPresent(regionInfo)); 167 } 168 } 169 } 170}