+ @Test
+ public void testCandidateSchedulesElectionTimeoutImmediatelyWhenItHasNoPeers() {
+ MockRaftActorContext context = createActorContext();
+
+ Stopwatch stopwatch = Stopwatch.createStarted();
+
+ candidate = createBehavior(context);
+
+ MessageCollectorActor.expectFirstMatching(candidateActor, ElectionTimeout.class);
+
+ long elapsed = stopwatch.elapsed(TimeUnit.MILLISECONDS);
+
+ assertTrue(elapsed < context.getConfigParams().getElectionTimeOutInterval().toMillis());
+ }
+
+ @Test
+ @Override
+ public void testHandleAppendEntriesAddSameEntryToLog() throws Exception {
+ MockRaftActorContext context = createActorContext();
+
+ context.getTermInformation().update(2, "test");
+
+ // Prepare the receivers log
+ MockRaftActorContext.MockPayload payload = new MockRaftActorContext.MockPayload("zero");
+ setLastLogEntry(context, 2, 0, payload);
+
+ List<ReplicatedLogEntry> entries = new ArrayList<>();
+ entries.add(new SimpleReplicatedLogEntry(0, 2, payload));
+
+ final AppendEntries appendEntries = new AppendEntries(2, "leader-1", -1, -1, entries, 2, -1, (short)0);
+
+ behavior = createBehavior(context);
+
+ // Resetting the Candidates term to make sure it will match
+ // the term sent by AppendEntries. If this was not done then
+ // the test will fail because the Candidate will assume that
+ // the message was sent to it from a lower term peer and will
+ // thus respond with a failure
+ context.getTermInformation().update(2, "test");
+
+ // Send an unknown message so that the state of the RaftActor remains unchanged
+ behavior.handleMessage(candidateActor, "unknown");