+ @Test
+ public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForMatches() {
+ MockRaftActorContext context = createActorContext();
+ context.getTermInformation().update(1000, null);
+
+ // Once a candidate is created it will immediately increment the current term so after
+ // construction the currentTerm should be 1001
+ candidate = new Candidate(context);
+
+ setupPeers(1);
+ candidate.handleMessage(peerActors[0], new RequestVote(1001, context.getId(), 10000, 999));
+
+ RequestVoteReply reply = MessageCollectorActor.expectFirstMatching(
+ peerActors[0], RequestVoteReply.class);
+ assertEquals("isVoteGranted", true, reply.isVoteGranted());
+ assertEquals("getTerm", 1001, reply.getTerm());
+ }
+
+ @Test
+ public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForDoesNotMatch() {
+ MockRaftActorContext context = createActorContext();
+ context.getTermInformation().update(1000, null);
+
+ // Once a candidate is created it will immediately increment the current term so after
+ // construction the currentTerm should be 1001
+ candidate = new Candidate(context);
+
+ setupPeers(1);
+
+ // RequestVote candidate ID ("candidate2") does not match this candidate's votedFor
+ // (it votes for itself)
+ candidate.handleMessage(peerActors[0], new RequestVote(1001, "candidate2", 10000, 999));
+
+ RequestVoteReply reply = MessageCollectorActor.expectFirstMatching(
+ peerActors[0], RequestVoteReply.class);
+ assertEquals("isVoteGranted", false, reply.isVoteGranted());
+ assertEquals("getTerm", 1001, reply.getTerm());
+ }
+
+ @Test
+ public void testCandidateSchedulesElectionTimeoutImmediatelyWhenItHasNoPeers(){
+ MockRaftActorContext context = createActorContext();
+
+ Stopwatch stopwatch = Stopwatch.createStarted();