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%2FCandidateTest.java;h=c76368370506af15ab4b7b567672514514e41690;hp=9efdbd7c54a497d6b07ce11977f35b7814a58e99;hb=475d28f717bae92b2cc10b0589131771fcc62242;hpb=97222f19035815199200e727f43960513073eb9e diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java index 9efdbd7c54..c763683705 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java @@ -4,19 +4,21 @@ import akka.actor.ActorRef; import akka.actor.Props; import akka.testkit.JavaTestKit; import junit.framework.Assert; +import org.junit.Before; import org.junit.Test; 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.internal.messages.ElectionTimeout; +import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout; import org.opendaylight.controller.cluster.raft.messages.AppendEntries; import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply; import org.opendaylight.controller.cluster.raft.messages.RequestVote; import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply; import org.opendaylight.controller.cluster.raft.utils.DoNothingActor; -import java.util.Arrays; import java.util.Collections; +import java.util.HashMap; +import java.util.Map; import static org.junit.Assert.assertEquals; @@ -37,14 +39,40 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { private final ActorRef peerActor4 = getSystem().actorOf(Props.create( DoNothingActor.class)); + private final Map onePeer = new HashMap<>(); + private final Map twoPeers = new HashMap<>(); + private final Map fourPeers = new HashMap<>(); + + @Before + public void setUp(){ + onePeer.put(peerActor1.path().toString(), + peerActor1.path().toString()); + + twoPeers.put(peerActor1.path().toString(), + peerActor1.path().toString()); + twoPeers.put(peerActor2.path().toString(), + peerActor2.path().toString()); + + fourPeers.put(peerActor1.path().toString(), + peerActor1.path().toString()); + fourPeers.put(peerActor2.path().toString(), + peerActor2.path().toString()); + fourPeers.put(peerActor3.path().toString(), + peerActor3.path().toString()); + fourPeers.put(peerActor4.path().toString(), + peerActor3.path().toString()); + + + } + @Test public void testWhenACandidateIsCreatedItIncrementsTheCurrentTermAndVotesForItself(){ RaftActorContext raftActorContext = createActorContext(); - long expectedTerm = raftActorContext.getTermInformation().getCurrentTerm().get(); + long expectedTerm = raftActorContext.getTermInformation().getCurrentTerm(); - new Candidate(raftActorContext, Collections.EMPTY_LIST); + new Candidate(raftActorContext); - assertEquals(expectedTerm+1, raftActorContext.getTermInformation().getCurrentTerm().get()); + assertEquals(expectedTerm+1, raftActorContext.getTermInformation().getCurrentTerm()); assertEquals(raftActorContext.getId(), raftActorContext.getTermInformation().getVotedFor()); } @@ -55,7 +83,7 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { new Within(duration("1 seconds")) { protected void run() { - Candidate candidate = new Candidate(createActorContext(getTestActor()), Collections.EMPTY_LIST); + Candidate candidate = new Candidate(createActorContext(getTestActor())); final Boolean out = new ExpectMsg(duration("1 seconds"), "ElectionTimeout") { // do not put code outside this method, will run afterwards @@ -78,7 +106,7 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { public void testHandleElectionTimeoutWhenThereAreZeroPeers(){ RaftActorContext raftActorContext = createActorContext(); Candidate candidate = - new Candidate(raftActorContext, Collections.EMPTY_LIST); + new Candidate(raftActorContext); RaftState raftState = candidate.handleMessage(candidateActor, new ElectionTimeout()); @@ -87,12 +115,12 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { } @Test - public void testHandleElectionTimeoutWhenThereAreTwoPeers(){ - RaftActorContext raftActorContext = createActorContext(); + public void testHandleElectionTimeoutWhenThereAreTwoNodesInCluster(){ + MockRaftActorContext raftActorContext = + (MockRaftActorContext) createActorContext(); + raftActorContext.setPeerAddresses(onePeer); Candidate candidate = - new Candidate(raftActorContext, Arrays - .asList(peerActor1.path().toString(), - peerActor2.path().toString())); + new Candidate(raftActorContext); RaftState raftState = candidate.handleMessage(candidateActor, new ElectionTimeout()); @@ -101,12 +129,12 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { } @Test - public void testBecomeLeaderOnReceivingMajorityVotesInThreePeerCluster(){ - RaftActorContext raftActorContext = createActorContext(); + public void testBecomeLeaderOnReceivingMajorityVotesInThreeNodesInCluster(){ + MockRaftActorContext raftActorContext = + (MockRaftActorContext) createActorContext(); + raftActorContext.setPeerAddresses(twoPeers); Candidate candidate = - new Candidate(raftActorContext, Arrays - .asList(peerActor1.path().toString(), - peerActor2.path().toString())); + new Candidate(raftActorContext); RaftState stateOnFirstVote = candidate.handleMessage(peerActor1, new RequestVoteReply(0, true)); @@ -115,17 +143,16 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { } @Test - public void testBecomeLeaderOnReceivingMajorityVotesInFivePeerCluster(){ - RaftActorContext raftActorContext = createActorContext(); + public void testBecomeLeaderOnReceivingMajorityVotesInFiveNodesInCluster(){ + MockRaftActorContext raftActorContext = + (MockRaftActorContext) createActorContext(); + raftActorContext.setPeerAddresses(fourPeers); Candidate candidate = - new Candidate(raftActorContext, Arrays - .asList(peerActor1.path().toString(), - peerActor2.path().toString(), - peerActor3.path().toString())); + new Candidate(raftActorContext); RaftState stateOnFirstVote = candidate.handleMessage(peerActor1, new RequestVoteReply(0, true)); - RaftState stateOnSecondVote = candidate.handleMessage(peerActor1, new RequestVoteReply(0, true)); + RaftState stateOnSecondVote = candidate.handleMessage(peerActor2, new RequestVoteReply(0, true)); Assert.assertEquals(RaftState.Candidate, stateOnFirstVote); Assert.assertEquals(RaftState.Leader, stateOnSecondVote); @@ -139,7 +166,7 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { new Within(duration("1 seconds")) { protected void run() { - Candidate candidate = new Candidate(createActorContext(getTestActor()), Collections.EMPTY_LIST); + Candidate candidate = new Candidate(createActorContext(getTestActor())); candidate.handleMessage(getTestActor(), new AppendEntries(0, "test", 0,0,Collections.EMPTY_LIST, 0)); @@ -168,7 +195,7 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { new Within(duration("1 seconds")) { protected void run() { - Candidate candidate = new Candidate(createActorContext(getTestActor()), Collections.EMPTY_LIST); + Candidate candidate = new Candidate(createActorContext(getTestActor())); candidate.handleMessage(getTestActor(), new RequestVote(0, "test", 0, 0)); @@ -190,18 +217,83 @@ public class CandidateTest extends AbstractRaftActorBehaviorTest { }}; } + @Test + public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNull(){ + new JavaTestKit(getSystem()) {{ + + new Within(duration("1 seconds")) { + protected void run() { + + RaftActorContext context = createActorContext(getTestActor()); + + context.getTermInformation().update(1000, null); + + // Once a candidate is created it will immediately increment the current term so after + // construction the currentTerm should be 1001 + RaftActorBehavior follower = createBehavior(context); + + follower.handleMessage(getTestActor(), new RequestVote(1001, "test", 10000, 999)); + + final Boolean out = new ExpectMsg(duration("1 seconds"), "RequestVoteReply") { + // do not put code outside this method, will run afterwards + protected Boolean match(Object in) { + if (in instanceof RequestVoteReply) { + RequestVoteReply reply = (RequestVoteReply) in; + return reply.isVoteGranted(); + } else { + throw noMatch(); + } + } + }.get(); + + assertEquals(true, out); + } + }; + }}; + } + + @Test + public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNotTheSameAsCandidateId(){ + new JavaTestKit(getSystem()) {{ + + new Within(duration("1 seconds")) { + protected void run() { + + RaftActorContext context = createActorContext(getTestActor()); + + context.getTermInformation().update(1000, "test"); + + RaftActorBehavior follower = createBehavior(context); + + follower.handleMessage(getTestActor(), new RequestVote(1001, "candidate", 10000, 999)); + + final Boolean out = new ExpectMsg(duration("1 seconds"), "RequestVoteReply") { + // do not put code outside this method, will run afterwards + protected Boolean match(Object in) { + if (in instanceof RequestVoteReply) { + RequestVoteReply reply = (RequestVoteReply) in; + return reply.isVoteGranted(); + } else { + throw noMatch(); + } + } + }.get(); + + assertEquals(false, out); + } + }; + }}; + } + @Override protected RaftActorBehavior createBehavior(RaftActorContext actorContext) { - return new Candidate(actorContext, Collections.EMPTY_LIST); + return new Candidate(actorContext); } @Override protected RaftActorContext createActorContext() { return new MockRaftActorContext("test", getSystem(), candidateActor); } - protected RaftActorContext createActorContext(ActorRef candidateActor) { - return new MockRaftActorContext("test", getSystem(), candidateActor); - } }