@Test
public void shouldThrowIllegalArgumentExceptionIfCallerSpecifiesIndexGreaterThanLastLogIndexInCallToGetNextCommittedAndBothLogAndSnapshotExist() throws Exception {

    // we have a snapshot that contains data to index 9 (inclusive)
    SnapshotsStore.ExtendedSnapshot storedSnapshot = new UnitTestSnapshot(9L, 2);
    // we have a log that contains entries from index 7 onwards
    LogEntry unappliedEntry0 = CLIENT(7, 2, new UnitTestCommand());
    LogEntry unAppliedEntry1 = NOOP(8, 2);
    LogEntry unappliedEntry2 = NOOP(9, 3);
    LogEntry unappliedEntry3 = CLIENT(10, 3, new UnitTestCommand());
    LogEntry unappliedEntry4 = CLIENT(11, 3, new UnitTestCommand());
    final LogEntry[] entries = new LogEntry[] {
            unappliedEntry0,
            unAppliedEntry1,
            unappliedEntry2,
            unappliedEntry3,
            unappliedEntry4, // <------ we've committed up to here
            CLIENT(12, 3, new UnitTestCommand())
    };
    clearLog(); // clear out the log completely - we don't even want the sentinel
    insertIntoLog(entries);
    // set the current term
    long currentTerm = 3;
    store.setCurrentTerm(currentTerm);
    // set the committed index
    long commitIndex = 11;
    store.setCommitIndex(commitIndex);
    // have the snapshot store return the snapshot
    when(snapshotsStore.getLatestSnapshot()).thenReturn(storedSnapshot);
    //
    // situation is as follows:
    //
    //                                             +----------- COMMITTED
    //                                             V
    //                       ------------------------------
    //    .... EMPTY ....   | 07 | 08 | 09 | 10 | 11 | 12 | (LOG)
    //                      ------------------------------
    //  ------------------------------------
    // |         LAST APPLIED = 9          | (SNAPSHOT)
    // ------------------------------------
    //                                                      ^
    //                                                      +----------- INDEX TO SEARCH FROM = 13
    //
    IllegalArgumentException callException = null;
    try {
        algorithm.getNextCommitted(entries[entries.length - 1].getIndex() + 1); // the caller is acting as if it got some entry after the end of the log
    } catch (IllegalArgumentException e) {
        callException = e;
    }
    assertThat(callException, notNullValue());
    // verify that the state hasn't changed
    assertThatLogContains(entries);
    assertThatTermAndCommitIndexHaveValues(currentTerm, commitIndex);
}