Remove unused exceptions
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / test / java / org / opendaylight / controller / cluster / raft / behaviors / IsolatedLeaderTest.java
1 /*
2  * Copyright (c) 2014 Cisco Systems, Inc. and others.  All rights reserved.
3  *
4  * This program and the accompanying materials are made available under the
5  * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6  * and is available at http://www.eclipse.org/legal/epl-v10.html
7  */
8 package org.opendaylight.controller.cluster.raft.behaviors;
9
10 import static org.junit.Assert.assertEquals;
11
12 import akka.actor.ActorRef;
13 import java.util.HashMap;
14 import java.util.Map;
15 import org.junit.After;
16 import org.junit.Test;
17 import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl;
18 import org.opendaylight.controller.cluster.raft.MockRaftActorContext;
19 import org.opendaylight.controller.cluster.raft.RaftActorContext;
20 import org.opendaylight.controller.cluster.raft.RaftState;
21 import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
22 import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
23
24 public class IsolatedLeaderTest extends AbstractLeaderTest<IsolatedLeader> {
25
26     private final ActorRef leaderActor = actorFactory.createActor(
27             MessageCollectorActor.props(), actorFactory.generateActorId("leader"));
28
29     private final ActorRef senderActor = actorFactory.createActor(
30             MessageCollectorActor.props(), actorFactory.generateActorId("sender"));
31
32     private AbstractLeader isolatedLeader;
33
34     @Override
35     @After
36     public void tearDown() {
37         if (isolatedLeader != null) {
38             isolatedLeader.close();
39         }
40
41         super.tearDown();
42     }
43
44     @Override
45     protected IsolatedLeader createBehavior(final RaftActorContext actorContext) {
46         return new IsolatedLeader(actorContext);
47     }
48
49     @Override
50     protected MockRaftActorContext createActorContext() {
51         return createActorContext(leaderActor);
52     }
53
54     @Override
55     protected MockRaftActorContext createActorContext(final ActorRef actor) {
56         DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
57         configParams.setElectionTimeoutFactor(100000);
58         MockRaftActorContext context = new MockRaftActorContext("isolated-leader", getSystem(), actor);
59         context.setConfigParams(configParams);
60         return context;
61     }
62
63     @Test
64     public void testHandleMessageWithThreeMembers() {
65         String followerAddress1 = "akka://test/user/$a";
66         String followerAddress2 = "akka://test/user/$b";
67
68         MockRaftActorContext leaderActorContext = createActorContext();
69         Map<String, String> peerAddresses = new HashMap<>();
70         peerAddresses.put("follower-1", followerAddress1);
71         peerAddresses.put("follower-2", followerAddress2);
72         leaderActorContext.setPeerAddresses(peerAddresses);
73
74         isolatedLeader = new IsolatedLeader(leaderActorContext);
75         leaderActorContext.setCurrentBehavior(isolatedLeader);
76         assertEquals("Raft state", RaftState.IsolatedLeader, isolatedLeader.state());
77
78         // in a 3 node cluster, even if 1 follower is returns a reply, the isolatedLeader is not isolated
79         RaftActorBehavior newBehavior = isolatedLeader.handleMessage(senderActor,
80                 new AppendEntriesReply("follower-1", isolatedLeader.lastTerm() - 1, true,
81                         isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short)0));
82
83         assertEquals("Raft state", RaftState.Leader, newBehavior.state());
84
85         isolatedLeader.close();
86         isolatedLeader = (AbstractLeader) newBehavior;
87
88         newBehavior = isolatedLeader.handleMessage(senderActor,
89                 new AppendEntriesReply("follower-2", isolatedLeader.lastTerm() - 1, true,
90                         isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short) 0));
91
92         assertEquals("Raft state", RaftState.Leader, newBehavior.state());
93     }
94
95     @Test
96     public void testHandleMessageWithFiveMembers() {
97         String followerAddress1 = "akka://test/user/$a";
98         String followerAddress2 = "akka://test/user/$b";
99         String followerAddress3 = "akka://test/user/$c";
100         String followerAddress4 = "akka://test/user/$d";
101
102         final MockRaftActorContext leaderActorContext = createActorContext();
103         Map<String, String> peerAddresses = new HashMap<>();
104         peerAddresses.put("follower-1", followerAddress1);
105         peerAddresses.put("follower-2", followerAddress2);
106         peerAddresses.put("follower-3", followerAddress3);
107         peerAddresses.put("follower-4", followerAddress4);
108         leaderActorContext.setPeerAddresses(peerAddresses);
109
110         isolatedLeader = new IsolatedLeader(leaderActorContext);
111         leaderActorContext.setCurrentBehavior(isolatedLeader);
112         assertEquals("Raft state", RaftState.IsolatedLeader, isolatedLeader.state());
113
114         // in a 5 member cluster, atleast 2 followers need to be active and return a reply
115         RaftActorBehavior newBehavior = isolatedLeader.handleMessage(senderActor,
116                 new AppendEntriesReply("follower-1", isolatedLeader.lastTerm() - 1, true,
117                         isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short) 0));
118
119         assertEquals("Raft state", RaftState.IsolatedLeader, newBehavior.state());
120
121         newBehavior = isolatedLeader.handleMessage(senderActor,
122                 new AppendEntriesReply("follower-2", isolatedLeader.lastTerm() - 1, true,
123                         isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short) 0));
124
125         assertEquals("Raft state", RaftState.Leader, newBehavior.state());
126
127         isolatedLeader.close();
128         isolatedLeader = (AbstractLeader) newBehavior;
129
130         newBehavior = isolatedLeader.handleMessage(senderActor,
131                 new AppendEntriesReply("follower-3", isolatedLeader.lastTerm() - 1, true,
132                         isolatedLeader.lastIndex() - 1, isolatedLeader.lastTerm() - 1, (short) 0));
133
134         assertEquals("Raft state", RaftState.Leader, newBehavior.state());
135     }
136
137     @Test
138     public void testHandleMessageFromAnotherLeader() {
139         String followerAddress1 = "akka://test/user/$a";
140         String followerAddress2 = "akka://test/user/$b";
141
142         MockRaftActorContext leaderActorContext = createActorContext();
143         Map<String, String> peerAddresses = new HashMap<>();
144         peerAddresses.put("follower-1", followerAddress1);
145         peerAddresses.put("follower-2", followerAddress2);
146         leaderActorContext.setPeerAddresses(peerAddresses);
147
148         isolatedLeader = new IsolatedLeader(leaderActorContext);
149         assertEquals("Raft state", RaftState.IsolatedLeader, isolatedLeader.state());
150
151         // if an append-entries reply is received by the isolated-leader, and that reply
152         // has a term  > than its own term, then IsolatedLeader switches to Follower
153         // bowing itself to another leader in the cluster
154         RaftActorBehavior newBehavior = isolatedLeader.handleMessage(senderActor,
155                 new AppendEntriesReply("follower-1", isolatedLeader.lastTerm() + 1, true,
156                         isolatedLeader.lastIndex() + 1, isolatedLeader.lastTerm() + 1, (short)0));
157
158         assertEquals("Raft state", RaftState.Follower, newBehavior.state());
159
160         newBehavior.close();
161     }
162 }