You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by br...@apache.org on 2011/07/01 00:53:29 UTC
svn commit: r1141746 [3/3] - in /zookeeper/trunk: ./ src/ src/c/
src/c/include/ src/c/src/ src/c/tests/ src/java/main/org/apache/zookeeper/
src/java/main/org/apache/zookeeper/server/
src/java/main/org/apache/zookeeper/server/quorum/ src/java/main/org/a...
Added: zookeeper/trunk/src/java/test/org/apache/zookeeper/test/MultiTransactionTest.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/MultiTransactionTest.java?rev=1141746&view=auto
==============================================================================
--- zookeeper/trunk/src/java/test/org/apache/zookeeper/test/MultiTransactionTest.java (added)
+++ zookeeper/trunk/src/java/test/org/apache/zookeeper/test/MultiTransactionTest.java Thu Jun 30 22:53:28 2011
@@ -0,0 +1,230 @@
+/*
+ * 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.log4j.Logger;
+import org.apache.zookeeper.*;
+import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.server.ServerCnxnFactory;
+import org.apache.zookeeper.server.SyncRequestProcessor;
+import org.apache.zookeeper.server.ZooKeeperServer;
+import org.apache.zookeeper.OpResult.ErrorResult;
+import org.junit.After;
+import org.junit.Assert;
+import org.junit.Before;
+import org.junit.Test;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+import java.util.ArrayList;
+
+import org.apache.zookeeper.data.Stat;
+
+import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+public class MultiTransactionTest extends ZKTestCase implements Watcher {
+ private static final Logger LOG = Logger.getLogger(MultiTransactionTest.class);
+
+ private static final String HOSTPORT = "127.0.0.1:" + PortAssignment.unique();
+
+ private ZooKeeper zk;
+ private ServerCnxnFactory serverFactory;
+
+ @Override
+ public void process(WatchedEvent event) {
+ // ignore
+ }
+
+ @Before
+ public void setupZk() throws Exception {
+ File tmpDir = ClientBase.createTmpDir();
+ ClientBase.setupTestEnv();
+ ZooKeeperServer zks = new ZooKeeperServer(tmpDir, tmpDir, 3000);
+ SyncRequestProcessor.setSnapCount(150);
+ final int PORT = Integer.parseInt(HOSTPORT.split(":")[1]);
+ serverFactory = ServerCnxnFactory.createFactory(PORT, -1);
+ serverFactory.startup(zks);
+ LOG.info("starting up the zookeeper server .. waiting");
+ Assert.assertTrue("waiting for server being up",
+ ClientBase.waitForServerUp(HOSTPORT, CONNECTION_TIMEOUT));
+ zk = new ZooKeeper(HOSTPORT, CONNECTION_TIMEOUT, this);
+ }
+
+ @After
+ public void shutdownServer() throws Exception {
+ zk.close();
+ serverFactory.shutdown();
+ }
+
+ @Test
+ public void testCreate() throws Exception {
+ List<OpResult> results = new ArrayList<OpResult>();
+
+ results = zk.multi(Arrays.asList(
+ Op.create("/multi0", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.create("/multi1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.create("/multi2", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
+ ));
+ zk.getData("/multi0", false, null);
+ zk.getData("/multi1", false, null);
+ zk.getData("/multi2", false, null);
+ }
+
+ @Test
+ public void testCreateDelete() throws Exception {
+
+ zk.multi(Arrays.asList(
+ Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.delete("/multi", 0)
+ ));
+
+ // '/multi' should have been deleted
+ Assert.assertNull(zk.exists("/multi", null));
+ }
+
+ @Test
+ public void testInvalidVersion() throws Exception {
+
+ try {
+ zk.multi(Arrays.asList(
+ Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.delete("/multi", 1)
+ ));
+ Assert.fail("delete /multi should have failed");
+ } catch (KeeperException e) {
+ /* PASS */
+ }
+ }
+
+ @Test
+ public void testNestedCreate() throws Exception {
+
+ zk.multi(Arrays.asList(
+ /* Create */
+ Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.create("/multi/a", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.create("/multi/a/1", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+
+ /* Delete */
+ Op.delete("/multi/a/1", 0),
+ Op.delete("/multi/a", 0),
+ Op.delete("/multi", 0)
+ ));
+
+ //Verify tree deleted
+ Assert.assertNull(zk.exists("/multi/a/1", null));
+ Assert.assertNull(zk.exists("/multi/a", null));
+ Assert.assertNull(zk.exists("/multi", null));
+ }
+
+ @Test
+ public void testSetData() throws Exception {
+
+ String[] names = {"/multi0", "/multi1", "/multi2"};
+ List<Op> ops = new ArrayList<Op>();
+
+ for (int i = 0; i < names.length; i++) {
+ ops.add(Op.create(names[i], new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT));
+ ops.add(Op.setData(names[i], names[i].getBytes(), 0));
+ }
+
+ zk.multi(ops) ;
+
+ for (int i = 0; i < names.length; i++) {
+ Assert.assertArrayEquals(names[i].getBytes(), zk.getData(names[i], false, null));
+ }
+ }
+
+ @Test
+ public void testUpdateConflict() throws Exception {
+
+ Assert.assertNull(zk.exists("/multi", null));
+
+ try {
+ zk.multi(Arrays.asList(
+ Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.setData("/multi", "X".getBytes(), 0),
+ Op.setData("/multi", "Y".getBytes(), 0)
+ ));
+ Assert.fail("Should have thrown a KeeperException for invalid version");
+ } catch (KeeperException e) {
+ //PASS
+ LOG.error("STACKTRACE: " + e);
+ }
+
+ Assert.assertNull(zk.exists("/multi", null));
+
+ //Updating version solves conflict -- order matters
+ zk.multi(Arrays.asList(
+ Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.setData("/multi", "X".getBytes(), 0),
+ Op.setData("/multi", "Y".getBytes(), 1)
+ ));
+
+ Assert.assertArrayEquals(zk.getData("/multi", false, null), "Y".getBytes());
+ }
+
+ @Test
+ public void TestDeleteUpdateConflict() throws Exception {
+
+ /* Delete of a node folowed by an update of the (now) deleted node */
+ try {
+ zk.multi(Arrays.asList(
+ Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.delete("/multi", 0),
+ Op.setData("/multi", "Y".getBytes(), 0)
+ ));
+ Assert.fail("/multi should have been deleted so setData should have failed");
+ } catch (KeeperException e) {
+ /* PASS */
+ }
+
+ // '/multi' should never have been created as entire op should fail
+ Assert.assertNull(zk.exists("/multi", null)) ;
+ }
+
+ @Test
+ public void TestGetResults() throws Exception {
+ /* Delete of a node folowed by an update of the (now) deleted node */
+ try {
+ zk.multi(Arrays.asList(
+ Op.create("/multi", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT),
+ Op.delete("/multi", 0),
+ Op.setData("/multi", "Y".getBytes(), 0),
+ Op.create("/foo", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)
+ ));
+ Assert.fail("/multi should have been deleted so setData should have failed");
+ } catch (KeeperException e) {
+ // '/multi' should never have been created as entire op should fail
+ Assert.assertNull(zk.exists("/multi", null));
+
+ for (OpResult r : e.getResults()) {
+ LOG.info("RESULT==> " + r);
+ if (r instanceof ErrorResult) {
+ ErrorResult er = (ErrorResult) r;
+ LOG.info("ERROR RESULT: " + er + " ERR=>" + KeeperException.Code.get(er.getErr()));
+ }
+ }
+ }
+ }
+
+
+
+}
Modified: zookeeper/trunk/src/zookeeper.jute
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/zookeeper.jute?rev=1141746&r1=1141745&r2=1141746&view=diff
==============================================================================
--- zookeeper/trunk/src/zookeeper.jute (original)
+++ zookeeper/trunk/src/zookeeper.jute Thu Jun 30 22:53:28 2011
@@ -21,7 +21,7 @@ module org.apache.zookeeper.data {
ustring scheme;
ustring id;
}
- class ACL {
+ class ACL {
int perms;
Id id;
}
@@ -66,12 +66,6 @@ module org.apache.zookeeper.data {
}
module org.apache.zookeeper.proto {
- class op_result_t {
- int rc;
- int op;
- buffer response;
- }
-
class ConnectRequest {
int protocolVersion;
long lastZxidSeen;
@@ -95,6 +89,11 @@ module org.apache.zookeeper.proto {
int xid;
int type;
}
+ class MultiHeader {
+ int type;
+ boolean done;
+ int err;
+ }
class AuthPacket {
int type;
ustring scheme;
@@ -135,6 +134,10 @@ module org.apache.zookeeper.proto {
ustring path;
boolean watch;
}
+ class CheckVersionRequest {
+ ustring path;
+ int version;
+ }
class GetMaxChildrenRequest {
ustring path;
}
@@ -167,7 +170,9 @@ module org.apache.zookeeper.proto {
int state; // state of the Keeper client runtime
ustring path;
}
-
+ class ErrorResponse {
+ int err;
+ }
class CreateResponse {
ustring path;
}
@@ -245,6 +250,10 @@ module org.apache.zookeeper.txn {
buffer data;
int version;
}
+ class CheckVersionTxn {
+ ustring path;
+ int version;
+ }
class SetACLTxn {
ustring path;
vector<org.apache.zookeeper.data.ACL> acl;
@@ -260,4 +269,11 @@ module org.apache.zookeeper.txn {
class ErrorTxn {
int err;
}
+ class Txn {
+ int type;
+ buffer data;
+ }
+ class MultiTxn {
+ vector<org.apache.zookeeper.txn.Txn> txns;
+ }
}