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;
19  
20  import static org.junit.Assert.assertEquals;
21  import static org.junit.Assert.assertFalse;
22  import static org.junit.Assert.assertNotEquals;
23  import static org.junit.Assert.assertTrue;
24  import java.io.File;
25  import java.io.IOException;
26  import java.util.HashMap;
27  import java.util.List;
28  import java.util.Map;
29  import java.util.Map.Entry;
30  import org.apache.commons.logging.Log;
31  import org.apache.commons.logging.LogFactory;
32  import org.apache.hadoop.conf.Configuration;
33  import org.apache.hadoop.fs.FileSystem;
34  import org.apache.hadoop.fs.FileUtil;
35  import org.apache.hadoop.fs.Path;
36  import org.apache.hadoop.hbase.client.Get;
37  import org.apache.hadoop.hbase.client.Put;
38  import org.apache.hadoop.hbase.client.Result;
39  import org.apache.hadoop.hbase.client.Table;
40  import org.apache.hadoop.hbase.http.ssl.KeyStoreTestUtil;
41  import org.apache.hadoop.hbase.testclassification.LargeTests;
42  import org.apache.hadoop.hbase.util.Bytes;
43  import org.apache.hadoop.hbase.zookeeper.MiniZooKeeperCluster;
44  import org.apache.hadoop.hdfs.MiniDFSCluster;
45  import org.junit.Test;
46  import org.junit.experimental.categories.Category;
47  
48  /**
49   * Test our testing utility class
50   */
51  @Category(LargeTests.class)
52  public class TestHBaseTestingUtility {
53    private static final Log LOG = LogFactory.getLog(TestHBaseTestingUtility.class);
54  
55    /**
56     * Basic sanity test that spins up multiple HDFS and HBase clusters that share
57     * the same ZK ensemble. We then create the same table in both and make sure
58     * that what we insert in one place doesn't end up in the other.
59     * @throws Exception
60     */
61    @Test (timeout=180000)
62    public void testMultiClusters() throws Exception {
63      // Create three clusters
64  
65      // Cluster 1.
66      HBaseTestingUtility htu1 = new HBaseTestingUtility();
67      // Set a different zk path for each cluster
68      htu1.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/1");
69      htu1.startMiniZKCluster();
70  
71      // Cluster 2
72      HBaseTestingUtility htu2 = new HBaseTestingUtility();
73      htu2.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/2");
74      htu2.getConfiguration().set(HConstants.ZOOKEEPER_CLIENT_PORT,
75        htu1.getConfiguration().get(HConstants.ZOOKEEPER_CLIENT_PORT, "-1"));
76      htu2.setZkCluster(htu1.getZkCluster());
77  
78      // Cluster 3; seed it with the conf from htu1 so we pickup the 'right'
79      // zk cluster config; it is set back into the config. as part of the
80      // start of minizkcluster.
81      HBaseTestingUtility htu3 = new HBaseTestingUtility();
82      htu3.getConfiguration().set(HConstants.ZOOKEEPER_ZNODE_PARENT, "/3");
83      htu3.getConfiguration().set(HConstants.ZOOKEEPER_CLIENT_PORT,
84        htu1.getConfiguration().get(HConstants.ZOOKEEPER_CLIENT_PORT, "-1"));
85      htu3.setZkCluster(htu1.getZkCluster());
86  
87      try {
88        htu1.startMiniCluster();
89        htu2.startMiniCluster();
90        htu3.startMiniCluster();
91  
92        final TableName TABLE_NAME = TableName.valueOf("test");
93        final byte[] FAM_NAME = Bytes.toBytes("fam");
94        final byte[] ROW = Bytes.toBytes("row");
95        final byte[] QUAL_NAME = Bytes.toBytes("qual");
96        final byte[] VALUE = Bytes.toBytes("value");
97  
98        Table table1 = htu1.createTable(TABLE_NAME, FAM_NAME);
99        Table table2 = htu2.createTable(TABLE_NAME, FAM_NAME);
100 
101       Put put = new Put(ROW);
102       put.add(FAM_NAME, QUAL_NAME, VALUE);
103       table1.put(put);
104 
105       Get get = new Get(ROW);
106       get.addColumn(FAM_NAME, QUAL_NAME);
107       Result res = table1.get(get);
108       assertEquals(1, res.size());
109 
110       res = table2.get(get);
111       assertEquals(0, res.size());
112 
113       table1.close();
114       table2.close();
115 
116     } finally {
117       htu3.shutdownMiniCluster();
118       htu2.shutdownMiniCluster();
119       htu1.shutdownMiniCluster();
120     }
121   }
122 
123   @Test public void testMiniCluster() throws Exception {
124     HBaseTestingUtility hbt = new HBaseTestingUtility();
125 
126     MiniHBaseCluster cluster = hbt.startMiniCluster();
127     try {
128       assertEquals(1, cluster.getLiveRegionServerThreads().size());
129     } finally {
130       hbt.shutdownMiniCluster();
131     }
132   }
133 
134   @Test
135   public void testMiniClusterBindToWildcard() throws Exception {
136     HBaseTestingUtility hbt = new HBaseTestingUtility();
137     hbt.getConfiguration().set("hbase.regionserver.ipc.address", "0.0.0.0");
138     MiniHBaseCluster cluster = hbt.startMiniCluster();
139     try {
140       assertEquals(1, cluster.getLiveRegionServerThreads().size());
141     } finally {
142       hbt.shutdownMiniCluster();
143     }
144   }
145 
146   @Test
147   public void testMiniClusterWithSSLOn() throws Exception {
148     final String BASEDIR = System.getProperty("test.build.dir",
149         "target/test-dir") + "/" + TestHBaseTestingUtility.class.getSimpleName();
150     String sslConfDir = KeyStoreTestUtil.getClasspathDir(TestHBaseTestingUtility.class);
151     String keystoresDir = new File(BASEDIR).getAbsolutePath();
152 
153     HBaseTestingUtility hbt = new HBaseTestingUtility();
154     File base = new File(BASEDIR);
155     FileUtil.fullyDelete(base);
156     base.mkdirs();
157 
158     KeyStoreTestUtil.setupSSLConfig(keystoresDir, sslConfDir, hbt.getConfiguration(), false);
159 
160     hbt.getConfiguration().set("hbase.ssl.enabled", "true");
161     hbt.getConfiguration().addResource("ssl-server.xml");
162     hbt.getConfiguration().addResource("ssl-client.xml");
163 
164     MiniHBaseCluster cluster = hbt.startMiniCluster();
165     try {
166       assertEquals(1, cluster.getLiveRegionServerThreads().size());
167     } finally {
168       hbt.shutdownMiniCluster();
169     }
170   }
171 
172   /**
173    *  Test that we can start and stop multiple time a cluster
174    *   with the same HBaseTestingUtility.
175    */
176   @Test public void testMultipleStartStop() throws Exception{
177     HBaseTestingUtility htu1 = new HBaseTestingUtility();
178     Path foo = new Path("foo");
179 
180     htu1.startMiniCluster();
181     htu1.getDFSCluster().getFileSystem().create(foo);
182     assertTrue( htu1.getDFSCluster().getFileSystem().exists(foo));
183     htu1.shutdownMiniCluster();
184 
185     htu1.startMiniCluster();
186     assertFalse( htu1.getDFSCluster().getFileSystem().exists(foo));
187     htu1.getDFSCluster().getFileSystem().create(foo);
188     assertTrue( htu1.getDFSCluster().getFileSystem().exists(foo));
189     htu1.shutdownMiniCluster();
190   }
191 
192   @Test
193   public void testMiniZooKeeperWithOneServer() throws Exception {
194     HBaseTestingUtility hbt = new HBaseTestingUtility();
195     MiniZooKeeperCluster cluster1 = hbt.startMiniZKCluster();
196     try {
197       assertEquals(0, cluster1.getBackupZooKeeperServerNum());
198       assertTrue((cluster1.killCurrentActiveZooKeeperServer() == -1));
199     } finally {
200       hbt.shutdownMiniZKCluster();
201     }
202   }
203 
204   @Test
205   public void testMiniZooKeeperWithMultipleServers() throws Exception {
206     HBaseTestingUtility hbt = new HBaseTestingUtility();
207     // set up zookeeper cluster with 5 zk servers
208     MiniZooKeeperCluster cluster2 = hbt.startMiniZKCluster(5);
209     int defaultClientPort = 21818;
210     cluster2.setDefaultClientPort(defaultClientPort);
211     try {
212       assertEquals(4, cluster2.getBackupZooKeeperServerNum());
213 
214       // killing the current active zk server
215       int currentActivePort = cluster2.killCurrentActiveZooKeeperServer();
216       assertTrue(currentActivePort >= defaultClientPort);
217       // Check if the client port is returning a proper value
218       assertTrue(cluster2.getClientPort() == currentActivePort);
219 
220       // kill another active zk server
221       currentActivePort = cluster2.killCurrentActiveZooKeeperServer();
222       assertTrue(currentActivePort >= defaultClientPort);
223       assertTrue(cluster2.getClientPort() == currentActivePort);      
224       assertEquals(2, cluster2.getBackupZooKeeperServerNum());
225       assertEquals(3, cluster2.getZooKeeperServerNum());
226 
227       // killing the backup zk servers
228       cluster2.killOneBackupZooKeeperServer();
229       cluster2.killOneBackupZooKeeperServer();
230       assertEquals(0, cluster2.getBackupZooKeeperServerNum());
231       assertEquals(1, cluster2.getZooKeeperServerNum());
232 
233       // killing the last zk server
234       currentActivePort = cluster2.killCurrentActiveZooKeeperServer();
235       assertTrue(currentActivePort == -1);
236       assertTrue(cluster2.getClientPort() == currentActivePort);
237       // this should do nothing.
238       cluster2.killOneBackupZooKeeperServer();
239       assertEquals(-1, cluster2.getBackupZooKeeperServerNum());
240       assertEquals(0, cluster2.getZooKeeperServerNum());
241     } finally {
242       hbt.shutdownMiniZKCluster();
243     }
244   }
245 
246   @Test
247   public void testMiniZooKeeperWithMultipleClientPorts() throws Exception {
248     int defaultClientPort = 8888;
249     int i, j;
250     HBaseTestingUtility hbt = new HBaseTestingUtility();
251 
252     // Test 1 - set up zookeeper cluster with same number of ZK servers and specified client ports
253     int [] clientPortList1 = {1111, 1112, 1113};
254     MiniZooKeeperCluster cluster1 = hbt.startMiniZKCluster(clientPortList1.length, clientPortList1);
255     try {
256       List<Integer> clientPortListInCluster = cluster1.getClientPortList();
257 
258       for (i = 0; i < clientPortListInCluster.size(); i++) {
259         assertEquals(clientPortListInCluster.get(i).intValue(), clientPortList1[i]);
260       }
261     } finally {
262       hbt.shutdownMiniZKCluster();
263     }
264 
265     // Test 2 - set up zookeeper cluster with more ZK servers than specified client ports
266     hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort);
267     int [] clientPortList2 = {2222, 2223};
268     MiniZooKeeperCluster cluster2 =
269         hbt.startMiniZKCluster(clientPortList2.length + 2, clientPortList2);
270 
271     try {
272       List<Integer> clientPortListInCluster = cluster2.getClientPortList();
273 
274       for (i = 0, j = 0; i < clientPortListInCluster.size(); i++) {
275         if (i < clientPortList2.length) {
276           assertEquals(clientPortListInCluster.get(i).intValue(), clientPortList2[i]);
277         } else {
278           // servers with no specified client port will use defaultClientPort or some other ports
279           // based on defaultClientPort
280           assertEquals(clientPortListInCluster.get(i).intValue(), defaultClientPort + j);
281           j++;
282         }
283       }
284     } finally {
285       hbt.shutdownMiniZKCluster();
286     }
287 
288     // Test 3 - set up zookeeper cluster with invalid client ports
289     hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort);
290     int [] clientPortList3 = {3333, -3334, 3335, 0};
291     MiniZooKeeperCluster cluster3 =
292         hbt.startMiniZKCluster(clientPortList3.length + 1, clientPortList3);
293 
294     try {
295       List<Integer> clientPortListInCluster = cluster3.getClientPortList();
296 
297       for (i = 0, j = 0; i < clientPortListInCluster.size(); i++) {
298         // Servers will only use valid client ports; if ports are not specified or invalid,
299         // the default port or a port based on default port will be used.
300         if (i < clientPortList3.length && clientPortList3[i] > 0) {
301           assertEquals(clientPortListInCluster.get(i).intValue(), clientPortList3[i]);
302         } else {
303           assertEquals(clientPortListInCluster.get(i).intValue(), defaultClientPort + j);
304           j++;
305         }
306       }
307     } finally {
308       hbt.shutdownMiniZKCluster();
309     }
310 
311     // Test 4 - set up zookeeper cluster with default port and some other ports used
312     // This test tests that the defaultClientPort and defaultClientPort+2 are used, so
313     // the algorithm should choice defaultClientPort+1 and defaultClientPort+3 to fill
314     // out the ports for servers without ports specified.
315     hbt.getConfiguration().setInt("test.hbase.zookeeper.property.clientPort", defaultClientPort);
316     int [] clientPortList4 = {-4444, defaultClientPort+2, 4446, defaultClientPort};
317     MiniZooKeeperCluster cluster4 =
318         hbt.startMiniZKCluster(clientPortList4.length + 1, clientPortList4);
319 
320     try {
321       List<Integer> clientPortListInCluster = cluster4.getClientPortList();
322 
323       for (i = 0, j = 1; i < clientPortListInCluster.size(); i++) {
324         // Servers will only use valid client ports; if ports are not specified or invalid,
325         // the default port or a port based on default port will be used.
326         if (i < clientPortList4.length && clientPortList4[i] > 0) {
327           assertEquals(clientPortListInCluster.get(i).intValue(), clientPortList4[i]);
328         } else {
329           assertEquals(clientPortListInCluster.get(i).intValue(), defaultClientPort + j);
330           j +=2;
331         }
332       }
333     } finally {
334       hbt.shutdownMiniZKCluster();
335     }
336 
337     // Test 5 - set up zookeeper cluster with same ports specified - fail is expected.
338     int [] clientPortList5 = {5555, 5556, 5556};
339 
340     try {
341       MiniZooKeeperCluster cluster5 =
342           hbt.startMiniZKCluster(clientPortList5.length, clientPortList5);
343       assertTrue(cluster5.getClientPort() == -1); // expected failure
344     } catch (Exception e) {
345       // exception is acceptable
346     } finally {
347       hbt.shutdownMiniZKCluster();
348     }
349   }
350 
351   @Test public void testMiniDFSCluster() throws Exception {
352     HBaseTestingUtility hbt = new HBaseTestingUtility();
353     MiniDFSCluster cluster = hbt.startMiniDFSCluster(null);
354     FileSystem dfs = cluster.getFileSystem();
355     Path dir = new Path("dir");
356     Path qualifiedDir = dfs.makeQualified(dir);
357     LOG.info("dir=" + dir + ", qualifiedDir=" + qualifiedDir);
358     assertFalse(dfs.exists(qualifiedDir));
359     assertTrue(dfs.mkdirs(qualifiedDir));
360     assertTrue(dfs.delete(qualifiedDir, true));
361     hbt.shutdownMiniCluster();
362   }
363 
364   @Test public void testSetupClusterTestBuildDir() throws Exception {
365     HBaseTestingUtility hbt = new HBaseTestingUtility();
366     Path testdir = hbt.getClusterTestDir();
367     LOG.info("uuid-subdir=" + testdir);
368     FileSystem fs = hbt.getTestFileSystem();
369 
370     assertFalse(fs.exists(testdir));
371 
372     hbt.startMiniDFSCluster(null);
373     assertTrue(fs.exists(testdir));
374 
375     hbt.shutdownMiniCluster();
376     assertFalse(fs.exists(testdir));
377   }
378 
379   @Test public void testTestDir() throws Exception {
380     HBaseTestingUtility hbt = new HBaseTestingUtility();
381     Path testdir = hbt.getDataTestDir();
382     LOG.info("testdir=" + testdir);
383     FileSystem fs = hbt.getTestFileSystem();
384     assertTrue(!fs.exists(testdir));
385     assertTrue(fs.mkdirs(testdir));
386     assertTrue(hbt.cleanupTestDir());
387   }
388 
389   @Test public void testMRYarnConfigsPopulation() throws IOException {
390     Map<String, String> dummyProps = new HashMap<>();
391     dummyProps.put("mapreduce.jobtracker.address", "dummyhost:11234");
392     dummyProps.put("yarn.resourcemanager.address", "dummyhost:11235");
393     dummyProps.put("mapreduce.jobhistory.address", "dummyhost:11236");
394     dummyProps.put("yarn.resourcemanager.scheduler.address", "dummyhost:11237");
395     dummyProps.put("mapreduce.jobhistory.webapp.address", "dummyhost:11238");
396     dummyProps.put("yarn.resourcemanager.webapp.address", "dummyhost:11239");
397   
398     HBaseTestingUtility hbt = new HBaseTestingUtility();
399     
400     // populate the mr props to the Configuration instance
401     for (Entry<String, String> entry : dummyProps.entrySet()) {
402       hbt.getConfiguration().set(entry.getKey(), entry.getValue());
403     }
404     
405     for (Entry<String,String> entry : dummyProps.entrySet()) {
406       assertTrue("The Configuration for key " + entry.getKey() +" and value: " + entry.getValue() +
407                  " is not populated correctly", hbt.getConfiguration().get(entry.getKey()).equals(entry.getValue()));
408     }
409 
410     hbt.startMiniMapReduceCluster();
411     
412     // Confirm that MiniMapReduceCluster overwrites the mr properties and updates the Configuration 
413     for (Entry<String,String> entry : dummyProps.entrySet()) {
414       assertFalse("The MR prop: " + entry.getValue() + " is not overwritten when map reduce mini"+
415                   "cluster is started", hbt.getConfiguration().get(entry.getKey()).equals(entry.getValue()));
416     }
417     
418     hbt.shutdownMiniMapReduceCluster();
419   }
420 
421   @Test
422   public void testOverridingOfDefaultPorts() throws Exception {
423     // confirm that default port properties being overridden to random
424     Configuration defaultConfig = HBaseConfiguration.create();
425     defaultConfig.setInt(HConstants.MASTER_INFO_PORT, HConstants.DEFAULT_MASTER_INFOPORT);
426     defaultConfig.setInt(HConstants.REGIONSERVER_INFO_PORT,
427             HConstants.DEFAULT_REGIONSERVER_INFOPORT);
428     HBaseTestingUtility htu = new HBaseTestingUtility(defaultConfig);
429     try {
430       MiniHBaseCluster defaultCluster = htu.startMiniCluster();
431       final String masterHostPort =
432               defaultCluster.getMaster().getServerName().getAddress().toString();
433       assertNotEquals(HConstants.DEFAULT_MASTER_INFOPORT,
434               defaultCluster.getConfiguration().getInt(HConstants.MASTER_INFO_PORT, 0));
435       assertNotEquals(HConstants.DEFAULT_REGIONSERVER_INFOPORT,
436               defaultCluster.getConfiguration().getInt(HConstants.REGIONSERVER_INFO_PORT, 0));
437       assertEquals(masterHostPort,
438               defaultCluster.getConfiguration().get(HConstants.MASTER_ADDRS_KEY));
439     } finally {
440       htu.shutdownMiniCluster();
441     }
442 
443     // confirm that nonDefault (custom) port settings are NOT overridden
444     Configuration altConfig = HBaseConfiguration.create();
445     final int nonDefaultMasterInfoPort = 3333;
446     final int nonDefaultRegionServerPort = 4444;
447     altConfig.setInt(HConstants.MASTER_INFO_PORT, nonDefaultMasterInfoPort);
448     altConfig.setInt(HConstants.REGIONSERVER_INFO_PORT, nonDefaultRegionServerPort);
449     altConfig.setBoolean(LocalHBaseCluster.ASSIGN_RANDOM_PORTS, false);
450     htu = new HBaseTestingUtility(altConfig);
451     try {
452       MiniHBaseCluster customCluster = htu.startMiniCluster();
453       final String masterHostPort =
454               customCluster.getMaster().getServerName().getAddress().toString();
455       assertEquals(nonDefaultMasterInfoPort,
456               customCluster.getConfiguration().getInt(HConstants.MASTER_INFO_PORT, 0));
457       assertEquals(nonDefaultRegionServerPort,
458               customCluster.getConfiguration().getInt(HConstants.REGIONSERVER_INFO_PORT, 0));
459       assertEquals(masterHostPort,
460               customCluster.getConfiguration().get(HConstants.MASTER_ADDRS_KEY));
461     } finally {
462       htu.shutdownMiniCluster();
463     }
464   }
465 }
466