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.base.messages.ApplyState;
12 import org.opendaylight.controller.cluster.raft.base.messages.Replicate;
13 import org.opendaylight.controller.cluster.raft.base.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"), "match hint") {
67 // do not put code outside this method, will run afterwards
68 protected String match(Object in) {
69 Object msg = fromSerializableMessage(in);
70 if (msg instanceof AppendEntries) {
71 if (((AppendEntries)msg).getTerm() == 0) {
79 }.get(); // this extracts the received message
81 assertEquals("match", out);
91 public void testHandleReplicateMessageSendAppendEntriesToFollower() {
92 new JavaTestKit(getSystem()) {{
94 new Within(duration("1 seconds")) {
95 protected void run() {
97 ActorRef followerActor = getTestActor();
99 MockRaftActorContext actorContext =
100 (MockRaftActorContext) createActorContext();
102 Map<String, String> peerAddresses = new HashMap();
104 peerAddresses.put(followerActor.path().toString(),
105 followerActor.path().toString());
107 actorContext.setPeerAddresses(peerAddresses);
109 Leader leader = new Leader(actorContext);
110 RaftState raftState = leader
111 .handleMessage(senderActor, new Replicate(null, null,
112 new MockRaftActorContext.MockReplicatedLogEntry(1,
114 new MockRaftActorContext.MockPayload("foo"))
117 // State should not change
118 assertEquals(RaftState.Leader, raftState);
121 new ExpectMsg<String>(duration("1 seconds"), "match hint") {
122 // do not put code outside this method, will run afterwards
123 protected String match(Object in) {
124 Object msg = fromSerializableMessage(in);
125 if (msg instanceof AppendEntries) {
126 if (((AppendEntries)msg).getTerm() == 0) {
134 }.get(); // this extracts the received message
136 assertEquals("match", out);
146 public void testHandleReplicateMessageWhenThereAreNoFollowers() {
147 new JavaTestKit(getSystem()) {{
149 new Within(duration("1 seconds")) {
150 protected void run() {
152 ActorRef raftActor = getTestActor();
154 MockRaftActorContext actorContext =
155 new MockRaftActorContext("test", getSystem(), raftActor);
157 Leader leader = new Leader(actorContext);
158 RaftState raftState = leader
159 .handleMessage(senderActor, new Replicate(null, "state-id",
160 new MockRaftActorContext.MockReplicatedLogEntry(1,
162 new MockRaftActorContext.MockPayload("foo"))
165 // State should not change
166 assertEquals(RaftState.Leader, raftState);
168 assertEquals(100, actorContext.getCommitIndex());
171 new ExpectMsg<String>(duration("1 seconds"),
173 // do not put code outside this method, will run afterwards
174 protected String match(Object in) {
175 if (in instanceof ApplyState) {
176 if (((ApplyState) in).getIdentifier().equals("state-id")) {
184 }.get(); // this extracts the received message
186 assertEquals("match", out);
195 @Override protected RaftActorBehavior createBehavior(
196 RaftActorContext actorContext) {
197 return new Leader(actorContext);
200 @Override protected RaftActorContext createActorContext() {
201 return new MockRaftActorContext("test", getSystem(), leaderActor);