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.jupiter.api.Assertions.assertEquals; 021import static org.junit.jupiter.api.Assertions.assertTrue; 022import static org.junit.jupiter.api.Assertions.fail; 023 024import java.security.Permission; 025import org.apache.hadoop.conf.Configuration; 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.jupiter.api.Tag; 032import org.junit.jupiter.api.Test; 033 034@Tag(ZKTests.TAG) 035@Tag(SmallTests.TAG) 036public class TestZKMainServer { 037 038 // ZKMS calls System.exit. Catch the call and prevent exit using trick described up in 039 // http://stackoverflow.com/questions/309396/java-how-to-test-methods-that-call-system-exit 040 protected static class ExitException extends SecurityException { 041 private static final long serialVersionUID = 1L; 042 043 ExitException() { 044 super("There is no escape!"); 045 } 046 } 047 048 private static class NoExitSecurityManager extends SecurityManager { 049 @Override 050 public void checkPermission(Permission perm) { 051 // allow anything. 052 } 053 054 @Override 055 public void checkPermission(Permission perm, Object context) { 056 // allow anything. 057 } 058 059 @Override 060 public void checkExit(int status) { 061 super.checkExit(status); 062 throw new ExitException(); 063 } 064 } 065 066 /** 067 * We need delete of a znode to work at least. 068 */ 069 @Test 070 public void testCommandLineWorks() throws Exception { 071 System.setSecurityManager(new NoExitSecurityManager()); 072 HBaseZKTestingUtil htu = new HBaseZKTestingUtil(); 073 // Make it long so for sure succeeds. 074 htu.getConfiguration().setInt(HConstants.ZK_SESSION_TIMEOUT, 30000); 075 htu.startMiniZKCluster(); 076 try { 077 ZKWatcher zkw = htu.getZooKeeperWatcher(); 078 String znode = "/testCommandLineWorks"; 079 ZKUtil.createWithParents(zkw, znode, HConstants.EMPTY_BYTE_ARRAY); 080 ZKUtil.checkExists(zkw, znode); 081 boolean exception = false; 082 try { 083 ZKMainServer.main( 084 new String[] { "-server", htu.getZkCluster().getAddress().toString(), "delete", znode }); 085 } catch (ExitException ee) { 086 // ZKMS calls System.exit which should trigger this exception. 087 exception = true; 088 } 089 assertTrue(exception); 090 assertEquals(-1, ZKUtil.checkExists(zkw, znode)); 091 } finally { 092 htu.shutdownMiniZKCluster(); 093 System.setSecurityManager(null); // or save and restore original 094 } 095 } 096 097 @Test 098 public void testHostPortParse() { 099 ZKMainServer parser = new ZKMainServer(); 100 Configuration c = HBaseConfiguration.create(); 101 assertEquals("127.0.0.1:" + c.get(HConstants.ZOOKEEPER_CLIENT_PORT), parser.parse(c)); 102 final String port = "1234"; 103 c.set(HConstants.ZOOKEEPER_CLIENT_PORT, port); 104 c.set("hbase.zookeeper.quorum", "example.com"); 105 assertEquals("example.com:" + port, parser.parse(c)); 106 c.set("hbase.zookeeper.quorum", "example1.com,example2.com,example3.com"); 107 String ensemble = parser.parse(c); 108 assertTrue(ensemble.matches("(example[1-3]\\.com:1234,){2}example[1-3]\\.com:" + port), port); 109 110 // multiple servers with its own port 111 c.set("hbase.zookeeper.quorum", "example1.com:5678,example2.com:9012,example3.com:3456"); 112 ensemble = parser.parse(c); 113 assertEquals("example1.com:5678,example2.com:9012,example3.com:3456", ensemble); 114 115 // some servers without its own port, which will be assigned the default client port 116 c.set("hbase.zookeeper.quorum", "example1.com:5678,example2.com:9012,example3.com"); 117 ensemble = parser.parse(c); 118 assertEquals("example1.com:5678,example2.com:9012,example3.com:" + port, ensemble); 119 120 // multiple servers(IPv6) with its own port 121 c.set("hbase.zookeeper.quorum", 122 "[2001:db8:1::242:ac11:2]:2181," + "[2001:db8:1::242:ac11:3]:5678"); 123 ensemble = parser.parse(c); 124 assertEquals("[2001:db8:1::242:ac11:2]:2181," + "[2001:db8:1::242:ac11:3]:5678", ensemble); 125 126 // some servers(IPv6) without its own port, which will be assigned the default client port 127 c.set("hbase.zookeeper.quorum", 128 "[1001:db8:1::242:ac11:8], [2001:db8:1::242:df23:2]:9876," + "[2001:db8:1::242:ac11:3]:5678"); 129 ensemble = parser.parse(c); 130 assertEquals("[1001:db8:1::242:ac11:8]:1234, [2001:db8:1::242:df23:2]:9876," 131 + "[2001:db8:1::242:ac11:3]:5678", ensemble); 132 133 // a bad case 134 try { 135 // some servers(IPv6) with an invaild Ipv6 address in it 136 c.set("hbase.zookeeper.quorum", "[1001:db8:1::242:ac11:8], [2001:db8:1::242:df23:2]:9876," 137 + "[1001:db8:1::242:ac11:8:89:67]:5678"); 138 parser.parse(c); 139 fail("IPv6 address should be 8 groups."); 140 } catch (IllegalArgumentException e) { 141 // expected 142 } 143 } 144}