/** * For ZOOKEEPER-1046. Verify if cversion and pzxid if incremented * after create/delete failure during restore. */ @Test public void testTxnFailure() throws Exception { long count = 1; File tmpDir = ClientBase.createTmpDir(); FileTxnSnapLog logFile = new FileTxnSnapLog(tmpDir, tmpDir); DataTree dt = new DataTree(); dt.createNode("/test", new byte[0], null, 0, -1, 1, 1); for (count = 1; count <= 3; count++) { dt.createNode("/test/" + count, new byte[0], null, 0, -1, count, System.currentTimeMillis()); } DataNode zk = dt.getNode("/test"); // Make create to fail, then verify cversion. LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.create, "/test/" + (count - 1), dt, zk); // Make delete fo fail, then verify cversion. // this doesn't happen anymore, we only set the cversion on create // LOG.info("Attempting to delete " + "/test/" + (count + 1)); // doOp(logFile, OpCode.delete, "/test/" + (count + 1), dt, zk); }
/** * * @param dataNode <code>DataNode</code> to print information from. * @param dataState <code>DataState</code> is needed because it holds ACL. */ public void printDataNode(DataNode dataNode, DataState dataState) { println("cZxid:\t\t" + Util.longToHexString(dataNode.stat.getCzxid())); println("mZxid:\t\t" + Util.longToHexString(dataNode.stat.getMzxid())); println("ctime:\t\t" + new Date(dataNode.stat.getCtime())); println("mtime:\t\t" + new Date(dataNode.stat.getMtime())); println("version:\t" + dataNode.stat.getVersion()); println("cversion:\t" + dataNode.stat.getCversion()); println("aversion:\t" + dataNode.stat.getAversion()); println("ephemeralOwner:\t" + Util.longToHexString(dataNode.stat.getEphemeralOwner())); printACL(dataState.getACL(dataNode)); byte[] data = readData(dataNode); if (data != null) { println("data:\t\t" + dd.decode(data)); } else { println("data:\t\tnull"); } }
/** * For ZOOKEEPER-1046. Verify if cversion and pzxid if incremented * after create/delete failure during restore. */ @Test public void testTxnFailure() throws Exception { long count = 1; File tmpDir = ClientBase.createTmpDir(); FileTxnSnapLog logFile = new FileTxnSnapLog(tmpDir, tmpDir); DataTree dt = new DataTree(); dt.createNode("/test", new byte[0], null, 0, 1, 1); for (count = 1; count <= 3; count++) { dt.createNode("/test/" + count, new byte[0], null, 0, count, System.currentTimeMillis()); } DataNode zk = dt.getNode("/test"); // Make create to fail, then verify cversion. doOp(logFile, OpCode.create, "/test/" + (count - 1), dt, zk); // Make delete fo fail, then verify cversion. doOp(logFile, OpCode.delete, "/test/" + (count + 1), dt, zk); }
/** * convert a given old datanode to new datanode * @param dt the new datatree * @param parent the parent of the datanode to be constructed * @param oldDataNode the old datanode * @return the new datanode */ private DataNode convertDataNode(DataTree dt, DataNode parent, DataNodeV1 oldDataNode) { StatPersisted stat = convertStat(oldDataNode.stat); DataNode dataNode = new DataNode(parent, oldDataNode.data, dt.getACL(oldDataNode), stat); dataNode.setChildren(oldDataNode.children); return dataNode; }
/** * recurse through the old datatree and construct the * new data tree * @param dataTree the new datatree to be constructed * @param path the path to start with */ private void recurseThroughDataTree(DataTree dataTree, String path) { if (path == null) return; DataNodeV1 oldDataNode = oldDataTree.getNode(path); HashSet<String> children = oldDataNode.children; DataNode parent = null; if ("".equals(path)) { parent = null; } else { int lastSlash = path.lastIndexOf('/'); String parentPath = path.substring(0, lastSlash); parent = dataTree.getNode(parentPath); } DataNode thisDatNode = convertDataNode(dataTree, parent, oldDataNode); dataTree.addDataNode(path, thisDatNode); if (children == null || children.size() == 0) { return; } else { for (String child: children) { recurseThroughDataTree(dataTree, path + "/" +child); } } }
/** * For ZOOKEEPER-1046 test if cversion is getting incremented correctly. */ @Test(timeout = 60000) public void testIncrementCversion() throws Exception { dt.createNode("/test", new byte[0], null, 0, dt.getNode("/").stat.getCversion()+1, 1, 1); DataNode zk = dt.getNode("/test"); int prevCversion = zk.stat.getCversion(); long prevPzxid = zk.stat.getPzxid(); dt.setCversionPzxid("/test/", prevCversion + 1, prevPzxid + 1); int newCversion = zk.stat.getCversion(); long newPzxid = zk.stat.getPzxid(); Assert.assertTrue("<cversion, pzxid> verification failed. Expected: <" + (prevCversion + 1) + ", " + (prevPzxid + 1) + ">, found: <" + newCversion + ", " + newPzxid + ">", (newCversion == prevCversion + 1 && newPzxid == prevPzxid + 1)); }
/** * For ZOOKEEPER-1046. Verify if cversion and pzxid if incremented * after create/delete failure during restore. */ @Test public void testTxnFailure() throws Exception { long count = 1; File tmpDir = ClientBase.createTmpDir(); FileTxnSnapLog logFile = new FileTxnSnapLog(tmpDir, tmpDir); DataTree dt = new DataTree(); dt.createNode("/test", new byte[0], null, 0, -1, 1, 1); for (count = 1; count <= 3; count++) { dt.createNode("/test/" + count, new byte[0], null, 0, -1, count, System.currentTimeMillis()); } DataNode zk = dt.getNode("/test"); // Make create to fail, then verify cversion. LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.create, "/test/" + (count - 1), dt, zk, -1); LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.create, "/test/" + (count - 1), dt, zk, zk.stat.getCversion() + 1); LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.multi, "/test/" + (count - 1), dt, zk, zk.stat.getCversion() + 1); LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.multi, "/test/" + (count - 1), dt, zk, -1); // Make delete fo fail, then verify cversion. // this doesn't happen anymore, we only set the cversion on create // LOG.info("Attempting to delete " + "/test/" + (count + 1)); // doOp(logFile, OpCode.delete, "/test/" + (count + 1), dt, zk); }
/** * For ZOOKEEPER-1046. Verify if cversion and pzxid if incremented * after create/delete failure during restore. */ @Test public void testTxnFailure() throws Exception { long count = 1; File tmpDir = ClientBase.createTmpDir(); FileTxnSnapLog logFile = new FileTxnSnapLog(tmpDir, tmpDir); DataTree dt = new DataTree(); dt.createNode("/test", new byte[0], null, 0, -1, 1, 1); for (count = 1; count <= 3; count++) { dt.createNode("/test/" + count, new byte[0], null, 0, -1, count, Time.currentElapsedTime()); } DataNode zk = dt.getNode("/test"); // Make create to fail, then verify cversion. LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.create, "/test/" + (count - 1), dt, zk, -1); LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.create, "/test/" + (count - 1), dt, zk, zk.stat.getCversion() + 1); LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.multi, "/test/" + (count - 1), dt, zk, zk.stat.getCversion() + 1); LOG.info("Attempting to create " + "/test/" + (count - 1)); doOp(logFile, OpCode.multi, "/test/" + (count - 1), dt, zk, -1); // Make delete fo fail, then verify cversion. // this doesn't happen anymore, we only set the cversion on create // LOG.info("Attempting to delete " + "/test/" + (count + 1)); // doOp(logFile, OpCode.delete, "/test/" + (count + 1), dt, zk); }
/** * convert a given old datanode to new datanode * @param dt the new datatree * @param parent the parent of the datanode to be constructed * @param oldDataNode the old datanode * @return the new datanode */ private DataNode convertDataNode(DataTree dt, DataNode parent, DataNodeV1 oldDataNode) { StatPersisted stat = convertStat(oldDataNode.stat); DataNode dataNode = new DataNode(parent, oldDataNode.data, dt.convertAcls(oldDataNode.acl), stat); dataNode.setChildren(oldDataNode.children); return dataNode; }
/** * For ZOOKEEPER-1046 test if cversion is getting incremented correctly. */ @Test public void testIncrementCversion() throws Exception { dt.createNode("/test", new byte[0], null, 0, dt.getNode("/").stat.getCversion()+1, 1, 1); DataNode zk = dt.getNode("/test"); int prevCversion = zk.stat.getCversion(); long prevPzxid = zk.stat.getPzxid(); dt.setCversionPzxid("/test/", prevCversion + 1, prevPzxid + 1); int newCversion = zk.stat.getCversion(); long newPzxid = zk.stat.getPzxid(); Assert.assertTrue("<cversion, pzxid> verification failed. Expected: <" + (prevCversion + 1) + ", " + (prevPzxid + 1) + ">, found: <" + newCversion + ", " + newPzxid + ">", (newCversion == prevCversion + 1 && newPzxid == prevPzxid + 1)); }
/** * For ZOOKEEPER-1046 test if cversion is getting incremented correctly. */ @Test public void testIncrementCversion() throws Exception { dt.createNode("/test", new byte[0], null, 0, dt.getNode("/").stat.getCversion()+1, 1, 1); DataNode zk = dt.getNode("/test"); long prevCversion = zk.stat.getCversion(); long prevPzxid = zk.stat.getPzxid(); dt.incrementCversion("/test/", prevPzxid + 1); long newCversion = zk.stat.getCversion(); long newPzxid = zk.stat.getPzxid(); Assert.assertTrue("<cversion, pzxid> verification failed. Expected: <" + (prevCversion + 1) + ", " + (prevPzxid + 1) + ">, found: <" + newCversion + ", " + newPzxid + ">", (newCversion == prevCversion + 1 && newPzxid == prevPzxid + 1)); }
private static void traverse(DataTree dt, int startId, String startPath) throws Exception { LinkedList<Pair> queue = new LinkedList<Pair>(); queue.add(new Pair(startPath, startId)); while (!queue.isEmpty()) { Pair pair = queue.removeFirst(); String path = pair._path; DataNode head = dt.getNode(path); Stat stat = new Stat(); byte[] data = null; try { data = dt.getData(path, stat, null); } catch (NoNodeException e) { e.printStackTrace(); } // print the node format(startId, pair, head, data); Set<String> children = head.getChildren(); if (children != null) { for (String child : children) { String childPath; if (path.endsWith("/")) { childPath = path + child; } else { childPath = path + "/" + child; } queue.add(new Pair(childPath, startId)); } } startId = startId + 1; } }