View Javadoc

1   /**
2    *
3    * Licensed to the Apache Software Foundation (ASF) under one
4    * or more contributor license agreements.  See the NOTICE file
5    * distributed with this work for additional information
6    * regarding copyright ownership.  The ASF licenses this file
7    * to you under the Apache License, Version 2.0 (the
8    * "License"); you may not use this file except in compliance
9    * with the License.  You may obtain a copy of the License at
10   *
11   *     http://www.apache.org/licenses/LICENSE-2.0
12   *
13   * Unless required by applicable law or agreed to in writing, software
14   * distributed under the License is distributed on an "AS IS" BASIS,
15   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16   * See the License for the specific language governing permissions and
17   * limitations under the License.
18   */
19  package org.apache.hadoop.hbase.master;
20  
21  import static org.junit.Assert.*;
22  
23  import java.io.IOException;
24  import java.io.StringWriter;
25  import java.util.HashSet;
26  import java.util.List;
27  import java.util.NavigableMap;
28  import java.util.Set;
29  import java.util.regex.Matcher;
30  import java.util.regex.Pattern;
31  
32  import org.apache.hadoop.conf.Configuration;
33  import org.apache.hadoop.hbase.*;
34  import org.apache.hadoop.hbase.client.HBaseAdmin;
35  import org.apache.hadoop.hbase.testclassification.MediumTests;
36  import org.apache.hadoop.hbase.util.Bytes;
37  import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker;
38  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
39  import org.apache.hadoop.hbase.regionserver.MetricsRegionServer;
40  import org.apache.hadoop.hbase.regionserver.MetricsRegionServerWrapperStub;
41  import org.apache.hadoop.hbase.tmpl.master.AssignmentManagerStatusTmpl;
42  import org.apache.hadoop.hbase.tmpl.master.MasterStatusTmpl;
43  import org.junit.Before;
44  import org.junit.Test;
45  import org.junit.experimental.categories.Category;
46  import org.mockito.Mockito;
47  
48  import com.google.common.collect.Lists;
49  import com.google.common.collect.Maps;
50  
51  /**
52   * Tests for the master status page and its template.
53   */
54  @Category(MediumTests.class)
55  public class TestMasterStatusServlet {
56  
57    private HMaster master;
58    private Configuration conf;
59    private HBaseAdmin admin;
60  
61    static final ServerName FAKE_HOST =
62        ServerName.valueOf("fakehost", 12345, 1234567890);
63    static final HTableDescriptor FAKE_TABLE =
64      new HTableDescriptor(TableName.valueOf("mytable"));
65    static final HRegionInfo FAKE_HRI =
66        new HRegionInfo(FAKE_TABLE.getTableName(),
67            Bytes.toBytes("a"), Bytes.toBytes("b"));
68  
69    @Before
70    public void setupBasicMocks() {
71      conf = HBaseConfiguration.create();
72  
73      master = Mockito.mock(HMaster.class);
74      Mockito.doReturn(FAKE_HOST).when(master).getServerName();
75      Mockito.doReturn(conf).when(master).getConfiguration();
76  
77      //Fake DeadServer
78      DeadServer deadServer = Mockito.mock(DeadServer.class);
79      // Fake serverManager
80      ServerManager serverManager = Mockito.mock(ServerManager.class);
81      Mockito.doReturn(1.0).when(serverManager).getAverageLoad();
82      Mockito.doReturn(serverManager).when(master).getServerManager();
83      Mockito.doReturn(deadServer).when(serverManager).getDeadServers();
84  
85      // Fake AssignmentManager and RIT
86      AssignmentManager am = Mockito.mock(AssignmentManager.class);
87      RegionStates rs = Mockito.mock(RegionStates.class);
88      NavigableMap<String, RegionState> regionsInTransition =
89        Maps.newTreeMap();
90      regionsInTransition.put("r1",
91        new RegionState(FAKE_HRI, RegionState.State.CLOSING, 12345L, FAKE_HOST));
92      Mockito.doReturn(rs).when(am).getRegionStates();
93      Mockito.doReturn(regionsInTransition).when(rs).getRegionsInTransition();
94      Mockito.doReturn(am).when(master).getAssignmentManager();
95      Mockito.doReturn(serverManager).when(master).getServerManager();
96  
97      // Fake ZKW
98      ZooKeeperWatcher zkw = Mockito.mock(ZooKeeperWatcher.class);
99      Mockito.doReturn("fakequorum").when(zkw).getQuorum();
100     Mockito.doReturn(zkw).when(master).getZooKeeper();
101 
102     // Fake MasterAddressTracker
103     MasterAddressTracker tracker = Mockito.mock(MasterAddressTracker.class);
104     Mockito.doReturn(tracker).when(master).getMasterAddressTracker();
105     Mockito.doReturn(FAKE_HOST).when(tracker).getMasterAddress();
106 
107     MetricsRegionServer rms = Mockito.mock(MetricsRegionServer.class);
108     Mockito.doReturn(new MetricsRegionServerWrapperStub()).when(rms).getRegionServerWrapper();
109     Mockito.doReturn(rms).when(master).getRegionServerMetrics();
110 
111     // Mock admin
112     admin = Mockito.mock(HBaseAdmin.class);
113   }
114 
115   private void setupMockTables() throws IOException {
116     HTableDescriptor tables[] = new HTableDescriptor[] {
117         new HTableDescriptor(TableName.valueOf("foo")),
118         new HTableDescriptor(TableName.valueOf("bar"))
119     };
120     Mockito.doReturn(tables).when(admin).listTables();
121   }
122 
123   @Test
124   public void testStatusTemplateNoTables() throws IOException {
125     new MasterStatusTmpl().render(new StringWriter(), master);
126   }
127 
128   @Test
129   public void testStatusTemplateMetaAvailable() throws IOException {
130     setupMockTables();
131 
132     new MasterStatusTmpl()
133       .setMetaLocation(ServerName.valueOf("metaserver,123,12345"))
134       .render(new StringWriter(), master);
135   }
136 
137   @Test
138   public void testStatusTemplateWithServers() throws IOException {
139     setupMockTables();
140 
141     List<ServerName> servers = Lists.newArrayList(
142         ServerName.valueOf("rootserver,123,12345"),
143         ServerName.valueOf("metaserver,123,12345"));
144     Set<ServerName> deadServers = new HashSet<ServerName>(
145         Lists.newArrayList(
146             ServerName.valueOf("badserver,123,12345"),
147             ServerName.valueOf("uglyserver,123,12345"))
148     );
149 
150     new MasterStatusTmpl()
151       .setMetaLocation(ServerName.valueOf("metaserver,123,12345"))
152       .setServers(servers)
153       .setDeadServers(deadServers)
154       .render(new StringWriter(), master);
155   }
156 
157   @Test
158   public void testAssignmentManagerTruncatedList() throws IOException {
159     AssignmentManager am = Mockito.mock(AssignmentManager.class);
160     RegionStates rs = Mockito.mock(RegionStates.class);
161 
162     // Add 100 regions as in-transition
163     NavigableMap<String, RegionState> regionsInTransition =
164       Maps.newTreeMap();
165     for (byte i = 0; i < 100; i++) {
166       HRegionInfo hri = new HRegionInfo(FAKE_TABLE.getTableName(),
167           new byte[]{i}, new byte[]{(byte) (i+1)});
168       regionsInTransition.put(hri.getEncodedName(),
169         new RegionState(hri, RegionState.State.CLOSING, 12345L, FAKE_HOST));
170     }
171     // Add hbase:meta in transition as well
172     regionsInTransition.put(
173         HRegionInfo.FIRST_META_REGIONINFO.getEncodedName(),
174         new RegionState(HRegionInfo.FIRST_META_REGIONINFO,
175                         RegionState.State.CLOSING, 12345L, FAKE_HOST));
176     Mockito.doReturn(rs).when(am).getRegionStates();
177     Mockito.doReturn(regionsInTransition).when(rs).getRegionsInTransition();
178 
179     // Render to a string
180     StringWriter sw = new StringWriter();
181     new AssignmentManagerStatusTmpl()
182       .setLimit(50)
183       .render(sw, am);
184     String result = sw.toString();
185 
186     // Should always include META
187     assertTrue(result.contains(HRegionInfo.FIRST_META_REGIONINFO.getEncodedName()));
188 
189     // Make sure we only see 50 of them
190     Matcher matcher = Pattern.compile("CLOSING").matcher(result);
191     int count = 0;
192     while (matcher.find()) {
193       count++;
194     }
195     assertEquals(50, count);
196   }
197 
198 }
199