public void testCandidateVotesForSelfOnRequest() throws Throwable {
    runOnServer(
        () -> {
          int self = serverState.getAddress().hashCode();
          serverState.setTerm(2);

          state.startElection();

          assertEquals(serverState.getTerm(), 3L);

          VoteRequest request =
              VoteRequest.builder()
                  .withTerm(3)
                  .withCandidate(self)
                  .withLogIndex(0)
                  .withLogTerm(0)
                  .build();

          VoteResponse response = state.vote(request).get();

          assertEquals(response.status(), Response.Status.OK);
          assertTrue(response.voted());
          assertEquals(serverState.getTerm(), 3L);
          assertEquals(serverState.getLastVotedFor(), self);
          assertEquals(response.term(), 3L);
        });
  }
  public void testCandidateRejectsVoteAndTransitionsOnTerm() throws Throwable {
    runOnServer(
        () -> {
          int candidate =
              serverState.getCluster().getActiveMembers().iterator().next().getAddress().hashCode();
          serverState.setTerm(1);

          append(2, 1);

          state.startElection();

          assertEquals(serverState.getTerm(), 2L);

          VoteRequest request =
              VoteRequest.builder()
                  .withTerm(3)
                  .withCandidate(candidate)
                  .withLogTerm(0)
                  .withLogIndex(0)
                  .build();

          VoteResponse response = state.vote(request).get();

          assertEquals(response.status(), Response.Status.OK);
          assertFalse(response.voted());
          assertEquals(serverState.getTerm(), 3L);
          assertEquals(serverState.getLastVotedFor(), 0);
          assertEquals(response.term(), 3L);
          assertEquals(serverState.getState(), RaftServer.State.FOLLOWER);
        });
  }