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  import static org.mockito.Matchers.any;
23  
24  import java.io.IOException;
25  import java.io.StringWriter;
26  import java.util.HashSet;
27  import java.util.List;
28  import java.util.Set;
29  import java.util.SortedSet;
30  import java.util.TreeSet;
31  import java.util.regex.Matcher;
32  import java.util.regex.Pattern;
33  
34  import org.apache.hadoop.conf.Configuration;
35  import org.apache.hadoop.hbase.*;
36  import org.apache.hadoop.hbase.client.HBaseAdmin;
37  import org.apache.hadoop.hbase.testclassification.MediumTests;
38  import org.apache.hadoop.hbase.util.Bytes;
39  import org.apache.hadoop.hbase.zookeeper.MasterAddressTracker;
40  import org.apache.hadoop.hbase.zookeeper.ZooKeeperWatcher;
41  import org.apache.hadoop.hbase.regionserver.MetricsRegionServer;
42  import org.apache.hadoop.hbase.regionserver.MetricsRegionServerWrapperStub;
43  import org.apache.hadoop.hbase.tmpl.master.AssignmentManagerStatusTmpl;
44  import org.apache.hadoop.hbase.tmpl.master.MasterStatusTmpl;
45  import org.junit.Before;
46  import org.junit.Test;
47  import org.junit.experimental.categories.Category;
48  import org.mockito.Mockito;
49  
50  import com.google.common.collect.Lists;
51  
52  /**
53   * Tests for the master status page and its template.
54   */
55  @Category(MediumTests.class)
56  public class TestMasterStatusServlet {
57  
58    private HMaster master;
59    private Configuration conf;
60    private HBaseAdmin admin;
61  
62    static final ServerName FAKE_HOST =
63        ServerName.valueOf("fakehost", 12345, 1234567890);
64    static final HTableDescriptor FAKE_TABLE =
65      new HTableDescriptor(TableName.valueOf("mytable"));
66    static final HRegionInfo FAKE_HRI =
67        new HRegionInfo(FAKE_TABLE.getTableName(),
68            Bytes.toBytes("a"), Bytes.toBytes("b"));
69  
70    @Before
71    public void setupBasicMocks() {
72      conf = HBaseConfiguration.create();
73  
74      master = Mockito.mock(HMaster.class);
75      Mockito.doReturn(FAKE_HOST).when(master).getServerName();
76      Mockito.doReturn(conf).when(master).getConfiguration();
77  
78      //Fake DeadServer
79      DeadServer deadServer = Mockito.mock(DeadServer.class);
80      // Fake serverManager
81      ServerManager serverManager = Mockito.mock(ServerManager.class);
82      Mockito.doReturn(1.0).when(serverManager).getAverageLoad();
83      Mockito.doReturn(serverManager).when(master).getServerManager();
84      Mockito.doReturn(deadServer).when(serverManager).getDeadServers();
85  
86      // Fake AssignmentManager and RIT
87      AssignmentManager am = Mockito.mock(AssignmentManager.class);
88      RegionStates rs = Mockito.mock(RegionStates.class);
89      Set<RegionState> regionsInTransition = new HashSet<RegionState>();
90      regionsInTransition.add(new RegionState(FAKE_HRI, RegionState.State.CLOSING, 12345L, FAKE_HOST));
91      Mockito.doReturn(rs).when(am).getRegionStates();
92      Mockito.doReturn(regionsInTransition).when(rs).getRegionsInTransition();
93      Mockito.doReturn(am).when(master).getAssignmentManager();
94      Mockito.doReturn(serverManager).when(master).getServerManager();
95  
96      // Fake ZKW
97      ZooKeeperWatcher zkw = Mockito.mock(ZooKeeperWatcher.class);
98      Mockito.doReturn("fakequorum").when(zkw).getQuorum();
99      Mockito.doReturn(zkw).when(master).getZooKeeper();
100 
101     // Fake MasterAddressTracker
102     MasterAddressTracker tracker = Mockito.mock(MasterAddressTracker.class);
103     Mockito.doReturn(tracker).when(master).getMasterAddressTracker();
104     Mockito.doReturn(FAKE_HOST).when(tracker).getMasterAddress();
105 
106     MetricsRegionServer rms = Mockito.mock(MetricsRegionServer.class);
107     Mockito.doReturn(new MetricsRegionServerWrapperStub()).when(rms).getRegionServerWrapper();
108     Mockito.doReturn(rms).when(master).getRegionServerMetrics();
109 
110     // Mock admin
111     admin = Mockito.mock(HBaseAdmin.class);
112   }
113 
114   private void setupMockTables() throws IOException {
115     HTableDescriptor tables[] = new HTableDescriptor[] {
116         new HTableDescriptor(TableName.valueOf("foo")),
117         new HTableDescriptor(TableName.valueOf("bar"))
118     };
119     Mockito.doReturn(tables).when(admin).listTables();
120   }
121 
122   @Test
123   public void testStatusTemplateNoTables() throws IOException {
124     new MasterStatusTmpl().render(new StringWriter(), master);
125   }
126 
127   @Test
128   public void testStatusTemplateMetaAvailable() throws IOException {
129     setupMockTables();
130 
131     new MasterStatusTmpl()
132       .setMetaLocation(ServerName.valueOf("metaserver,123,12345"))
133       .render(new StringWriter(), master);
134   }
135 
136   @Test
137   public void testStatusTemplateWithServers() throws IOException {
138     setupMockTables();
139 
140     List<ServerName> servers = Lists.newArrayList(
141         ServerName.valueOf("rootserver,123,12345"),
142         ServerName.valueOf("metaserver,123,12345"));
143     Set<ServerName> deadServers = new HashSet<ServerName>(
144         Lists.newArrayList(
145             ServerName.valueOf("badserver,123,12345"),
146             ServerName.valueOf("uglyserver,123,12345"))
147     );
148 
149     new MasterStatusTmpl()
150       .setMetaLocation(ServerName.valueOf("metaserver,123,12345"))
151       .setServers(servers)
152       .setDeadServers(deadServers)
153       .render(new StringWriter(), master);
154   }
155 
156   @Test
157   public void testAssignmentManagerTruncatedList() throws IOException {
158     AssignmentManager am = Mockito.mock(AssignmentManager.class);
159     RegionStates rs = Mockito.mock(RegionStates.class);
160 
161     // Add 100 regions as in-transition
162     SortedSet<RegionState> regionsInTransition = new TreeSet<>(RegionStates.REGION_STATE_COMPARATOR);
163     for (byte i = 0; i < 100; i++) {
164       HRegionInfo hri = new HRegionInfo(FAKE_TABLE.getTableName(),
165           new byte[]{i}, new byte[]{(byte) (i+1)});
166       regionsInTransition.add(
167         new RegionState(hri, RegionState.State.CLOSING, 12345L, FAKE_HOST));
168     }
169     // Add hbase:meta in transition as well
170     regionsInTransition.add(
171         new RegionState(HRegionInfo.FIRST_META_REGIONINFO,
172                         RegionState.State.CLOSING, 123L, FAKE_HOST));
173     Mockito.doReturn(rs).when(am).getRegionStates();
174     Mockito.doReturn(regionsInTransition).when(rs).getRegionsInTransition();
175     Mockito.doReturn(regionsInTransition).when(rs).getRegionsInTransitionOrderedByTimestamp();
176 
177     // Render to a string
178     StringWriter sw = new StringWriter();
179     new AssignmentManagerStatusTmpl()
180       .setLimit(50)
181       .render(sw, am);
182     String result = sw.toString();
183 
184     // Should always include META
185     assertTrue(result.contains(HRegionInfo.FIRST_META_REGIONINFO.getEncodedName()));
186 
187     // Make sure we only see 50 of them
188     Matcher matcher = Pattern.compile("CLOSING").matcher(result);
189     int count = 0;
190     while (matcher.find()) {
191       count++;
192     }
193     assertEquals(50, count);
194   }
195 
196 }
197