Author: phunt
Date: Tue Sep 14 21:05:43 2010
New Revision: 997096

URL: http://svn.apache.org/viewvc?rev=997096&view=rev
Log:
Zookeeper 3.3.1 shouldn't infinite loop if someone creates a server.0 line 
(part 2)

Added:
    
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/StandaloneTest.java
Modified:
    hadoop/zookeeper/trunk/CHANGES.txt
    
hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java
    
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerTestBase.java
    
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ObserverTest.java
    
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/QuorumTest.java

Modified: hadoop/zookeeper/trunk/CHANGES.txt
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/CHANGES.txt?rev=997096&r1=997095&r2=997096&view=diff
==============================================================================
--- hadoop/zookeeper/trunk/CHANGES.txt (original)
+++ hadoop/zookeeper/trunk/CHANGES.txt Tue Sep 14 21:05:43 2010
@@ -88,7 +88,11 @@ BUGFIXES: 
 
   ZOOKEEPER-867. ClientTest is failing on hudson - fd cleanup (phunt)
 
-  ZOOKEEPER-785. Zookeeper 3.3.1 shouldn't infinite loop if someone creates a 
server.0 line (phunt and Andrei Savu via breed)
+  ZOOKEEPER-785. Zookeeper 3.3.1 shouldn't infinite loop if someone creates a
+  server.0 line (phunt and Andrei Savu via breed)
+
+  ZOOKEEPER-785. Zookeeper 3.3.1 shouldn't infinite loop if someone creates a
+  server.0 line (part 2) (phunt)
 
 IMPROVEMENTS:
   ZOOKEEPER-724. Improve junit test integration - log harness information 

Modified: 
hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java?rev=997096&r1=997095&r2=997096&view=diff
==============================================================================
--- 
hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java
 (original)
+++ 
hadoop/zookeeper/trunk/src/java/main/org/apache/zookeeper/server/quorum/QuorumPeerConfig.java
 Tue Sep 14 21:05:43 2010
@@ -243,13 +243,29 @@ public class QuorumPeerConfig {
             throw new IllegalArgumentException(
                     "minSessionTimeout must not be larger than 
maxSessionTimeout");
         }
-        if (servers.size() == 1) {
+        if (servers.size() == 0) {
+            if (observers.size() > 0) {
+                throw new IllegalArgumentException("Observers w/o participants 
is an invalid configuration");
+            }
+            // Not a quorum configuration so return immediately - not an error
+            // case (for b/w compatibility), server will default to standalone
+            // mode.
+            return;
+        } else if (servers.size() == 1) {
+            if (observers.size() > 0) {
+                throw new IllegalArgumentException("Observers w/o quorum is an 
invalid configuration");
+            }
+
+            // HBase currently adds a single server line to the config, for
+            // b/w compatibility reasons we need to keep this here.
             LOG.error("Invalid configuration, only one server specified 
(ignoring)");
             servers.clear();
         } else if (servers.size() > 1) {
             if (servers.size() == 2) {
                 LOG.warn("No server failure will be tolerated. " +
                     "You need at least 3 servers.");
+            } else if (servers.size() % 2 == 0) {
+                LOG.warn("Non-optimial configuration, consider an odd number 
of servers.");
             }
             if (initLimit == 0) {
                 throw new IllegalArgumentException("initLimit is not set");
@@ -300,7 +316,7 @@ public class QuorumPeerConfig {
             // Now add observers to servers, once the quorums have been
             // figured out
             servers.putAll(observers);
-
+    
             File myIdFile = new File(dataDir, "myid");
             if (!myIdFile.exists()) {
                 throw new IllegalArgumentException(myIdFile.toString()
@@ -315,7 +331,7 @@ public class QuorumPeerConfig {
             }
             try {
                 serverId = Long.parseLong(myIdString);
-               MDC.put("myid", serverId);
+                MDC.put("myid", serverId);
             } catch (NumberFormatException e) {
                 throw new IllegalArgumentException("serverid " + myIdString
                         + " is not a number");
@@ -328,10 +344,9 @@ public class QuorumPeerConfig {
                 LOG.warn("Peer type from servers list (" + roleByServersList
                         + ") doesn't match peerType (" + peerType
                         + "). Defaulting to servers list.");
-
+    
                 peerType = roleByServersList;
             }
-            
         }
     }
 

Modified: 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerTestBase.java
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerTestBase.java?rev=997096&r1=997095&r2=997096&view=diff
==============================================================================
--- 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerTestBase.java
 (original)
+++ 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/server/quorum/QuorumPeerTestBase.java
 Tue Sep 14 21:05:43 2010
@@ -47,7 +47,9 @@ public class QuorumPeerTestBase extends 
     public static  class TestQPMain extends QuorumPeerMain {
         public void shutdown() {
             // ensure it closes - in particular wait for thread to exit
-            QuorumBase.shutdown(quorumPeer);
+            if (quorumPeer != null) {
+                QuorumBase.shutdown(quorumPeer);
+            }
         }
     }
 

Modified: 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ObserverTest.java
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ObserverTest.java?rev=997096&r1=997095&r2=997096&view=diff
==============================================================================
--- 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ObserverTest.java
 (original)
+++ 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/ObserverTest.java
 Tue Sep 14 21:05:43 2010
@@ -20,18 +20,17 @@ package org.apache.zookeeper.test;
 
 import static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
 
-import java.io.IOException;
 import java.util.concurrent.CountDownLatch;
 
 import org.apache.log4j.Logger;
 import org.apache.zookeeper.CreateMode;
+import org.apache.zookeeper.KeeperException.ConnectionLossException;
 import org.apache.zookeeper.PortAssignment;
 import org.apache.zookeeper.WatchedEvent;
 import org.apache.zookeeper.Watcher;
-import org.apache.zookeeper.ZooKeeper;
-import org.apache.zookeeper.KeeperException.ConnectionLossException;
 import org.apache.zookeeper.Watcher.Event.KeeperState;
 import org.apache.zookeeper.ZooDefs.Ids;
+import org.apache.zookeeper.ZooKeeper;
 import org.apache.zookeeper.ZooKeeper.States;
 import org.apache.zookeeper.server.quorum.QuorumPeerTestBase;
 import org.junit.Assert;
@@ -192,25 +191,42 @@ public class ObserverTest extends Quorum
     /**
      * This test ensures that an Observer does not elect itself as a leader, or
      * indeed come up properly, if it is the lone member of an ensemble.
-     * @throws IOException
+     * @throws Exception
      */
     @Test
-    public void testSingleObserver() throws IOException{
+    public void testObserverOnly() throws Exception {
         ClientBase.setupTestEnv();
         final int CLIENT_PORT_QP1 = PortAssignment.unique();        
-        final int CLIENT_PORT_QP2 = PortAssignment.unique();
         
         String quorumCfgSection =
-            "server.1=127.0.0.1:" + (CLIENT_PORT_QP1)
-            + ":" + (CLIENT_PORT_QP2) + "\npeerType=observer";
+            "server.1=127.0.0.1:" + (PortAssignment.unique())
+            + ":" + (PortAssignment.unique()) + 
":observer\npeerType=observer\n";
                     
         MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
         q1.start();
-        Assert.assertFalse("Observer shouldn't come up",
-                ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1,
-                                            CONNECTION_TIMEOUT));
-        
-        q1.shutdown();
+        q1.join(ClientBase.CONNECTION_TIMEOUT);
+        Assert.assertFalse(q1.isAlive());
     }    
     
+    /**
+     * Ensure that observer only comes up when a proper ensemble is configured.
+     * (and will not come up with standalone server).
+     */
+    @Test
+    public void testObserverWithStandlone() throws Exception {
+        ClientBase.setupTestEnv();
+        final int CLIENT_PORT_QP1 = PortAssignment.unique();        
+
+        String quorumCfgSection =
+            "server.1=127.0.0.1:" + (PortAssignment.unique())
+            + ":" + (PortAssignment.unique()) + ":observer\n"
+            + "server.2=127.0.0.1:" + (PortAssignment.unique())
+            + ":" + (PortAssignment.unique()) + "\npeerType=observer\n";
+
+        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
+        q1.start();
+        q1.join(ClientBase.CONNECTION_TIMEOUT);
+        Assert.assertFalse(q1.isAlive());
+    }    
+
 }

Modified: 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/QuorumTest.java
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/QuorumTest.java?rev=997096&r1=997095&r2=997096&view=diff
==============================================================================
--- 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/QuorumTest.java 
(original)
+++ 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/QuorumTest.java 
Tue Sep 14 21:05:43 2010
@@ -19,9 +19,8 @@
 package org.apache.zookeeper.test;
 import java.io.IOException;
 import java.util.ArrayList;
-import java.util.concurrent.TimeUnit;
 import java.util.concurrent.Semaphore;
-
+import java.util.concurrent.TimeUnit;
 
 import org.apache.log4j.Logger;
 import org.apache.zookeeper.AsyncCallback;
@@ -36,7 +35,6 @@ import org.apache.zookeeper.ZooKeeper;
 import org.apache.zookeeper.data.Stat;
 import org.apache.zookeeper.server.quorum.Leader;
 import org.apache.zookeeper.server.quorum.LearnerHandler;
-import org.apache.zookeeper.server.quorum.QuorumPeer;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
@@ -398,7 +396,6 @@ public class QuorumTest extends QuorumBa
                 "Current epoch: " + epochF, epochF == epochL);
         
     }
-    
-    
+
     // skip superhammer and clientcleanup as they are too expensive for quorum
 }

Added: 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/StandaloneTest.java
URL: 
http://svn.apache.org/viewvc/hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/StandaloneTest.java?rev=997096&view=auto
==============================================================================
--- 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/StandaloneTest.java
 (added)
+++ 
hadoop/zookeeper/trunk/src/java/test/org/apache/zookeeper/test/StandaloneTest.java
 Tue Sep 14 21:05:43 2010
@@ -0,0 +1,64 @@
+/**
+ * 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 static org.apache.zookeeper.test.ClientBase.CONNECTION_TIMEOUT;
+
+import org.apache.log4j.Logger;
+import org.apache.zookeeper.PortAssignment;
+import org.apache.zookeeper.Watcher;
+import org.apache.zookeeper.server.quorum.QuorumPeerTestBase;
+import org.junit.Assert;
+import org.junit.Test;
+
+/**
+ * Standalone server tests.
+ */
+public class StandaloneTest extends QuorumPeerTestBase implements Watcher{
+    protected static final Logger LOG =
+        Logger.getLogger(StandaloneTest.class);    
+      
+    /**
+     * Ensure that a single standalone server comes up when misconfigured
+     * with a single server.# line in the configuration. This handles the
+     * case of HBase, which configures zoo.cfg in this way. Maintain b/w
+     * compatibility.
+     * TODO remove in a future version (4.0.0 hopefully)
+     */
+    @Test
+    public void testStandaloneQuorum() throws Exception {
+        ClientBase.setupTestEnv();
+        final int CLIENT_PORT_QP1 = PortAssignment.unique();        
+        
+        String quorumCfgSection =
+            "server.1=127.0.0.1:" + (PortAssignment.unique())
+            + ":" + (PortAssignment.unique()) + "\n";
+                    
+        MainThread q1 = new MainThread(1, CLIENT_PORT_QP1, quorumCfgSection);
+        q1.start();
+        try {
+            Assert.assertTrue("waiting for server 1 being up",
+                    ClientBase.waitForServerUp("127.0.0.1:" + CLIENT_PORT_QP1,
+                            CONNECTION_TIMEOUT));
+        } finally {
+            q1.shutdown();
+        }
+    }    
+    
+}


Reply via email to