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.http; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertFalse; 022import static org.junit.Assert.assertNotNull; 023import static org.junit.Assert.assertNull; 024 025import java.io.IOException; 026import java.util.ArrayList; 027import java.util.Collections; 028import java.util.HashMap; 029import java.util.List; 030import java.util.Map; 031import java.util.Optional; 032import org.apache.hadoop.conf.Configuration; 033import org.apache.hadoop.hbase.HBaseClassTestRule; 034import org.apache.hadoop.hbase.HBaseConfiguration; 035import org.apache.hadoop.hbase.ServerName; 036import org.apache.hadoop.hbase.TableDescriptors; 037import org.apache.hadoop.hbase.TableName; 038import org.apache.hadoop.hbase.client.RegionInfo; 039import org.apache.hadoop.hbase.client.RegionInfoBuilder; 040import org.apache.hadoop.hbase.client.TableDescriptor; 041import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 042import org.apache.hadoop.hbase.master.DeadServer; 043import org.apache.hadoop.hbase.master.HMaster; 044import org.apache.hadoop.hbase.master.RegionState; 045import org.apache.hadoop.hbase.master.ServerManager; 046import org.apache.hadoop.hbase.master.assignment.AssignmentManager; 047import org.apache.hadoop.hbase.master.assignment.RegionStateNode; 048import org.apache.hadoop.hbase.master.assignment.RegionStates; 049import org.apache.hadoop.hbase.testclassification.MasterTests; 050import org.apache.hadoop.hbase.testclassification.SmallTests; 051import org.apache.hadoop.hbase.util.Bytes; 052import org.apache.hadoop.hbase.zookeeper.ZKWatcher; 053import org.apache.hadoop.hbase.zookeeper.ZNodePaths; 054import org.junit.Before; 055import org.junit.ClassRule; 056import org.junit.Test; 057import org.junit.experimental.categories.Category; 058import org.mockito.Mockito; 059 060@Category({ MasterTests.class, SmallTests.class }) 061public class TestMasterStatusUtil { 062 063 @ClassRule 064 public static final HBaseClassTestRule CLASS_RULE = 065 HBaseClassTestRule.forClass(TestMasterStatusUtil.class); 066 067 private HMaster master; 068 private Configuration conf; 069 070 static final ServerName FAKE_HOST = ServerName.valueOf("fakehost", 12345, 1234567890); 071 static final TableDescriptor FAKE_TABLE = 072 TableDescriptorBuilder.newBuilder(TableName.valueOf("mytable")).build(); 073 074 static final RegionInfo FAKE_HRI = RegionInfoBuilder.newBuilder(FAKE_TABLE.getTableName()) 075 .setStartKey(Bytes.toBytes("a")).setEndKey(Bytes.toBytes("b")).build(); 076 077 @Before 078 public void setupBasicMocks() { 079 conf = HBaseConfiguration.create(); 080 081 master = Mockito.mock(HMaster.class); 082 Mockito.doReturn(FAKE_HOST).when(master).getServerName(); 083 Mockito.doReturn(conf).when(master).getConfiguration(); 084 Mockito.doReturn(true).when(master).isInitialized(); 085 086 // Fake DeadServer 087 DeadServer deadServer = Mockito.mock(DeadServer.class); 088 // Fake serverManager 089 ServerManager serverManager = Mockito.mock(ServerManager.class); 090 Mockito.doReturn(1.0).when(serverManager).getAverageLoad(); 091 Mockito.doReturn(serverManager).when(master).getServerManager(); 092 Mockito.doReturn(deadServer).when(serverManager).getDeadServers(); 093 094 // Fake AssignmentManager and RIT 095 AssignmentManager am = Mockito.mock(AssignmentManager.class); 096 RegionStates rs = Mockito.mock(RegionStates.class); 097 List<RegionState> regionsInTransition = new ArrayList<>(); 098 regionsInTransition 099 .add(new RegionState(FAKE_HRI, RegionState.State.CLOSING, 12345L, FAKE_HOST)); 100 Mockito.doReturn(rs).when(am).getRegionStates(); 101 Mockito.doReturn(regionsInTransition).when(am).getRegionsInTransition(); 102 Mockito.doReturn(am).when(master).getAssignmentManager(); 103 Mockito.doReturn(serverManager).when(master).getServerManager(); 104 105 // Fake ZKW 106 ZKWatcher zkw = Mockito.mock(ZKWatcher.class); 107 Mockito.doReturn(new ZNodePaths(conf)).when(zkw).getZNodePaths(); 108 Mockito.doReturn("fakequorum").when(zkw).getQuorum(); 109 Mockito.doReturn(zkw).when(master).getZooKeeper(); 110 111 // Fake ActiveMaster 112 Mockito.doReturn(Optional.of(FAKE_HOST)).when(master).getActiveMaster(); 113 } 114 115 @Test 116 public void testGetUserTables() throws IOException { 117 Map<String, TableDescriptor> mockTables = new HashMap<>(); 118 mockTables.put("foo", TableDescriptorBuilder.newBuilder(TableName.valueOf("foo")).build()); 119 mockTables.put("bar", TableDescriptorBuilder.newBuilder(TableName.valueOf("bar")).build()); 120 121 TableDescriptors tableDescriptors = Mockito.mock(TableDescriptors.class); 122 Mockito.doReturn(tableDescriptors).when(master).getTableDescriptors(); 123 124 Mockito.doReturn(mockTables).when(tableDescriptors).getAll(); 125 126 List<TableDescriptor> tables = new ArrayList<>(); 127 128 String errorMessage = MasterStatusUtil.getUserTables(master, tables); 129 130 assertNull(errorMessage); 131 assertEquals(2, tables.size()); 132 } 133 134 @Test 135 public void testGetUserTablesFilterOutSystemTables() throws IOException { 136 Map<String, TableDescriptor> mockTables = new HashMap<>(); 137 mockTables.put("foo", TableDescriptorBuilder.newBuilder(TableName.valueOf("foo")).build()); 138 mockTables.put("bar", TableDescriptorBuilder.newBuilder(TableName.valueOf("bar")).build()); 139 mockTables.put("meta", 140 TableDescriptorBuilder.newBuilder(TableName.valueOf("hbase", "meta")).build()); 141 142 TableDescriptors tableDescriptors = Mockito.mock(TableDescriptors.class); 143 Mockito.doReturn(tableDescriptors).when(master).getTableDescriptors(); 144 145 Mockito.doReturn(mockTables).when(tableDescriptors).getAll(); 146 147 List<TableDescriptor> tables = new ArrayList<>(); 148 149 String errorMessage = MasterStatusUtil.getUserTables(master, tables); 150 151 assertNull(errorMessage); 152 assertEquals(2, tables.size()); 153 } 154 155 @Test 156 public void testGetUserTablesNoUserTables() throws IOException { 157 Map<Object, Object> emptyMap = Collections.emptyMap(); 158 159 TableDescriptors tableDescriptors = Mockito.mock(TableDescriptors.class); 160 Mockito.doReturn(tableDescriptors).when(master).getTableDescriptors(); 161 162 Mockito.doReturn(emptyMap).when(tableDescriptors).getAll(); 163 164 List<TableDescriptor> tables = new ArrayList<>(); 165 166 String errorMessage = MasterStatusUtil.getUserTables(master, tables); 167 168 assertNull(errorMessage); 169 assertEquals(0, tables.size()); 170 } 171 172 @Test 173 public void testGetUserTablesMasterNotInitialized() { 174 Mockito.doReturn(false).when(master).isInitialized(); 175 176 List<TableDescriptor> tables = new ArrayList<>(); 177 178 String errorMessage = MasterStatusUtil.getUserTables(master, tables); 179 180 assertNull(errorMessage); 181 assertEquals(0, tables.size()); 182 } 183 184 @Test 185 public void testGetUserTablesException() throws IOException { 186 TableDescriptors tableDescriptors = Mockito.mock(TableDescriptors.class); 187 Mockito.doReturn(tableDescriptors).when(master).getTableDescriptors(); 188 189 Mockito.doThrow(new IOException("some error")).when(tableDescriptors).getAll(); 190 191 List<TableDescriptor> tables = new ArrayList<>(); 192 String errorMessage = MasterStatusUtil.getUserTables(master, tables); 193 assertEquals("Got user tables error, some error", errorMessage); 194 } 195 196 @Test 197 public void testGetFragmentationInfoTurnedOff() throws IOException { 198 conf.setBoolean("hbase.master.ui.fragmentation.enabled", false); 199 assertNull(MasterStatusUtil.getFragmentationInfo(master, conf)); 200 } 201 202 @Test 203 public void testGetFragmentationInfoTurnedOn() throws IOException { 204 conf.setBoolean("hbase.master.ui.fragmentation.enabled", true); 205 Map<String, Integer> fragmentationInfo = MasterStatusUtil.getFragmentationInfo(master, conf); 206 assertNotNull(fragmentationInfo); 207 assertFalse(fragmentationInfo.isEmpty()); 208 } 209 210 @Test 211 public void testGetMetaLocationOrNull() { 212 mockMetaLocation(true); 213 214 ServerName location = MasterStatusUtil.getMetaLocationOrNull(master); 215 assertNotNull(location); 216 assertEquals(FAKE_HOST, location); 217 } 218 219 @Test 220 public void testGetMetaLocationOrNullNotOpen() { 221 mockMetaLocation(false); 222 223 ServerName location = MasterStatusUtil.getMetaLocationOrNull(master); 224 assertNull(location); 225 } 226 227 private void mockMetaLocation(boolean isOpen) { 228 RegionStates rs = master.getAssignmentManager().getRegionStates(); 229 RegionStateNode rsn = Mockito.mock(RegionStateNode.class); 230 Mockito.doReturn(rsn).when(rs).getRegionStateNode(RegionInfoBuilder.FIRST_META_REGIONINFO); 231 Mockito.doReturn(isOpen).when(rsn).isInState(RegionState.State.OPEN); 232 if (isOpen) { 233 Mockito.doReturn(FAKE_HOST).when(rsn).getRegionLocation(); 234 } 235 } 236 237 @Test 238 public void testServerNameLink() { 239 Mockito.doReturn(16030).when(master).getRegionServerInfoPort(FAKE_HOST); 240 241 String link = MasterStatusUtil.serverNameLink(master, FAKE_HOST); 242 243 assertNotNull(link); 244 assertEquals("<a href=\"//fakehost:16030/regionserver.jsp\">fakehost,12345,1234567890</a>", 245 link); 246 } 247 248 @Test 249 public void testServerNameLinkNoInfoPort() { 250 Mockito.doReturn(-1).when(master).getRegionServerInfoPort(FAKE_HOST); 251 252 String link = MasterStatusUtil.serverNameLink(master, FAKE_HOST); 253 254 assertNotNull(link); 255 assertEquals("fakehost,12345,1234567890", link); 256 } 257}