Properly handle RequestVote in all states
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / test / java / org / opendaylight / controller / cluster / raft / behaviors / FollowerTest.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.ElectionTimeout;
12 import org.opendaylight.controller.cluster.raft.messages.RequestVote;
13 import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply;
14 import org.opendaylight.controller.cluster.raft.utils.DoNothingActor;
15
16 import static org.junit.Assert.assertEquals;
17
18 public class FollowerTest extends AbstractRaftActorBehaviorTest {
19
20     private final ActorRef followerActor = getSystem().actorOf(Props.create(
21         DoNothingActor.class));
22
23
24     @Override protected RaftActorBehavior createBehavior(RaftActorContext actorContext) {
25         return new Follower(actorContext);
26     }
27
28     @Override protected RaftActorContext createActorContext() {
29         return new MockRaftActorContext("test", getSystem(), followerActor);
30     }
31
32     @Test
33     public void testThatAnElectionTimeoutIsTriggered(){
34         new JavaTestKit(getSystem()) {{
35
36             new Within(duration("1 seconds")) {
37                 protected void run() {
38
39                     Follower follower = new Follower(createActorContext(getTestActor()));
40
41                     final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "ElectionTimeout") {
42                         // do not put code outside this method, will run afterwards
43                         protected Boolean match(Object in) {
44                             if (in instanceof ElectionTimeout) {
45                                 return true;
46                             } else {
47                                 throw noMatch();
48                             }
49                         }
50                     }.get();
51
52                     assertEquals(true, out);
53                 }
54             };
55         }};
56     }
57
58     @Test
59     public void testHandleElectionTimeout(){
60         RaftActorContext raftActorContext = createActorContext();
61         Follower follower =
62             new Follower(raftActorContext);
63
64         RaftState raftState =
65             follower.handleMessage(followerActor, new ElectionTimeout());
66
67         Assert.assertEquals(RaftState.Candidate, raftState);
68     }
69
70     @Test
71     public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNull(){
72         new JavaTestKit(getSystem()) {{
73
74             new Within(duration("1 seconds")) {
75                 protected void run() {
76
77                     RaftActorContext context = createActorContext(getTestActor());
78
79                     context.getTermInformation().update(1000, null);
80
81                     RaftActorBehavior follower = createBehavior(context);
82
83                     follower.handleMessage(getTestActor(), new RequestVote(1000, "test", 10000, 999));
84
85                     final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "RequestVoteReply") {
86                         // do not put code outside this method, will run afterwards
87                         protected Boolean match(Object in) {
88                             if (in instanceof RequestVoteReply) {
89                                 RequestVoteReply reply = (RequestVoteReply) in;
90                                 return reply.isVoteGranted();
91                             } else {
92                                 throw noMatch();
93                             }
94                         }
95                     }.get();
96
97                     assertEquals(true, out);
98                 }
99             };
100         }};
101     }
102
103     @Test
104     public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNotTheSameAsCandidateId(){
105         new JavaTestKit(getSystem()) {{
106
107             new Within(duration("1 seconds")) {
108                 protected void run() {
109
110                     RaftActorContext context = createActorContext(getTestActor());
111
112                     context.getTermInformation().update(1000, "test");
113
114                     RaftActorBehavior follower = createBehavior(context);
115
116                     follower.handleMessage(getTestActor(), new RequestVote(1000, "candidate", 10000, 999));
117
118                     final Boolean out = new ExpectMsg<Boolean>(duration("1 seconds"), "RequestVoteReply") {
119                         // do not put code outside this method, will run afterwards
120                         protected Boolean match(Object in) {
121                             if (in instanceof RequestVoteReply) {
122                                 RequestVoteReply reply = (RequestVoteReply) in;
123                                 return reply.isVoteGranted();
124                             } else {
125                                 throw noMatch();
126                             }
127                         }
128                     }.get();
129
130                     assertEquals(false, out);
131                 }
132             };
133         }};
134     }
135
136 }