Repository: incubator-ratis
Updated Branches:
  refs/heads/master abc1538fb -> 7f57773b8


RATIS-179. Improve the log message in leader election and refactor the tests. 
Tsz Wo Nicholas Sze.


Project: http://git-wip-us.apache.org/repos/asf/incubator-ratis/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ratis/commit/7f57773b
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ratis/tree/7f57773b
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ratis/diff/7f57773b

Branch: refs/heads/master
Commit: 7f57773b8ab62e11b6307cef2acf594b44b03e97
Parents: abc1538
Author: Chen Liang <[email protected]>
Authored: Tue Jan 2 11:06:24 2018 -0800
Committer: Chen Liang <[email protected]>
Committed: Tue Jan 2 11:06:24 2018 -0800

----------------------------------------------------------------------
 .../java/org/apache/ratis/util/JavaUtils.java   |  8 +-
 .../ratis/grpc/TestLeaderElectionWithGrpc.java  | 36 +++++++++
 .../org/apache/ratis/grpc/TestRaftWithGrpc.java | 18 -----
 .../TestLeaderElectionWithHadoopRpc.java        | 56 +++++++++++++
 .../ratis/hadooprpc/TestRaftWithHadoopRpc.java  | 11 ---
 .../netty/TestLeaderElectionWithNetty.java      | 35 ++++++++
 .../apache/ratis/netty/TestRaftWithNetty.java   | 18 -----
 .../ratis/server/impl/RaftServerImpl.java       | 20 ++---
 .../apache/ratis/server/impl/ServerState.java   | 13 +--
 .../java/org/apache/ratis/MiniRaftCluster.java  |  7 +-
 .../java/org/apache/ratis/RaftBasicTests.java   | 50 +-----------
 .../ratis/server/impl/LeaderElectionTests.java  | 84 ++++++++++++++++++++
 .../TestLeaderElectionWithSimulatedRpc.java     | 25 ++++++
 13 files changed, 267 insertions(+), 114 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java
----------------------------------------------------------------------
diff --git a/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java 
b/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java
index e910f28..0a99527 100644
--- a/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java
+++ b/ratis-common/src/main/java/org/apache/ratis/util/JavaUtils.java
@@ -184,10 +184,8 @@ public interface JavaUtils {
     }
   }
 
-  Supplier<Timer> TIMER = memoize(() -> new Timer(true));
-
-  static UncheckedAutoCloseable runRepeatedly(Runnable runnable, long delay, 
long period, TimeUnit unit) {
-    final Timer timer = TIMER.get();
+  static Timer runRepeatedly(Runnable runnable, long delay, long period, 
TimeUnit unit) {
+    final Timer timer = new Timer();
     timer.schedule(new TimerTask() {
       @Override
       public void run() {
@@ -195,7 +193,7 @@ public interface JavaUtils {
       }
     }, unit.toMillis(delay), unit.toMillis(period));
 
-    return timer::cancel;
+    return timer;
   }
 
   static void dumpAllThreads(Consumer<String> println) {

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestLeaderElectionWithGrpc.java
----------------------------------------------------------------------
diff --git 
a/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestLeaderElectionWithGrpc.java
 
b/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestLeaderElectionWithGrpc.java
new file mode 100644
index 0000000..a62dab0
--- /dev/null
+++ 
b/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestLeaderElectionWithGrpc.java
@@ -0,0 +1,36 @@
+/**
+ * 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.ratis.grpc;
+
+import org.apache.ratis.server.impl.BlockRequestHandlingInjection;
+import org.apache.ratis.server.impl.LeaderElectionTests;
+import org.junit.Test;
+
+public class TestLeaderElectionWithGrpc
+    extends LeaderElectionTests<MiniRaftClusterWithGRpc>
+    implements MiniRaftClusterWithGRpc.FactoryGet {
+
+  @Override
+  @Test
+  public void testEnforceLeader() throws Exception {
+    super.testEnforceLeader();
+
+    MiniRaftClusterWithGRpc.sendServerRequestInjection.clear();
+    BlockRequestHandlingInjection.getInstance().unblockAll();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftWithGrpc.java
----------------------------------------------------------------------
diff --git 
a/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftWithGrpc.java 
b/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftWithGrpc.java
index 76a64b3..b79e41e 100644
--- a/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftWithGrpc.java
+++ b/ratis-grpc/src/test/java/org/apache/ratis/grpc/TestRaftWithGrpc.java
@@ -17,23 +17,14 @@
  */
 package org.apache.ratis.grpc;
 
-import org.apache.log4j.Level;
 import org.apache.ratis.RaftBasicTests;
 import org.apache.ratis.server.impl.BlockRequestHandlingInjection;
-import org.apache.ratis.server.impl.RaftServerImpl;
-import org.apache.ratis.util.FileUtils;
-import org.apache.ratis.util.LogUtils;
 import org.junit.Assert;
 import org.junit.Test;
 
 import java.io.IOException;
 
 public class TestRaftWithGrpc extends RaftBasicTests {
-  static {
-    LogUtils.setLogLevel(RaftServerImpl.LOG, Level.DEBUG);
-    LogUtils.setLogLevel(FileUtils.LOG, Level.DEBUG);
-  }
-
   private final MiniRaftClusterWithGRpc cluster;
 
   public TestRaftWithGrpc() throws IOException {
@@ -49,15 +40,6 @@ public class TestRaftWithGrpc extends RaftBasicTests {
 
   @Override
   @Test
-  public void testEnforceLeader() throws Exception {
-    super.testEnforceLeader();
-
-    MiniRaftClusterWithGRpc.sendServerRequestInjection.clear();
-    BlockRequestHandlingInjection.getInstance().unblockAll();
-  }
-
-  @Override
-  @Test
   public void testWithLoad() throws Exception {
     super.testWithLoad();
     BlockRequestHandlingInjection.getInstance().unblockAll();

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestLeaderElectionWithHadoopRpc.java
----------------------------------------------------------------------
diff --git 
a/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestLeaderElectionWithHadoopRpc.java
 
b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestLeaderElectionWithHadoopRpc.java
new file mode 100644
index 0000000..a730fa5
--- /dev/null
+++ 
b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestLeaderElectionWithHadoopRpc.java
@@ -0,0 +1,56 @@
+/**
+ * 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.ratis.hadooprpc;
+
+import org.apache.hadoop.conf.Configuration;
+import org.apache.hadoop.fs.CommonConfigurationKeys;
+import org.apache.log4j.Level;
+import org.apache.ratis.server.impl.BlockRequestHandlingInjection;
+import org.apache.ratis.server.impl.LeaderElectionTests;
+import org.apache.ratis.util.LogUtils;
+import org.junit.Test;
+
+import java.io.IOException;
+
+public class TestLeaderElectionWithHadoopRpc
+    extends LeaderElectionTests<MiniRaftClusterWithHadoopRpc>
+    implements MiniRaftClusterWithHadoopRpc.Factory.Get {
+  static {
+    LogUtils.setLogLevel(MiniRaftClusterWithHadoopRpc.LOG, Level.DEBUG);
+  }
+
+  @Override
+  public MiniRaftClusterWithHadoopRpc newCluster(int numPeers) throws 
IOException {
+    final Configuration conf = new Configuration();
+    HadoopConfigKeys.Ipc.setHandlers(conf, 20);
+    conf.setInt(CommonConfigurationKeys.IPC_CLIENT_CONNECT_MAX_RETRIES_KEY, 0);
+    conf.setInt(CommonConfigurationKeys.IPC_SERVER_HANDLER_QUEUE_SIZE_KEY, 
1000);
+    conf.setInt(CommonConfigurationKeys.IPC_CLIENT_RPC_TIMEOUT_KEY, 1000);
+    return MiniRaftClusterWithHadoopRpc.FACTORY.newCluster(
+        numPeers, getProperties(), conf);
+  }
+
+  @Override
+  @Test
+  public void testEnforceLeader() throws Exception {
+    super.testEnforceLeader();
+
+    MiniRaftClusterWithHadoopRpc.sendServerRequest.clear();
+    BlockRequestHandlingInjection.getInstance().unblockAll();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestRaftWithHadoopRpc.java
----------------------------------------------------------------------
diff --git 
a/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestRaftWithHadoopRpc.java
 
b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestRaftWithHadoopRpc.java
index b977c18..3f51c0b 100644
--- 
a/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestRaftWithHadoopRpc.java
+++ 
b/ratis-hadoop/src/test/java/org/apache/ratis/hadooprpc/TestRaftWithHadoopRpc.java
@@ -27,8 +27,6 @@ import org.junit.Test;
 
 import java.io.IOException;
 
-import static 
org.apache.ratis.hadooprpc.MiniRaftClusterWithHadoopRpc.sendServerRequest;
-
 public class TestRaftWithHadoopRpc extends RaftBasicTests {
   static {
     LogUtils.setLogLevel(MiniRaftClusterWithHadoopRpc.LOG, Level.DEBUG);
@@ -53,15 +51,6 @@ public class TestRaftWithHadoopRpc extends RaftBasicTests {
 
   @Override
   @Test
-  public void testEnforceLeader() throws Exception {
-    super.testEnforceLeader();
-
-    sendServerRequest.clear();
-    BlockRequestHandlingInjection.getInstance().unblockAll();
-  }
-
-  @Override
-  @Test
   public void testWithLoad() throws Exception {
     super.testWithLoad();
     BlockRequestHandlingInjection.getInstance().unblockAll();

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-netty/src/test/java/org/apache/ratis/netty/TestLeaderElectionWithNetty.java
----------------------------------------------------------------------
diff --git 
a/ratis-netty/src/test/java/org/apache/ratis/netty/TestLeaderElectionWithNetty.java
 
b/ratis-netty/src/test/java/org/apache/ratis/netty/TestLeaderElectionWithNetty.java
new file mode 100644
index 0000000..6d40b60
--- /dev/null
+++ 
b/ratis-netty/src/test/java/org/apache/ratis/netty/TestLeaderElectionWithNetty.java
@@ -0,0 +1,35 @@
+/**
+ * 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.ratis.netty;
+
+import org.apache.ratis.server.impl.BlockRequestHandlingInjection;
+import org.apache.ratis.server.impl.LeaderElectionTests;
+import org.junit.Test;
+
+public class TestLeaderElectionWithNetty
+    extends LeaderElectionTests<MiniRaftClusterWithNetty>
+    implements MiniRaftClusterWithNetty.FactoryGet {
+  @Override
+  @Test
+  public void testEnforceLeader() throws Exception {
+    super.testEnforceLeader();
+
+    MiniRaftClusterWithNetty.sendServerRequest.clear();
+    BlockRequestHandlingInjection.getInstance().unblockAll();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-netty/src/test/java/org/apache/ratis/netty/TestRaftWithNetty.java
----------------------------------------------------------------------
diff --git 
a/ratis-netty/src/test/java/org/apache/ratis/netty/TestRaftWithNetty.java 
b/ratis-netty/src/test/java/org/apache/ratis/netty/TestRaftWithNetty.java
index afb7c2b..b3996ac 100644
--- a/ratis-netty/src/test/java/org/apache/ratis/netty/TestRaftWithNetty.java
+++ b/ratis-netty/src/test/java/org/apache/ratis/netty/TestRaftWithNetty.java
@@ -17,22 +17,13 @@
  */
 package org.apache.ratis.netty;
 
-import org.apache.log4j.Level;
 import org.apache.ratis.RaftBasicTests;
-import org.apache.ratis.client.RaftClient;
 import org.apache.ratis.server.impl.BlockRequestHandlingInjection;
-import org.apache.ratis.server.impl.RaftServerImpl;
-import org.apache.ratis.util.LogUtils;
 import org.junit.Test;
 
 import java.io.IOException;
 
 public class TestRaftWithNetty extends RaftBasicTests {
-  static {
-    LogUtils.setLogLevel(RaftServerImpl.LOG, Level.DEBUG);
-    LogUtils.setLogLevel(RaftClient.LOG, Level.DEBUG);
-  }
-
   private final MiniRaftClusterWithNetty cluster;
 
   public TestRaftWithNetty() throws IOException {
@@ -47,15 +38,6 @@ public class TestRaftWithNetty extends RaftBasicTests {
 
   @Override
   @Test
-  public void testEnforceLeader() throws Exception {
-    super.testEnforceLeader();
-
-    MiniRaftClusterWithNetty.sendServerRequest.clear();
-    BlockRequestHandlingInjection.getInstance().unblockAll();
-  }
-
-  @Override
-  @Test
   public void testWithLoad() throws Exception {
     super.testWithLoad();
     BlockRequestHandlingInjection.getInstance().unblockAll();

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
----------------------------------------------------------------------
diff --git 
a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java 
b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
index 8b784e6..773b0b0 100644
--- 
a/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
+++ 
b/ratis-server/src/main/java/org/apache/ratis/server/impl/RaftServerImpl.java
@@ -153,8 +153,9 @@ public class RaftServerImpl implements RaftServerProtocol,
     return proxy.getServerRpc();
   }
 
-  private void setRole(Role newRole) {
-    LOG.debug("{} changes role from {} to {}", getId(), this.role, newRole);
+  private void setRole(Role newRole, String op) {
+    LOG.info("{} changes role from {} to {} at term {} for {}",
+        getId(), this.role, newRole, state.getCurrentTerm(), op);
     this.role = newRole;
   }
 
@@ -186,7 +187,7 @@ public class RaftServerImpl implements RaftServerProtocol,
    * The peer belongs to the current configuration, should start as a follower
    */
   private void startAsFollower() {
-    setRole(Role.FOLLOWER);
+    setRole(Role.FOLLOWER, "startAsFollower");
     startHeartbeatMonitor();
     lifeCycle.transition(RUNNING);
   }
@@ -197,7 +198,7 @@ public class RaftServerImpl implements RaftServerProtocol,
    * start election.
    */
   private void startInitializing() {
-    setRole(Role.FOLLOWER);
+    setRole(Role.FOLLOWER, "startInitializing");
     // do not start heartbeatMonitoring
   }
 
@@ -273,7 +274,7 @@ public class RaftServerImpl implements RaftServerProtocol,
     final boolean metadataUpdated = state.updateCurrentTerm(newTerm);
 
     if (old != Role.FOLLOWER) {
-      setRole(Role.FOLLOWER);
+      setRole(Role.FOLLOWER, "changeToFollower");
       if (old == Role.LEADER) {
         shutdownLeaderState(false);
       } else if (old == Role.CANDIDATE) {
@@ -312,8 +313,9 @@ public class RaftServerImpl implements RaftServerProtocol,
   synchronized void changeToLeader() {
     Preconditions.assertTrue(isCandidate());
     shutdownElectionDaemon();
-    setRole(Role.LEADER);
+    setRole(Role.LEADER, "changeToLeader");
     state.becomeLeader();
+
     // start sending AppendEntries RPC to followers
     leaderState = new LeaderState(this, getProxy().getProperties());
     leaderState.start();
@@ -338,7 +340,7 @@ public class RaftServerImpl implements RaftServerProtocol,
   synchronized void changeToCandidate() {
     Preconditions.assertTrue(isFollower());
     shutdownHeartbeatMonitor();
-    setRole(Role.CANDIDATE);
+    setRole(Role.CANDIDATE, "changeToCandidate");
     // start election
     electionDaemon = new LeaderElection(this);
     electionDaemon.start();
@@ -740,7 +742,7 @@ public class RaftServerImpl implements RaftServerProtocol,
         return reply;
       }
       changeToFollower(leaderTerm, true);
-      state.setLeader(leaderId);
+      state.setLeader(leaderId, "appendEntries");
 
       if (!initializing && lifeCycle.compareAndTransition(STARTING, RUNNING)) {
         startHeartbeatMonitor();
@@ -837,7 +839,7 @@ public class RaftServerImpl implements RaftServerProtocol,
         return reply;
       }
       changeToFollower(leaderTerm, true);
-      state.setLeader(leaderId);
+      state.setLeader(leaderId, "installSnapshot");
 
       if (lifeCycle.getCurrentState() == RUNNING) {
         heartbeatMonitor.updateLastRpcTime(true);

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
----------------------------------------------------------------------
diff --git 
a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java 
b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
index a51d4b9..b50393e 100644
--- a/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
+++ b/ratis-server/src/main/java/org/apache/ratis/server/impl/ServerState.java
@@ -171,7 +171,7 @@ public class ServerState implements Closeable {
     if (newTerm > currentTerm) {
       currentTerm = newTerm;
       votedFor = null;
-      setLeader(null);
+      setLeader(null, "updateCurrentTerm");
       return true;
     }
     return false;
@@ -190,7 +190,7 @@ public class ServerState implements Closeable {
    */
   long initElection() {
     votedFor = selfId;
-    setLeader(null);
+    setLeader(null, "initElection");
     return ++currentTerm;
   }
 
@@ -203,18 +203,19 @@ public class ServerState implements Closeable {
    */
   void grantVote(RaftPeerId candidateId) {
     votedFor = candidateId;
-    setLeader(null);
+    setLeader(null, "grantVote");
   }
 
-  void setLeader(RaftPeerId newLeaderId) {
+  void setLeader(RaftPeerId newLeaderId, String op) {
     if (!Objects.equals(leaderId, newLeaderId)) {
-      LOG.info("{}: change Leader from {} to {}", selfId, leaderId, 
newLeaderId);
+      LOG.info("{}: change Leader from {} to {} at term {} for {}",
+          selfId, leaderId, newLeaderId, getCurrentTerm(), op);
       leaderId = newLeaderId;
     }
   }
 
   void becomeLeader() {
-    setLeader(selfId);
+    setLeader(selfId, "becomeLeader");
   }
 
   public RaftLog getLog() {

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java
----------------------------------------------------------------------
diff --git a/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java 
b/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java
index b50d847..26df59c 100644
--- a/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java
+++ b/ratis-server/src/test/java/org/apache/ratis/MiniRaftCluster.java
@@ -140,12 +140,15 @@ public abstract class MiniRaftCluster {
   protected final Parameters parameters;
   protected final Map<RaftPeerId, RaftServerProxy> servers = new 
ConcurrentHashMap<>();
 
+  private final Timer timer;
+
   protected MiniRaftCluster(String[] ids, RaftProperties properties, 
Parameters parameters) {
     this.group = initRaftGroup(Arrays.asList(ids));
     this.properties = new RaftProperties(properties);
     this.parameters = parameters;
 
-    JavaUtils.runRepeatedly(() -> LOG.info("TIMED-PRINT" + printServers()), 
10, 10, TimeUnit.SECONDS);
+    this.timer = JavaUtils.runRepeatedly(() -> LOG.info("TIMED-PRINT: " + 
printServers()),
+        10, 10, TimeUnit.SECONDS);
     ExitUtils.disableSystemExit();
   }
 
@@ -519,6 +522,8 @@ public abstract class MiniRaftCluster {
     LOG.info("***     Stopping " + getClass().getSimpleName());
     LOG.info("*** ");
     LOG.info("************************************************************** 
");
+
+    timer.cancel();
     
getServerAliveStream().map(RaftServerImpl::getProxy).forEach(RaftServerProxy::close);
 
     ExitUtils.assertNotTerminated();

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java
----------------------------------------------------------------------
diff --git a/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java 
b/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java
index 85b165e..99c14b1 100644
--- a/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java
+++ b/ratis-server/src/test/java/org/apache/ratis/RaftBasicTests.java
@@ -18,38 +18,28 @@
 package org.apache.ratis;
 
 import org.apache.log4j.Level;
-import org.apache.ratis.RaftTestUtil.SimpleMessage;
+import org.apache.ratis.RaftTestUtil.*;
 import org.apache.ratis.client.RaftClient;
 import org.apache.ratis.conf.RaftProperties;
-
 import org.apache.ratis.protocol.RaftClientReply;
 import org.apache.ratis.protocol.RaftPeerId;
 import org.apache.ratis.server.impl.BlockRequestHandlingInjection;
 import org.apache.ratis.server.impl.RaftServerImpl;
-import org.apache.ratis.server.storage.RaftStorageTestUtils;
+import org.apache.ratis.server.storage.RaftLog;
 import org.apache.ratis.shaded.proto.RaftProtos.LogEntryProto;
-import org.apache.ratis.util.ExitUtils;
-
-
 import org.apache.ratis.util.JavaUtils;
 import org.apache.ratis.util.LogUtils;
 import org.junit.After;
 import org.junit.Assert;
 import org.junit.Before;
 import org.junit.Test;
-import org.apache.ratis.server.storage.RaftLog;
 import org.slf4j.Logger;
 
-
-import static org.apache.ratis.RaftTestUtil.*;
-import static org.junit.Assert.assertTrue;
-
 import java.io.IOException;
 import java.util.List;
 import java.util.Timer;
 import java.util.TimerTask;
 import java.util.concurrent.CompletableFuture;
-import java.util.concurrent.ThreadLocalRandom;
 import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
@@ -57,6 +47,8 @@ import java.util.function.Predicate;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;
 
+import static org.apache.ratis.RaftTestUtil.*;
+import static org.junit.Assert.assertTrue;
 
 public abstract class RaftBasicTests extends BaseTest {
   {
@@ -89,30 +81,6 @@ public abstract class RaftBasicTests extends BaseTest {
   }
 
   @Test
-  public void testBasicLeaderElection() throws Exception {
-    LOG.info("Running testBasicLeaderElection");
-    final MiniRaftCluster cluster = getCluster();
-    waitAndKillLeader(cluster, true);
-    waitAndKillLeader(cluster, true);
-    waitAndKillLeader(cluster, true);
-    waitAndKillLeader(cluster, false);
-  }
-
-  @Test
-  public void testChangeLeader() throws Exception {
-    RaftStorageTestUtils.setRaftLogWorkerLogLevel(Level.TRACE);
-    LOG.info("Running testChangeLeader");
-    final MiniRaftCluster cluster = getCluster();
-
-    RaftPeerId leader = RaftTestUtil.waitForLeader(cluster).getId();
-    for(int i = 0; i < 10; i++) {
-      leader = RaftTestUtil.changeLeader(cluster, leader);
-      ExitUtils.assertNotTerminated();
-    }
-    RaftStorageTestUtils.setRaftLogWorkerLogLevel(Level.INFO);
-  }
-
-  @Test
   public void testBasicAppendEntries() throws Exception {
     runTestBasicAppendEntries(false, 10, getCluster(), LOG);
   }
@@ -235,16 +203,6 @@ public abstract class RaftBasicTests extends BaseTest {
             .forEach(log -> RaftTestUtil.checkLogEntries(log, messages, 
predicate));
   }
 
-  @Test
-  public void testEnforceLeader() throws Exception {
-    LOG.info("Running testEnforceLeader");
-    final String leader = "s" + 
ThreadLocalRandom.current().nextInt(NUM_SERVERS);
-    LOG.info("enforce leader to " + leader);
-    final MiniRaftCluster cluster = getCluster();
-    waitForLeader(cluster);
-    waitForLeader(cluster, leader);
-  }
-
   class Client4TestWithLoad extends Thread {
     final int index;
     final SimpleMessage[] messages;

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-server/src/test/java/org/apache/ratis/server/impl/LeaderElectionTests.java
----------------------------------------------------------------------
diff --git 
a/ratis-server/src/test/java/org/apache/ratis/server/impl/LeaderElectionTests.java
 
b/ratis-server/src/test/java/org/apache/ratis/server/impl/LeaderElectionTests.java
new file mode 100644
index 0000000..736c5e7
--- /dev/null
+++ 
b/ratis-server/src/test/java/org/apache/ratis/server/impl/LeaderElectionTests.java
@@ -0,0 +1,84 @@
+/**
+ * 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.ratis.server.impl;
+
+import org.apache.log4j.Level;
+import org.apache.ratis.BaseTest;
+import org.apache.ratis.MiniRaftCluster;
+import org.apache.ratis.RaftTestUtil;
+import org.apache.ratis.client.RaftClient;
+import org.apache.ratis.protocol.RaftPeerId;
+import org.apache.ratis.server.storage.RaftStorageTestUtils;
+import org.apache.ratis.util.ExitUtils;
+import org.apache.ratis.util.LogUtils;
+import org.junit.Test;
+
+import java.util.concurrent.ThreadLocalRandom;
+
+import static org.apache.ratis.RaftTestUtil.waitAndKillLeader;
+import static org.apache.ratis.RaftTestUtil.waitForLeader;
+
+public abstract class LeaderElectionTests<CLUSTER extends MiniRaftCluster>
+    extends BaseTest
+    implements MiniRaftCluster.Factory.Get<CLUSTER> {
+  {
+    LogUtils.setLogLevel(RaftServerImpl.LOG, Level.DEBUG);
+    LogUtils.setLogLevel(RaftClient.LOG, Level.DEBUG);
+  }
+
+  @Test
+  public void testBasicLeaderElection() throws Exception {
+    LOG.info("Running testBasicLeaderElection");
+    final MiniRaftCluster cluster = newCluster(5);
+    cluster.start();
+    waitAndKillLeader(cluster, true);
+    waitAndKillLeader(cluster, true);
+    waitAndKillLeader(cluster, true);
+    waitAndKillLeader(cluster, false);
+    cluster.shutdown();
+  }
+
+  @Test
+  public void testChangeLeader() throws Exception {
+    RaftStorageTestUtils.setRaftLogWorkerLogLevel(Level.TRACE);
+    LOG.info("Running testChangeLeader");
+    final MiniRaftCluster cluster = newCluster(3);
+    cluster.start();
+
+    RaftPeerId leader = RaftTestUtil.waitForLeader(cluster).getId();
+    for(int i = 0; i < 10; i++) {
+      leader = RaftTestUtil.changeLeader(cluster, leader);
+      ExitUtils.assertNotTerminated();
+    }
+    RaftStorageTestUtils.setRaftLogWorkerLogLevel(Level.INFO);
+    cluster.shutdown();
+  }
+
+  @Test
+  public void testEnforceLeader() throws Exception {
+    final int numServer = 3;
+    LOG.info("Running testEnforceLeader");
+    final String leader = "s" + ThreadLocalRandom.current().nextInt(numServer);
+    LOG.info("enforce leader to " + leader);
+    final MiniRaftCluster cluster = newCluster(numServer);
+    cluster.start();
+    waitForLeader(cluster);
+    waitForLeader(cluster, leader);
+    cluster.shutdown();
+  }
+}

http://git-wip-us.apache.org/repos/asf/incubator-ratis/blob/7f57773b/ratis-server/src/test/java/org/apache/ratis/server/simulation/TestLeaderElectionWithSimulatedRpc.java
----------------------------------------------------------------------
diff --git 
a/ratis-server/src/test/java/org/apache/ratis/server/simulation/TestLeaderElectionWithSimulatedRpc.java
 
b/ratis-server/src/test/java/org/apache/ratis/server/simulation/TestLeaderElectionWithSimulatedRpc.java
new file mode 100644
index 0000000..7ea273b
--- /dev/null
+++ 
b/ratis-server/src/test/java/org/apache/ratis/server/simulation/TestLeaderElectionWithSimulatedRpc.java
@@ -0,0 +1,25 @@
+/**
+ * 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.ratis.server.simulation;
+
+import org.apache.ratis.server.impl.LeaderElectionTests;
+
+public class TestLeaderElectionWithSimulatedRpc
+    extends LeaderElectionTests<MiniRaftClusterWithSimulatedRpc>
+    implements MiniRaftClusterWithSimulatedRpc.FactoryGet {
+}

Reply via email to