View Javadoc

1   /**
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *     http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing, software
13   * distributed under the License is distributed on an "AS IS" BASIS,
14   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15   * See the License for the specific language governing permissions and
16   * limitations under the License.
17   */
18  package org.apache.hadoop.hbase.client;
19  
20  import java.io.IOException;
21  import java.util.List;
22  import java.util.concurrent.atomic.AtomicInteger;
23  import org.apache.hadoop.conf.Configuration;
24  import org.apache.hadoop.hbase.ClusterStatus;
25  import org.apache.hadoop.hbase.HBaseConfiguration;
26  import org.apache.hadoop.hbase.HBaseTestingUtility;
27  import org.apache.hadoop.hbase.MiniHBaseCluster;
28  import org.apache.hadoop.hbase.ServerName;
29  import org.apache.hadoop.hbase.Waiter;
30  import org.apache.hadoop.hbase.Waiter.Predicate;
31  import org.apache.hadoop.hbase.coprocessor.BaseMasterObserver;
32  import org.apache.hadoop.hbase.coprocessor.CoprocessorHost;
33  import org.apache.hadoop.hbase.coprocessor.MasterCoprocessorEnvironment;
34  import org.apache.hadoop.hbase.coprocessor.ObserverContext;
35  import org.apache.hadoop.hbase.master.HMaster;
36  import org.apache.hadoop.hbase.regionserver.HRegionServer;
37  import org.apache.hadoop.hbase.testclassification.SmallTests;
38  import org.apache.hadoop.hbase.util.JVMClusterUtil.MasterThread;
39  import org.apache.hadoop.hbase.util.JVMClusterUtil.RegionServerThread;
40  import org.junit.AfterClass;
41  import org.junit.Assert;
42  import org.junit.BeforeClass;
43  import org.junit.Test;
44  import org.junit.experimental.categories.Category;
45  
46  /**
47   * Test the ClusterStatus.
48   */
49  @Category(SmallTests.class)
50  public class TestClientClusterStatus {
51    private static HBaseTestingUtility UTIL;
52    private static HBaseAdmin ADMIN;
53    private final static int SLAVES = 5;
54    private final static int MASTERS = 3;
55    private static MiniHBaseCluster CLUSTER;
56    private static HRegionServer DEAD;
57  
58    @BeforeClass
59    public static void setUpBeforeClass() throws Exception {
60      Configuration conf = HBaseConfiguration.create();
61      conf.set(CoprocessorHost.MASTER_COPROCESSOR_CONF_KEY, MyObserver.class.getName());
62      UTIL = new HBaseTestingUtility(conf);
63      UTIL.startMiniCluster(MASTERS, SLAVES);
64      CLUSTER = UTIL.getHBaseCluster();
65      CLUSTER.waitForActiveAndReadyMaster();
66      ADMIN = UTIL.getHBaseAdmin();
67      // Kill one region server
68      List<RegionServerThread> rsts = CLUSTER.getLiveRegionServerThreads();
69      RegionServerThread rst = rsts.get(rsts.size() - 1);
70      DEAD = rst.getRegionServer();
71      DEAD.stop("Test dead servers status");
72      while (rst.isAlive()) {
73        Thread.sleep(500);
74      }
75    }
76  
77    @Test
78    public void testDefaults() throws Exception {
79      ClusterStatus origin = ADMIN.getClusterStatus();
80      ClusterStatus defaults = ADMIN.getClusterStatus();
81      Assert.assertEquals(origin.getHBaseVersion(), defaults.getHBaseVersion());
82      Assert.assertEquals(origin.getClusterId(), defaults.getClusterId());
83      Assert.assertTrue(origin.getAverageLoad() == defaults.getAverageLoad());
84      Assert.assertTrue(origin.getBackupMastersSize() == defaults.getBackupMastersSize());
85      Assert.assertTrue(origin.getDeadServers() == defaults.getDeadServers());
86      Assert.assertTrue(origin.getRegionsCount() == defaults.getRegionsCount());
87      Assert.assertTrue(origin.getServersSize() == defaults.getServersSize());
88      Assert.assertTrue(origin.equals(defaults));
89    }
90  
91    @Test
92    public void testLiveAndDeadServersStatus() throws Exception {
93      // Count the number of live regionservers
94      List<RegionServerThread> regionserverThreads = CLUSTER.getLiveRegionServerThreads();
95      int numRs = 0;
96      int len = regionserverThreads.size();
97      for (int i = 0; i < len; i++) {
98        if (regionserverThreads.get(i).isAlive()) {
99          numRs++;
100       }
101     }
102     // Retrieve live servers and dead servers info.
103     // Depending on the (random) order of unit execution we may run this unit before the
104     // minicluster is fully up and recovered from the RS shutdown done during test init.
105     Waiter.waitFor(CLUSTER.getConfiguration(), 10 * 1000, 100, new Predicate<Exception>() {
106       @Override
107       public boolean evaluate() throws Exception {
108         ClusterStatus status = ADMIN.getClusterStatus();
109         Assert.assertNotNull(status);
110         return status.getRegionsCount() > 0;
111       }
112     });
113     ClusterStatus status = ADMIN.getClusterStatus();
114     Assert.assertNotNull(status);
115     Assert.assertNotNull(status.getServers());
116     // exclude a dead region server
117     Assert.assertEquals(SLAVES -1, numRs);
118     // live servers = nums of regionservers
119     // By default, HMaster don't carry any regions so it won't report its load.
120     // Hence, it won't be in the server list.
121     Assert.assertEquals(status.getServers().size(), numRs);
122     Assert.assertTrue(status.getRegionsCount() > 0);
123     Assert.assertNotNull(status.getDeadServerNames());
124     Assert.assertEquals(1, status.getDeadServers());
125     ServerName deadServerName = status.getDeadServerNames().iterator().next();
126     Assert.assertEquals(DEAD.getServerName(), deadServerName);
127   }
128 
129   @Test
130   public void testMasterAndBackupMastersStatus() throws Exception {
131     // get all the master threads
132     List<MasterThread> masterThreads = CLUSTER.getMasterThreads();
133     int numActive = 0;
134     int activeIndex = 0;
135     ServerName activeName = null;
136     HMaster active = null;
137     for (int i = 0; i < masterThreads.size(); i++) {
138       if (masterThreads.get(i).getMaster().isActiveMaster()) {
139         numActive++;
140         activeIndex = i;
141         active = masterThreads.get(activeIndex).getMaster();
142         activeName = active.getServerName();
143       }
144     }
145     Assert.assertNotNull(active);
146     Assert.assertEquals(1, numActive);
147     Assert.assertEquals(MASTERS, masterThreads.size());
148     // Retrieve master and backup masters infos only.
149     ClusterStatus status = ADMIN.getClusterStatus();
150     Assert.assertTrue(status.getMaster().equals(activeName));
151     Assert.assertEquals(MASTERS - 1, status.getBackupMastersSize());
152   }
153 
154   @Test
155   public void testOtherStatusInfos() throws Exception {
156     ClusterStatus status = ADMIN.getClusterStatus();
157     Assert.assertTrue(status.getMasterCoprocessors().length == 1);
158     Assert.assertNotNull(status.getHBaseVersion());
159     Assert.assertNotNull(status.getClusterId());
160     Assert.assertNotNull(status.getBalancerOn());
161   }
162 
163   @AfterClass
164   public static void tearDownAfterClass() throws Exception {
165     if (ADMIN != null) ADMIN.close();
166     UTIL.shutdownMiniCluster();
167   }
168 
169   @Test
170   public void testObserver() throws IOException {
171     int preCount = MyObserver.PRE_COUNT.get();
172     int postCount = MyObserver.POST_COUNT.get();
173     boolean find = false;
174     for (String s : ADMIN.getClusterStatus().getMasterCoprocessors()) {
175       if (s.equals(MyObserver.class.getSimpleName())) {
176         find = true;
177       }
178     }
179     Assert.assertTrue(find);
180     Assert.assertEquals(preCount + 1, MyObserver.PRE_COUNT.get());
181     Assert.assertEquals(postCount + 1, MyObserver.POST_COUNT.get());
182   }
183 
184   public static class MyObserver extends BaseMasterObserver {
185     private static final AtomicInteger PRE_COUNT = new AtomicInteger(0);
186     private static final AtomicInteger POST_COUNT = new AtomicInteger(0);
187 
188 
189     @Override
190     public void preGetClusterStatus(ObserverContext<MasterCoprocessorEnvironment> ctx)
191       throws IOException {
192       PRE_COUNT.incrementAndGet();
193     }
194 
195     @Override public void postGetClusterStatus(ObserverContext<MasterCoprocessorEnvironment> ctx,
196       ClusterStatus status) throws IOException {
197       POST_COUNT.incrementAndGet();
198     }
199   }
200 }