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);
+ }
+}
|