zookeeper-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From ph...@apache.org
Subject zookeeper git commit: ZOOKEEPER-2980 Backport ZOOKEEPER-2939 Deal with maxbuffer as it relates to proposals - branch-3.4
Date Fri, 11 May 2018 20:57:22 GMT
Repository: zookeeper
Updated Branches:
  refs/heads/branch-3.4 2a80654d5 -> 1155a081f


ZOOKEEPER-2980 Backport ZOOKEEPER-2939 Deal with maxbuffer as it relates to proposals - branch-3.4

Branch 3.4 version of https://github.com/apache/zookeeper/pull/415

Author: Andor Molnar <andor@cloudera.com>

Reviewers: phunt@apache.org

Closes #462 from anmolnar/ZOOKEEPER-2939_34

Change-Id: Ide68c0bb03f4ea1bc9d8aed9831d4219653c6321


Project: http://git-wip-us.apache.org/repos/asf/zookeeper/repo
Commit: http://git-wip-us.apache.org/repos/asf/zookeeper/commit/1155a081
Tree: http://git-wip-us.apache.org/repos/asf/zookeeper/tree/1155a081
Diff: http://git-wip-us.apache.org/repos/asf/zookeeper/diff/1155a081

Branch: refs/heads/branch-3.4
Commit: 1155a081fa9a01d183e8a669f8608d4fa968938b
Parents: 2a80654
Author: Andor Molnar <andor@cloudera.com>
Authored: Fri May 11 13:56:46 2018 -0700
Committer: Patrick Hunt <phunt@apache.org>
Committed: Fri May 11 13:56:46 2018 -0700

----------------------------------------------------------------------
 build.xml                                       |   2 +-
 .../apache/zookeeper/server/NIOServerCnxn.java  |  22 ++-
 .../zookeeper/server/NettyServerCnxn.java       |  23 ++-
 .../org/apache/zookeeper/server/Request.java    |  12 ++
 .../org/apache/zookeeper/server/ZKDatabase.java |  16 +-
 .../zookeeper/server/ZooKeeperServerBean.java   |   6 +
 .../zookeeper/server/ZooKeeperServerMXBean.java |   6 +
 .../apache/zookeeper/server/quorum/Leader.java  |  27 ++--
 .../zookeeper/server/quorum/LeaderBean.java     |  20 +++
 .../zookeeper/server/quorum/LeaderMXBean.java   |  20 +++
 .../zookeeper/server/quorum/ProposalStats.java  |  71 +++++++++
 .../zookeeper/server/util/SerializeUtils.java   |  18 +++
 .../zookeeper/server/quorum/LeaderBeanTest.java | 151 +++++++++++++++++++
 .../server/quorum/ProposalStatsTest.java        |  58 +++++++
 .../server/util/SerializeUtilsTest.java         | 128 ++++++++++++++++
 15 files changed, 542 insertions(+), 38 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/build.xml
----------------------------------------------------------------------
diff --git a/build.xml b/build.xml
index e441adb..ef63e8c 100644
--- a/build.xml
+++ b/build.xml
@@ -220,7 +220,7 @@ xmlns:cs="antlib:com.puppycrawl.tools.checkstyle">
 
     <property name="netty.version" value="3.10.6.Final"/>
 
-    <property name="junit.version" value="4.8.1"/>
+    <property name="junit.version" value="4.12"/>
     <property name="mockito.version" value="1.8.5"/>
     <property name="checkstyle.version" value="6.1.1"/>
     <property name="commons-collections.version" value="3.2.2"/>

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java b/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
index f191129..6bd33f1 100644
--- a/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
+++ b/src/java/main/org/apache/zookeeper/server/NIOServerCnxn.java
@@ -31,12 +31,12 @@ import java.nio.channels.SelectionKey;
 import java.nio.channels.SocketChannel;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.LinkedBlockingQueue;
 
 import org.apache.jute.BinaryInputArchive;
 import org.apache.jute.BinaryOutputArchive;
 import org.apache.jute.Record;
+import org.apache.zookeeper.server.quorum.ProposalStats;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.zookeeper.Environment;
@@ -613,8 +613,12 @@ public class NIOServerCnxn extends ServerCnxn {
             if (!isZKServerRunning()) {
                 pw.println(ZK_NOT_SERVING);
             }
-            else { 
-                zkServer.serverStats().reset();
+            else {
+                ServerStats serverStats = zkServer.serverStats();
+                serverStats.reset();
+                if (serverStats.getServerState().equals("leader")) {
+                    ((LeaderZooKeeperServer)zkServer).getLeader().getProposalStats().reset();
+                }
                 pw.println("Server stats reset.");
             }
         }
@@ -695,9 +699,15 @@ public class NIOServerCnxn extends ServerCnxn {
                     }
                     pw.println();
                 }
-                pw.print(zkServer.serverStats().toString());
+                ServerStats serverStats = zkServer.serverStats();
+                pw.print(serverStats.toString());
                 pw.print("Node count: ");
                 pw.println(zkServer.getZKDatabase().getNodeCount());
+                if (serverStats.getServerState().equals("leader")) {
+                    Leader leader = ((LeaderZooKeeperServer)zkServer).getLeader();
+                    ProposalStats proposalStats = leader.getProposalStats();
+                    pw.printf("Proposal sizes last/min/max: %s%n", proposalStats.toString());
+                }
             }
             
         }
@@ -800,6 +810,10 @@ public class NIOServerCnxn extends ServerCnxn {
                 print("followers", leader.getLearners().size());
                 print("synced_followers", leader.getForwardingFollowers().size());
                 print("pending_syncs", leader.getNumPendingSyncs());
+
+                print("last_proposal_size", leader.getProposalStats().getLastProposalSize());
+                print("max_proposal_size", leader.getProposalStats().getMaxProposalSize());
+                print("min_proposal_size", leader.getProposalStats().getMinProposalSize());
             }
         }
 

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java b/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java
index a1ca54b..8abbb7a 100644
--- a/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java
+++ b/src/java/main/org/apache/zookeeper/server/NettyServerCnxn.java
@@ -32,12 +32,12 @@ import java.nio.ByteBuffer;
 import java.util.AbstractSet;
 import java.util.HashSet;
 import java.util.List;
-import java.util.Set;
 import java.util.concurrent.atomic.AtomicLong;
 
 import org.apache.jute.BinaryInputArchive;
 import org.apache.jute.BinaryOutputArchive;
 import org.apache.jute.Record;
+import org.apache.zookeeper.server.quorum.ProposalStats;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 import org.apache.zookeeper.Environment;
@@ -397,8 +397,12 @@ public class NettyServerCnxn extends ServerCnxn {
             if (!isZKServerRunning()) {
                 pw.println(ZK_NOT_SERVING);
             }
-            else { 
-                zkServer.serverStats().reset();
+            else {
+                ServerStats serverStats = zkServer.serverStats();
+                serverStats.reset();
+                if (serverStats.getServerState().equals("leader")) {
+                    ((LeaderZooKeeperServer)zkServer).getLeader().getProposalStats().reset();
+                }
                 pw.println("Server stats reset.");
             }
         }
@@ -477,11 +481,16 @@ public class NettyServerCnxn extends ServerCnxn {
                     }
                     pw.println();
                 }
-                pw.print(zkServer.serverStats().toString());
+                ServerStats serverStats = zkServer.serverStats();
+                pw.print(serverStats.toString());
                 pw.print("Node count: ");
                 pw.println(zkServer.getZKDatabase().getNodeCount());
+                if (serverStats.getServerState().equals("leader")) {
+                    Leader leader = ((LeaderZooKeeperServer)zkServer).getLeader();
+                    ProposalStats proposalStats = leader.getProposalStats();
+                    pw.printf("Proposal sizes last/min/max: %s%n", proposalStats.toString());
+                }
             }
-            
         }
     }
     
@@ -581,6 +590,10 @@ public class NettyServerCnxn extends ServerCnxn {
                 print("followers", leader.getLearners().size());
                 print("synced_followers", leader.getForwardingFollowers().size());
                 print("pending_syncs", leader.getNumPendingSyncs());
+
+                print("last_proposal_size", leader.getProposalStats().getLastProposalSize());
+                print("max_proposal_size", leader.getProposalStats().getMaxProposalSize());
+                print("min_proposal_size", leader.getProposalStats().getMinProposalSize());
             }
         }
 

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/Request.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/Request.java b/src/java/main/org/apache/zookeeper/server/Request.java
index bb8b1ca..92eb3cc 100644
--- a/src/java/main/org/apache/zookeeper/server/Request.java
+++ b/src/java/main/org/apache/zookeeper/server/Request.java
@@ -58,6 +58,18 @@ public class Request {
         this.authInfo = authInfo;
     }
 
+    public Request(long sessionId, int xid, int type, TxnHeader hdr, Record txn, long zxid)
{
+        this.sessionId = sessionId;
+        this.cxid = xid;
+        this.type = type;
+        this.hdr = hdr;
+        this.txn = txn;
+        this.zxid = zxid;
+        this.request = null;
+        this.cnxn = null;
+        this.authInfo = null;
+    }
+
     public final long sessionId;
 
     public final int cxid;

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/ZKDatabase.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/ZKDatabase.java b/src/java/main/org/apache/zookeeper/server/ZKDatabase.java
index ce36422..75f4048 100644
--- a/src/java/main/org/apache/zookeeper/server/ZKDatabase.java
+++ b/src/java/main/org/apache/zookeeper/server/ZKDatabase.java
@@ -257,19 +257,9 @@ public class ZKDatabase {
                 maxCommittedLog = request.zxid;
             }
 
-            ByteArrayOutputStream baos = new ByteArrayOutputStream();
-            BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
-            try {
-                request.hdr.serialize(boa, "hdr");
-                if (request.txn != null) {
-                    request.txn.serialize(boa, "txn");
-                }
-                baos.close();
-            } catch (IOException e) {
-                LOG.error("This really should be impossible", e);
-            }
-            QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, request.zxid,
-                    baos.toByteArray(), null);
+            //
+            byte[] data = SerializeUtils.serializeRequest(request);
+            QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, request.zxid, data, null);
             Proposal p = new Proposal();
             p.packet = pp;
             p.request = request;

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/ZooKeeperServerBean.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/ZooKeeperServerBean.java b/src/java/main/org/apache/zookeeper/server/ZooKeeperServerBean.java
index 0eb5c7f..4fb69dd 100644
--- a/src/java/main/org/apache/zookeeper/server/ZooKeeperServerBean.java
+++ b/src/java/main/org/apache/zookeeper/server/ZooKeeperServerBean.java
@@ -22,6 +22,7 @@ import java.net.InetAddress;
 import java.net.UnknownHostException;
 import java.util.Date;
 
+import org.apache.jute.BinaryInputArchive;
 import org.apache.zookeeper.Version;
 import org.apache.zookeeper.jmx.ZKMBeanInfo;
 
@@ -144,4 +145,9 @@ public class ZooKeeperServerBean implements ZooKeeperServerMXBean, ZKMBeanInfo
{
     public long getNumAliveConnections() {
         return zks.getNumAliveConnections();
     }
+
+    @Override
+    public int getJuteMaxBufferSize() {
+        return BinaryInputArchive.maxBuffer;
+    }
 }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/ZooKeeperServerMXBean.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/ZooKeeperServerMXBean.java b/src/java/main/org/apache/zookeeper/server/ZooKeeperServerMXBean.java
index 127ead8..a5b64aa 100644
--- a/src/java/main/org/apache/zookeeper/server/ZooKeeperServerMXBean.java
+++ b/src/java/main/org/apache/zookeeper/server/ZooKeeperServerMXBean.java
@@ -107,4 +107,10 @@ public interface ZooKeeperServerMXBean {
      * @return number of alive client connections
      */
     public long getNumAliveConnections();
+
+    /**
+     *
+     * @return Returns the value of the following config setting: jute.maxbuffer
+     */
+    public int getJuteMaxBufferSize();
 }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/quorum/Leader.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/quorum/Leader.java b/src/java/main/org/apache/zookeeper/server/quorum/Leader.java
index 7013cac..ed715fd 100644
--- a/src/java/main/org/apache/zookeeper/server/quorum/Leader.java
+++ b/src/java/main/org/apache/zookeeper/server/quorum/Leader.java
@@ -48,6 +48,7 @@ import org.apache.zookeeper.server.RequestProcessor;
 import org.apache.zookeeper.server.ZooKeeperThread;
 import org.apache.zookeeper.server.quorum.QuorumPeer.LearnerType;
 import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier;
+import org.apache.zookeeper.server.util.SerializeUtils;
 import org.apache.zookeeper.server.util.ZxidUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
@@ -101,7 +102,13 @@ public class Leader {
     // list of followers that are ready to follow (i.e synced with the leader)
     private final HashSet<LearnerHandler> forwardingFollowers =
         new HashSet<LearnerHandler>();
-    
+
+    private final ProposalStats proposalStats;
+
+    public ProposalStats getProposalStats() {
+        return proposalStats;
+    }
+
     /**
      * Returns a copy of the current forwarding follower snapshot
      */
@@ -185,6 +192,7 @@ public class Leader {
 
     Leader(QuorumPeer self,LeaderZooKeeperServer zk) throws IOException {
         this.self = self;
+        this.proposalStats = new ProposalStats();
         try {
             if (self.getQuorumListenOnAllIPs()) {
                 ss = new ServerSocket(self.getQuorumAddress().getPort());
@@ -764,20 +772,9 @@ public class Leader {
             shutdown(msg);
             throw new XidRolloverException(msg);
         }
-
-        ByteArrayOutputStream baos = new ByteArrayOutputStream();
-        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
-        try {
-            request.hdr.serialize(boa, "hdr");
-            if (request.txn != null) {
-                request.txn.serialize(boa, "txn");
-            }
-            baos.close();
-        } catch (IOException e) {
-            LOG.warn("This really should be impossible", e);
-        }
-        QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, request.zxid, 
-                baos.toByteArray(), null);
+        byte[] data = SerializeUtils.serializeRequest(request);
+        proposalStats.setLastProposalSize(data.length);
+        QuorumPacket pp = new QuorumPacket(Leader.PROPOSAL, request.zxid, data, null);
         
         Proposal p = new Proposal();
         p.packet = pp;

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/quorum/LeaderBean.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/quorum/LeaderBean.java b/src/java/main/org/apache/zookeeper/server/quorum/LeaderBean.java
index 6ab2c30..4862567 100644
--- a/src/java/main/org/apache/zookeeper/server/quorum/LeaderBean.java
+++ b/src/java/main/org/apache/zookeeper/server/quorum/LeaderBean.java
@@ -54,4 +54,24 @@ public class LeaderBean extends ZooKeeperServerBean implements LeaderMXBean
{
     public long getElectionTimeTaken() {
         return leader.self.getElectionTimeTaken();
     }
+
+    @Override
+    public int getLastProposalSize() {
+        return leader.getProposalStats().getLastProposalSize();
+    }
+
+    @Override
+    public int getMinProposalSize() {
+        return leader.getProposalStats().getMinProposalSize();
+    }
+
+    @Override
+    public int getMaxProposalSize() {
+        return leader.getProposalStats().getMaxProposalSize();
+    }
+
+    @Override
+    public void resetProposalStatistics() {
+        leader.getProposalStats().reset();
+    }
 }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/quorum/LeaderMXBean.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/quorum/LeaderMXBean.java b/src/java/main/org/apache/zookeeper/server/quorum/LeaderMXBean.java
index 66428a4..7a1a439 100644
--- a/src/java/main/org/apache/zookeeper/server/quorum/LeaderMXBean.java
+++ b/src/java/main/org/apache/zookeeper/server/quorum/LeaderMXBean.java
@@ -38,4 +38,24 @@ public interface LeaderMXBean extends ZooKeeperServerMXBean {
      * @return time taken for leader election in milliseconds.
      */
     public long getElectionTimeTaken();
+
+    /**
+     * @return size of latest generated proposal
+     */
+    public int getLastProposalSize();
+
+    /**
+     * @return size of smallest generated proposal
+     */
+    public int getMinProposalSize();
+
+    /**
+     * @return size of largest generated proposal
+     */
+    public int getMaxProposalSize();
+
+    /**
+     * Resets statistics of proposal size (min/max/last)
+     */
+    public void resetProposalStatistics();
 }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/quorum/ProposalStats.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/quorum/ProposalStats.java b/src/java/main/org/apache/zookeeper/server/quorum/ProposalStats.java
new file mode 100644
index 0000000..2f3a9c7
--- /dev/null
+++ b/src/java/main/org/apache/zookeeper/server/quorum/ProposalStats.java
@@ -0,0 +1,71 @@
+/**
+ * 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.server.quorum;
+
+/**
+ * Provides live statistics about a running Leader.
+ */
+public class ProposalStats {
+    /**
+     * Size of the last generated proposal. This should fit into server's jute.maxbuffer
setting.
+     */
+    private int lastProposalSize = -1;
+
+    /**
+     * Size of the smallest proposal which has been generated since the server was started.
+     */
+    private int minProposalSize = -1;
+
+    /**
+     * Size of the largest proposal which has been generated since the server was started.
+     */
+    private int maxProposalSize = -1;
+
+    public synchronized int getLastProposalSize() {
+        return lastProposalSize;
+    }
+
+    synchronized void setLastProposalSize(int value) {
+        lastProposalSize = value;
+        if (minProposalSize == -1 || value < minProposalSize) {
+            minProposalSize = value;
+        }
+        if (value > maxProposalSize) {
+            maxProposalSize = value;
+        }
+    }
+
+    public synchronized int getMinProposalSize() {
+        return minProposalSize;
+    }
+
+    public synchronized int getMaxProposalSize() {
+        return maxProposalSize;
+    }
+
+    public synchronized void reset() {
+        lastProposalSize = -1;
+        minProposalSize = -1;
+        maxProposalSize = -1;
+    }
+
+    public synchronized String toString() {
+        return String.format("%d/%d/%d", lastProposalSize, minProposalSize, maxProposalSize);
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/main/org/apache/zookeeper/server/util/SerializeUtils.java
----------------------------------------------------------------------
diff --git a/src/java/main/org/apache/zookeeper/server/util/SerializeUtils.java b/src/java/main/org/apache/zookeeper/server/util/SerializeUtils.java
index f9647c4..ebb30bb 100644
--- a/src/java/main/org/apache/zookeeper/server/util/SerializeUtils.java
+++ b/src/java/main/org/apache/zookeeper/server/util/SerializeUtils.java
@@ -19,12 +19,15 @@
 package org.apache.zookeeper.server.util;
 
 import java.io.ByteArrayInputStream;
+import java.io.ByteArrayOutputStream;
 import java.io.EOFException;
 import java.io.IOException;
 import java.util.HashMap;
 import java.util.Map;
 import java.util.Map.Entry;
 
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.zookeeper.server.Request;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
@@ -138,4 +141,19 @@ public class SerializeUtils {
         dt.serialize(oa, "tree");
     }
 
+    public static byte[] serializeRequest(Request request) {
+        if (request == null || request.hdr == null) return null;
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+        try {
+            request.hdr.serialize(boa, "hdr");
+            if (request.txn != null) {
+                request.txn.serialize(boa, "txn");
+            }
+            baos.close();
+        } catch (IOException e) {
+            LOG.error("This really should be impossible", e);
+        }
+        return baos.toByteArray();
+    }
 }

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/test/org/apache/zookeeper/server/quorum/LeaderBeanTest.java
----------------------------------------------------------------------
diff --git a/src/java/test/org/apache/zookeeper/server/quorum/LeaderBeanTest.java b/src/java/test/org/apache/zookeeper/server/quorum/LeaderBeanTest.java
new file mode 100644
index 0000000..0b47952
--- /dev/null
+++ b/src/java/test/org/apache/zookeeper/server/quorum/LeaderBeanTest.java
@@ -0,0 +1,151 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.server.quorum;
+
+import org.apache.jute.OutputArchive;
+import org.apache.jute.Record;
+import org.apache.zookeeper.server.Request;
+import org.apache.zookeeper.server.ZKDatabase;
+import org.apache.zookeeper.server.persistence.FileTxnSnapLog;
+import org.apache.zookeeper.server.quorum.flexible.QuorumVerifier;
+import org.apache.zookeeper.server.util.SerializeUtils;
+import org.apache.zookeeper.test.ClientBase;
+import org.apache.zookeeper.txn.TxnHeader;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.File;
+import java.io.IOException;
+
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotEquals;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.mock;
+
+public class LeaderBeanTest {
+    private Leader leader;
+    private LeaderBean leaderBean;
+    private FileTxnSnapLog fileTxnSnapLog;
+    private LeaderZooKeeperServer zks;
+    private QuorumPeer qp;
+
+    @Before
+    public void setUp() throws IOException {
+        qp = new QuorumPeer();
+        QuorumVerifier quorumVerifierMock = mock(QuorumVerifier.class);
+        qp.setQuorumVerifier(quorumVerifierMock);
+        File tmpDir = ClientBase.createTmpDir();
+        fileTxnSnapLog = new FileTxnSnapLog(new File(tmpDir, "data"),
+                new File(tmpDir, "data_txnlog"));
+        ZKDatabase zkDb = new ZKDatabase(fileTxnSnapLog);
+
+        zks = new LeaderZooKeeperServer(fileTxnSnapLog, qp, null, zkDb);
+        leader = new Leader(qp, zks);
+        leaderBean = new LeaderBean(leader, zks);
+    }
+
+    @After
+    public void tearDown() throws IOException {
+        fileTxnSnapLog.close();
+    }
+
+    @Test
+    public void testGetName() {
+        assertEquals("Leader", leaderBean.getName());
+    }
+
+    @Test
+    public void testGetCurrentZxid() {
+        // Arrange
+        zks.setZxid(1);
+
+        // Assert
+        assertEquals("0x1", leaderBean.getCurrentZxid());
+    }
+
+    @Test
+    public void testGetElectionTimeTaken() {
+        // Arrange
+        qp.setElectionTimeTaken(1);
+
+        // Assert
+        assertEquals(1, leaderBean.getElectionTimeTaken());
+    }
+
+    @Test
+    public void testGetProposalSize() throws IOException, Leader.XidRolloverException {
+        // Arrange
+        Request req = createMockRequest();
+
+        // Act
+        leader.propose(req);
+
+        // Assert
+        byte[] data = SerializeUtils.serializeRequest(req);
+        assertEquals(data.length, leaderBean.getLastProposalSize());
+        assertEquals(data.length, leaderBean.getMinProposalSize());
+        assertEquals(data.length, leaderBean.getMaxProposalSize());
+    }
+
+    @Test
+    public void testResetProposalStats() throws IOException, Leader.XidRolloverException
{
+        // Arrange
+        int initialProposalSize = leaderBean.getLastProposalSize();
+        Request req = createMockRequest();
+
+        // Act
+        leader.propose(req);
+
+        // Assert
+        assertNotEquals(initialProposalSize, leaderBean.getLastProposalSize());
+        leaderBean.resetProposalStatistics();
+        assertEquals(initialProposalSize, leaderBean.getLastProposalSize());
+        assertEquals(initialProposalSize, leaderBean.getMinProposalSize());
+        assertEquals(initialProposalSize, leaderBean.getMaxProposalSize());
+    }
+
+    private Request createMockRequest() throws IOException {
+        TxnHeader header = mock(TxnHeader.class);
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                OutputArchive oa = (OutputArchive) args[0];
+                oa.writeString("header", "test");
+                return null;
+            }
+        }).when(header).serialize(any(OutputArchive.class), anyString());
+        Record txn = mock(Record.class);
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                OutputArchive oa = (OutputArchive) args[0];
+                oa.writeString("record", "test");
+                return null;
+            }
+        }).when(txn).serialize(any(OutputArchive.class), anyString());
+        return new Request(1, 2, 3, header, txn, 4);
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/test/org/apache/zookeeper/server/quorum/ProposalStatsTest.java
----------------------------------------------------------------------
diff --git a/src/java/test/org/apache/zookeeper/server/quorum/ProposalStatsTest.java b/src/java/test/org/apache/zookeeper/server/quorum/ProposalStatsTest.java
new file mode 100644
index 0000000..1f71979
--- /dev/null
+++ b/src/java/test/org/apache/zookeeper/server/quorum/ProposalStatsTest.java
@@ -0,0 +1,58 @@
+/**
+ * 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.server.quorum;
+
+import org.junit.Test;
+
+import static org.junit.Assert.assertEquals;
+
+public class ProposalStatsTest {
+    @Test
+    public void testSetProposalSizeSetMinMax() {
+        ProposalStats stats = new ProposalStats();
+        assertEquals(-1, stats.getLastProposalSize());
+        assertEquals(-1, stats.getMinProposalSize());
+        assertEquals(-1, stats.getMaxProposalSize());
+        stats.setLastProposalSize(10);
+        assertEquals(10, stats.getLastProposalSize());
+        assertEquals(10, stats.getMinProposalSize());
+        assertEquals(10, stats.getMaxProposalSize());
+        stats.setLastProposalSize(20);
+        assertEquals(20, stats.getLastProposalSize());
+        assertEquals(10, stats.getMinProposalSize());
+        assertEquals(20, stats.getMaxProposalSize());
+        stats.setLastProposalSize(5);
+        assertEquals(5, stats.getLastProposalSize());
+        assertEquals(5, stats.getMinProposalSize());
+        assertEquals(20, stats.getMaxProposalSize());
+    }
+
+    @Test
+    public void testReset() {
+        ProposalStats stats = new ProposalStats();
+        stats.setLastProposalSize(10);
+        assertEquals(10, stats.getLastProposalSize());
+        assertEquals(10, stats.getMinProposalSize());
+        assertEquals(10, stats.getMaxProposalSize());
+        stats.reset();
+        assertEquals(-1, stats.getLastProposalSize());
+        assertEquals(-1, stats.getMinProposalSize());
+        assertEquals(-1, stats.getMaxProposalSize());
+    }
+}

http://git-wip-us.apache.org/repos/asf/zookeeper/blob/1155a081/src/java/test/org/apache/zookeeper/server/util/SerializeUtilsTest.java
----------------------------------------------------------------------
diff --git a/src/java/test/org/apache/zookeeper/server/util/SerializeUtilsTest.java b/src/java/test/org/apache/zookeeper/server/util/SerializeUtilsTest.java
new file mode 100644
index 0000000..61893f7
--- /dev/null
+++ b/src/java/test/org/apache/zookeeper/server/util/SerializeUtilsTest.java
@@ -0,0 +1,128 @@
+/**
+ * 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
+ * <p>
+ * http://www.apache.org/licenses/LICENSE-2.0
+ * <p>
+ * 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.server.util;
+
+import org.apache.jute.BinaryOutputArchive;
+import org.apache.jute.OutputArchive;
+import org.apache.jute.Record;
+import org.apache.zookeeper.server.Request;
+import org.apache.zookeeper.txn.TxnHeader;
+import org.junit.Test;
+import org.mockito.InOrder;
+import org.mockito.invocation.InvocationOnMock;
+import org.mockito.stubbing.Answer;
+
+import java.io.ByteArrayOutputStream;
+import java.io.IOException;
+
+import static org.junit.Assert.assertArrayEquals;
+import static org.junit.Assert.assertNotNull;
+import static org.junit.Assert.assertNull;
+import static org.mockito.Matchers.any;
+import static org.mockito.Matchers.anyString;
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.doAnswer;
+import static org.mockito.Mockito.inOrder;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.verify;
+
+public class SerializeUtilsTest {
+
+    @Test
+    public void testSerializeRequestRequestIsNull() {
+        byte[] data = SerializeUtils.serializeRequest(null);
+        assertNull(data);
+    }
+
+    @Test
+    public void testSerializeRequestRequestHeaderIsNull() {
+        Request request = new Request(0, 0, 0, null, null, 0);
+        byte[] data = SerializeUtils.serializeRequest(request);
+        assertNull(data);
+    }
+
+    @Test
+    public void testSerializeRequestWithoutTxn() throws IOException {
+        // Arrange
+        TxnHeader header = mock(TxnHeader.class);
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                OutputArchive oa = (OutputArchive) args[0];
+                oa.writeString("header", "test");
+                return null;
+            }
+        }).when(header).serialize(any(OutputArchive.class), anyString());
+        Request request = new Request(1, 2, 3, header, null, 4);
+
+        // Act
+        byte[] data = SerializeUtils.serializeRequest(request);
+
+        // Assert
+        assertNotNull(data);
+        verify(header).serialize(any(OutputArchive.class), eq("hdr"));
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+        boa.writeString("header", "test");
+        baos.close();
+        assertArrayEquals(baos.toByteArray(), data);
+    }
+
+    @Test
+    public void testSerializeRequestWithTxn() throws IOException {
+        // Arrange
+        TxnHeader header = mock(TxnHeader.class);
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                OutputArchive oa = (OutputArchive) args[0];
+                oa.writeString("header", "test");
+                return null;
+            }
+        }).when(header).serialize(any(OutputArchive.class), anyString());
+        Record txn = mock(Record.class);
+        doAnswer(new Answer() {
+            @Override
+            public Object answer(InvocationOnMock invocation) throws Throwable {
+                Object[] args = invocation.getArguments();
+                OutputArchive oa = (OutputArchive) args[0];
+                oa.writeString("record", "test");
+                return null;
+            }
+        }).when(txn).serialize(any(OutputArchive.class), anyString());
+        Request request = new Request(1, 2, 3, header, txn, 4);
+
+        // Act
+        byte[] data = SerializeUtils.serializeRequest(request);
+
+        // Assert
+        assertNotNull(data);
+        InOrder inOrder = inOrder(header, txn);
+        inOrder.verify(header).serialize(any(OutputArchive.class), eq("hdr"));
+        inOrder.verify(txn).serialize(any(OutputArchive.class), eq("txn"));
+        ByteArrayOutputStream baos = new ByteArrayOutputStream();
+        BinaryOutputArchive boa = BinaryOutputArchive.getArchive(baos);
+        boa.writeString("header", "test");
+        boa.writeString("record", "test");
+        baos.close();
+        assertArrayEquals(baos.toByteArray(), data);
+    }
+}


Mime
View raw message