@Test
public void shouldIncreaseCurrentTermAndGrantVoteAndResetElectionTimeoutIfReceiveARequestVoteWithHigherTermWhileCurrentlyALeader() throws StorageException {

    becomeLeaderInTerm(3, false);
    // move time forward half-way to the point at which we'd send out a heartbeat
    // assume that we're getting no replies
    long preRequestVoteHeartbeatTimeoutTick = getHeartbeatTimeoutTick();
    long ticksBeforeRequestVoteIsReceived = (preRequestVoteHeartbeatTimeoutTick - timer.getTick()) / 2;
    timer.fastForward(ticksBeforeRequestVoteIsReceived);
    sender.drainSentRPCs(); // clear out any heartbeats we may have already sent
    // get a Request Vote with a greater term and a greater prevLogTerm
    // check that the vote was granted, and that we've shifted our state
    algorithm.onRequestVote(S_01, 6, 1, 5);
    assertThatStateAfterRequestVoteIs(6, S_01, FOLLOWER);
    RequestVoteReply requestVoteReply = sender.nextAndRemove(RequestVoteReply.class);
    assertThatRequestVoteReplyHasValues(requestVoteReply, S_01, 6, true);
    assertThatNoMoreRPCsWereSent();
    // and that we increased our election timeout
    long postRequestVoteElectionTimeoutTick = getElectionTimeoutTick();
    assertThat(postRequestVoteElectionTimeoutTick, greaterThan(preRequestVoteHeartbeatTimeoutTick));
    assertThat(postRequestVoteElectionTimeoutTick, equalTo(timer.getTick() + RaftConstants.MIN_ELECTION_TIMEOUT));
    // and that our final state is sane
    assertThatLogContains(
            SENTINEL(),
            NOOP(1, 3) // the NOOP that we issued on becoming the leader
    );
    assertThatTermAndCommitIndexHaveValues(6, 0);
}