You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@zookeeper.apache.org by fp...@apache.org on 2014/01/25 01:17:07 UTC

svn commit: r1561236 - in /zookeeper/trunk: ./ src/java/test/org/apache/zookeeper/test/

Author: fpj
Date: Sat Jan 25 00:17:07 2014
New Revision: 1561236

URL: http://svn.apache.org/r1561236
Log:
ZOOKEEPER-1858. JMX checks - potential race conditions while stopping 
  and starting server (Rakesh R via fpj)


Modified:
    zookeeper/trunk/CHANGES.txt
    zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientBase.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java
    zookeeper/trunk/src/java/test/org/apache/zookeeper/test/JMXEnv.java

Modified: zookeeper/trunk/CHANGES.txt
URL: http://svn.apache.org/viewvc/zookeeper/trunk/CHANGES.txt?rev=1561236&r1=1561235&r2=1561236&view=diff
==============================================================================
--- zookeeper/trunk/CHANGES.txt (original)
+++ zookeeper/trunk/CHANGES.txt Sat Jan 25 00:17:07 2014
@@ -536,6 +536,9 @@ BUGFIXES:
   ZOOKEEPER-1837. Fix JMXEnv checks (potential race conditions)
   (Germán Blanco via fpj)
 
+  ZOOKEEPER-1858. JMX checks - potential race conditions while stopping
+  and starting server (Rakesh R via fpj)
+
 IMPROVEMENTS:
 
   ZOOKEEPER-1170. Fix compiler (eclipse) warnings: unused imports,

Modified: zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientBase.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientBase.java?rev=1561236&r1=1561235&r2=1561236&view=diff
==============================================================================
--- zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientBase.java (original)
+++ zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ClientBase.java Sat Jan 25 00:17:07 2014
@@ -27,15 +27,20 @@ import java.io.FileInputStream;
 import java.io.IOException;
 import java.util.ArrayList;
 import java.util.Arrays;
+import java.util.Iterator;
 import java.util.LinkedList;
 import java.util.List;
 import java.util.Map;
 import java.util.Map.Entry;
+import java.util.Set;
 import java.util.concurrent.CountDownLatch;
 import java.util.concurrent.TimeUnit;
 import java.util.concurrent.TimeoutException;
 
 import javax.management.MBeanServerConnection;
+import javax.management.ObjectName;
+
+import junit.framework.TestCase;
 
 import org.apache.zookeeper.KeeperException;
 import org.apache.zookeeper.PortAssignment;
@@ -188,7 +193,7 @@ public abstract class ClientBase extends
             }
             if (allClients != null) {
                 allClients.add(zk);
-                JMXEnv.ensureAll("0x" + Long.toHexString(zk.getSessionId()));
+                JMXEnv.ensureAll(getHexSessionId(zk.getSessionId()));
             } else {
                 // test done - close the zk, not needed
                 zk.close();
@@ -439,8 +444,46 @@ public abstract class ClientBase extends
         serverFactory = createNewServerInstance(serverFactory, hostPort,
                 maxCnxns);
         startServerInstance(tmpDir, serverFactory, hostPort);
-        // ensure that only server and data bean are registered
-        JMXEnv.ensureOnly("InMemoryDataTree", "StandaloneServer_port");
+        // ensure that server and data bean are registered
+        Set<ObjectName> children = JMXEnv.ensureParent("InMemoryDataTree",
+                "StandaloneServer_port");
+        // Remove beans which are related to zk client sessions. Strong
+        // assertions cannot be done for these client sessions because
+        // registeration of these beans with server will happen only on their
+        // respective reconnection interval
+        verifyUnexpectedBeans(children);
+    }
+
+    private void verifyUnexpectedBeans(Set<ObjectName> children) {
+        if (allClients != null) {
+            for (ZooKeeper zkc : allClients) {
+                Iterator<ObjectName> childItr = children.iterator();
+                while (childItr.hasNext()) {
+                    ObjectName clientBean = childItr.next();
+                    if (clientBean.toString().contains(
+                            getHexSessionId(zkc.getSessionId()))) {
+                        LOG.info("found name:" + zkc.getSessionId()
+                                + " client bean:" + clientBean.toString());
+                        childItr.remove();
+                    }
+                }
+            }
+        }
+        for (ObjectName bean : children) {
+            LOG.info("unexpected:" + bean.toString());
+        }
+        TestCase.assertEquals("Unexpected bean exists!", 0, children.size());
+    }
+
+    /**
+     * Returns a string representation of the given long value session id
+     * 
+     * @param sessionId
+     *            long value of session id
+     * @return string representation of session id
+     */
+    protected static String getHexSessionId(long sessionId) {
+        return "0x" + Long.toHexString(sessionId);
     }
 
     protected void stopServer() throws Exception {

Modified: zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java?rev=1561236&r1=1561235&r2=1561236&view=diff
==============================================================================
--- zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java (original)
+++ zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsQuorumTest.java Sat Jan 25 00:17:07 2014
@@ -55,7 +55,7 @@ public class FourLetterWordsQuorumTest e
             verify(hp, "cons", "queued");
 
             TestableZooKeeper zk = createClient(hp);
-            String sid = "0x" + Long.toHexString(zk.getSessionId());
+            String sid = getHexSessionId(zk.getSessionId());
 
             verify(hp, "stat", "queued");
             verify(hp, "srvr", "Outstanding");

Modified: zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java?rev=1561236&r1=1561235&r2=1561236&view=diff
==============================================================================
--- zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java (original)
+++ zookeeper/trunk/src/java/test/org/apache/zookeeper/test/FourLetterWordsTest.java Sat Jan 25 00:17:07 2014
@@ -57,7 +57,7 @@ public class FourLetterWordsTest extends
         verify("cons", "queued");
 
         TestableZooKeeper zk = createClient();
-        String sid = "0x" + Long.toHexString(zk.getSessionId());
+        String sid = getHexSessionId(zk.getSessionId());
 
         verify("stat", "queued");
         verify("srvr", "Outstanding");

Modified: zookeeper/trunk/src/java/test/org/apache/zookeeper/test/JMXEnv.java
URL: http://svn.apache.org/viewvc/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/JMXEnv.java?rev=1561236&r1=1561235&r2=1561236&view=diff
==============================================================================
--- zookeeper/trunk/src/java/test/org/apache/zookeeper/test/JMXEnv.java (original)
+++ zookeeper/trunk/src/java/test/org/apache/zookeeper/test/JMXEnv.java Sat Jan 25 00:17:07 2014
@@ -204,4 +204,69 @@ public class JMXEnv {
         }
     }
 
+    /**
+     * Ensure that the specified parent names are registered. Note that these
+     * are components of the name. It waits in a loop up to 60 seconds before
+     * failing if there is a mismatch. This will return the beans which are not
+     * matched.
+     * 
+     * {@link https://issues.apache.org/jira/browse/ZOOKEEPER-1858}
+     * 
+     * @param expectedNames
+     *            - expected beans
+     * @return the beans which are not matched with the given expected names
+     * 
+     * @throws IOException
+     * @throws InterruptedException
+     */
+    public static Set<ObjectName> ensureParent(String... expectedNames)
+            throws IOException, InterruptedException {
+        LOG.info("ensureParent:" + Arrays.toString(expectedNames));
+
+        Set<ObjectName> beans;
+        int nTry = 0;
+        Set<ObjectName> found = new HashSet<ObjectName>();
+        do {
+            if (nTry++ > 0) {
+                Thread.sleep(500);
+            }
+            try {
+                beans = conn().queryNames(
+                        new ObjectName(CommonNames.DOMAIN + ":*"), null);
+            } catch (MalformedObjectNameException e) {
+                throw new RuntimeException(e);
+            }
+            found.clear();
+            for (String name : expectedNames) {
+                LOG.info("expect:" + name);
+                for (ObjectName bean : beans) {
+                    // check the existence of name in bean
+                    if (compare(bean.toString(), name)) {
+                        LOG.info("found:" + name + " " + bean);
+                        found.add(bean);
+                        break;
+                    }
+                }
+                beans.removeAll(found);
+            }
+        } while (expectedNames.length != found.size() && nTry < 120);
+        TestCase.assertEquals("expected " + Arrays.toString(expectedNames),
+                expectedNames.length, found.size());
+        return beans;
+    }
+
+    /**
+     * Comparing that the given name exists in the bean. For component beans,
+     * the component name will be present at the end of the bean name
+     * 
+     * For example 'StandaloneServer' will present in the bean name like
+     * 'org.apache.ZooKeeperService:name0=StandaloneServer_port-1'
+     */
+    private static boolean compare(String bean, String name) {
+        String[] names = bean.split("=");
+        if (names.length > 0 && names[names.length - 1].contains(name)) {
+            return true;
+        }
+        return false;
+    }
 }