Merge "Make Raft messages serializable"
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / test / java / org / opendaylight / controller / cluster / raft / behaviors / LeaderTest.java
1 package org.opendaylight.controller.cluster.raft.behaviors;
2
3 import akka.actor.ActorRef;
4 import akka.actor.Props;
5 import akka.testkit.JavaTestKit;
6 import junit.framework.Assert;
7 import org.junit.Test;
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;
16
17 import java.util.HashMap;
18 import java.util.Map;
19
20 import static org.junit.Assert.assertEquals;
21
22 public class LeaderTest extends AbstractRaftActorBehaviorTest {
23
24     private ActorRef leaderActor =
25         getSystem().actorOf(Props.create(DoNothingActor.class));
26     private ActorRef senderActor =
27         getSystem().actorOf(Props.create(DoNothingActor.class));
28
29     @Test
30     public void testHandleMessageForUnknownMessage() throws Exception {
31         new JavaTestKit(getSystem()) {{
32             Leader leader =
33                 new Leader(createActorContext());
34
35             // handle message should return the Leader state when it receives an
36             // unknown message
37             RaftState state = leader.handleMessage(senderActor, "foo");
38             Assert.assertEquals(RaftState.Leader, state);
39         }};
40     }
41
42
43     @Test
44     public void testThatLeaderSendsAHeartbeatMessageToAllFollowers() {
45         new JavaTestKit(getSystem()) {{
46
47             new Within(duration("1 seconds")) {
48                 protected void run() {
49
50                     ActorRef followerActor = getTestActor();
51
52                     MockRaftActorContext actorContext =
53                         (MockRaftActorContext) createActorContext();
54
55                     Map<String, String> peerAddresses = new HashMap();
56
57                     peerAddresses.put(followerActor.path().toString(),
58                         followerActor.path().toString());
59
60                     actorContext.setPeerAddresses(peerAddresses);
61
62                     Leader leader = new Leader(actorContext);
63                     leader.handleMessage(senderActor, new SendHeartBeat());
64
65                     final String out =
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) {
72                                         return "match";
73                                     }
74                                     return null;
75                                 } else {
76                                     throw noMatch();
77                                 }
78                             }
79                         }.get(); // this extracts the received message
80
81                     assertEquals("match", out);
82
83                 }
84
85
86             };
87         }};
88     }
89
90     @Test
91     public void testHandleReplicateMessageSendAppendEntriesToFollower() {
92         new JavaTestKit(getSystem()) {{
93
94             new Within(duration("1 seconds")) {
95                 protected void run() {
96
97                     ActorRef followerActor = getTestActor();
98
99                     MockRaftActorContext actorContext =
100                         (MockRaftActorContext) createActorContext();
101
102                     Map<String, String> peerAddresses = new HashMap();
103
104                     peerAddresses.put(followerActor.path().toString(),
105                         followerActor.path().toString());
106
107                     actorContext.setPeerAddresses(peerAddresses);
108
109                     Leader leader = new Leader(actorContext);
110                     RaftState raftState = leader
111                         .handleMessage(senderActor, new Replicate(null, null,
112                             new MockRaftActorContext.MockReplicatedLogEntry(1,
113                                 100,
114                                 new MockRaftActorContext.MockPayload("foo"))
115                         ));
116
117                     // State should not change
118                     assertEquals(RaftState.Leader, raftState);
119
120                     final String out =
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) {
127                                         return "match";
128                                     }
129                                     return null;
130                                 } else {
131                                     throw noMatch();
132                                 }
133                             }
134                         }.get(); // this extracts the received message
135
136                     assertEquals("match", out);
137
138                 }
139
140
141             };
142         }};
143     }
144
145     @Test
146     public void testHandleReplicateMessageWhenThereAreNoFollowers() {
147         new JavaTestKit(getSystem()) {{
148
149             new Within(duration("1 seconds")) {
150                 protected void run() {
151
152                     ActorRef raftActor = getTestActor();
153
154                     MockRaftActorContext actorContext =
155                         new MockRaftActorContext("test", getSystem(), raftActor);
156
157                     Leader leader = new Leader(actorContext);
158                     RaftState raftState = leader
159                         .handleMessage(senderActor, new Replicate(null, "state-id",
160                             new MockRaftActorContext.MockReplicatedLogEntry(1,
161                                 100,
162                                 new MockRaftActorContext.MockPayload("foo"))
163                         ));
164
165                     // State should not change
166                     assertEquals(RaftState.Leader, raftState);
167
168                     assertEquals(100, actorContext.getCommitIndex());
169
170                     final String out =
171                         new ExpectMsg<String>(duration("1 seconds"),
172                             "match hint") {
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")) {
177                                         return "match";
178                                     }
179                                     return null;
180                                 } else {
181                                     throw noMatch();
182                                 }
183                             }
184                         }.get(); // this extracts the received message
185
186                     assertEquals("match", out);
187
188                 }
189
190
191             };
192         }};
193     }
194
195     @Override protected RaftActorBehavior createBehavior(
196         RaftActorContext actorContext) {
197         return new Leader(actorContext);
198     }
199
200     @Override protected RaftActorContext createActorContext() {
201         return new MockRaftActorContext("test", getSystem(), leaderActor);
202     }
203 }