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;
19  
20  import static org.junit.Assert.fail;
21  
22  import java.io.IOException;
23  
24  import org.apache.hadoop.conf.Configuration;
25  import org.apache.hadoop.hbase.client.HTable;
26  import org.apache.hadoop.hbase.client.ResultScanner;
27  import org.apache.hadoop.hbase.client.Scan;
28  import org.apache.hadoop.hbase.master.HMaster;
29  import org.apache.hadoop.hbase.regionserver.HRegionServer;
30  import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
31  import org.apache.zookeeper.KeeperException;
32  import org.junit.Test;
33  import org.junit.experimental.categories.Category;
34  
35  @Category(MediumTests.class)
36  public class TestLocalHBaseCluster {
37    private static final HBaseTestingUtility TEST_UTIL = new HBaseTestingUtility();
38  
39    /**
40     * Check that we can start a local HBase cluster specifying a custom master
41     * and regionserver class and then cast back to those classes; also that
42     * the cluster will launch and terminate cleanly. See HBASE-6011.
43     */
44    @Test
45    public void testLocalHBaseCluster() throws Exception {
46      Configuration conf = TEST_UTIL.getConfiguration();
47      conf.set(HConstants.HBASE_DIR, TEST_UTIL.getDataTestDir("hbase.rootdir").
48        makeQualified(TEST_UTIL.getTestFileSystem().getUri(), 
49          TEST_UTIL.getTestFileSystem().getWorkingDirectory()).toString());
50      MiniZooKeeperCluster zkCluster = TEST_UTIL.startMiniZKCluster();
51      conf.set(HConstants.ZOOKEEPER_CLIENT_PORT, Integer.toString(zkCluster.getClientPort()));
52      LocalHBaseCluster cluster = new LocalHBaseCluster(conf, 1, 1, MyHMaster.class,
53        MyHRegionServer.class);
54      // Can we cast back to our master class?
55      try {
56        ((MyHMaster)cluster.getMaster(0)).setZKCluster(zkCluster);
57      } catch (ClassCastException e) {
58        fail("Could not cast master to our class");
59      }
60      // Can we cast back to our regionserver class?
61      try {
62        ((MyHRegionServer)cluster.getRegionServer(0)).echo(42);
63      } catch (ClassCastException e) {
64        fail("Could not cast regionserver to our class");
65      }
66      // Does the cluster start successfully?
67      try {
68        cluster.startup();
69        waitForClusterUp(conf);
70      } catch (IOException e) {
71        fail("LocalHBaseCluster did not start successfully");
72      } finally {
73        cluster.shutdown();
74      }
75    }
76  
77    private void waitForClusterUp(Configuration conf) throws IOException {
78      HTable t = new HTable(conf, HConstants.META_TABLE_NAME);
79      ResultScanner s = t.getScanner(new Scan());
80      while (s.next() != null) {
81        continue;
82      }
83      s.close();
84      t.close();
85    }
86  
87    /**
88     * A private master class similar to that used by HMasterCommandLine when
89     * running in local mode.
90     */
91    public static class MyHMaster extends HMaster {
92      private MiniZooKeeperCluster zkcluster = null;
93  
94      public MyHMaster(Configuration conf) throws IOException, KeeperException,
95          InterruptedException {
96        super(conf);
97      }
98  
99      @Override
100     public void run() {
101       super.run();
102       if (this.zkcluster != null) {
103         try {
104           this.zkcluster.shutdown();
105         } catch (IOException e) {
106           e.printStackTrace();
107         }
108       }
109     }
110 
111     void setZKCluster(final MiniZooKeeperCluster zkcluster) {
112       this.zkcluster = zkcluster;
113     }
114   }
115 
116   /**
117    * A private regionserver class with a dummy method for testing casts
118    */
119   public static class MyHRegionServer extends HRegionServer {
120 
121     public MyHRegionServer(Configuration conf) throws IOException,
122         InterruptedException {
123       super(conf);
124     }
125 
126     public int echo(int val) {
127       return val;
128     }
129   }
130 }