You are viewing a plain text version of this content. The canonical link for it is here.
Posted to issues@bookkeeper.apache.org by GitBox <gi...@apache.org> on 2018/01/25 05:58:22 UTC
[GitHub] sijie closed pull request #1051: New testcases for ZKClient
sijie closed pull request #1051: New testcases for ZKClient
URL: https://github.com/apache/bookkeeper/pull/1051
This is a PR merged from a forked repository.
As GitHub hides the original diff on merge, it is displayed below for
the sake of provenance:
As this is a foreign pull request (from a fork), the diff is supplied
below (as it won't show otherwise due to GitHub magic):
diff --git a/bookkeeper-server/src/test/java/org/apache/bookkeeper/zookeeper/TestZooKeeperClient.java b/bookkeeper-server/src/test/java/org/apache/bookkeeper/zookeeper/TestZooKeeperClient.java
index 33c67505a..c2aaf906d 100644
--- a/bookkeeper-server/src/test/java/org/apache/bookkeeper/zookeeper/TestZooKeeperClient.java
+++ b/bookkeeper-server/src/test/java/org/apache/bookkeeper/zookeeper/TestZooKeeperClient.java
@@ -26,12 +26,15 @@
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicReference;
import junit.framework.TestCase;
import org.apache.bookkeeper.stats.NullStatsLogger;
import org.apache.bookkeeper.test.ZooKeeperUtil;
+import org.apache.zookeeper.AsyncCallback;
+import org.apache.zookeeper.AsyncCallback.ACLCallback;
import org.apache.zookeeper.AsyncCallback.Children2Callback;
import org.apache.zookeeper.AsyncCallback.Create2Callback;
import org.apache.zookeeper.AsyncCallback.DataCallback;
@@ -46,6 +49,7 @@
import org.apache.zookeeper.Watcher.Event.KeeperState;
import org.apache.zookeeper.ZooDefs.Ids;
import org.apache.zookeeper.ZooKeeper;
+import org.apache.zookeeper.data.ACL;
import org.apache.zookeeper.data.Stat;
import org.junit.After;
import org.junit.Assert;
@@ -236,6 +240,501 @@ public void testRetrySyncOperations() throws Exception {
logger.info("Delete children from znode " + path);
}
+ @Test
+ public void testSyncAfterSessionExpiry() throws Exception {
+ final int timeout = 2000;
+ ZooKeeperClient client = ZooKeeperClient.createConnectedZooKeeperClient(zkUtil.getZooKeeperConnectString(),
+ timeout, new HashSet<Watcher>(),
+ new BoundExponentialBackoffRetryPolicy(timeout, timeout, Integer.MAX_VALUE));
+ Assert.assertTrue("Client failed to connect an alive ZooKeeper.", client.getState().isConnected());
+
+ String path = "/testSyncAfterSessionExpiry";
+ byte[] data = "test".getBytes();
+
+ // create a node
+ logger.info("Create znode " + path);
+ List<ACL> setACLList = new ArrayList<ACL>();
+ setACLList.addAll(Ids.OPEN_ACL_UNSAFE);
+ client.create(path, data, setACLList, CreateMode.PERSISTENT);
+
+ // expire the ZKClient session
+ expireZooKeeperSession(client, timeout);
+
+ // the current Client connection should be in connected state even after the session expiry
+ Assert.assertTrue("Client failed to connect an alive ZooKeeper.", client.getState().isConnected());
+
+ // even after the previous session expiry client should be able to sync
+ CountDownLatch latch = new CountDownLatch(1);
+ final int[] rcArray = { -1 };
+ client.sync(path, new VoidCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx) {
+ CountDownLatch cdLatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ cdLatch.countDown();
+ }
+ }, latch);
+ Assert.assertTrue("client.sync operation should have completed successfully",
+ latch.await(6000, TimeUnit.MILLISECONDS));
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail("Sync failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+
+ // delete the node
+ client.delete(path, -1);
+ }
+
+ @Test
+ public void testACLSetAndGet() throws Exception {
+ final int timeout = 2000;
+ ZooKeeperClient client = ZooKeeperClient.createConnectedZooKeeperClient(zkUtil.getZooKeeperConnectString(),
+ timeout, new HashSet<Watcher>(),
+ new BoundExponentialBackoffRetryPolicy(timeout, timeout, Integer.MAX_VALUE));
+ Assert.assertTrue("Client failed to connect an alive ZooKeeper.", client.getState().isConnected());
+
+ String path = "/testACLSetAndGet";
+ byte[] data = "test".getBytes();
+
+ // create a node and call getACL to verify the received ACL
+ logger.info("Create znode " + path);
+ List<ACL> setACLList = new ArrayList<ACL>();
+ setACLList.addAll(Ids.OPEN_ACL_UNSAFE);
+ client.create(path, data, setACLList, CreateMode.PERSISTENT);
+ Stat status = new Stat();
+ List<ACL> receivedACLList = client.getACL(path, status);
+ Assert.assertEquals("Test1 - ACLs are expected to match", setACLList, receivedACLList);
+
+ // update node's ACL and call getACL to verify the received ACL
+ setACLList.clear();
+ setACLList.addAll(Ids.OPEN_ACL_UNSAFE);
+ setACLList.addAll(Ids.READ_ACL_UNSAFE);
+ status = client.setACL(path, setACLList, status.getAversion());
+ receivedACLList = client.getACL(path, status);
+ Assert.assertEquals("Test2 - ACLs are expected to match", setACLList, receivedACLList);
+
+ // update node's ACL by calling async setACL and call async getACL to verify the received ACL
+ setACLList.clear();
+ setACLList.addAll(Ids.OPEN_ACL_UNSAFE);
+ CountDownLatch latch = new CountDownLatch(1);
+ final Stat[] statArray = { null };
+ final int[] rcArray = { -1 };
+ client.setACL(path, setACLList, status.getAversion(), new StatCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, Stat stat) {
+ CountDownLatch cdLatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ statArray[0] = stat;
+ cdLatch.countDown();
+ }
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail("Test3 - SetACL call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ status = statArray[0];
+ latch = new CountDownLatch(1);
+ rcArray[0] = 0;
+ statArray[0] = null;
+ final List<List<ACL>> aclListArray = new ArrayList<List<ACL>>(1);
+ client.getACL(path, status, new ACLCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, List<ACL> acl, Stat stat) {
+ CountDownLatch cdLatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ statArray[0] = stat;
+ aclListArray.add(acl);
+ cdLatch.countDown();
+ }
+
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail("Test4 - GetACL call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ status = statArray[0];
+ receivedACLList = aclListArray.get(0);
+ Assert.assertEquals("Test5 - ACLs are expected to match", setACLList, receivedACLList);
+
+ // delete the node
+ client.delete(path, status.getVersion());
+ }
+
+ @Test
+ public void testACLSetAndGetAfterSessionExpiry() throws Exception {
+ final int timeout = 2000;
+ ZooKeeperClient client = ZooKeeperClient.createConnectedZooKeeperClient(zkUtil.getZooKeeperConnectString(),
+ timeout, new HashSet<Watcher>(),
+ new BoundExponentialBackoffRetryPolicy(timeout, timeout, Integer.MAX_VALUE));
+ Assert.assertTrue("Client failed to connect an alive ZooKeeper.", client.getState().isConnected());
+
+ String path = "/testACLSetAndGetAfterSessionExpiry";
+ byte[] data = "test".getBytes();
+
+ // create a node
+ logger.info("Create znode " + path);
+ List<ACL> setACLList = new ArrayList<ACL>();
+ setACLList.addAll(Ids.OPEN_ACL_UNSAFE);
+ client.create(path, data, setACLList, CreateMode.PERSISTENT);
+
+ // expire the ZKClient session
+ expireZooKeeperSession(client, timeout);
+
+ // call getACL and verify if it returns the previously set ACL
+ Stat status = new Stat();
+ List<ACL> receivedACLList = client.getACL(path, status);
+ Assert.assertEquals("Test1 - ACLs are expected to match", setACLList, receivedACLList);
+
+ // update ACL of that node
+ setACLList.clear();
+ setACLList.addAll(Ids.OPEN_ACL_UNSAFE);
+ setACLList.addAll(Ids.READ_ACL_UNSAFE);
+ status = client.setACL(path, setACLList, status.getAversion());
+
+ // expire the ZKClient session
+ expireZooKeeperSession(client, timeout);
+
+ // call getACL and verify if it returns the previously set ACL
+ receivedACLList = client.getACL(path, status);
+ Assert.assertEquals("Test2 - ACLs are expected to match", setACLList, receivedACLList);
+
+ // update the ACL of node by calling async setACL
+ setACLList.clear();
+ setACLList.addAll(Ids.OPEN_ACL_UNSAFE);
+ CountDownLatch latch = new CountDownLatch(1);
+ final Stat[] statArray = { null };
+ final int[] rcArray = { -1 };
+ client.setACL(path, setACLList, status.getAversion(), new StatCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, Stat stat) {
+ CountDownLatch cdLatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ statArray[0] = stat;
+ cdLatch.countDown();
+ }
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail("Test3 - SetACL call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ status = statArray[0];
+
+ // expire the ZKClient session
+ expireZooKeeperSession(client, timeout);
+
+ // call async getACL and verify if it returns the previously set ACL
+ latch = new CountDownLatch(1);
+ rcArray[0] = 0;
+ statArray[0] = null;
+ final List<List<ACL>> aclListArray = new ArrayList<List<ACL>>(1);
+ client.getACL(path, status, new ACLCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, List<ACL> acl, Stat stat) {
+ CountDownLatch cdLatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ statArray[0] = stat;
+ aclListArray.add(acl);
+ cdLatch.countDown();
+ }
+
+ }, latch);
+ Assert.assertTrue("getACL operation should have completed successfully",
+ latch.await(6000, TimeUnit.MILLISECONDS));
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail("Test4 - GetACL call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ status = statArray[0];
+ receivedACLList = aclListArray.get(0);
+ Assert.assertEquals("Test5 - ACLs are expected to match", setACLList, receivedACLList);
+
+ client.delete(path, status.getVersion());
+ }
+
+ @Test
+ public void testZnodeExists() throws Exception {
+ final int timeout = 2000;
+ ZooKeeperClient client = ZooKeeperClient.createConnectedZooKeeperClient(zkUtil.getZooKeeperConnectString(),
+ timeout, new HashSet<Watcher>(),
+ new BoundExponentialBackoffRetryPolicy(timeout, timeout, Integer.MAX_VALUE));
+ Assert.assertTrue("Client failed to connect an alive ZooKeeper.", client.getState().isConnected());
+
+ String path = "/testZnodeExists";
+ byte[] data = "test".getBytes();
+
+ // create a node
+ logger.info("Create znode " + path);
+ client.create(path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ // expire the ZKClient session and then call exists method for the path
+ expireZooKeeperSession(client, timeout);
+ final AtomicBoolean isDeleted = new AtomicBoolean(false);
+ final CountDownLatch latch = new CountDownLatch(1);
+ Stat stat = client.exists(path, new Watcher() {
+ @Override
+ public void process(WatchedEvent event) {
+ if (event.getType() == Watcher.Event.EventType.NodeDeleted) {
+ isDeleted.set(true);
+ latch.countDown();
+ }
+ }
+ });
+ Assert.assertNotNull("node with path " + path + " should exists", stat);
+
+ // now delete the znode and verify if the Watcher is called
+ client.delete(path, stat.getVersion());
+ latch.await(5000, TimeUnit.MILLISECONDS);
+ Assert.assertTrue("The watcher on the node should have been called", isDeleted.get());
+
+ // calling async exists method and verifying the return values
+ CountDownLatch latch2 = new CountDownLatch(1);
+ final int[] rcArray = { -1 };
+ final boolean[] statIsnull = { false };
+ client.exists(path, null, new StatCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, Stat stat) {
+ CountDownLatch cdlatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ statIsnull[0] = (stat == null);
+ cdlatch.countDown();
+ }
+ }, latch2);
+ latch2.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.NONODE.intValue()) {
+ Assert.fail("exists call is supposed to return NONODE rcvalue, but it returned - "
+ + KeeperException.Code.get(rcArray[0]));
+ }
+ Assert.assertTrue("exists is supposed to return null for Stat,"
+ + " since the node is already deleted", statIsnull[0]);
+ }
+
+ @Test
+ public void testGetSetData() throws Exception {
+ final int timeout = 2000;
+ ZooKeeperClient client = ZooKeeperClient.createConnectedZooKeeperClient(zkUtil.getZooKeeperConnectString(),
+ timeout, new HashSet<Watcher>(),
+ new BoundExponentialBackoffRetryPolicy(timeout, timeout, Integer.MAX_VALUE));
+ Assert.assertTrue("Client failed to connect an alive ZooKeeper.", client.getState().isConnected());
+
+ String path = "/testGetSetData";
+ byte[] data = "test".getBytes();
+
+ // create a node and call async getData method and verify its return value
+ logger.info("Create znode " + path);
+ client.create(path, data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ CountDownLatch latch = new CountDownLatch(1);
+ final Stat[] statArray = { null };
+ final int[] rcArray = { -1 };
+ final byte[][] dataArray = { {} };
+ client.getData(path, true, new DataCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
+ CountDownLatch cdLatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ statArray[0] = stat;
+ dataArray[0] = data;
+ cdLatch.countDown();
+ }
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail("Test1 - getData call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ Assert.assertArrayEquals("Test1 - getData output - ", data, dataArray[0]);
+ Stat stat = statArray[0];
+
+ // expire the ZKClient session and then call async setData with new data
+ expireZooKeeperSession(client, timeout);
+ latch = new CountDownLatch(1);
+ data = "newtest".getBytes();
+ client.setData(path, data, stat.getVersion(), new StatCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, Stat stat) {
+ CountDownLatch cdlatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ statArray[0] = stat;
+ cdlatch.countDown();
+ }
+ }, latch);
+ Assert.assertTrue("setData operation should have completed successfully",
+ latch.await(6000, TimeUnit.MILLISECONDS));
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail("Test2 - setData call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ stat = statArray[0];
+
+ // call getData
+ byte[] getDataRet = client.getData(path, null, stat);
+ Assert.assertArrayEquals("Test3 - getData output - ", data, getDataRet);
+
+ // call setdata and then async getData call
+ data = "newesttest".getBytes();
+ stat = client.setData(path, data, stat.getVersion());
+ latch = new CountDownLatch(1);
+ client.getData(path, null, new DataCallback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, byte[] data, Stat stat) {
+ CountDownLatch cdLatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ statArray[0] = stat;
+ dataArray[0] = data;
+ cdLatch.countDown();
+ }
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail("Test4 - getData call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ Assert.assertArrayEquals("Test4 - getData output - ", data, dataArray[0]);
+ stat = statArray[0];
+
+ client.delete(path, stat.getVersion());
+ }
+
+ @Test
+ public void testGetChildren() throws Exception {
+ final int timeout = 2000;
+ ZooKeeperClient client = ZooKeeperClient.createConnectedZooKeeperClient(zkUtil.getZooKeeperConnectString(),
+ timeout, new HashSet<Watcher>(),
+ new BoundExponentialBackoffRetryPolicy(timeout, timeout, Integer.MAX_VALUE));
+ Assert.assertTrue("Client failed to connect an alive ZooKeeper.", client.getState().isConnected());
+
+ // create a root node
+ String root = "/testGetChildren";
+ byte[] rootData = "root".getBytes();
+ logger.info("Create znode " + root);
+ client.create(root, rootData, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ // create a child1 node
+ String child1 = root + "/" + "child1";
+ logger.info("Create znode " + child1);
+ byte[] child1Data = "child1".getBytes();
+ client.create(child1, child1Data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+ // create a child2 node
+ String child2 = root + "/" + "child2";
+ logger.info("Create znode " + child2);
+ byte[] child2Data = "child2".getBytes();
+ client.create(child2, child2Data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ // call getChildren method and verify its return value
+ Stat rootStat = new Stat();
+ List<String> children = client.getChildren(root, null, rootStat);
+ Assert.assertEquals("Test1 - children size", 2, children.size());
+
+ // create a child3 node
+ String child3 = root + "/" + "child3";
+ logger.info("Create znode " + child3);
+ byte[] child3Data = "child3".getBytes();
+ client.create(child3, child3Data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ // call getChildren method and verify its return value
+ children = client.getChildren(root, true, rootStat);
+ Assert.assertEquals("Test2 - children size", 3, children.size());
+
+ // call async getChildren method and verify its return value
+ CountDownLatch latch = new CountDownLatch(1);
+ final Stat[] statArray = { null };
+ final int[] rcArray = { -1 };
+ final int[] childrenCount = { 0 };
+ client.getChildren(root, null, new Children2Callback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
+ CountDownLatch cdlatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ childrenCount[0] = children.size();
+ statArray[0] = stat;
+ cdlatch.countDown();
+ }
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail(
+ "Test3 - getChildren call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ Assert.assertEquals("Test3 - children size", 3, childrenCount[0]);
+ rootStat = statArray[0];
+
+ // call async getChildren method and verify its return value
+ latch = new CountDownLatch(1);
+ client.getChildren(root, true, new Children2Callback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
+ CountDownLatch cdlatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ childrenCount[0] = children.size();
+ statArray[0] = stat;
+ cdlatch.countDown();
+ }
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail(
+ "Test4 - getChildren call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ Assert.assertEquals("Test4 - children size", 3, childrenCount[0]);
+ rootStat = statArray[0];
+
+ // expire the ZKClient session and then call async setData with new data
+ expireZooKeeperSession(client, timeout);
+
+ // this is after previous session expiry. call getChildren method and verify its return value
+ children = client.getChildren(root, null, rootStat);
+ Assert.assertEquals("Test5 - children size", 3, children.size());
+
+ // create a child4 node
+ String child4 = root + "/" + "child4";
+ logger.info("Create znode " + child4);
+ byte[] child4Data = "child4".getBytes();
+ client.create(child4, child4Data, Ids.OPEN_ACL_UNSAFE, CreateMode.PERSISTENT);
+
+ // call async getChildren method and verify its return value
+ latch = new CountDownLatch(1);
+ client.getChildren(root, null, new Children2Callback() {
+ @Override
+ public void processResult(int rc, String path, Object ctx, List<String> children, Stat stat) {
+ CountDownLatch cdlatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ childrenCount[0] = children.size();
+ statArray[0] = stat;
+ cdlatch.countDown();
+ }
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail(
+ "Test6 - getChildren call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ Assert.assertEquals("Test6 - children size", 4, childrenCount[0]);
+ rootStat = statArray[0];
+
+ // expire the ZKClient session and then call async setData with new data
+ expireZooKeeperSession(client, timeout);
+
+ // call getChildren method and verify its return value
+ children = client.getChildren(root, null);
+ Assert.assertEquals("Test7 - children size", 4, children.size());
+
+ // call getChildren method and verify its return value
+ children = client.getChildren(root, true);
+ Assert.assertEquals("Test8 - children size", 4, children.size());
+
+ // call async getChildren method and verify its return value
+ latch = new CountDownLatch(1);
+ client.getChildren(root, true, new AsyncCallback.ChildrenCallback() {
+
+ @Override
+ public void processResult(int rc, String path, Object ctx, List<String> children) {
+ CountDownLatch cdlatch = (CountDownLatch) ctx;
+ rcArray[0] = rc;
+ childrenCount[0] = children.size();
+ cdlatch.countDown();
+ }
+ }, latch);
+ latch.await(3000, TimeUnit.MILLISECONDS);
+ if (rcArray[0] != KeeperException.Code.OK.intValue()) {
+ Assert.fail(
+ "Test9 - getChildren call failed because of exception - " + KeeperException.Code.get(rcArray[0]));
+ }
+ Assert.assertEquals("Test9 - children size", 4, childrenCount[0]);
+ }
+
@Test
public void testRetryOnCreatingEphemeralZnode() throws Exception {
final int timeout = 2000;
----------------------------------------------------------------
This is an automated message from the Apache Git Service.
To respond to the message, please log on GitHub and use the
URL above to go to the specific comment.
For queries about this service, please contact Infrastructure at:
users@infra.apache.org
With regards,
Apache Git Services