@Test
public void shouldMarkEntryAsCommittedIfReceiveAQuorumOfAcks() throws RPCException, StorageException {

    setupLeaderForCommitUnitTests();
    long heartbeatTimeout = getHeartbeatTimeoutTick();
    long heartbeatInterval = heartbeatTimeout - timer.getTick();
    // move time forward a bit and get our first responses
    timer.fastForward(heartbeatInterval / 2);
    // the real clients won't do this, but I'm testing this for the sake
    // of commit logic
    algorithm.onAppendEntriesReply(S_03, 3, 3, 1, true); // only wants to apply only the initial NOOP
    algorithm.onAppendEntriesReply(S_01, 3, 3, 6, true); // wants to apply everything
    // at this point we've achieved quorum on the NOOP
    assertThatTermAndCommitIndexHaveValues(3, 4);
    // move time forward a bit more and get additional responses
    timer.fastForward(heartbeatInterval / 4);
    algorithm.onAppendEntriesReply(S_02, 3, 3, 2, true); // only wants to apply the initial NOOP and the term after
    // at this point we've achieved quorum on everything up to logIndex 5
    assertThatTermAndCommitIndexHaveValues(3, 5);
    // move to the heartbeat timeout and verify that we've updated
    // nextIndex and the commitIndex appropriately
    fastForwardToHeartbeat();
    Collection<AppendEntries> heartbeats = getRPCs(4, AppendEntries.class);
    for (AppendEntries heartbeat : heartbeats) {
        if (heartbeat.server.equals(S_01)) {
            assertThatAppendEntriesHasValues(heartbeat, 3, 5, 9, 3);
        } else if (heartbeat.server.equals(S_02)) {
            assertThatAppendEntriesHasValues(
                    heartbeat,
                    3, 5, 5, 3,
                    NOOP(6, 3),
                    NOOP(7, 3),
                    NOOP(8, 3),
                    NOOP(9, 3)
            );
        } else if (heartbeat.server.equals(S_03)) {
            assertThatAppendEntriesHasValues(
                    heartbeat,
                    3, 5, 4, 3,
                    NOOP(5, 3),
                    NOOP(6, 3),
                    NOOP(7, 3),
                    NOOP(8, 3),
                    NOOP(9, 3)
            );
        } else {
            assertThatAppendEntriesHasValues(
                    heartbeat,
                    3, 5, 3, 2,
                    NOOP(4, 3),
                    NOOP(5, 3),
                    NOOP(6, 3),
                    NOOP(7, 3),
                    NOOP(8, 3),
                    NOOP(9, 3)
            );
        }
    }
    assertThatNoMoreRPCsWereSent();
    // final verification
    assertThatLogContains(
            SENTINEL(),
            NOOP(1, 1),
            NOOP(2, 1),
            NOOP(3, 2),
            NOOP(4, 3),
            NOOP(5, 3),
            NOOP(6, 3),
            NOOP(7, 3),
            NOOP(8, 3),
            NOOP(9, 3)
    );
    assertThatTermAndCommitIndexHaveValues(3, 5);
}