1 package org.opendaylight.controller.cluster.raft.behaviors;
3 import akka.actor.ActorRef;
4 import akka.actor.Props;
5 import akka.testkit.JavaTestKit;
6 import junit.framework.Assert;
8 import org.opendaylight.controller.cluster.raft.MockRaftActorContext;
9 import org.opendaylight.controller.cluster.raft.RaftActorContext;
10 import org.opendaylight.controller.cluster.raft.RaftState;
11 import org.opendaylight.controller.cluster.raft.internal.messages.ApplyState;
12 import org.opendaylight.controller.cluster.raft.internal.messages.Replicate;
13 import org.opendaylight.controller.cluster.raft.internal.messages.SendHeartBeat;
14 import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
15 import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
17 import java.util.HashMap;
20 import static org.junit.Assert.assertEquals;
22 public class LeaderTest extends AbstractRaftActorBehaviorTest {
24 private ActorRef leaderActor =
25 getSystem().actorOf(Props.create(DoNothingActor.class));
26 private ActorRef senderActor =
27 getSystem().actorOf(Props.create(DoNothingActor.class));
30 public void testHandleMessageForUnknownMessage() throws Exception {
31 new JavaTestKit(getSystem()) {{
33 new Leader(createActorContext());
35 // handle message should return the Leader state when it receives an
37 RaftState state = leader.handleMessage(senderActor, "foo");
38 Assert.assertEquals(RaftState.Leader, state);
44 public void testThatLeaderSendsAHeartbeatMessageToAllFollowers() {
45 new JavaTestKit(getSystem()) {{
47 new Within(duration("1 seconds")) {
48 protected void run() {
50 ActorRef followerActor = getTestActor();
52 MockRaftActorContext actorContext =
53 (MockRaftActorContext) createActorContext();
55 Map<String, String> peerAddresses = new HashMap();
57 peerAddresses.put(followerActor.path().toString(),
58 followerActor.path().toString());
60 actorContext.setPeerAddresses(peerAddresses);
62 Leader leader = new Leader(actorContext);
63 leader.handleMessage(senderActor, new SendHeartBeat());
66 new ExpectMsg<String>(duration("1 seconds"),
68 // do not put code outside this method, will run afterwards
69 protected String match(Object in) {
70 if (in instanceof AppendEntries) {
71 if (((AppendEntries) in).getTerm()
80 }.get(); // this extracts the received message
82 assertEquals("match", out);
92 public void testHandleReplicateMessageSendAppendEntriesToFollower() {
93 new JavaTestKit(getSystem()) {{
95 new Within(duration("1 seconds")) {
96 protected void run() {
98 ActorRef followerActor = getTestActor();
100 MockRaftActorContext actorContext =
101 (MockRaftActorContext) createActorContext();
103 Map<String, String> peerAddresses = new HashMap();
105 peerAddresses.put(followerActor.path().toString(),
106 followerActor.path().toString());
108 actorContext.setPeerAddresses(peerAddresses);
110 Leader leader = new Leader(actorContext);
111 RaftState raftState = leader
112 .handleMessage(senderActor, new Replicate(null, null,
113 new MockRaftActorContext.MockReplicatedLogEntry(1,
118 // State should not change
119 assertEquals(RaftState.Leader, raftState);
122 new ExpectMsg<String>(duration("1 seconds"),
124 // do not put code outside this method, will run afterwards
125 protected String match(Object in) {
126 if (in instanceof AppendEntries) {
127 if (((AppendEntries) in).getTerm()
136 }.get(); // this extracts the received message
138 assertEquals("match", out);
148 public void testHandleReplicateMessageWhenThereAreNoFollowers() {
149 new JavaTestKit(getSystem()) {{
151 new Within(duration("1 seconds")) {
152 protected void run() {
154 ActorRef raftActor = getTestActor();
156 MockRaftActorContext actorContext =
157 new MockRaftActorContext("test", getSystem(), raftActor);
159 Leader leader = new Leader(actorContext);
160 RaftState raftState = leader
161 .handleMessage(senderActor, new Replicate(null, "state-id",
162 new MockRaftActorContext.MockReplicatedLogEntry(1,
167 // State should not change
168 assertEquals(RaftState.Leader, raftState);
170 assertEquals(100, actorContext.getCommitIndex());
173 new ExpectMsg<String>(duration("1 seconds"),
175 // do not put code outside this method, will run afterwards
176 protected String match(Object in) {
177 if (in instanceof ApplyState) {
178 if (((ApplyState) in).getIdentifier().equals("state-id")) {
186 }.get(); // this extracts the received message
188 assertEquals("match", out);
197 @Override protected RaftActorBehavior createBehavior(
198 RaftActorContext actorContext) {
199 return new Leader(actorContext);
202 @Override protected RaftActorContext createActorContext() {
203 return new MockRaftActorContext("test", getSystem(), leaderActor);