Search in sources :

Example 66 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class AppendingTest method shouldNotAttemptToTruncateAtIndexBeforeTheLogPrevIndex.

@Test
public void shouldNotAttemptToTruncateAtIndexBeforeTheLogPrevIndex() throws Exception {
    // given
    // a log with prevIndex and prevTerm set
    ReadableRaftLog logMock = mock(ReadableRaftLog.class);
    long prevIndex = 5;
    long prevTerm = 5;
    when(logMock.prevIndex()).thenReturn(prevIndex);
    when(logMock.readEntryTerm(prevIndex)).thenReturn(prevTerm);
    // and which also properly returns -1 as the term for an unknown entry, in this case prevIndex - 2
    when(logMock.readEntryTerm(prevIndex - 2)).thenReturn(-1L);
    // also, a state with a given commitIndex, obviously ahead of prevIndex
    long commitIndex = 10;
    ReadableRaftState state = mock(ReadableRaftState.class);
    when(state.entryLog()).thenReturn(logMock);
    when(state.commitIndex()).thenReturn(commitIndex);
    // which is also the append index
    when(logMock.appendIndex()).thenReturn(commitIndex);
    // when
    // an appendEntriesRequest arrives for appending entries before the prevIndex (for whatever reason)
    Outcome outcome = mock(Outcome.class);
    Appending.handleAppendEntriesRequest(state, outcome, new RaftMessages.AppendEntries.Request(aMember, prevTerm, prevIndex - 2, prevTerm, new RaftLogEntry[] { new RaftLogEntry(prevTerm, ReplicatedInteger.valueOf(2)) }, commitIndex + 3), NullLog.getInstance());
    // then
    // there should be no truncate commands. Actually, the whole thing should be a no op
    verify(outcome, times(0)).addLogCommand(any());
}
Also used : ReadableRaftLog(org.neo4j.causalclustering.core.consensus.log.ReadableRaftLog) Outcome(org.neo4j.causalclustering.core.consensus.outcome.Outcome) ReadableRaftState(org.neo4j.causalclustering.core.consensus.state.ReadableRaftState) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) Test(org.junit.Test)

Example 67 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class RaftLogShipperTest method shouldSendAllEntriesAndCatchupCompletely.

@Test
public void shouldSendAllEntriesAndCatchupCompletely() throws Throwable {
    // given
    final int ENTRY_COUNT = catchupBatchSize * 10;
    Collection<RaftLogEntry> entries = new ArrayList<>();
    for (int i = 0; i < ENTRY_COUNT; i++) {
        entries.add(new RaftLogEntry(0, ReplicatedInteger.valueOf(i)));
    }
    for (RaftLogEntry entry : entries) {
        raftLog.append(entry);
    }
    // then
    startLogShipper();
    // back-tracking stage
    RaftMessages.AppendEntries.Request expected = new RaftMessages.AppendEntries.Request(leader, leaderTerm, 0, 0, RaftLogEntry.empty, leaderCommit);
    while (!outbound.sentTo(follower).contains(expected)) {
        logShipper.onMismatch(-1, new LeaderContext(0, 0));
    }
    // catchup stage
    long matchIndex;
    do {
        AppendEntries.Request last = (AppendEntries.Request) Iterables.last(outbound.sentTo(follower));
        matchIndex = last.prevLogIndex() + last.entries().length;
        outbound.clear();
        logShipper.onMatch(matchIndex, new LeaderContext(0, 0));
    } while (outbound.sentTo(follower).size() > 0);
    assertEquals(ENTRY_COUNT - 1, matchIndex);
}
Also used : ArrayList(java.util.ArrayList) RaftMessages(org.neo4j.causalclustering.core.consensus.RaftMessages) AppendEntries(org.neo4j.causalclustering.core.consensus.RaftMessages.AppendEntries) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) LeaderContext(org.neo4j.causalclustering.core.consensus.LeaderContext) Test(org.junit.Test)

Example 68 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class RaftStateTest method shouldUpdateCacheState.

@Test
public void shouldUpdateCacheState() throws Exception {
    //Test that updates applied to the raft state will be refelcted in the entry cache.
    //given
    InFlightMap<RaftLogEntry> cache = new InFlightMap<>();
    RaftState raftState = new RaftState(member(0), new InMemoryStateStorage<>(new TermState()), new FakeMembership(), new InMemoryRaftLog(), new InMemoryStateStorage<>(new VoteState()), cache, NullLogProvider.getInstance());
    List<RaftLogCommand> logCommands = new LinkedList<RaftLogCommand>() {

        {
            add(new AppendLogEntry(1, new RaftLogEntry(0L, valueOf(0))));
            add(new AppendLogEntry(2, new RaftLogEntry(0L, valueOf(1))));
            add(new AppendLogEntry(3, new RaftLogEntry(0L, valueOf(2))));
            add(new AppendLogEntry(4, new RaftLogEntry(0L, valueOf(4))));
            add(new TruncateLogCommand(3));
            add(new AppendLogEntry(3, new RaftLogEntry(0L, valueOf(5))));
        }
    };
    Outcome raftTestMemberOutcome = new Outcome(CANDIDATE, 0, null, -1, null, emptySet(), -1, initialFollowerStates(), true, logCommands, emptyOutgoingMessages(), emptySet(), -1, emptySet());
    //when
    raftState.update(raftTestMemberOutcome);
    //then
    assertNotNull(cache.get(1L));
    assertNotNull(cache.get(2L));
    assertNotNull(cache.get(3L));
    assertEquals(valueOf(5), cache.get(3L).content());
    assertNull(cache.get(4L));
}
Also used : TruncateLogCommand(org.neo4j.causalclustering.core.consensus.outcome.TruncateLogCommand) LinkedList(java.util.LinkedList) RaftLogCommand(org.neo4j.causalclustering.core.consensus.outcome.RaftLogCommand) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) InMemoryRaftLog(org.neo4j.causalclustering.core.consensus.log.InMemoryRaftLog) VoteState(org.neo4j.causalclustering.core.consensus.vote.VoteState) Outcome(org.neo4j.causalclustering.core.consensus.outcome.Outcome) AppendLogEntry(org.neo4j.causalclustering.core.consensus.outcome.AppendLogEntry) InFlightMap(org.neo4j.causalclustering.core.consensus.log.segmented.InFlightMap) TermState(org.neo4j.causalclustering.core.consensus.term.TermState) Test(org.junit.Test)

Example 69 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class HeartbeatTest method shouldNotResultInCommitIfReferringToFutureEntries.

@Test
public void shouldNotResultInCommitIfReferringToFutureEntries() throws Exception {
    InMemoryRaftLog raftLog = new InMemoryRaftLog();
    RaftState state = raftState().myself(myself).entryLog(raftLog).build();
    long leaderTerm = state.term() + leaderTermDifference;
    raftLog.append(new RaftLogEntry(leaderTerm, content()));
    RaftMessages.Heartbeat heartbeat = heartbeat().from(leader).commitIndex(// The leader is talking about committing stuff we don't know about
    raftLog.appendIndex() + 1).commitIndexTerm(// And is in the same term
    leaderTerm).leaderTerm(leaderTerm).build();
    Outcome outcome = role.handler.handle(heartbeat, state, log());
    assertThat(outcome.getLogCommands(), empty());
}
Also used : InMemoryRaftLog(org.neo4j.causalclustering.core.consensus.log.InMemoryRaftLog) Outcome(org.neo4j.causalclustering.core.consensus.outcome.Outcome) RaftState(org.neo4j.causalclustering.core.consensus.state.RaftState) RaftMessages(org.neo4j.causalclustering.core.consensus.RaftMessages) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) Test(org.junit.Test)

Example 70 with RaftLogEntry

use of org.neo4j.causalclustering.core.consensus.log.RaftLogEntry in project neo4j by neo4j.

the class HeartbeatTest method shouldResultInCommitIfHistoryMatches.

@Test
public void shouldResultInCommitIfHistoryMatches() throws Exception {
    InMemoryRaftLog raftLog = new InMemoryRaftLog();
    RaftState state = raftState().myself(myself).entryLog(raftLog).build();
    long leaderTerm = state.term() + leaderTermDifference;
    raftLog.append(new RaftLogEntry(leaderTerm - 1, content()));
    RaftMessages.Heartbeat heartbeat = heartbeat().from(leader).commitIndex(// The leader is talking about committing stuff we don't know about
    raftLog.appendIndex()).commitIndexTerm(// And is in the same term
    leaderTerm).leaderTerm(leaderTerm).build();
    Outcome outcome = role.handler.handle(heartbeat, state, log());
    assertThat(outcome.getLogCommands(), empty());
}
Also used : InMemoryRaftLog(org.neo4j.causalclustering.core.consensus.log.InMemoryRaftLog) Outcome(org.neo4j.causalclustering.core.consensus.outcome.Outcome) RaftState(org.neo4j.causalclustering.core.consensus.state.RaftState) RaftMessages(org.neo4j.causalclustering.core.consensus.RaftMessages) RaftLogEntry(org.neo4j.causalclustering.core.consensus.log.RaftLogEntry) Test(org.junit.Test)

Aggregations

RaftLogEntry (org.neo4j.causalclustering.core.consensus.log.RaftLogEntry)87 Test (org.junit.Test)69 Outcome (org.neo4j.causalclustering.core.consensus.outcome.Outcome)27 InMemoryRaftLog (org.neo4j.causalclustering.core.consensus.log.InMemoryRaftLog)25 RaftState (org.neo4j.causalclustering.core.consensus.state.RaftState)20 RaftMessages (org.neo4j.causalclustering.core.consensus.RaftMessages)12 RaftLog (org.neo4j.causalclustering.core.consensus.log.RaftLog)10 ReadableRaftState (org.neo4j.causalclustering.core.consensus.state.ReadableRaftState)10 AppendLogEntry (org.neo4j.causalclustering.core.consensus.outcome.AppendLogEntry)8 NewLeaderBarrier (org.neo4j.causalclustering.core.consensus.NewLeaderBarrier)7 AppendEntries (org.neo4j.causalclustering.core.consensus.RaftMessages.AppendEntries)7 MemberId (org.neo4j.causalclustering.identity.MemberId)7 InOrder (org.mockito.InOrder)6 RaftLogCursor (org.neo4j.causalclustering.core.consensus.log.RaftLogCursor)6 ReadableRaftLog (org.neo4j.causalclustering.core.consensus.log.ReadableRaftLog)5 RaftTestGroup (org.neo4j.causalclustering.core.consensus.membership.RaftTestGroup)5 BatchAppendLogEntries (org.neo4j.causalclustering.core.consensus.outcome.BatchAppendLogEntries)5 ShipCommand (org.neo4j.causalclustering.core.consensus.outcome.ShipCommand)5 TruncateLogCommand (org.neo4j.causalclustering.core.consensus.outcome.TruncateLogCommand)5 File (java.io.File)4