zookeeper-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From an...@apache.org
Subject [10/51] [partial] zookeeper git commit: ZOOKEEPER-3032: MAVEN MIGRATION - branch-3.5 - zookeeper-server
Date Wed, 24 Oct 2018 09:31:05 GMT
http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLRootTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
new file mode 100644
index 0000000..15c7cef
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLRootTest.java
@@ -0,0 +1,94 @@
+/**
+ * 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 org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ACLRootTest extends ClientBase {
+    @Test
+    public void testRootAcl() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            // set auth using digest
+            zk.addAuthInfo("digest", "pat:test".getBytes());
+            zk.setACL("/", Ids.CREATOR_ALL_ACL, -1);
+            zk.getData("/", false, null);
+            zk.close();
+            // verify no access
+            zk = createClient();
+            try {
+                zk.getData("/", false, null);
+                Assert.fail("validate auth");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            try {
+                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                        CreateMode.PERSISTENT);
+                Assert.fail("validate auth");
+            } catch (KeeperException.InvalidACLException e) {
+                // expected
+            }
+            zk.addAuthInfo("digest", "world:anyone".getBytes());
+            try {
+                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                        CreateMode.PERSISTENT);
+                Assert.fail("validate auth");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify access using original auth
+            zk = createClient();
+            zk.addAuthInfo("digest", "pat:test".getBytes());
+            zk.getData("/", false, null);
+            zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                    CreateMode.PERSISTENT);
+            zk.delete("/apps", -1);
+            // reset acl (back to open) and verify accessible again
+            zk.setACL("/", Ids.OPEN_ACL_UNSAFE, -1);
+            zk.close();
+            zk = createClient();
+            zk.getData("/", false, null);
+            zk.create("/apps", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+            try {
+                zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                        CreateMode.PERSISTENT);
+                Assert.fail("validate auth");
+            } catch (KeeperException.InvalidACLException e) {
+                // expected
+            }
+            zk.delete("/apps", -1);
+            zk.addAuthInfo("digest", "world:anyone".getBytes());
+            zk.create("/apps", null, Ids.CREATOR_ALL_ACL,
+                    CreateMode.PERSISTENT);
+            zk.close();
+            zk = createClient();
+            zk.delete("/apps", -1);
+        } finally {
+            zk.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLTest.java
new file mode 100644
index 0000000..e88f7f4
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ACLTest.java
@@ -0,0 +1,192 @@
+/**
+ * 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 static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.concurrent.CountDownLatch;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Id;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.server.auth.IPAuthenticationProvider;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class ACLTest extends ZKTestCase implements Watcher {
+    private static final Logger LOG = LoggerFactory.getLogger(ACLTest.class);
+    private static final String HOSTPORT =
+        "127.0.0.1:" + PortAssignment.unique();
+    private volatile CountDownLatch startSignal;
+
+    @Test
+    public void testIPAuthenticationIsValidCIDR() throws Exception {
+        IPAuthenticationProvider prov = new IPAuthenticationProvider();
+        Assert.assertTrue("testing no netmask", prov.isValid("127.0.0.1"));
+        Assert.assertTrue("testing single ip netmask", prov.isValid("127.0.0.1/32"));
+        Assert.assertTrue("testing lowest netmask possible", prov.isValid("127.0.0.1/0"));
+        Assert.assertFalse("testing netmask too high", prov.isValid("127.0.0.1/33"));
+        Assert.assertFalse("testing netmask too low", prov.isValid("10.0.0.1/-1"));
+    }
+
+    @Test
+    public void testDisconnectedAddAuth() throws Exception {
+        File tmpDir = ClientBase.createTmpDir();
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        SyncRequestProcessor.setSnapCount(1000);
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        try {
+            LOG.info("starting up the zookeeper server .. waiting");
+            Assert.assertTrue("waiting for server being up",
+                    ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+            ZooKeeper zk = ClientBase.createZKClient(HOSTPORT);
+            try {
+                zk.addAuthInfo("digest", "pat:test".getBytes());
+                zk.setACL("/", Ids.CREATOR_ALL_ACL, -1);
+            } finally {
+                zk.close();
+            }
+        } finally {
+            f.shutdown();
+            zks.shutdown();
+            Assert.assertTrue("waiting for server down",
+                    ClientBase.waitForServerDown(HOSTPORT,
+                            ClientBase.CONNECTION_TIMEOUT));
+        }
+    }
+
+    /**
+     * Verify that acl optimization of storing just
+     * a few acls and there references in the data
+     * node is actually working.
+     */
+    @Test
+    public void testAcls() throws Exception {
+        File tmpDir = ClientBase.createTmpDir();
+        ClientBase.setupTestEnv();
+        ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        SyncRequestProcessor.setSnapCount(1000);
+        final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+        ServerCnxnFactory f = ServerCnxnFactory.createFactory(PORT, -1);
+        f.startup(zks);
+        ZooKeeper zk;
+        String path;
+        try {
+            LOG.info("starting up the zookeeper server .. waiting");
+            Assert.assertTrue("waiting for server being up",
+                    ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+            zk = ClientBase.createZKClient(HOSTPORT);
+            LOG.info("starting creating acls");
+            for (int i = 0; i < 100; i++) {
+                path = "/" + i;
+                zk.create(path, path.getBytes(), Ids.OPEN_ACL_UNSAFE,
+                        CreateMode.PERSISTENT);
+            }
+            int size = zks.getZKDatabase().getAclSize();
+            Assert.assertTrue("size of the acl map ", (2 == zks.getZKDatabase().getAclSize()));
+            for (int j = 100; j < 200; j++) {
+                path = "/" + j;
+                ACL acl = new ACL();
+                acl.setPerms(0);
+                Id id = new Id();
+                id.setId("1.1.1."+j);
+                id.setScheme("ip");
+                acl.setId(id);
+                ArrayList<ACL> list = new ArrayList<ACL>();
+                list.add(acl);
+                zk.create(path, path.getBytes(), list, CreateMode.PERSISTENT);
+            }
+            Assert.assertTrue("size of the acl map ", (102 == zks.getZKDatabase().getAclSize()));
+        } finally {
+            // now shutdown the server and restart it
+            f.shutdown();
+            zks.shutdown();
+            Assert.assertTrue("waiting for server down",
+                    ClientBase.waitForServerDown(HOSTPORT, CONNECTION_TIMEOUT));
+        }
+
+        zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+        f = ServerCnxnFactory.createFactory(PORT, -1);
+
+        f.startup(zks);
+        try {
+            Assert.assertTrue("waiting for server up",
+                       ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+            zk = ClientBase.createZKClient(HOSTPORT);
+            Assert.assertTrue("acl map ", (102 == zks.getZKDatabase().getAclSize()));
+            for (int j = 200; j < 205; j++) {
+                path = "/" + j;
+                ACL acl = new ACL();
+                acl.setPerms(0);
+                Id id = new Id();
+                id.setId("1.1.1."+j);
+                id.setScheme("ip");
+                acl.setId(id);
+                ArrayList<ACL> list = new ArrayList<ACL>();
+                list.add(acl);
+                zk.create(path, path.getBytes(), list, CreateMode.PERSISTENT);
+            }
+            Assert.assertTrue("acl map ", (107 == zks.getZKDatabase().getAclSize()));
+    
+            zk.close();
+        } finally {
+            f.shutdown();
+            zks.shutdown();
+            Assert.assertTrue("waiting for server down",
+                       ClientBase.waitForServerDown(HOSTPORT,
+                               ClientBase.CONNECTION_TIMEOUT));
+        }
+
+    }
+
+    /*
+     * (non-Javadoc)
+     *
+     * @see org.apache.zookeeper.Watcher#process(org.apache.zookeeper.WatcherEvent)
+     */
+    public void process(WatchedEvent event) {
+        LOG.info("Event:" + event.getState() + " " + event.getType() + " "
+                 + event.getPath());
+        if (event.getState() == KeeperState.SyncConnected) {
+            if (startSignal != null && startSignal.getCount() > 0) {
+                LOG.info("startsignal.countDown()");
+                startSignal.countDown();
+            } else {
+                LOG.warn("startsignal " + startSignal);
+            }
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
new file mode 100644
index 0000000..1ccdc0b
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncHammerTest.java
@@ -0,0 +1,244 @@
+/**
+ * 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 static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+import static org.apache.zookeeper.test.ClientBase.verifyThreadTerminated;
+
+import java.util.LinkedList;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.Stat;
+import org.apache.zookeeper.test.ClientBase.CountdownWatcher;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AsyncHammerTest extends ZKTestCase
+    implements StringCallback, VoidCallback, DataCallback
+{
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncHammerTest.class);
+
+    private QuorumBase qb = new QuorumBase();
+
+    private volatile boolean bang;
+
+    public void setUp(boolean withObservers) throws Exception {
+        qb.setUp(withObservers);
+    }
+
+    protected void restart() throws Exception {
+        LOG.info("RESTARTING " + getTestName());
+        qb.tearDown();
+
+        // don't call setup - we don't want to reassign ports/dirs, etc...
+        JMXEnv.setUp();
+        qb.startServers();
+    }
+
+    public void tearDown() throws Exception {
+        LOG.info("Test clients shutting down");
+        qb.tearDown();
+    }
+
+    /**
+     * Create /test- sequence nodes asynchronously, max 30 outstanding
+     */
+    class HammerThread extends Thread implements StringCallback, VoidCallback {
+        private static final int MAX_OUTSTANDING = 30;
+
+        private TestableZooKeeper zk;
+        private int outstanding;
+
+        private volatile boolean failed = false;
+
+        public HammerThread(String name) {
+            super(name);
+        }
+
+        public void run() {
+            try {
+                CountdownWatcher watcher = new CountdownWatcher();
+                zk = new TestableZooKeeper(qb.hostPort, CONNECTION_TIMEOUT,
+                        watcher);
+                watcher.waitForConnected(CONNECTION_TIMEOUT);
+                while(bang) {
+                    incOutstanding(); // before create otw race
+                    zk.create("/test-", new byte[0], Ids.OPEN_ACL_UNSAFE,
+                            CreateMode.PERSISTENT_SEQUENTIAL, this, null);
+                }
+            } catch (InterruptedException e) {
+                if (bang) {
+                    LOG.error("sanity check Assert.failed!!!"); // sanity check
+                    return;
+                }
+            } catch (Exception e) {
+                LOG.error("Client create operation Assert.failed", e);
+                return;
+            } finally {
+                if (zk != null) {
+                    try {
+                        if (!zk.close(CONNECTION_TIMEOUT)) {
+                            failed = true;
+                            LOG.error("Client did not shutdown");
+                        }
+                    } catch (InterruptedException e) {
+                        LOG.info("Interrupted", e);
+                    }
+                }
+            }
+        }
+
+        private synchronized void incOutstanding() throws InterruptedException {
+            outstanding++;
+            while(outstanding > MAX_OUTSTANDING) {
+                wait();
+            }
+        }
+
+        private synchronized void decOutstanding() {
+            outstanding--;
+            Assert.assertTrue("outstanding >= 0", outstanding >= 0);
+            notifyAll();
+        }
+
+        public void process(WatchedEvent event) {
+            // ignore for purposes of this test
+        }
+
+        public void processResult(int rc, String path, Object ctx, String name) {
+            if (rc != KeeperException.Code.OK.intValue()) {
+                if (bang) {
+                    failed = true;
+                    LOG.error("Create Assert.failed for 0x"
+                            + Long.toHexString(zk.getSessionId())
+                            + "with rc:" + rc + " path:" + path);
+                }
+                decOutstanding();
+                return;
+            }
+            try {
+                decOutstanding();
+                zk.delete(name, -1, this, null);
+            } catch (Exception e) {
+                if (bang) {
+                    failed = true;
+                    LOG.error("Client delete Assert.failed", e);
+                }
+            }
+        }
+
+        public void processResult(int rc, String path, Object ctx) {
+            if (rc != KeeperException.Code.OK.intValue()) {
+                if (bang) {
+                    failed = true;
+                    LOG.error("Delete Assert.failed for 0x"
+                            + Long.toHexString(zk.getSessionId())
+                            + "with rc:" + rc + " path:" + path);
+                }
+            }
+        }
+    }
+
+    @Test
+    public void testHammer() throws Exception {
+        setUp(false);
+        bang = true;
+        LOG.info("Starting hammers");
+        HammerThread[] hammers = new HammerThread[100];
+        for (int i = 0; i < hammers.length; i++) {
+            hammers[i] = new HammerThread("HammerThread-" + i);
+            hammers[i].start();
+        }
+        LOG.info("Started hammers");
+        Thread.sleep(5000); // allow the clients to run for max 5sec
+        bang = false;
+        LOG.info("Stopping hammers");
+        for (int i = 0; i < hammers.length; i++) {
+            hammers[i].interrupt();
+            verifyThreadTerminated(hammers[i], 60000);
+            Assert.assertFalse(hammers[i].failed);
+        }
+
+        // before restart
+        LOG.info("Hammers stopped, verifying consistency");
+        qb.verifyRootOfAllServersMatch(qb.hostPort);
+
+        restart();
+
+        // after restart
+        LOG.info("Verifying hammers 2");
+        qb.verifyRootOfAllServersMatch(qb.hostPort);
+        tearDown();
+    }
+
+    @Test
+    public void testObserversHammer() throws Exception {
+        setUp(true);
+        bang = true;
+        Thread[] hammers = new Thread[100];
+        for (int i = 0; i < hammers.length; i++) {
+            hammers[i] = new HammerThread("HammerThread-" + i);
+            hammers[i].start();
+        }
+        Thread.sleep(5000); // allow the clients to run for max 5sec
+        bang = false;
+        for (int i = 0; i < hammers.length; i++) {
+            hammers[i].interrupt();
+            verifyThreadTerminated(hammers[i], 60000);
+        }
+        // before restart
+        qb.verifyRootOfAllServersMatch(qb.hostPort);
+        tearDown();
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, String name) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, byte[] data,
+            Stat stat) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOps.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOps.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOps.java
new file mode 100644
index 0000000..b634c9f
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOps.java
@@ -0,0 +1,827 @@
+/**
+ * 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.lang.Exception;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.List;
+import java.util.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.Op;
+import org.apache.zookeeper.OpResult;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.AsyncCallback.ACLCallback;
+import org.apache.zookeeper.AsyncCallback.Children2Callback;
+import org.apache.zookeeper.AsyncCallback.ChildrenCallback;
+import org.apache.zookeeper.AsyncCallback.Create2Callback;
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.StatCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.AsyncCallback.MultiCallback;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.data.ACL;
+import org.apache.zookeeper.data.Stat;
+import org.junit.Assert;
+
+public class AsyncOps {
+    /**
+     * This is the base class for all of the async callback classes. It will
+     * verify the expected value against the actual value.
+     * 
+     * Basic operation is that the subclasses will generate an "expected" value
+     * which is defined by the "toString" method of the subclass. This is
+     * passed through to the verify clause by specifying it as the ctx object
+     * of each async call (processResult methods get the ctx as part of
+     * the callback). Additionally the callback will also overwrite any
+     * instance fields with matching parameter arguments to the processResult
+     * method. The cb instance can then compare the expected to the
+     * actual value by again calling toString and comparing the two.
+     * 
+     * The format of each expected value differs (is defined) by subclass.
+     * Generally the expected value starts with the result code (rc) and path
+     * of the node being operated on, followed by the fields specific to
+     * each operation type (cb subclass). For example ChildrenCB specifies
+     * a list of the expected children suffixed onto the rc and path. See
+     * the toString() method of each subclass for details of it's format. 
+     */
+    public static abstract class AsyncCB {
+        protected final ZooKeeper zk;
+        protected long defaultTimeoutMillis = 30000;
+        
+        /** the latch is used to await the results from the server */
+        CountDownLatch latch;
+
+        Code rc = Code.OK;
+        String path = "/foo";
+        String expected;
+        
+        public AsyncCB(ZooKeeper zk, CountDownLatch latch) {
+            this.zk = zk;
+            this.latch = latch;
+        }
+        
+        public void setRC(Code rc) {
+            this.rc = rc;
+        }
+        
+        public void setPath(String path) {
+            this.path = path;
+        }
+        
+        public void processResult(Code rc, String path, Object ctx)
+        {
+            this.rc = rc;
+            this.path = path;
+            this.expected = (String)ctx;
+            latch.countDown();
+        }
+        
+        /** String format is rc:path:<suffix> where <suffix> is defined by each
+         * subclass individually. */
+        @Override
+        public String toString() {
+            return rc + ":" + path + ":"; 
+        }
+
+        protected void verify() {
+            try {
+                latch.await(defaultTimeoutMillis, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                Assert.fail("unexpected interrupt");
+            }
+            // on the lookout for timeout
+            Assert.assertSame(0L, latch.getCount());
+            
+            String actual = toString();
+            
+            Assert.assertEquals(expected, actual);
+        }
+    }
+    
+    public static class StringCB extends AsyncCB implements StringCallback {
+        byte[] data = new byte[10];
+        List<ACL> acl = Ids.CREATOR_ALL_ACL;
+        CreateMode flags = CreateMode.PERSISTENT;
+        String name = path;
+        
+        StringCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+        
+        StringCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+        
+        public void setPath(String path) {
+            super.setPath(path);
+            this.name = path;
+        }
+        
+        public String nodeName() {
+            return path.substring(path.lastIndexOf('/') + 1);
+        }
+        
+        public void processResult(int rc, String path, Object ctx, String name)
+        {
+            this.name = name;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+
+        public AsyncCB create() {
+            zk.create(path, data, acl, flags, this, toString());
+            return this;
+        }
+
+        public AsyncCB createEphemeral() {
+            zk.create(path, data, acl, CreateMode.EPHEMERAL, this, toString());
+            return this;
+        }
+        
+        public void verifyCreate() {
+            create();
+            verify();
+        }
+
+        public void verifyCreateEphemeral() {
+            createEphemeral();
+            verify();
+        }
+        
+        public void verifyCreateFailure_NodeExists() {
+            new StringCB(zk).verifyCreate();
+            
+            rc = Code.NODEEXISTS;
+            name = null;
+            zk.create(path, data, acl, flags, this, toString());
+            verify();
+        }
+
+        public void verifyCreateFailure_NoNode() {
+
+            rc = Code.NONODE;
+            name = null;
+            path = path + "/bar";
+            zk.create(path, data, acl, flags, this, toString());
+
+            verify();
+        }
+
+        public void verifyCreateFailure_NoChildForEphemeral() {
+            new StringCB(zk).verifyCreateEphemeral();
+
+            rc = Code.NOCHILDRENFOREPHEMERALS;
+            name = null;
+            path = path + "/bar";
+            zk.create(path, data, acl, flags, this, toString());
+
+            verify();
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + name; 
+        }
+    }
+
+    public static class ACLCB extends AsyncCB implements ACLCallback {
+        List<ACL> acl = Ids.CREATOR_ALL_ACL;
+        int version = 0;
+        Stat stat = new Stat();
+        byte[] data = "testing".getBytes();
+        
+        ACLCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        ACLCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+            stat.setAversion(0);
+            stat.setCversion(0);
+            stat.setEphemeralOwner(0);
+            stat.setVersion(0);
+        }
+
+        public void processResult(int rc, String path, Object ctx,
+                List<ACL> acl, Stat stat)
+        {
+            this.acl = acl;
+            this.stat = stat;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public void verifyGetACL() {
+            new StringCB(zk).verifyCreate();
+
+            zk.getACL(path, stat, this, toString());
+            verify();
+        }
+
+        public void verifyGetACLFailure_NoNode(){
+            rc = Code.NONODE;
+            stat = null;
+            acl = null;
+            zk.getACL(path, stat, this, toString());
+
+            verify();
+        }
+        
+        public String toString(List<ACL> acls) {
+            if (acls == null) {
+                return "";
+            }
+
+            StringBuilder result = new StringBuilder();
+            for(ACL acl : acls) {
+                result.append(acl.getPerms()).append("::");
+            }
+            return result.toString();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString() + toString(acl) + ":" 
+                + ":" + version + ":" + new String(data)
+                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
+                        + stat.getCversion() + ":" + stat.getEphemeralOwner()
+                        + ":" + stat.getVersion()); 
+        }
+    }
+
+    public static class ChildrenCB extends AsyncCB implements ChildrenCallback {
+        List<String> children = new ArrayList<String>();
+        
+        ChildrenCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        ChildrenCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+        
+        public void processResult(int rc, String path, Object ctx,
+                List<String> children)
+        {
+            this.children =
+                (children == null ? new ArrayList<String>() : children);
+            Collections.sort(this.children);
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public StringCB createNode() {
+            StringCB parent = new StringCB(zk);
+            parent.verifyCreate();
+
+            return parent;
+        }
+        
+        public StringCB createNode(StringCB parent) {
+            String childName = "bar";
+
+            return createNode(parent, childName);
+        }
+
+        public StringCB createNode(StringCB parent, String childName) {
+            StringCB child = new StringCB(zk);
+            child.setPath(parent.path + "/" + childName);
+            child.verifyCreate();
+            
+            return child;
+        }
+        
+        public void verifyGetChildrenEmpty() {
+            StringCB parent = createNode();
+            path = parent.path;
+            verify();
+        }
+
+        public void verifyGetChildrenSingle() {
+            StringCB parent = createNode();
+            StringCB child = createNode(parent);
+
+            path = parent.path;
+            children.add(child.nodeName());
+            
+            verify();
+        }
+        
+        public void verifyGetChildrenTwo() {
+            StringCB parent = createNode();
+            StringCB child1 = createNode(parent, "child1");
+            StringCB child2 = createNode(parent, "child2");
+        
+            path = parent.path;
+            children.add(child1.nodeName());
+            children.add(child2.nodeName());
+            
+            verify();
+        }
+        
+        public void verifyGetChildrenFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            verify();
+        }
+        
+        @Override
+        public void verify() {
+            zk.getChildren(path, false, this, toString());
+            super.verify();
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + children.toString();
+        }
+    }
+
+    public static class Children2CB extends AsyncCB implements Children2Callback {
+        List<String> children = new ArrayList<String>();
+
+        Children2CB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        Children2CB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+
+        public void processResult(int rc, String path, Object ctx,
+                List<String> children, Stat stat)
+        {
+            this.children =
+                (children == null ? new ArrayList<String>() : children);
+            Collections.sort(this.children);
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public StringCB createNode() {
+            StringCB parent = new StringCB(zk);
+            parent.verifyCreate();
+
+            return parent;
+        }
+        
+        public StringCB createNode(StringCB parent) {
+            String childName = "bar";
+
+            return createNode(parent, childName);
+        }
+
+        public StringCB createNode(StringCB parent, String childName) {
+            StringCB child = new StringCB(zk);
+            child.setPath(parent.path + "/" + childName);
+            child.verifyCreate();
+            
+            return child;
+        }
+        
+        public void verifyGetChildrenEmpty() {
+            StringCB parent = createNode();
+            path = parent.path;
+            verify();
+        }
+
+        public void verifyGetChildrenSingle() {
+            StringCB parent = createNode();
+            StringCB child = createNode(parent);
+
+            path = parent.path;
+            children.add(child.nodeName());
+            
+            verify();
+        }
+        
+        public void verifyGetChildrenTwo() {
+            StringCB parent = createNode();
+            StringCB child1 = createNode(parent, "child1");
+            StringCB child2 = createNode(parent, "child2");
+        
+            path = parent.path;
+            children.add(child1.nodeName());
+            children.add(child2.nodeName());
+            
+            verify();
+        }
+        
+        public void verifyGetChildrenFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            verify();
+        }
+        
+        @Override
+        public void verify() {
+            zk.getChildren(path, false, this, toString());
+            super.verify();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString() + children.toString(); 
+        }
+    }
+
+    public static class Create2CB extends AsyncCB implements Create2Callback {
+    	  byte[] data = new byte[10];
+        List<ACL> acl = Ids.CREATOR_ALL_ACL;
+        CreateMode flags = CreateMode.PERSISTENT;
+        String name = path;
+        Stat stat = new Stat();
+
+        Create2CB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        Create2CB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+
+        public void setPath(String path) {
+            super.setPath(path);
+            this.name = path;
+        }
+
+        public String nodeName() {
+            return path.substring(path.lastIndexOf('/') + 1);
+        }
+
+        public void processResult(int rc, String path, Object ctx,
+                String name, Stat stat) {
+            this.name = name;
+            this.stat = stat;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+
+        public AsyncCB create() {
+            zk.create(path, data, acl, flags, this, toString());
+            return this;
+        }
+
+        public void verifyCreate() {
+            create();
+            verify();
+        }
+
+        public void verifyCreateFailure_NodeExists() {
+            new Create2CB(zk).verifyCreate();
+            rc = Code.NODEEXISTS;
+            name = null;
+            stat = null;
+            zk.create(path, data, acl, flags, this, toString());
+            verify();
+        }
+
+        public void verifyCreateFailure_NoNode() {
+            rc = Code.NONODE;
+            name = null;
+            stat = null;
+            path = path + "/bar";
+            zk.create(path, data, acl, flags, this, toString());
+
+            verify();
+        }
+
+        public void verifyCreateFailure_NoChildForEphemeral() {
+            new StringCB(zk).verifyCreateEphemeral();
+
+            rc = Code.NOCHILDRENFOREPHEMERALS;
+            name = null;
+            stat = null;
+            path = path + "/bar";
+            zk.create(path, data, acl, flags, this, toString());
+
+            verify();
+        }
+
+        @Override
+        public String toString() {
+            return super.toString() + name + ":" +
+                (stat == null ? "null" : stat.getAversion() + ":" +
+            		 stat.getCversion() + ":" + stat.getEphemeralOwner() +
+                 ":" + stat.getVersion());
+        }
+    }
+
+    public static class DataCB extends AsyncCB implements DataCallback {
+        byte[] data = new byte[10];
+        Stat stat = new Stat();
+        
+        DataCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        DataCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+            stat.setAversion(0);
+            stat.setCversion(0);
+            stat.setEphemeralOwner(0);
+            stat.setVersion(0);
+        }
+        
+        public void processResult(int rc, String path, Object ctx, byte[] data,
+                Stat stat)
+        {
+            this.data = data;
+            this.stat = stat;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public void verifyGetData() {
+            new StringCB(zk).verifyCreate();
+
+            zk.getData(path, false, this, toString());
+            verify();
+        }
+        
+        public void verifyGetDataFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            data = null;
+            stat = null;
+            zk.getData(path, false, this, toString());
+            verify();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString()
+                + ":" + (data == null ? "null" : new String(data))
+                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
+                    + stat.getCversion() + ":" + stat.getEphemeralOwner()
+                    + ":" + stat.getVersion()); 
+        }
+    }
+
+    public static class StatCB extends AsyncCB implements StatCallback {
+        List<ACL> acl = Ids.CREATOR_ALL_ACL;
+        int version = 0;
+        Stat stat = new Stat();
+        byte[] data = "testing".getBytes();
+        
+        StatCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+
+        StatCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+            stat.setAversion(0);
+            stat.setCversion(0);
+            stat.setEphemeralOwner(0);
+            stat.setVersion(0);
+        }
+        
+        public void processResult(int rc, String path, Object ctx, Stat stat) {
+            this.stat = stat;
+            super.processResult(Code.get(rc), path, ctx);
+        }
+        
+        public void verifySetACL() {
+            stat.setAversion(1);
+            new StringCB(zk).verifyCreate();
+
+            zk.setACL(path, acl, version, this, toString());
+            verify();
+        }
+        
+        public void verifySetACLFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            stat = null;
+            zk.setACL(path, acl, version, this, toString());
+            verify();
+        }
+
+        public void verifySetACLFailure_BadVersion() {
+            new StringCB(zk).verifyCreate();
+
+            rc = Code.BADVERSION;
+            stat = null;
+            zk.setACL(path, acl, version + 1, this, toString());
+
+            verify();
+        }
+        
+        public void setData() {
+            zk.setData(path, data, version, this, toString());
+        }
+        
+        public void verifySetData() {
+            stat.setVersion(1);
+            new StringCB(zk).verifyCreate();
+
+            setData();
+            verify();
+        }
+        
+        public void verifySetDataFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            stat = null;
+            zk.setData(path, data, version, this, toString());
+            verify();
+        }
+
+        public void verifySetDataFailure_BadVersion() {
+            new StringCB(zk).verifyCreate();
+
+            rc = Code.BADVERSION;
+            stat = null;
+            zk.setData(path, data, version + 1, this, toString());
+
+            verify();
+        }
+        
+        public void verifyExists() {
+            new StringCB(zk).verifyCreate();
+
+            zk.exists(path, false, this, toString());
+            verify();
+        }
+        
+        public void verifyExistsFailure_NoNode() {
+            rc = KeeperException.Code.NONODE;
+            stat = null;
+            zk.exists(path, false, this, toString());
+            verify();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString() + version
+                + ":" + new String(data)
+                + ":" + (stat == null ? "null" : stat.getAversion() + ":" 
+                        + stat.getCversion() + ":" + stat.getEphemeralOwner()
+                        + ":" + stat.getVersion()); 
+        }
+    }
+
+    public static class VoidCB extends AsyncCB implements VoidCallback {
+        int version = 0;
+        
+        VoidCB(ZooKeeper zk) {
+            this(zk, new CountDownLatch(1));
+        }
+        
+        VoidCB(ZooKeeper zk, CountDownLatch latch) {
+            super(zk, latch);
+        }
+        
+        public void processResult(int rc, String path, Object ctx) {
+            super.processResult(Code.get(rc), path, ctx);
+        }
+
+        public void delete() {
+            zk.delete(path, version, this, toString());
+        }
+        
+        public void verifyDelete() {
+            new StringCB(zk).verifyCreate();
+
+            delete();
+            verify();
+        }
+        
+        public void verifyDeleteFailure_NoNode() {
+            rc = Code.NONODE;
+            zk.delete(path, version, this, toString());
+            verify();
+        }
+
+        public void verifyDeleteFailure_BadVersion() {
+            new StringCB(zk).verifyCreate();
+            rc = Code.BADVERSION;
+            zk.delete(path, version + 1, this, toString());
+            verify();
+        }
+
+        public void verifyDeleteFailure_NotEmpty() {
+            StringCB scb = new StringCB(zk);
+            scb.create();
+            scb.setPath(path + "/bar");
+            scb.create();
+
+            rc = Code.NOTEMPTY;
+            zk.delete(path, version, this, toString());
+            verify();
+        }
+        
+        public void sync() {
+            zk.sync(path, this, toString());
+        }
+        
+        public void verifySync() {
+            sync();
+            verify();
+        }
+        
+        @Override
+        public String toString() {
+            return super.toString() + version; 
+        }
+    }
+
+    public static class MultiCB implements MultiCallback {
+        ZooKeeper zk;
+        int rc;
+        List<OpResult> opResults;
+        final CountDownLatch latch = new CountDownLatch(1);
+
+        MultiCB(ZooKeeper zk) {
+            this.zk = zk;
+        }
+
+        public void processResult(int rc, String path, Object ctx,
+                                  List<OpResult> opResults) {
+            this.rc = rc;
+            this.opResults = opResults;
+            latch.countDown();
+        }
+
+        void latch_await(){
+            try {
+                latch.await(10000, TimeUnit.MILLISECONDS);
+            } catch (InterruptedException e) {
+                Assert.fail("unexpected interrupt");
+            }
+            Assert.assertSame(0L, latch.getCount());
+        }
+
+        public void verifyMulti() {
+            List<Op> ops = Arrays.asList(
+                    Op.create("/multi", new byte[0],
+                            Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                    Op.delete("/multi", -1));
+            zk.multi(ops, this, null);
+            latch_await();
+
+            Assert.assertEquals(this.rc, KeeperException.Code.OK.intValue());
+            Assert.assertTrue(this.opResults.get(0) instanceof OpResult.CreateResult);
+            Assert.assertTrue(this.opResults.get(1) instanceof OpResult.DeleteResult);
+        }
+
+        public void verifyMultiFailure_AllErrorResult() {
+            List<Op> ops = Arrays.asList(
+                    Op.create("/multi", new byte[0],
+                            Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                    Op.delete("/nonexist1", -1),
+                    Op.setData("/multi", "test".getBytes(), -1));
+            zk.multi(ops, this, null);
+            latch_await();
+
+            Assert.assertTrue(this.opResults.get(0) instanceof OpResult.ErrorResult);
+            Assert.assertTrue(this.opResults.get(1) instanceof OpResult.ErrorResult);
+            Assert.assertTrue(this.opResults.get(2) instanceof OpResult.ErrorResult);
+        }
+
+        public void verifyMultiFailure_NoSideEffect() throws KeeperException, InterruptedException {
+            List<Op> ops = Arrays.asList(
+                    Op.create("/multi", new byte[0],
+                            Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+                    Op.delete("/nonexist1", -1));
+            zk.multi(ops, this, null);
+            latch_await();
+
+            Assert.assertTrue(this.opResults.get(0) instanceof OpResult.ErrorResult);
+            Assert.assertNull(zk.exists("/multi", false));
+        }
+
+        public void verifyMultiSequential_NoSideEffect() throws Exception{
+            StringCB scb = new StringCB(zk);
+            scb.verifyCreate();
+            String path = scb.path + "-";
+            String seqPath = path + "0000000002";
+
+            zk.create(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            Assert.assertNotNull(zk.exists(path + "0000000001", false));
+
+            List<Op> ops = Arrays.asList(
+                    Op.create(path , new byte[0],
+                            Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL),
+                    Op.delete("/nonexist", -1));
+            zk.multi(ops, this, null);
+            latch_await();
+
+            Assert.assertNull(zk.exists(seqPath, false));
+            zk.create(path, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            Assert.assertNotNull(zk.exists(seqPath, false));
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
new file mode 100644
index 0000000..037ea2f
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncOpsTest.java
@@ -0,0 +1,271 @@
+/**
+ * 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.lang.Exception;
+import java.util.concurrent.CountDownLatch;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.test.AsyncOps.ACLCB;
+import org.apache.zookeeper.test.AsyncOps.Children2CB;
+import org.apache.zookeeper.test.AsyncOps.ChildrenCB;
+import org.apache.zookeeper.test.AsyncOps.Create2CB;
+import org.apache.zookeeper.test.AsyncOps.DataCB;
+import org.apache.zookeeper.test.AsyncOps.StatCB;
+import org.apache.zookeeper.test.AsyncOps.StringCB;
+import org.apache.zookeeper.test.AsyncOps.VoidCB;
+import org.apache.zookeeper.test.AsyncOps.MultiCB;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AsyncOpsTest extends ClientBase {
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncOpsTest.class);
+
+    private ZooKeeper zk;
+
+    @Before
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        LOG.info("Creating client " + getTestName());
+
+        zk = createClient();
+        zk.addAuthInfo("digest", "ben:passwd".getBytes());
+    }
+
+    @After
+    @Override
+    public void tearDown() throws Exception {
+        zk.close();
+
+        super.tearDown();
+
+        LOG.info("Test clients shutting down");
+    }
+
+    @Test
+    public void testAsyncCreate() {
+        new StringCB(zk).verifyCreate();
+    }
+
+    @Test
+    public void testAsyncCreate2() {
+        new Create2CB(zk).verifyCreate();
+    }
+
+    @Test
+    public void testAsyncCreateThree() {
+        CountDownLatch latch = new CountDownLatch(3);
+
+        StringCB op1 = new StringCB(zk, latch);
+        op1.setPath("/op1");
+        StringCB op2 = new StringCB(zk, latch);
+        op2.setPath("/op2");
+        StringCB op3 = new StringCB(zk, latch);
+        op3.setPath("/op3");
+
+        op1.create();
+        op2.create();
+        op3.create();
+
+        op1.verify();
+        op2.verify();
+        op3.verify();
+    }
+
+    @Test
+    public void testAsyncCreateFailure_NodeExists() {
+        new StringCB(zk).verifyCreateFailure_NodeExists();
+    }
+
+    @Test
+    public void testAsyncCreateFailure_NoNode() {
+        new StringCB(zk).verifyCreateFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncCreateFailure_NoChildForEphemeral() {
+        new StringCB(zk).verifyCreateFailure_NoChildForEphemeral();
+    }
+
+    @Test
+    public void testAsyncCreate2Failure_NodeExists() {
+        new Create2CB(zk).verifyCreateFailure_NodeExists();
+    }
+
+    @Test
+    public void testAsyncCreate2Failure_NoNode() {
+        new Create2CB(zk).verifyCreateFailure_NoNode();
+    }
+
+
+    @Test
+    public void testAsyncCreate2Failure_NoChildForEphemeral() {
+        new Create2CB(zk).verifyCreateFailure_NoChildForEphemeral();
+    }
+
+    @Test
+    public void testAsyncDelete() {
+        new VoidCB(zk).verifyDelete();
+    }
+
+    @Test
+    public void testAsyncDeleteFailure_NoNode() {
+        new VoidCB(zk).verifyDeleteFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncDeleteFailure_BadVersion() {
+        new VoidCB(zk).verifyDeleteFailure_BadVersion();
+    }
+
+    @Test
+    public void testAsyncDeleteFailure_NotEmpty() {
+        new VoidCB(zk).verifyDeleteFailure_NotEmpty();
+    }
+
+    @Test
+    public void testAsyncSync() {
+        new VoidCB(zk).verifySync();
+    }
+
+    @Test
+    public void testAsyncSetACL() {
+        new StatCB(zk).verifySetACL();
+    }
+
+    @Test
+    public void testAsyncSetACLFailure_NoNode() {
+        new StatCB(zk).verifySetACLFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncSetACLFailure_BadVersion() {
+        new StatCB(zk).verifySetACLFailure_BadVersion();
+    }
+
+    @Test
+    public void testAsyncSetData() {
+        new StatCB(zk).verifySetData();
+    }
+
+    @Test
+    public void testAsyncSetDataFailure_NoNode() {
+        new StatCB(zk).verifySetDataFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncSetDataFailure_BadVersion() {
+        new StatCB(zk).verifySetDataFailure_BadVersion();
+    }
+
+    @Test
+    public void testAsyncExists() {
+        new StatCB(zk).verifyExists();
+    }
+
+    @Test
+    public void testAsyncExistsFailure_NoNode() {
+        new StatCB(zk).verifyExistsFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncGetACL() {
+        new ACLCB(zk).verifyGetACL();
+    }
+
+    @Test
+    public void testAsyncGetACLFailure_NoNode() {
+        new ACLCB(zk).verifyGetACLFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncGetChildrenEmpty() {
+        new ChildrenCB(zk).verifyGetChildrenEmpty();
+    }
+
+    @Test
+    public void testAsyncGetChildrenSingle() {
+        new ChildrenCB(zk).verifyGetChildrenSingle();
+    }
+
+    @Test
+    public void testAsyncGetChildrenTwo() {
+        new ChildrenCB(zk).verifyGetChildrenTwo();
+    }
+
+    @Test
+    public void testAsyncGetChildrenFailure_NoNode() {
+        new ChildrenCB(zk).verifyGetChildrenFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncGetChildren2Empty() {
+        new Children2CB(zk).verifyGetChildrenEmpty();
+    }
+
+    @Test
+    public void testAsyncGetChildren2Single() {
+        new Children2CB(zk).verifyGetChildrenSingle();
+    }
+
+    @Test
+    public void testAsyncGetChildren2Two() {
+        new Children2CB(zk).verifyGetChildrenTwo();
+    }
+
+    @Test
+    public void testAsyncGetChildren2Failure_NoNode() {
+        new Children2CB(zk).verifyGetChildrenFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncGetData() {
+        new DataCB(zk).verifyGetData();
+    }
+
+    @Test
+    public void testAsyncGetDataFailure_NoNode() {
+        new DataCB(zk).verifyGetDataFailure_NoNode();
+    }
+
+    @Test
+    public void testAsyncMulti() {
+        new MultiCB(zk).verifyMulti();
+    }
+
+    @Test
+    public void testAsyncMultiFailure_AllErrorResult() {
+        new MultiCB(zk).verifyMultiFailure_AllErrorResult();
+    }
+
+    @Test
+    public void testAsyncMultiFailure_NoSideEffect() throws Exception{
+        new MultiCB(zk).verifyMultiFailure_NoSideEffect();
+    }
+
+    @Test
+    public void testAsyncMultiSequential_NoSideEffect() throws Exception{
+        new MultiCB(zk).verifyMultiSequential_NoSideEffect();
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncTest.java
new file mode 100644
index 0000000..801d08c
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AsyncTest.java
@@ -0,0 +1,143 @@
+/**
+ * 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.util.LinkedList;
+
+import org.apache.zookeeper.AsyncCallback.DataCallback;
+import org.apache.zookeeper.AsyncCallback.StringCallback;
+import org.apache.zookeeper.AsyncCallback.VoidCallback;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.KeeperException.Code;
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.Stat;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+public class AsyncTest extends ZKTestCase
+    implements StringCallback, VoidCallback, DataCallback
+{
+    private static final Logger LOG = LoggerFactory.getLogger(AsyncTest.class);
+
+    private QuorumBase qb = new QuorumBase();
+
+    @Before
+    public void setUp() throws Exception {
+        qb.setUp();
+    }
+
+    @After
+    public void tearDown() throws Exception {
+        LOG.info("Test clients shutting down");
+        qb.tearDown();
+    }
+
+    private ZooKeeper createClient() throws Exception,InterruptedException {
+        return createClient(qb.hostPort);
+    }
+
+    private ZooKeeper createClient(String hp)
+        throws Exception, InterruptedException
+    {
+        ZooKeeper zk = ClientBase.createZKClient(hp);
+        return zk;
+    }
+
+    LinkedList<Integer> results = new LinkedList<Integer>();
+    @Test
+    public void testAsync() throws Exception
+    {
+        ZooKeeper zk = null;
+        zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "ben:passwd".getBytes());
+            zk.create("/ben", new byte[0], Ids.READ_ACL_UNSAFE, CreateMode.PERSISTENT, this, results);
+            zk.create("/ben/2", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT, this, results);
+            zk.delete("/ben", -1, this, results);
+            zk.create("/ben2", new byte[0], Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT, this, results);
+            zk.getData("/ben2", false, this, results);
+            synchronized (results) {
+                while (results.size() < 5) {
+                    results.wait();
+                }
+            }
+            Assert.assertEquals(0, (int) results.get(0));
+            Assert.assertEquals(Code.NOAUTH, Code.get(results.get(1)));
+            Assert.assertEquals(0, (int) results.get(2));
+            Assert.assertEquals(0, (int) results.get(3));
+            Assert.assertEquals(0, (int) results.get(4));
+        } finally {
+            zk.close();
+        }
+
+        zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "ben:passwd2".getBytes());
+            try {
+                zk.getData("/ben2", false, new Stat());
+                Assert.fail("Should have received a permission error");
+            } catch (KeeperException e) {
+                Assert.assertEquals(Code.NOAUTH, e.code());
+            }
+        } finally {
+            zk.close();
+        }
+
+        zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "ben:passwd".getBytes());
+            zk.getData("/ben2", false, new Stat());
+        } finally {
+            zk.close();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, String name) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+
+    @SuppressWarnings("unchecked")
+    public void processResult(int rc, String path, Object ctx, byte[] data,
+            Stat stat) {
+        synchronized(ctx) {
+            ((LinkedList<Integer>)ctx).add(rc);
+            ctx.notifyAll();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
new file mode 100644
index 0000000..cbd2b77
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AtomicFileOutputStreamTest.java
@@ -0,0 +1,200 @@
+/**
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
+
+import org.apache.zookeeper.ZKTestCase;
+import org.apache.zookeeper.common.AtomicFileOutputStream;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+
+public class AtomicFileOutputStreamTest extends ZKTestCase {
+    private static final String TEST_STRING = "hello world";
+    private static final String TEST_STRING_2 = "goodbye world";
+
+    private File testDir;
+    private File dstFile;
+
+    @Before
+    public void setupTestDir() throws IOException {
+        testDir = ClientBase.createEmptyTestDir();
+        dstFile = new File(testDir, "test.txt");
+    }
+    @After
+    public void cleanupTestDir() throws IOException {
+        ClientBase.recursiveDelete(testDir);
+    }
+
+    /**
+     * Test case where there is no existing file
+     */
+    @Test
+    public void testWriteNewFile() throws IOException {
+        OutputStream fos = new AtomicFileOutputStream(dstFile);
+        assertFalse(dstFile.exists());
+        fos.write(TEST_STRING.getBytes());
+        fos.flush();
+        assertFalse(dstFile.exists());
+        fos.close();
+        assertTrue(dstFile.exists());
+
+        String readBackData = ClientBase.readFile(dstFile);
+        assertEquals(TEST_STRING, readBackData);
+    }
+
+    /**
+     * Test case where there is no existing file
+     */
+    @Test
+    public void testOverwriteFile() throws IOException {
+        assertTrue("Creating empty dst file", dstFile.createNewFile());
+
+        OutputStream fos = new AtomicFileOutputStream(dstFile);
+
+        assertTrue("Empty file still exists", dstFile.exists());
+        fos.write(TEST_STRING.getBytes());
+        fos.flush();
+
+        // Original contents still in place
+        assertEquals("", ClientBase.readFile(dstFile));
+
+        fos.close();
+
+        // New contents replace original file
+        String readBackData = ClientBase.readFile(dstFile);
+        assertEquals(TEST_STRING, readBackData);
+    }
+
+    /**
+     * Test case where the flush() fails at close time - make sure that we clean
+     * up after ourselves and don't touch any existing file at the destination
+     */
+    @Test
+    public void testFailToFlush() throws IOException {
+        // Create a file at destination
+        FileOutputStream fos = new FileOutputStream(dstFile);
+        fos.write(TEST_STRING_2.getBytes());
+        fos.close();
+
+        OutputStream failingStream = createFailingStream();
+        failingStream.write(TEST_STRING.getBytes());
+        try {
+            failingStream.close();
+            fail("Close didn't throw exception");
+        } catch (IOException ioe) {
+            // expected
+        }
+
+        // Should not have touched original file
+        assertEquals(TEST_STRING_2, ClientBase.readFile(dstFile));
+
+        assertEquals("Temporary file should have been cleaned up",
+                dstFile.getName(), ClientBase.join(",", testDir.list()));
+    }
+
+    /**
+     * Create a stream that fails to flush at close time
+     */
+    private OutputStream createFailingStream() throws FileNotFoundException {
+        return new AtomicFileOutputStream(dstFile) {
+            @Override
+            public void flush() throws IOException {
+                throw new IOException("injected failure");
+            }
+        };
+    }
+
+    /**
+     * Ensure the tmp file is cleaned up and dstFile is not created when
+     * aborting a new file.
+     */
+    @Test
+    public void testAbortNewFile() throws IOException {
+        AtomicFileOutputStream fos = new AtomicFileOutputStream(dstFile);
+
+        fos.abort();
+
+        assertEquals(0, testDir.list().length);
+    }
+
+    /**
+     * Ensure the tmp file is cleaned up and dstFile is not created when
+     * aborting a new file.
+     */
+    @Test
+    public void testAbortNewFileAfterFlush() throws IOException {
+        AtomicFileOutputStream fos = new AtomicFileOutputStream(dstFile);
+        fos.write(TEST_STRING.getBytes());
+        fos.flush();
+
+        fos.abort();
+
+        assertEquals(0, testDir.list().length);
+    }
+
+    /**
+     * Ensure the tmp file is cleaned up and dstFile is untouched when
+     * aborting an existing file overwrite.
+     */
+    @Test
+    public void testAbortExistingFile() throws IOException {
+        FileOutputStream fos1 = new FileOutputStream(dstFile);
+        fos1.write(TEST_STRING.getBytes());
+        fos1.close();
+
+        AtomicFileOutputStream fos2 = new AtomicFileOutputStream(dstFile);
+
+        fos2.abort();
+
+        // Should not have touched original file
+        assertEquals(TEST_STRING, ClientBase.readFile(dstFile));
+        assertEquals(1, testDir.list().length);
+    }
+
+    /**
+     * Ensure the tmp file is cleaned up and dstFile is untouched when
+     * aborting an existing file overwrite.
+     */
+    @Test
+    public void testAbortExistingFileAfterFlush() throws IOException {
+        FileOutputStream fos1 = new FileOutputStream(dstFile);
+        fos1.write(TEST_STRING.getBytes());
+        fos1.close();
+
+        AtomicFileOutputStream fos2 = new AtomicFileOutputStream(dstFile);
+        fos2.write(TEST_STRING_2.getBytes());
+        fos2.flush();
+
+        fos2.abort();
+
+        // Should not have touched original file
+        assertEquals(TEST_STRING, ClientBase.readFile(dstFile));
+        assertEquals(1, testDir.list().length);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/AuthTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/AuthTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AuthTest.java
new file mode 100644
index 0000000..60e3453
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/AuthTest.java
@@ -0,0 +1,174 @@
+/**
+ * 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.concurrent.CountDownLatch;
+import java.util.concurrent.TimeUnit;
+
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.TestableZooKeeper;
+import org.apache.zookeeper.WatchedEvent;
+import org.apache.zookeeper.Watcher.Event.KeeperState;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.junit.Assert;
+import org.junit.Test;
+
+public class AuthTest extends ClientBase {
+    static {
+        // password is test
+        System.setProperty("zookeeper.DigestAuthenticationProvider.superDigest",
+                "super:D/InIHSb7yEEbrWz8b9l71RjZJU=");    
+        System.setProperty("zookeeper.authProvider.1", "org.apache.zookeeper.test.InvalidAuthProvider");
+    }
+
+    private final CountDownLatch authFailed = new CountDownLatch(1);
+
+    @Override
+    protected TestableZooKeeper createClient(String hp)
+    throws IOException, InterruptedException
+    {
+        MyWatcher watcher = new MyWatcher();
+        return createClient(watcher, hp);
+    }
+
+    private class MyWatcher extends CountdownWatcher {
+        @Override
+        public synchronized void process(WatchedEvent event) {
+            if (event.getState() == KeeperState.AuthFailed) {
+                authFailed.countDown();
+            }
+            else {
+                super.process(event);
+            }
+        }
+    }
+
+    @Test
+    public void testBadAuthNotifiesWatch() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.addAuthInfo("FOO", "BAR".getBytes());
+            zk.getData("/path1", false, null);
+            Assert.fail("Should get auth state error");
+        } catch(KeeperException.AuthFailedException e) {
+            if(!authFailed.await(CONNECTION_TIMEOUT,
+                    TimeUnit.MILLISECONDS))
+            {
+                Assert.fail("Should have called my watcher");
+            }
+        }
+        finally {
+            zk.close();
+        }
+    }
+    
+    @Test
+    public void testBadAuthThenSendOtherCommands() throws Exception {
+        ZooKeeper zk = createClient();     
+        try {        
+            zk.addAuthInfo("INVALID", "BAR".getBytes());
+            zk.exists("/foobar", false);             
+            zk.getData("/path1", false, null);
+            Assert.fail("Should get auth state error");
+        } catch(KeeperException.AuthFailedException e) {
+            if(!authFailed.await(CONNECTION_TIMEOUT,
+                    TimeUnit.MILLISECONDS))
+            {
+                Assert.fail("Should have called my watcher");
+            }
+        }
+        finally {
+            zk.close();          
+        }
+    }
+
+    
+    @Test
+    public void testSuper() throws Exception {
+        ZooKeeper zk = createClient();
+        try {
+            zk.addAuthInfo("digest", "pat:pass".getBytes());
+            zk.create("/path1", null, Ids.CREATOR_ALL_ACL,
+                    CreateMode.PERSISTENT);
+            zk.close();
+            // verify no auth
+            zk = createClient();
+            try {
+                zk.getData("/path1", false, null);
+                Assert.fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify bad pass Assert.fails
+            zk = createClient();
+            zk.addAuthInfo("digest", "pat:pass2".getBytes());
+            try {
+                zk.getData("/path1", false, null);
+                Assert.fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify super with bad pass Assert.fails
+            zk = createClient();
+            zk.addAuthInfo("digest", "super:test2".getBytes());
+            try {
+                zk.getData("/path1", false, null);
+                Assert.fail("auth verification");
+            } catch (KeeperException.NoAuthException e) {
+                // expected
+            }
+            zk.close();
+            // verify super with correct pass success
+            zk = createClient();
+            zk.addAuthInfo("digest", "super:test".getBytes());
+            zk.getData("/path1", false, null);
+        } finally {
+            zk.close();
+        }
+    }
+    
+    @Test
+    public void testSuperACL() throws Exception {
+    	 ZooKeeper zk = createClient();
+         try {
+             zk.addAuthInfo("digest", "pat:pass".getBytes());
+             zk.create("/path1", null, Ids.CREATOR_ALL_ACL,
+                     CreateMode.PERSISTENT);
+             zk.close();
+             // verify super can do anything and ignores ACLs
+             zk = createClient();
+             zk.addAuthInfo("digest", "super:test".getBytes());
+             zk.getData("/path1", false, null);
+             
+             zk.setACL("/path1", Ids.READ_ACL_UNSAFE, -1);
+             zk.create("/path1/foo", null, Ids.CREATOR_ALL_ACL, CreateMode.PERSISTENT);
+           
+             
+             zk.setACL("/path1", Ids.OPEN_ACL_UNSAFE, -1);
+        	 
+         } finally {
+             zk.close();
+         }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
new file mode 100644
index 0000000..f164298
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/BufferSizeTest.java
@@ -0,0 +1,135 @@
+/**
+ * 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 static org.junit.Assert.assertEquals;
+import static org.junit.Assert.fail;
+
+import java.io.File;
+import java.io.IOException;
+
+import org.apache.jute.BinaryInputArchive;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
+import org.junit.Before;
+import org.junit.Test;
+
+public class BufferSizeTest extends ClientBase {
+    public static final int TEST_MAXBUFFER = 100;
+    private static final File TEST_DATA = new File(
+            System.getProperty("test.data.dir", "build/test/data"),
+            "buffersize");
+    
+    private ZooKeeper zk;
+
+    @Before
+    public void setMaxBuffer() throws IOException, InterruptedException {
+        System.setProperty("jute.maxbuffer", "" + TEST_MAXBUFFER);
+        assertEquals("Can't set jute.maxbuffer!", TEST_MAXBUFFER, BinaryInputArchive.maxBuffer);
+        zk = createClient();
+    }
+    
+    @Test
+    public void testCreatesReqs() throws Exception {
+        testRequests(new ClientOp() {
+            @Override
+            public void execute(byte[] data) throws Exception {
+                zk.create("/create_test", data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT_SEQUENTIAL);
+            }
+        });
+    }
+    
+    @Test
+    public void testSetReqs() throws Exception {
+        final String path = "/set_test";
+        zk.create(path, new byte[1], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        testRequests(new ClientOp() {
+            @Override
+            public void execute(byte[] data) throws Exception {
+                zk.setData(path, data, -1);
+            }
+        });
+    }
+    
+    /** Issues requests containing data smaller, equal, and greater than TEST_MAXBUFFER. */
+    private void testRequests(ClientOp clientOp) throws Exception {
+        clientOp.execute(new byte[TEST_MAXBUFFER - 60]);
+        try {
+            // This should fail since the buffer size > the data size due to extra fields
+            clientOp.execute(new byte[TEST_MAXBUFFER]);
+            fail("Request exceeding jute.maxbuffer succeeded!");
+        } catch (KeeperException.ConnectionLossException e) {}
+        try {
+            clientOp.execute(new byte[TEST_MAXBUFFER + 10]);
+            fail("Request exceeding jute.maxbuffer succeeded!");
+        } catch (KeeperException.ConnectionLossException e) {}
+    }
+
+    private interface ClientOp {
+        void execute(byte[] data) throws Exception;
+    }
+
+    @Test
+    public void testStartup() throws Exception {
+        final String path = "/test_node";
+        zk.create(path, new byte[TEST_MAXBUFFER - 60], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+        zk.setData(path, new byte[TEST_MAXBUFFER - 50], -1);
+
+        stopServer();
+        startServer();
+    }
+    
+    @Test
+    public void testStartupFailureCreate() throws Exception {
+        // Empty snapshot and logfile containing a 5000-byte create
+        testStartupFailure(new File(TEST_DATA, "create"),
+                "Server started despite create exceeding jute.maxbuffer!");
+    }
+    
+    @Test
+    public void testStartupFailureSet() throws Exception {
+        // Empty snapshot and logfile containing a 1-byte create and 5000-byte set
+        testStartupFailure(new File(TEST_DATA, "set"),
+                "Server started despite set exceeding jute.maxbuffer!");
+    }
+    
+    @Test
+    public void testStartupFailureSnapshot() throws Exception {
+        // Snapshot containing 5000-byte znode and logfile containing create txn
+        testStartupFailure(new File(TEST_DATA, "snapshot"),
+                "Server started despite znode exceeding jute.maxbuffer!");
+    }
+    
+    private void testStartupFailure(File testDir, String failureMsg) throws Exception {
+        stopServer();
+        // Point server at testDir
+        File oldTmpDir = tmpDir;
+        tmpDir = testDir;
+        try {
+            startServer();
+            fail(failureMsg);
+        } catch (IOException e) {
+            LOG.info("Successfully caught IOException: " + e);
+        } finally {
+            tmpDir = oldTmpDir;
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
new file mode 100644
index 0000000..e60ea04
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootAsyncTest.java
@@ -0,0 +1,47 @@
+/**
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+
+public class ChrootAsyncTest extends AsyncOpsTest {
+    private static final Logger LOG = LoggerFactory.getLogger(ChrootAsyncTest.class);
+
+    @Override
+    public void setUp() throws Exception {
+        String hp = hostPort;
+        hostPort = hostPort + "/chrootasynctest";
+
+        super.setUp();
+
+        LOG.info("Creating client " + getTestName());
+
+        ZooKeeper zk = createClient(hp);
+        try {
+            zk.create("/chrootasynctest", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        } finally {
+            zk.close();
+        }
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/43d71c2e/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
----------------------------------------------------------------------
diff --git a/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
new file mode 100644
index 0000000..e0286e1
--- /dev/null
+++ b/zookeeper-server/src/test/java/org/apache/zookeeper/test/ChrootClientTest.java
@@ -0,0 +1,54 @@
+/**
+ * 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 org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.junit.Test;
+
+public class ChrootClientTest extends ClientTest {
+    private static final Logger LOG = LoggerFactory.getLogger(ChrootClientTest.class);
+
+    @Override
+    public void setUp() throws Exception {
+        String hp = hostPort;
+        hostPort = hostPort + "/chrootclienttest";
+
+        System.out.println(hostPort);
+        super.setUp();
+
+        LOG.info("STARTING " + getTestName());
+
+        ZooKeeper zk = createClient(hp);
+        try {
+            zk.create("/chrootclienttest", null, Ids.OPEN_ACL_UNSAFE,
+                    CreateMode.PERSISTENT);
+        } finally {
+            zk.close();
+        }
+    }
+    
+    @Test
+    public void testPing() throws Exception {
+        // not necessary to repeat this, expensive and not chroot related
+    }
+}


Mime
View raw message