X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2Fbehaviors%2FLeaderTest.java;h=d33b33925b5e7aba358152ff6067e4842fec3b71;hb=c46e223995956f1f759c551163c212947c1e2fb7;hp=d0497f3d0a0727cf5a86a5b7579e827c8acd0cc9;hpb=26cd54f2cbe0737db6e82aa96cd31671c6f6bf7e;p=controller.git diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java index d0497f3d0a..d33b33925b 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/LeaderTest.java @@ -1,64 +1,187 @@ package org.opendaylight.controller.cluster.raft.behaviors; +import akka.actor.ActorRef; +import akka.actor.Props; import akka.testkit.JavaTestKit; import junit.framework.Assert; 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.SendHeartBeat; +import org.opendaylight.controller.cluster.raft.base.messages.ApplyState; +import org.opendaylight.controller.cluster.raft.base.messages.Replicate; +import org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat; import org.opendaylight.controller.cluster.raft.messages.AppendEntries; +import org.opendaylight.controller.cluster.raft.utils.DoNothingActor; -import java.util.ArrayList; -import java.util.Collections; -import java.util.List; +import java.util.HashMap; +import java.util.Map; import static org.junit.Assert.assertEquals; public class LeaderTest extends AbstractRaftActorBehaviorTest { + private ActorRef leaderActor = + getSystem().actorOf(Props.create(DoNothingActor.class)); + private ActorRef senderActor = + getSystem().actorOf(Props.create(DoNothingActor.class)); + @Test public void testHandleMessageForUnknownMessage() throws Exception { new JavaTestKit(getSystem()) {{ Leader leader = - new Leader(new MockRaftActorContext(), Collections.EMPTY_LIST); + new Leader(createActorContext()); // handle message should return the Leader state when it receives an // unknown message - RaftState state = leader.handleMessage(getRef(), "foo"); + RaftState state = leader.handleMessage(senderActor, "foo"); Assert.assertEquals(RaftState.Leader, state); }}; } @Test - public void testThatLeaderSendsAHeartbeatMessageToAllFollowers(){ + public void testThatLeaderSendsAHeartbeatMessageToAllFollowers() { + new JavaTestKit(getSystem()) {{ + + new Within(duration("1 seconds")) { + protected void run() { + + ActorRef followerActor = getTestActor(); + + MockRaftActorContext actorContext = + (MockRaftActorContext) createActorContext(); + + Map peerAddresses = new HashMap(); + + peerAddresses.put(followerActor.path().toString(), + followerActor.path().toString()); + + actorContext.setPeerAddresses(peerAddresses); + + Leader leader = new Leader(actorContext); + leader.handleMessage(senderActor, new SendHeartBeat()); + + final String out = + new ExpectMsg(duration("1 seconds"), "match hint") { + // do not put code outside this method, will run afterwards + protected String match(Object in) { + Object msg = fromSerializableMessage(in); + if (msg instanceof AppendEntries) { + if (((AppendEntries)msg).getTerm() == 0) { + return "match"; + } + return null; + } else { + throw noMatch(); + } + } + }.get(); // this extracts the received message + + assertEquals("match", out); + + } + + + }; + }}; + } + + @Test + public void testHandleReplicateMessageSendAppendEntriesToFollower() { new JavaTestKit(getSystem()) {{ new Within(duration("1 seconds")) { protected void run() { - List followers = new ArrayList(); + ActorRef followerActor = getTestActor(); + + MockRaftActorContext actorContext = + (MockRaftActorContext) createActorContext(); + + Map peerAddresses = new HashMap(); + + peerAddresses.put(followerActor.path().toString(), + followerActor.path().toString()); + + actorContext.setPeerAddresses(peerAddresses); + + Leader leader = new Leader(actorContext); + RaftState raftState = leader + .handleMessage(senderActor, new Replicate(null, null, + new MockRaftActorContext.MockReplicatedLogEntry(1, + 100, + new MockRaftActorContext.MockPayload("foo")) + )); + + // State should not change + assertEquals(RaftState.Leader, raftState); + + final String out = + new ExpectMsg(duration("1 seconds"), "match hint") { + // do not put code outside this method, will run afterwards + protected String match(Object in) { + Object msg = fromSerializableMessage(in); + if (msg instanceof AppendEntries) { + if (((AppendEntries)msg).getTerm() == 0) { + return "match"; + } + return null; + } else { + throw noMatch(); + } + } + }.get(); // this extracts the received message - followers.add(getTestActor().path().toString()); + assertEquals("match", out); + + } - Leader leader = new Leader(new MockRaftActorContext("test", getSystem(), getTestActor()), followers); - leader.handleMessage(getRef(), new SendHeartBeat()); - final String out = new ExpectMsg(duration("1 seconds"), "match hint") { - // do not put code outside this method, will run afterwards - protected String match(Object in) { - if (in instanceof AppendEntries) { - if (((AppendEntries) in).getTerm() - == 0) { - return "match"; + }; + }}; + } + + @Test + public void testHandleReplicateMessageWhenThereAreNoFollowers() { + new JavaTestKit(getSystem()) {{ + + new Within(duration("1 seconds")) { + protected void run() { + + ActorRef raftActor = getTestActor(); + + MockRaftActorContext actorContext = + new MockRaftActorContext("test", getSystem(), raftActor); + + Leader leader = new Leader(actorContext); + RaftState raftState = leader + .handleMessage(senderActor, new Replicate(null, "state-id", + new MockRaftActorContext.MockReplicatedLogEntry(1, + 100, + new MockRaftActorContext.MockPayload("foo")) + )); + + // State should not change + assertEquals(RaftState.Leader, raftState); + + assertEquals(100, actorContext.getCommitIndex()); + + final String out = + new ExpectMsg(duration("1 seconds"), + "match hint") { + // do not put code outside this method, will run afterwards + protected String match(Object in) { + if (in instanceof ApplyState) { + if (((ApplyState) in).getIdentifier().equals("state-id")) { + return "match"; + } + return null; + } else { + throw noMatch(); } - return null; - } else { - throw noMatch(); } - } - }.get(); // this extracts the received message + }.get(); // this extracts the received message assertEquals("match", out); @@ -69,7 +192,12 @@ public class LeaderTest extends AbstractRaftActorBehaviorTest { }}; } - @Override protected RaftActorBehavior createBehavior(RaftActorContext actorContext) { - return new Leader(actorContext, Collections.EMPTY_LIST); + @Override protected RaftActorBehavior createBehavior( + RaftActorContext actorContext) { + return new Leader(actorContext); + } + + @Override protected RaftActorContext createActorContext() { + return new MockRaftActorContext("test", getSystem(), leaderActor); } }