001/* 002 * Licensed to the Apache Software Foundation (ASF) under one 003 * or more contributor license agreements. See the NOTICE file 004 * distributed with this work for additional information 005 * regarding copyright ownership. The ASF licenses this file 006 * to you under the Apache License, Version 2.0 (the 007 * "License"); you may not use this file except in compliance 008 * with the License. You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.apache.hadoop.hbase.zookeeper; 019 020import static org.junit.Assert.assertEquals; 021import static org.junit.Assert.assertTrue; 022 023import java.security.Permission; 024import org.apache.hadoop.conf.Configuration; 025import org.apache.hadoop.hbase.HBaseClassTestRule; 026import org.apache.hadoop.hbase.HBaseConfiguration; 027import org.apache.hadoop.hbase.HBaseZKTestingUtil; 028import org.apache.hadoop.hbase.HConstants; 029import org.apache.hadoop.hbase.testclassification.SmallTests; 030import org.apache.hadoop.hbase.testclassification.ZKTests; 031import org.junit.Assert; 032import org.junit.ClassRule; 033import org.junit.Test; 034import org.junit.experimental.categories.Category; 035 036@Category({ ZKTests.class, SmallTests.class }) 037public class TestZKMainServer { 038 @ClassRule 039 public static final HBaseClassTestRule CLASS_RULE = 040 HBaseClassTestRule.forClass(TestZKMainServer.class); 041 042 // ZKMS calls System.exit. Catch the call and prevent exit using trick described up in 043 // http://stackoverflow.com/questions/309396/java-how-to-test-methods-that-call-system-exit 044 protected static class ExitException extends SecurityException { 045 private static final long serialVersionUID = 1L; 046 047 ExitException() { 048 super("There is no escape!"); 049 } 050 } 051 052 private static class NoExitSecurityManager extends SecurityManager { 053 @Override 054 public void checkPermission(Permission perm) { 055 // allow anything. 056 } 057 058 @Override 059 public void checkPermission(Permission perm, Object context) { 060 // allow anything. 061 } 062 063 @Override 064 public void checkExit(int status) { 065 super.checkExit(status); 066 throw new ExitException(); 067 } 068 } 069 070 /** 071 * We need delete of a znode to work at least. 072 */ 073 @Test 074 public void testCommandLineWorks() throws Exception { 075 System.setSecurityManager(new NoExitSecurityManager()); 076 HBaseZKTestingUtil htu = new HBaseZKTestingUtil(); 077 // Make it long so for sure succeeds. 078 htu.getConfiguration().setInt(HConstants.ZK_SESSION_TIMEOUT, 30000); 079 htu.startMiniZKCluster(); 080 try { 081 ZKWatcher zkw = htu.getZooKeeperWatcher(); 082 String znode = "/testCommandLineWorks"; 083 ZKUtil.createWithParents(zkw, znode, HConstants.EMPTY_BYTE_ARRAY); 084 ZKUtil.checkExists(zkw, znode); 085 boolean exception = false; 086 try { 087 ZKMainServer.main( 088 new String[] { "-server", htu.getZkCluster().getAddress().toString(), "delete", znode }); 089 } catch (ExitException ee) { 090 // ZKMS calls System.exit which should trigger this exception. 091 exception = true; 092 } 093 assertTrue(exception); 094 assertEquals(-1, ZKUtil.checkExists(zkw, znode)); 095 } finally { 096 htu.shutdownMiniZKCluster(); 097 System.setSecurityManager(null); // or save and restore original 098 } 099 } 100 101 @Test 102 public void testHostPortParse() { 103 ZKMainServer parser = new ZKMainServer(); 104 Configuration c = HBaseConfiguration.create(); 105 assertEquals("127.0.0.1:" + c.get(HConstants.ZOOKEEPER_CLIENT_PORT), parser.parse(c)); 106 final String port = "1234"; 107 c.set(HConstants.ZOOKEEPER_CLIENT_PORT, port); 108 c.set("hbase.zookeeper.quorum", "example.com"); 109 assertEquals("example.com:" + port, parser.parse(c)); 110 c.set("hbase.zookeeper.quorum", "example1.com,example2.com,example3.com"); 111 String ensemble = parser.parse(c); 112 assertTrue(port, ensemble.matches("(example[1-3]\\.com:1234,){2}example[1-3]\\.com:" + port)); 113 114 // multiple servers with its own port 115 c.set("hbase.zookeeper.quorum", "example1.com:5678,example2.com:9012,example3.com:3456"); 116 ensemble = parser.parse(c); 117 assertEquals("example1.com:5678,example2.com:9012,example3.com:3456", ensemble); 118 119 // some servers without its own port, which will be assigned the default client port 120 c.set("hbase.zookeeper.quorum", "example1.com:5678,example2.com:9012,example3.com"); 121 ensemble = parser.parse(c); 122 assertEquals(ensemble, "example1.com:5678,example2.com:9012,example3.com:" + port); 123 124 // multiple servers(IPv6) with its own port 125 c.set("hbase.zookeeper.quorum", 126 "[2001:db8:1::242:ac11:2]:2181," + "[2001:db8:1::242:ac11:3]:5678"); 127 ensemble = parser.parse(c); 128 assertEquals("[2001:db8:1::242:ac11:2]:2181," + "[2001:db8:1::242:ac11:3]:5678", ensemble); 129 130 // some servers(IPv6) without its own port, which will be assigned the default client port 131 c.set("hbase.zookeeper.quorum", 132 "[1001:db8:1::242:ac11:8], [2001:db8:1::242:df23:2]:9876," + "[2001:db8:1::242:ac11:3]:5678"); 133 ensemble = parser.parse(c); 134 assertEquals("[1001:db8:1::242:ac11:8]:1234, [2001:db8:1::242:df23:2]:9876," 135 + "[2001:db8:1::242:ac11:3]:5678", ensemble); 136 137 // a bad case 138 try { 139 // some servers(IPv6) with an invaild Ipv6 address in it 140 c.set("hbase.zookeeper.quorum", "[1001:db8:1::242:ac11:8], [2001:db8:1::242:df23:2]:9876," 141 + "[1001:db8:1::242:ac11:8:89:67]:5678"); 142 parser.parse(c); 143 Assert.fail("IPv6 address should be 8 groups."); 144 } catch (IllegalArgumentException e) { 145 // expected 146 } 147 } 148}