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.regionserver.http; 019 020import static org.junit.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022 023import java.io.IOException; 024import java.net.URL; 025import java.util.List; 026import org.apache.hadoop.conf.Configuration; 027import org.apache.hadoop.fs.Path; 028import org.apache.hadoop.hbase.HBaseTestingUtil; 029import org.apache.hadoop.hbase.HConstants; 030import org.apache.hadoop.hbase.LocalHBaseCluster; 031import org.apache.hadoop.hbase.ServerName; 032import org.apache.hadoop.hbase.TableName; 033import org.apache.hadoop.hbase.client.ColumnFamilyDescriptor; 034import org.apache.hadoop.hbase.client.ColumnFamilyDescriptorBuilder; 035import org.apache.hadoop.hbase.client.TableDescriptor; 036import org.apache.hadoop.hbase.client.TableDescriptorBuilder; 037import org.apache.hadoop.hbase.master.HMaster; 038import org.apache.hadoop.hbase.master.ServerManager; 039import org.apache.hadoop.hbase.testclassification.MediumTests; 040import org.apache.hadoop.hbase.testclassification.RegionServerTests; 041import org.apache.hadoop.hbase.util.CommonFSUtils; 042import org.apache.hadoop.hbase.util.TestServerHttpUtils; 043import org.junit.jupiter.api.AfterAll; 044import org.junit.jupiter.api.BeforeAll; 045import org.junit.jupiter.api.BeforeEach; 046import org.junit.jupiter.api.Tag; 047import org.junit.jupiter.api.Test; 048import org.junit.jupiter.api.TestInfo; 049 050/** 051 * Tests for the region server status page and its template. 052 */ 053@Tag(RegionServerTests.TAG) 054@Tag(MediumTests.TAG) 055public class TestRSStatusPage { 056 057 private static LocalHBaseCluster CLUSTER; 058 059 private final static HBaseTestingUtil UTIL = new HBaseTestingUtil(); 060 public static final String TEST_TABLE_NAME_1 = "TEST_TABLE_1"; 061 public static final String TEST_TABLE_NAME_2 = "TEST_TABLE_2"; 062 063 private String name; 064 065 @BeforeEach 066 public void initTestName(TestInfo testInfo) { 067 name = testInfo.getTestMethod().get().getName(); 068 } 069 070 @BeforeAll 071 public static void beforeClass() throws Exception { 072 Configuration conf = UTIL.getConfiguration(); 073 UTIL.startMiniZKCluster(); 074 075 UTIL.startMiniDFSCluster(1); 076 Path rootdir = UTIL.getDataTestDirOnTestFS("TestRSStatusPage"); 077 CommonFSUtils.setRootDir(conf, rootdir); 078 079 // The info servers do not run in tests by default. 080 // Set them to ephemeral ports so they will start 081 // setup configuration 082 conf.setInt(HConstants.MASTER_INFO_PORT, 0); 083 conf.setInt(HConstants.REGIONSERVER_INFO_PORT, 0); 084 085 CLUSTER = new LocalHBaseCluster(conf, 1); 086 CLUSTER.startup(); 087 CLUSTER.getActiveMaster().waitForMetaOnline(); 088 } 089 090 /** 091 * Helper method to shut down the cluster (if running) 092 */ 093 @AfterAll 094 public static void shutDownMiniCluster() throws Exception { 095 if (CLUSTER != null) { 096 CLUSTER.shutdown(); 097 CLUSTER.join(); 098 } 099 UTIL.shutdownMiniCluster(); 100 } 101 102 @Test 103 public void testStatusPage() throws Exception { 104 HMaster master = CLUSTER.getActiveMaster(); 105 106 int masterPort = master.getActiveMasterManager().getActiveMasterInfoPort(); 107 ServerName activeMaster = 108 master.getActiveMaster().orElseThrow(() -> new IllegalStateException("No active master")); 109 String masterHostname = activeMaster.getHostname(); 110 111 createTestTables(master); 112 113 ServerManager serverManager = master.getServerManager(); 114 List<ServerName> onlineServersList = serverManager.getOnlineServersList(); 115 116 assertEquals(1, onlineServersList.size()); 117 118 ServerName firstServerName = onlineServersList.get(0); 119 int infoPort = master.getRegionServerInfoPort(firstServerName); 120 String hostname = firstServerName.getHostname(); 121 int port = firstServerName.getPort(); 122 123 URL url = new URL("http://" + hostname + ":" + infoPort + "/regionserver.jsp"); 124 String page = TestServerHttpUtils.getPageContent(url, "text/html;charset=utf-8"); 125 126 assertTrue(page.contains("<title>HBase Region Server: " + masterHostname + "</title>")); 127 128 String expectedPageHeader = "<h1>RegionServer <small>" + hostname + "," + port + "," 129 + firstServerName.getStartCode() + "</small></h1>"; 130 assertTrue(page.contains(expectedPageHeader)); 131 assertTrue(page.contains("<h2>Server Metrics</h2>")); 132 assertTrue(page.contains("<th>Requests Per Second</th>")); 133 assertTrue(page.contains("<h2>Block Cache</h2>")); 134 assertTrue(page.contains("<h2>Regions</h2>")); 135 assertTrue(page.contains("<h2>Replication Status</h2>")); 136 assertTrue(page.contains("<h2>Software Attributes</h2>")); 137 138 // Should have a link to master 139 String expectedMasterLink = "<a href=\"//" + masterHostname + ":" + masterPort 140 + "/master.jsp\">" + masterHostname + ":" + masterPort + "</a>"; 141 assertTrue(page.contains(expectedMasterLink)); 142 } 143 144 private static void createTestTables(HMaster master) throws IOException { 145 ColumnFamilyDescriptor cf = ColumnFamilyDescriptorBuilder.of("CF"); 146 TableDescriptor tableDescriptor1 = TableDescriptorBuilder 147 .newBuilder(TableName.valueOf(TEST_TABLE_NAME_1)).setColumnFamily(cf).build(); 148 master.createTable(tableDescriptor1, null, 0, 0); 149 TableDescriptor tableDescriptor2 = TableDescriptorBuilder 150 .newBuilder(TableName.valueOf(TEST_TABLE_NAME_2)).setColumnFamily(cf).build(); 151 master.createTable(tableDescriptor2, null, 0, 0); 152 master.flushMasterStore(); 153 } 154}