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