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 org.apache.hadoop.hbase.ClusterStatus;
22  import org.apache.hadoop.hbase.HBaseTestingUtility;
23  import org.apache.hadoop.hbase.LargeTests;
24  import org.apache.hadoop.hbase.MasterNotRunningException;
25  import org.apache.hadoop.hbase.MiniHBaseCluster;
26  import org.apache.hadoop.hbase.util.JVMClusterUtil;
27  import org.junit.Test;
28  import org.junit.experimental.categories.Category;
29  
30  import java.io.IOException;
31  import java.util.List;
32  
33  import static org.junit.Assert.assertFalse;
34  import static org.junit.Assert.assertTrue;
35  
36  @Category(LargeTests.class)
37  public class TestMasterFailoverBalancerPersistence {
38  
39    /**
40     * Test that if the master fails, the load balancer maintains its
41     * state (running or not) when the next master takes over
42     *
43     * @throws Exception
44     */
45    @Test(timeout = 240000)
46    public void testMasterFailoverBalancerPersistence() throws Exception {
47      final int NUM_MASTERS = 3;
48      final int NUM_RS = 1;
49  
50      // Start the cluster
51      HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
52  
53      TEST_UTIL.startMiniCluster(NUM_MASTERS, NUM_RS);
54      MiniHBaseCluster cluster = TEST_UTIL.getHBaseCluster();
55  
56      assertTrue(cluster.waitForActiveAndReadyMaster());
57      HMaster active = cluster.getMaster();
58      // check that the balancer is on by default for the active master
59      ClusterStatus clusterStatus = active.getClusterStatus();
60      assertTrue(clusterStatus.isBalancerOn());
61  
62      active = killActiveAndWaitForNewActive(cluster);
63  
64      // ensure the load balancer is still running on new master
65      clusterStatus = active.getClusterStatus();
66      assertTrue(clusterStatus.isBalancerOn());
67  
68      // turn off the load balancer
69      active.balanceSwitch(false);
70  
71      // once more, kill active master and wait for new active master to show up
72      active = killActiveAndWaitForNewActive(cluster);
73  
74      // ensure the load balancer is not running on the new master
75      clusterStatus = active.getClusterStatus();
76      assertFalse(clusterStatus.isBalancerOn());
77  
78      // Stop the cluster
79      TEST_UTIL.shutdownMiniCluster();
80    }
81  
82    /**
83     * Kill the master and wait for a new active master to show up
84     *
85     * @param cluster
86     * @return the new active master
87     * @throws InterruptedException
88     * @throws java.io.IOException
89     */
90    private HMaster killActiveAndWaitForNewActive(MiniHBaseCluster cluster)
91        throws InterruptedException, IOException {
92      int activeIndex = getActiveMasterIndex(cluster);
93      HMaster active = cluster.getMaster();
94      cluster.stopMaster(activeIndex);
95      cluster.waitOnMaster(activeIndex);
96      assertTrue(cluster.waitForActiveAndReadyMaster());
97      // double check this is actually a new master
98      HMaster newActive = cluster.getMaster();
99      assertFalse(active == newActive);
100     return newActive;
101   }
102 
103   /**
104    * return the index of the active master in the cluster
105    *
106    * @throws org.apache.hadoop.hbase.MasterNotRunningException
107    *          if no active master found
108    */
109   private int getActiveMasterIndex(MiniHBaseCluster cluster) throws MasterNotRunningException {
110     // get all the master threads
111     List<JVMClusterUtil.MasterThread> masterThreads = cluster.getMasterThreads();
112 
113     for (int i = 0; i < masterThreads.size(); i++) {
114       if (masterThreads.get(i).getMaster().isActiveMaster()) {
115         return i;
116       }
117     }
118     throw new MasterNotRunningException();
119   }
120 
121 }