/** * Licensed to the Apache Software Foundation (ASF) under one * or more contributor license agreements. See the NOTICE file * distributed with this work for additional information * regarding copyright ownership. The ASF licenses this file * to you under the Apache License, Version 2.0 (the * "License"); you may not use this file except in compliance * with the License. You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package org.apache.zookeeper.test; import java.io.IOException; import java.util.List; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.TimeUnit; import org.apache.zookeeper.CreateMode; import org.apache.zookeeper.KeeperException; import org.apache.zookeeper.WatchedEvent; import org.apache.zookeeper.Watcher; import org.apache.zookeeper.ZKTestCase; import org.apache.zookeeper.ZooKeeper; import org.apache.zookeeper.KeeperException.Code; import org.apache.zookeeper.Watcher.Event.EventType; import org.apache.zookeeper.ZooDefs.Ids; import org.apache.zookeeper.data.Stat; import org.junit.Assert; public class ZooKeeperTestClient extends ZKTestCase implements Watcher { protected String hostPort = "127.0.0.1:22801"; protected static final String dirOnZK = "/test_dir"; protected String testDirOnZK = dirOnZK + "/" + System.currentTimeMillis(); LinkedBlockingQueue<WatchedEvent> events = new LinkedBlockingQueue<WatchedEvent>(); private WatchedEvent getEvent(int numTries) throws InterruptedException { WatchedEvent event = null; for (int i = 0; i < numTries; i++) { System.out.println("i = " + i); event = events.poll(10, TimeUnit.SECONDS); if (event != null) { break; } Thread.sleep(5000); } return event; } private void deleteZKDir(ZooKeeper zk, String nodeName) throws IOException, InterruptedException, KeeperException { Stat stat = zk.exists(nodeName, false); if (stat == null) { return; } List<String> children1 = zk.getChildren(nodeName, false); List<String> c2 = zk.getChildren(nodeName, false, stat); if (!children1.equals(c2)) { Assert.fail("children lists from getChildren()/getChildren2() do not match"); } if (!stat.equals(stat)) { Assert.fail("stats from exists()/getChildren2() do not match"); } if (children1.size() == 0) { zk.delete(nodeName, -1); return; } for (String n : children1) { deleteZKDir(zk, n); } } private void checkRoot() throws IOException, InterruptedException { ZooKeeper zk = new ZooKeeper(hostPort, 10000, this); try { zk.create(dirOnZK, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } catch (KeeperException.NodeExistsException ke) { // expected, sort of } catch (KeeperException ke) { Assert.fail("Unexpected exception code for create " + dirOnZK + ": " + ke.getMessage()); } try { zk.create(testDirOnZK, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } catch (KeeperException.NodeExistsException ke) { // expected, sort of } catch (KeeperException ke) { Assert.fail("Unexpected exception code for create " + testDirOnZK + ": " + ke.getMessage()); } zk.close(); } private void enode_test_1() throws IOException, InterruptedException, KeeperException { checkRoot(); String parentName = testDirOnZK; String nodeName = parentName + "/enode_abc"; ZooKeeper zk = new ZooKeeper(hostPort, 10000, this); Stat stat = zk.exists(parentName, false); if (stat == null) { try { zk.create(parentName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } catch (KeeperException ke) { Assert.fail("Creating node " + parentName + ke.getMessage()); } } try { zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NODEEXISTS; if (!valid) { Assert.fail("Unexpected exception code for createin: " + ke.getMessage()); } } stat = zk.exists(nodeName, false); if (stat == null) { Assert.fail("node " + nodeName + " should exist"); } System.out.println("Closing client with sessionid: 0x" + Long.toHexString(zk.getSessionId())); zk.close(); zk = new ZooKeeper(hostPort, 10000, this); for (int i = 0; i < 10; i++) { System.out.println("i = " + i); stat = zk.exists(nodeName, false); if (stat != null) { System.out.println("node " + nodeName + " should not exist after reconnection close"); } else { System.out.println("node " + nodeName + " is gone after reconnection close!"); break; } Thread.sleep(5000); } deleteZKDir(zk, nodeName); zk.close(); } private void enode_test_2() throws IOException, InterruptedException, KeeperException { checkRoot(); String parentName = testDirOnZK; String nodeName = parentName + "/enode_abc"; ZooKeeper zk = new ZooKeeper(hostPort, 10000, this); ZooKeeper zk_1 = new ZooKeeper(hostPort, 10000, this); Stat stat_parent = zk_1.exists(parentName, false); if (stat_parent == null) { try { zk.create(parentName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } catch (KeeperException ke) { Assert.fail("Creating node " + parentName + ke.getMessage()); } } Stat stat_node = zk_1.exists(nodeName, false); if (stat_node != null) { try { zk.delete(nodeName, -1); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NONODE || code == KeeperException.Code.NOTEMPTY; if (!valid) { Assert.fail("Unexpected exception code for delete: " + ke.getMessage()); } } } List<String> firstGen1 = zk_1.getChildren(parentName, true); Stat stat = new Stat(); List<String> firstGen2 = zk_1.getChildren(parentName, true, stat); if (!firstGen1.equals(firstGen2)) { Assert.fail("children lists from getChildren()/getChildren2() do not match"); } if (!stat_parent.equals(stat)) { Assert.fail("stat from exists()/getChildren() do not match"); } try { zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NODEEXISTS; if (!valid) { Assert.fail("Unexpected exception code for createin: " + ke.getMessage()); } } Thread.sleep(5000); WatchedEvent event = events.poll(10, TimeUnit.SECONDS); if (event == null) { throw new IOException("No event was delivered promptly"); } if (event.getType() != EventType.NodeChildrenChanged || !event.getPath().equalsIgnoreCase(parentName)) { Assert.fail("Unexpected event was delivered: " + event.toString()); } stat_node = zk_1.exists(nodeName, false); if (stat_node == null) { Assert.fail("node " + nodeName + " should exist"); } try { zk.delete(parentName, -1); Assert.fail("Should be impossible to delete a non-empty node " + parentName); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NOTEMPTY; if (!valid) { Assert.fail("Unexpected exception code for delete: " + code); } } try { zk.create(nodeName + "/def", null, Ids.OPEN_ACL_UNSAFE, CreateMode.EPHEMERAL); Assert.fail("Should be impossible to create child off Ephemeral node " + nodeName); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NOCHILDRENFOREPHEMERALS; if (!valid) { Assert.fail("Unexpected exception code for createin: " + code); } } try { List<String> children1 = zk.getChildren(nodeName, false); List<String> children2 = zk.getChildren(nodeName, false, null); if (!children1.equals(children2)) { Assert.fail("children lists from getChildren()/getChildren2() does not match"); } if (children1.size() > 0) { Assert.fail("ephemeral node " + nodeName + " should not have children"); } } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NONODE; if (!valid) { Assert.fail("Unexpected exception code for createin: " + code); } } firstGen1 = zk_1.getChildren(parentName, true); firstGen2 = zk_1.getChildren(parentName, true, null); if (!firstGen1.equals(firstGen2)) { Assert.fail("children list from getChildren()/getChildren2() does not match"); } stat_node = zk_1.exists(nodeName, true); if (stat_node == null) { Assert.fail("node " + nodeName + " should exist"); } System.out.println("session id of zk: " + zk.getSessionId()); System.out.println("session id of zk_1: " + zk_1.getSessionId()); zk.close(); Stat no_stat = zk_1.exists("nosuchnode", false); event = this.getEvent(10); if (event == null) { throw new Error("First event was not delivered promptly"); } if (!((event.getType() == EventType.NodeChildrenChanged && event.getPath().equalsIgnoreCase(parentName)) || (event.getType() == EventType.NodeDeleted && event.getPath().equalsIgnoreCase(nodeName)))) { System.out.print(parentName + " " + EventType.NodeChildrenChanged + " " + nodeName + " " + EventType.NodeDeleted); Assert.fail("Unexpected first event was delivered: " + event.toString()); } event = this.getEvent(10); if (event == null) { throw new Error("Second event was not delivered promptly"); } if (!((event.getType() == EventType.NodeChildrenChanged && event.getPath().equalsIgnoreCase(parentName)) || (event.getType() == EventType.NodeDeleted && event.getPath().equalsIgnoreCase(nodeName)))) { System.out.print(parentName + " " + EventType.NodeChildrenChanged + " " + nodeName + " " + EventType.NodeDeleted); Assert.fail("Unexpected second event was delivered: " + event.toString()); } firstGen1 = zk_1.getChildren(parentName, false); stat_node = zk_1.exists(nodeName, false); if (stat_node != null) { Assert.fail("node " + nodeName + " should have been deleted"); } if (firstGen1.contains(nodeName)) { Assert.fail("node " + nodeName + " should not be a children"); } deleteZKDir(zk_1, nodeName); zk_1.close(); } private void delete_create_get_set_test_1() throws IOException, InterruptedException, KeeperException { checkRoot(); ZooKeeper zk = new ZooKeeper(hostPort, 10000, this); String parentName = testDirOnZK; String nodeName = parentName + "/benwashere"; try { zk.delete(nodeName, -1); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NONODE || code == KeeperException.Code.NOTEMPTY; if (!valid) { Assert.fail("Unexpected exception code for delete: " + ke.getMessage()); } } try { zk.create(nodeName, null, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NODEEXISTS; if (!valid) { Assert.fail("Unexpected exception code for create: " + ke.getMessage()); } } try { zk.setData(nodeName, "hi".getBytes(), 5700); Assert.fail("Should have gotten BadVersion exception"); } catch (KeeperException ke) { if (ke.code() != Code.BADVERSION) { Assert.fail("Should have gotten BadVersion exception"); } } zk.setData(nodeName, "hi".getBytes(), -1); Stat st = new Stat(); byte[] bytes = zk.getData(nodeName, false, st); String retrieved = new String(bytes); if (!"hi".equals(retrieved)) { Assert.fail("The retrieved data [" + retrieved + "] is differented than the expected [hi]"); } try { zk.delete(nodeName, 6800); Assert.fail("Should have gotten BadVersion exception"); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NOTEMPTY || code == KeeperException.Code.BADVERSION; if (!valid) { Assert.fail("Unexpected exception code for delete: " + ke.getMessage()); } } try { zk.delete(nodeName, -1); } catch (KeeperException ke) { Code code = ke.code(); boolean valid = code == KeeperException.Code.NOTEMPTY; if (!valid) { Assert.fail("Unexpected exception code for delete: " + code); } } deleteZKDir(zk, nodeName); zk.close(); } public void my_test_1() throws IOException, InterruptedException, KeeperException { enode_test_1(); enode_test_2(); delete_create_get_set_test_1(); } synchronized public void process(WatchedEvent event) { try { System.out.println("Got an event " + event.toString()); events.put(event); } catch (InterruptedException e) { e.printStackTrace(); } } public static void main(String[] args) { ZooKeeperTestClient zktc = new ZooKeeperTestClient(); try { zktc.my_test_1(); } catch (Exception e) { e.printStackTrace(); } } }