/** * ZOOKEEPER-2052: * This test checks that if a multi operation aborted, and during the multi there is side effect * that changed outstandingChangesForPath, after aborted the side effect should be removed and * everything should be restored correctly. */ @Test public void testMultiRollbackNoLastChange() throws Exception { zks.getZKDatabase().dataTree.createNode("/foo", new byte[0], Ids.OPEN_ACL_UNSAFE, 0, 0, 0, 0); zks.getZKDatabase().dataTree.createNode("/foo/bar", new byte[0], Ids.OPEN_ACL_UNSAFE, 0, 0, 0, 0); Assert.assertNull(zks.outstandingChangesForPath.get("/foo")); // multi record: // set "/foo" => succeed, leave a outstanding change // delete "/foo" => fail, roll back change process(Arrays.asList( Op.setData("/foo", new byte[0], -1), Op.delete("/foo", -1))); // aborting multi shouldn't leave any record. Assert.assertNull(zks.outstandingChangesForPath.get("/foo")); }
/** * Test verifies the multi calls with blank znode path */ @Test(timeout = 90000) public void testBlankPath() throws Exception { List<Integer> expectedResultCodes = new ArrayList<Integer>(); expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY .intValue()); expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue()); expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY .intValue()); expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue()); // delete String expectedErr = "Path cannot be null"; List<Op> opList = Arrays.asList(Op.delete("/multi0", -1), Op.delete(null, 100), Op.delete("/multi2", 5), Op.delete("", -1)); multiHavingErrors(zk, opList, expectedResultCodes, expectedErr); }
/** * Test verifies the multi.create with invalid createModeFlag */ @Test(timeout = 90000) public void testInvalidCreateModeFlag() throws Exception { List<Integer> expectedResultCodes = new ArrayList<Integer>(); expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY .intValue()); expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue()); expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY .intValue()); int createModeFlag = 6789; List<Op> opList = Arrays.asList(Op.create("/multi0", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT), Op.create("/multi1", new byte[0], Ids.OPEN_ACL_UNSAFE, createModeFlag), Op.create("/multi2", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)); String expectedErr = KeeperException.Code.BADARGUMENTS.name(); multiHavingErrors(zk, opList, expectedResultCodes, expectedErr); }
@Test public void testChRootCreateDelete() throws Exception { // creating the subtree for chRoot clients. String chRoot = createNameSpace(); // Creating child using chRoot client. zk_chroot = createClient(this.hostPort + chRoot); Op createChild = Op.create("/myid", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); multi(zk_chroot, Arrays.asList(createChild)); Assert.assertNotNull("zNode is not created under chroot:" + chRoot, zk .exists(chRoot + "/myid", false)); Assert.assertNotNull("zNode is not created under chroot:" + chRoot, zk_chroot.exists("/myid", false)); Assert.assertNull("zNode is created directly under '/', ignored configured chroot", zk.exists("/myid", false)); // Deleting child using chRoot client. Op deleteChild = Op.delete("/myid", 0); multi(zk_chroot, Arrays.asList(deleteChild)); Assert.assertNull("zNode exists under chroot:" + chRoot, zk.exists( chRoot + "/myid", false)); Assert.assertNull("zNode exists under chroot:" + chRoot, zk_chroot .exists("/myid", false)); }
@Test public void testChRootSetData() throws Exception { // creating the subtree for chRoot clients. String chRoot = createNameSpace(); // setData using chRoot client. zk_chroot = createClient(this.hostPort + chRoot); 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)); } multi(zk_chroot, ops) ; for (int i = 0; i < names.length; i++) { Assert.assertArrayEquals("zNode data not matching", names[i] .getBytes(), zk_chroot.getData(names[i], false, null)); } }
@Test public void testChRootCheck() throws Exception { // creating the subtree for chRoot clients. String chRoot = createNameSpace(); // checking the child version using chRoot client. zk_chroot = createClient(this.hostPort + chRoot); String[] names = {"/multi0", "/multi1", "/multi2"}; List<Op> ops = new ArrayList<Op>(); for (int i = 0; i < names.length; i++) { zk.create(chRoot + names[i], new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT); } for (int i = 0; i < names.length; i++) { ops.add(Op.check(names[i], 0)); } multi(zk_chroot, ops) ; }
@Test public void testNestedCreate() throws Exception { multi(zk, 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)); } multi(zk, ops) ; for (int i = 0; i < names.length; i++) { Assert.assertArrayEquals(names[i].getBytes(), zk.getData(names[i], false, null)); } }
@Test public void TestDeleteUpdateConflict() throws Exception { /* Delete of a node folowed by an update of the (now) deleted node */ try { multi(zk, 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 testNoWatchesTriggeredForFailedMultiRequest() throws InterruptedException, KeeperException { HasTriggeredWatcher watcher = new HasTriggeredWatcher(); zk.getChildren("/", watcher); try { multi(zk, Arrays.asList( Op.create("/t", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT), Op.delete("/nonexisting", -1) )); fail("expected previous multi op to fail!"); } catch (KeeperException.NoNodeException e) { // expected } SyncCallback cb = new SyncCallback(); zk.sync("/", cb, null); // by waiting for the callback we're assured that the event queue is flushed cb.done.await(CONNECTION_TIMEOUT, TimeUnit.MILLISECONDS); assertEquals(1, watcher.triggered.getCount()); }
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)); }
/** * Test verifies the multi.create with invalid createModeFlag */ @Test(timeout = 90000) public void testInvalidCreateModeFlag() throws Exception { List<Integer> expectedResultCodes = new ArrayList<Integer>(); expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY .intValue()); expectedResultCodes.add(KeeperException.Code.BADARGUMENTS.intValue()); expectedResultCodes.add(KeeperException.Code.RUNTIMEINCONSISTENCY .intValue()); int createModeFlag = 6789; List<Op> opList = Arrays.asList(Op.create("/multi0", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT), Op.create( "/multi1", new byte[0], Ids.OPEN_ACL_UNSAFE, createModeFlag), Op.create("/multi2", new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)); String expectedErr = KeeperException.Code.BADARGUMENTS.name(); multiHavingErrors(zk, opList, expectedResultCodes, expectedErr); }
@Test public void testDeleteUpdateConflict() throws Exception { /* Delete of a node folowed by an update of the (now) deleted node */ try { multi(zk, 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)) ; }
@Override public synchronized void removeApplicationStateInternal( ApplicationStateData appState) throws Exception { String appId = appState.getApplicationSubmissionContext().getApplicationId() .toString(); String appIdRemovePath = getNodePath(rmAppRoot, appId); ArrayList<Op> opList = new ArrayList<Op>(); for (ApplicationAttemptId attemptId : appState.attempts.keySet()) { String attemptRemovePath = getNodePath(appIdRemovePath, attemptId.toString()); opList.add(Op.delete(attemptRemovePath, -1)); } opList.add(Op.delete(appIdRemovePath, -1)); if (LOG.isDebugEnabled()) { LOG.debug("Removing info for app: " + appId + " at: " + appIdRemovePath + " and its attempts."); } doDeleteMultiWithRetries(opList); }
@Override protected synchronized void removeRMDelegationTokenState( RMDelegationTokenIdentifier rmDTIdentifier) throws Exception { String nodeRemovePath = getNodePath(delegationTokensRootPath, DELEGATION_TOKEN_PREFIX + rmDTIdentifier.getSequenceNumber()); if (LOG.isDebugEnabled()) { LOG.debug("Removing RMDelegationToken_" + rmDTIdentifier.getSequenceNumber()); } if (existsWithRetries(nodeRemovePath, false) != null) { ArrayList<Op> opList = new ArrayList<Op>(); opList.add(Op.delete(nodeRemovePath, -1)); doDeleteMultiWithRetries(opList); } else { LOG.debug("Attempted to delete a non-existing znode " + nodeRemovePath); } }
@Override protected synchronized void updateRMDelegationTokenState( RMDelegationTokenIdentifier rmDTIdentifier, Long renewDate) throws Exception { ArrayList<Op> opList = new ArrayList<Op>(); String nodeRemovePath = getNodePath(delegationTokensRootPath, DELEGATION_TOKEN_PREFIX + rmDTIdentifier.getSequenceNumber()); if (existsWithRetries(nodeRemovePath, false) == null) { // in case znode doesn't exist addStoreOrUpdateOps(opList, rmDTIdentifier, renewDate, false); LOG.debug("Attempted to update a non-existing znode " + nodeRemovePath); } else { // in case znode exists addStoreOrUpdateOps(opList, rmDTIdentifier, renewDate, true); } doStoreMultiWithRetries(opList); }
/** * Helper method that creates fencing node, executes the passed * delete related operations and deletes the fencing node. */ private synchronized void doDeleteMultiWithRetries( final List<Op> opList) throws Exception { final List<Op> execOpList = new ArrayList<Op>(opList.size() + 2); execOpList.add(createFencingNodePathOp); execOpList.addAll(opList); execOpList.add(deleteFencingNodePathOp); new ZKAction<Void>() { @Override public Void run() throws KeeperException, InterruptedException { setHasDeleteNodeOp(true); zkClient.multi(execOpList); return null; } }.runWithRetries(); }
private void createZNodeTree(String rootZNode) throws KeeperException, InterruptedException { List<Op> opList = new ArrayList<Op>(); opList.add(Op.create(rootZNode, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)); int level = 0; String parentZNode = rootZNode; while (level < 10) { // define parent node parentZNode = parentZNode + "/" + level; opList.add(Op.create(parentZNode, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)); int elements = 0; // add elements to the parent node while (elements < level) { opList.add(Op.create(parentZNode + "/" + elements, new byte[0], Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT)); elements++; } level++; } zkw.getRecoverableZooKeeper().multi(opList); }
/** * Convert from ZKUtilOp to ZKOp */ private static Op toZooKeeperOp(ZooKeeperWatcher zkw, ZKUtilOp op) throws UnsupportedOperationException { if(op == null) return null; if (op instanceof CreateAndFailSilent) { CreateAndFailSilent cafs = (CreateAndFailSilent)op; return Op.create(cafs.getPath(), cafs.getData(), createACL(zkw, cafs.getPath()), CreateMode.PERSISTENT); } else if (op instanceof DeleteNodeFailSilent) { DeleteNodeFailSilent dnfs = (DeleteNodeFailSilent)op; return Op.delete(dnfs.getPath(), -1); } else if (op instanceof SetData) { SetData sd = (SetData)op; return Op.setData(sd.getPath(), sd.getData(), -1); } else { throw new UnsupportedOperationException("Unexpected ZKUtilOp type: " + op.getClass().getName()); } }