X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2Fbehaviors%2FIsolatedLeaderTest.java;h=618bd4bb0d15d07ee41d27913151afaf6c9cedd1;hp=708068a78952db5ba287501c1a534a31721556ad;hb=e1eca73a5ae2ffae8dd78c6fe5281cd2f45d5ef3;hpb=e773a75ec0a88fb88c3314f89ce92d951401e585 diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/IsolatedLeaderTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/IsolatedLeaderTest.java index 708068a789..618bd4bb0d 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/IsolatedLeaderTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/IsolatedLeaderTest.java @@ -7,135 +7,158 @@ */ package org.opendaylight.controller.cluster.raft.behaviors; +import static org.junit.Assert.assertEquals; + import akka.actor.ActorRef; import akka.actor.Props; -import akka.testkit.JavaTestKit; +import akka.testkit.TestActorRef; import java.util.HashMap; import java.util.Map; +import org.junit.After; import org.junit.Test; +import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl; import org.opendaylight.controller.cluster.raft.MockRaftActorContext; import org.opendaylight.controller.cluster.raft.RaftActorContext; import org.opendaylight.controller.cluster.raft.RaftState; import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply; -import org.opendaylight.controller.cluster.raft.utils.DoNothingActor; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertTrue; +import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor; + +public class IsolatedLeaderTest extends AbstractLeaderTest { + + private final TestActorRef leaderActor = actorFactory.createTestActor( + Props.create(MessageCollectorActor.class), actorFactory.generateActorId("leader")); + + private final TestActorRef senderActor = actorFactory.createTestActor( + Props.create(MessageCollectorActor.class), actorFactory.generateActorId("sender")); -public class IsolatedLeaderTest extends AbstractRaftActorBehaviorTest { + private AbstractLeader isolatedLeader; - private ActorRef leaderActor = - getSystem().actorOf(Props.create(DoNothingActor.class)); + @Override + @After + public void tearDown() throws Exception { + if (isolatedLeader != null) { + isolatedLeader.close(); + } - private ActorRef senderActor = - getSystem().actorOf(Props.create(DoNothingActor.class)); + super.tearDown(); + } @Override - protected RaftActorBehavior createBehavior( - RaftActorContext actorContext) { - return new Leader(actorContext); + protected IsolatedLeader createBehavior(RaftActorContext actorContext) { + return new IsolatedLeader(actorContext); } @Override - protected RaftActorContext createActorContext() { + protected MockRaftActorContext createActorContext() { return createActorContext(leaderActor); } + @Override + protected MockRaftActorContext createActorContext(ActorRef actor) { + DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl(); + configParams.setElectionTimeoutFactor(100000); + MockRaftActorContext context = new MockRaftActorContext("isolated-leader", getSystem(), actor); + context.setConfigParams(configParams); + return context; + } @Test - public void testHandleMessageWithThreeMembers() { - new JavaTestKit(getSystem()) {{ - String followerAddress1 = "akka://test/user/$a"; - String followerAddress2 = "akka://test/user/$b"; - - MockRaftActorContext leaderActorContext = (MockRaftActorContext) createActorContext(); - Map peerAddresses = new HashMap<>(); - peerAddresses.put("follower-1", followerAddress1); - peerAddresses.put("follower-2", followerAddress2); - leaderActorContext.setPeerAddresses(peerAddresses); - - IsolatedLeader isolatedLeader = new IsolatedLeader(leaderActorContext); - assertTrue(isolatedLeader.state() == RaftState.IsolatedLeader); - - // in a 3 node cluster, even if 1 follower is returns a reply, the isolatedLeader is not isolated - RaftActorBehavior behavior = isolatedLeader.handleMessage(senderActor, + public void testHandleMessageWithThreeMembers() throws Exception { + String followerAddress1 = "akka://test/user/$a"; + String followerAddress2 = "akka://test/user/$b"; + + MockRaftActorContext leaderActorContext = createActorContext(); + Map peerAddresses = new HashMap<>(); + peerAddresses.put("follower-1", followerAddress1); + peerAddresses.put("follower-2", followerAddress2); + leaderActorContext.setPeerAddresses(peerAddresses); + + isolatedLeader = new IsolatedLeader(leaderActorContext); + leaderActorContext.setCurrentBehavior(isolatedLeader); + assertEquals("Raft state", RaftState.IsolatedLeader, isolatedLeader.state()); + + // in a 3 node cluster, even if 1 follower is returns a reply, the isolatedLeader is not isolated + RaftActorBehavior newBehavior = isolatedLeader.handleMessage(senderActor, new AppendEntriesReply("follower-1", isolatedLeader.lastTerm() - 1, true, - isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1)); + isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short)0)); + + assertEquals("Raft state", RaftState.Leader, newBehavior.state()); - assertEquals(RaftState.Leader, behavior.state()); + isolatedLeader.close(); + isolatedLeader = (AbstractLeader) newBehavior; - behavior = isolatedLeader.handleMessage(senderActor, + newBehavior = isolatedLeader.handleMessage(senderActor, new AppendEntriesReply("follower-2", isolatedLeader.lastTerm() - 1, true, - isolatedLeader.lastIndex() -1, isolatedLeader.lastTerm() -1 )); + isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short)0 )); - assertEquals(RaftState.Leader, behavior.state()); - }}; + assertEquals("Raft state", RaftState.Leader, newBehavior.state()); } @Test - public void testHandleMessageWithFiveMembers() { - new JavaTestKit(getSystem()) {{ - - String followerAddress1 = "akka://test/user/$a"; - String followerAddress2 = "akka://test/user/$b"; - String followerAddress3 = "akka://test/user/$c"; - String followerAddress4 = "akka://test/user/$d"; - - MockRaftActorContext leaderActorContext = (MockRaftActorContext) createActorContext(); - Map peerAddresses = new HashMap<>(); - peerAddresses.put("follower-1", followerAddress1); - peerAddresses.put("follower-2", followerAddress2); - peerAddresses.put("follower-3", followerAddress3); - peerAddresses.put("follower-4", followerAddress4); - leaderActorContext.setPeerAddresses(peerAddresses); - - IsolatedLeader isolatedLeader = new IsolatedLeader(leaderActorContext); - assertEquals(RaftState.IsolatedLeader, isolatedLeader.state()); - - // in a 5 member cluster, atleast 2 followers need to be active and return a reply - RaftActorBehavior behavior = isolatedLeader.handleMessage(senderActor, + public void testHandleMessageWithFiveMembers() throws Exception { + String followerAddress1 = "akka://test/user/$a"; + String followerAddress2 = "akka://test/user/$b"; + String followerAddress3 = "akka://test/user/$c"; + String followerAddress4 = "akka://test/user/$d"; + + final MockRaftActorContext leaderActorContext = createActorContext(); + Map peerAddresses = new HashMap<>(); + peerAddresses.put("follower-1", followerAddress1); + peerAddresses.put("follower-2", followerAddress2); + peerAddresses.put("follower-3", followerAddress3); + peerAddresses.put("follower-4", followerAddress4); + leaderActorContext.setPeerAddresses(peerAddresses); + + isolatedLeader = new IsolatedLeader(leaderActorContext); + leaderActorContext.setCurrentBehavior(isolatedLeader); + assertEquals("Raft state", RaftState.IsolatedLeader, isolatedLeader.state()); + + // in a 5 member cluster, atleast 2 followers need to be active and return a reply + RaftActorBehavior newBehavior = isolatedLeader.handleMessage(senderActor, new AppendEntriesReply("follower-1", isolatedLeader.lastTerm() - 1, true, - isolatedLeader.lastIndex() -1, isolatedLeader.lastTerm() -1 )); + isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short)0 )); - assertEquals(RaftState.IsolatedLeader, behavior.state()); + assertEquals("Raft state", RaftState.IsolatedLeader, newBehavior.state()); - behavior = isolatedLeader.handleMessage(senderActor, + newBehavior = isolatedLeader.handleMessage(senderActor, new AppendEntriesReply("follower-2", isolatedLeader.lastTerm() - 1, true, - isolatedLeader.lastIndex() -1, isolatedLeader.lastTerm() -1 )); + isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short)0 )); + + assertEquals("Raft state", RaftState.Leader, newBehavior.state()); - assertEquals(RaftState.Leader, behavior.state()); + isolatedLeader.close(); + isolatedLeader = (AbstractLeader) newBehavior; - behavior = isolatedLeader.handleMessage(senderActor, + newBehavior = isolatedLeader.handleMessage(senderActor, new AppendEntriesReply("follower-3", isolatedLeader.lastTerm() - 1, true, - isolatedLeader.lastIndex() -1, isolatedLeader.lastTerm() -1 )); + isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short)0 )); - assertEquals(RaftState.Leader, behavior.state()); - }}; + assertEquals("Raft state", RaftState.Leader, newBehavior.state()); } @Test - public void testHandleMessageFromAnotherLeader() { - new JavaTestKit(getSystem()) {{ - String followerAddress1 = "akka://test/user/$a"; - String followerAddress2 = "akka://test/user/$b"; - - MockRaftActorContext leaderActorContext = (MockRaftActorContext) createActorContext(); - Map peerAddresses = new HashMap<>(); - peerAddresses.put("follower-1", followerAddress1); - peerAddresses.put("follower-2", followerAddress2); - leaderActorContext.setPeerAddresses(peerAddresses); - - IsolatedLeader isolatedLeader = new IsolatedLeader(leaderActorContext); - assertTrue(isolatedLeader.state() == RaftState.IsolatedLeader); - - // if an append-entries reply is received by the isolated-leader, and that reply - // has a term > than its own term, then IsolatedLeader switches to Follower - // bowing itself to another leader in the cluster - RaftActorBehavior behavior = isolatedLeader.handleMessage(senderActor, + public void testHandleMessageFromAnotherLeader() throws Exception { + String followerAddress1 = "akka://test/user/$a"; + String followerAddress2 = "akka://test/user/$b"; + + MockRaftActorContext leaderActorContext = createActorContext(); + Map peerAddresses = new HashMap<>(); + peerAddresses.put("follower-1", followerAddress1); + peerAddresses.put("follower-2", followerAddress2); + leaderActorContext.setPeerAddresses(peerAddresses); + + isolatedLeader = new IsolatedLeader(leaderActorContext); + assertEquals("Raft state", RaftState.IsolatedLeader, isolatedLeader.state()); + + // if an append-entries reply is received by the isolated-leader, and that reply + // has a term > than its own term, then IsolatedLeader switches to Follower + // bowing itself to another leader in the cluster + RaftActorBehavior newBehavior = isolatedLeader.handleMessage(senderActor, new AppendEntriesReply("follower-1", isolatedLeader.lastTerm() + 1, true, - isolatedLeader.lastIndex() + 1, isolatedLeader.lastTerm() + 1)); + isolatedLeader.lastIndex() + 1, isolatedLeader.lastTerm() + 1, (short)0)); - assertEquals(RaftState.Follower, behavior.state()); - }}; + assertEquals("Raft state", RaftState.Follower, newBehavior.state()); + newBehavior.close(); } }