use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.
the class ReplicatedLogImplTest method testAppendAndPersistExpectingNoCapture.
@SuppressWarnings("unchecked")
@Test
public void testAppendAndPersistExpectingNoCapture() throws Exception {
ReplicatedLog log = ReplicatedLogImpl.newInstance(context);
ReplicatedLogEntry logEntry1 = new SimpleReplicatedLogEntry(1, 1, new MockPayload("1"));
log.appendAndPersist(logEntry1, null, true);
verifyPersist(logEntry1);
assertEquals("size", 1, log.size());
reset(mockPersistence);
ReplicatedLogEntry logEntry2 = new SimpleReplicatedLogEntry(2, 1, new MockPayload("2"));
Procedure<ReplicatedLogEntry> mockCallback = Mockito.mock(Procedure.class);
log.appendAndPersist(logEntry2, mockCallback, true);
verifyPersist(logEntry2);
verify(mockCallback).apply(same(logEntry2));
assertEquals("size", 2, log.size());
}
use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.
the class ReplicatedLogImplTest method testAppendAndPersistExpectingCaptureDueToJournalCount.
@Test
public void testAppendAndPersistExpectingCaptureDueToJournalCount() throws Exception {
configParams.setSnapshotBatchCount(2);
doReturn(1L).when(mockBehavior).getReplicatedToAllIndex();
ReplicatedLog log = ReplicatedLogImpl.newInstance(context);
final ReplicatedLogEntry logEntry1 = new SimpleReplicatedLogEntry(2, 1, new MockPayload("2"));
final ReplicatedLogEntry logEntry2 = new SimpleReplicatedLogEntry(3, 1, new MockPayload("3"));
log.appendAndPersist(logEntry1, null, true);
verifyPersist(logEntry1);
reset(mockPersistence);
log.appendAndPersist(logEntry2, null, true);
verifyPersist(logEntry2);
assertEquals("size", 2, log.size());
}
use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.
the class ReplicationAndSnapshotsIntegrationTest method runTest.
@Test
public void runTest() throws Exception {
testLog.info("testReplicationAndSnapshots starting");
// Setup the persistent journal for the leader. We'll start up with 3 journal log entries (one less
// than the snapshotBatchCount).
long seqId = 1;
InMemoryJournal.addEntry(leaderId, seqId++, new UpdateElectionTerm(initialTerm, leaderId));
recoveredPayload0 = new MockPayload("zero");
InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(0, initialTerm, recoveredPayload0));
recoveredPayload1 = new MockPayload("one");
InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(1, initialTerm, recoveredPayload1));
recoveredPayload2 = new MockPayload("two");
InMemoryJournal.addEntry(leaderId, seqId++, new SimpleReplicatedLogEntry(2, initialTerm, recoveredPayload2));
InMemoryJournal.addEntry(leaderId, seqId++, new ApplyJournalEntries(2));
origLeaderJournal = InMemoryJournal.get(leaderId, SimpleReplicatedLogEntry.class);
// Create the leader and 2 follower actors and verify initial syncing of the followers after leader
// persistence recovery.
DefaultConfigParamsImpl followerConfigParams = newFollowerConfigParams();
followerConfigParams.setSnapshotBatchCount(snapshotBatchCount);
follower1Actor = newTestRaftActor(follower1Id, ImmutableMap.of(leaderId, testActorPath(leaderId), follower2Id, testActorPath(follower2Id)), followerConfigParams);
follower2Actor = newTestRaftActor(follower2Id, ImmutableMap.of(leaderId, testActorPath(leaderId), follower1Id, testActorPath(follower1Id)), followerConfigParams);
peerAddresses = ImmutableMap.<String, String>builder().put(follower1Id, follower1Actor.path().toString()).put(follower2Id, follower2Actor.path().toString()).build();
leaderConfigParams = newLeaderConfigParams();
leaderActor = newTestRaftActor(leaderId, peerAddresses, leaderConfigParams);
follower1CollectorActor = follower1Actor.underlyingActor().collectorActor();
follower2CollectorActor = follower2Actor.underlyingActor().collectorActor();
leaderCollectorActor = leaderActor.underlyingActor().collectorActor();
leaderContext = leaderActor.underlyingActor().getRaftActorContext();
verifyLeaderRecoveryAndInitialization();
testFirstSnapshot();
testSubsequentReplications();
testSecondSnapshot();
testLeaderReinstatement();
testLog.info("testReplicationAndSnapshots ending");
}
use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.
the class ReplicationAndSnapshotsWithLaggingFollowerIntegrationTest method testReplicationsWithLaggingFollowerCaughtUpViaAppendEntries.
/**
* Send 2 payload instances with follower 2 lagging then resume the follower and verifies it gets
* caught up via AppendEntries.
*/
@Test
public void testReplicationsWithLaggingFollowerCaughtUpViaAppendEntries() throws Exception {
testLog.info("testReplicationsWithLaggingFollowerCaughtUpViaAppendEntries starting: sending 2 new payloads");
setup();
// Simulate lagging by dropping AppendEntries messages in follower 2.
follower2Actor.underlyingActor().startDropMessages(AppendEntries.class);
// Send the payloads.
MockPayload payload0 = sendPayloadData(leaderActor, "zero");
MockPayload payload1 = sendPayloadData(leaderActor, "one");
// Verify the leader got consensus and applies each log entry even though follower 2 didn't respond.
List<ApplyState> applyStates = MessageCollectorActor.expectMatching(leaderCollectorActor, ApplyState.class, 2);
verifyApplyState(applyStates.get(0), leaderCollectorActor, payload0.toString(), currentTerm, 0, payload0);
verifyApplyState(applyStates.get(1), leaderCollectorActor, payload1.toString(), currentTerm, 1, payload1);
// Verify follower 1 applies each log entry.
applyStates = MessageCollectorActor.expectMatching(follower1CollectorActor, ApplyState.class, 2);
verifyApplyState(applyStates.get(0), null, null, currentTerm, 0, payload0);
verifyApplyState(applyStates.get(1), null, null, currentTerm, 1, payload1);
// Ensure there's at least 1 more heartbeat.
MessageCollectorActor.clearMessages(leaderCollectorActor);
MessageCollectorActor.expectFirstMatching(leaderCollectorActor, AppendEntriesReply.class);
// The leader should not have performed fake snapshots to trim the log because the entries have not
// been replicated to follower 2.
assertEquals("Leader snapshot term", -1, leaderContext.getReplicatedLog().getSnapshotTerm());
assertEquals("Leader snapshot index", -1, leaderContext.getReplicatedLog().getSnapshotIndex());
assertEquals("Leader journal log size", 2, leaderContext.getReplicatedLog().size());
assertEquals("Leader journal last index", 1, leaderContext.getReplicatedLog().lastIndex());
assertEquals("Leader commit index", 1, leaderContext.getCommitIndex());
assertEquals("Leader last applied", 1, leaderContext.getLastApplied());
assertEquals("Leader replicatedToAllIndex", -1, leader.getReplicatedToAllIndex());
testLog.info("testReplicationsWithLaggingFollowerCaughtUpViaAppendEntries: new entries applied - resuming follower {}", follower2Id);
// Now stop dropping AppendEntries in follower 2.
follower2Actor.underlyingActor().stopDropMessages(AppendEntries.class);
// Verify follower 2 applies each log entry.
applyStates = MessageCollectorActor.expectMatching(follower2CollectorActor, ApplyState.class, 2);
verifyApplyState(applyStates.get(0), null, null, currentTerm, 0, payload0);
verifyApplyState(applyStates.get(1), null, null, currentTerm, 1, payload1);
// Ensure there's at least 1 more heartbeat.
MessageCollectorActor.clearMessages(leaderCollectorActor);
MessageCollectorActor.expectFirstMatching(leaderCollectorActor, AppendEntriesReply.class);
// The leader should now have performed fake snapshots to trim the log.
verifyLeadersTrimmedLog(1);
// Even though follower 2 lagged behind, the leader should not have tried to install a snapshot
// to catch it up because no snapshotting was done so the follower's next index was present in the log.
InstallSnapshot installSnapshot = MessageCollectorActor.getFirstMatching(follower2CollectorActor, InstallSnapshot.class);
Assert.assertNull("Follower 2 received unexpected InstallSnapshot", installSnapshot);
testLog.info("testReplicationsWithLaggingFollowerCaughtUpViaAppendEntries complete");
}
use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.
the class ReplicationAndSnapshotsWithLaggingFollowerIntegrationTest method verifyReplicationsAndSnapshotWithNoLaggingAfterInstallSnapshot.
/**
* Do another round of payloads and snapshot to verify replicatedToAllIndex gets back on track and
* snapshots works as expected after doing a follower snapshot. In this step we don't lag a follower.
*/
private long verifyReplicationsAndSnapshotWithNoLaggingAfterInstallSnapshot() throws Exception {
testLog.info("verifyReplicationsAndSnapshotWithNoLaggingAfterInstallSnapshot starting: replicatedToAllIndex: {}", leader.getReplicatedToAllIndex());
// Send another payload - a snapshot should occur.
MockPayload payload4 = sendPayloadData(leaderActor, "four");
// Wait for the snapshot to complete.
MessageCollectorActor.expectFirstMatching(leaderCollectorActor, SaveSnapshotSuccess.class);
ApplyState applyState = MessageCollectorActor.expectFirstMatching(leaderCollectorActor, ApplyState.class);
verifyApplyState(applyState, leaderCollectorActor, payload4.toString(), currentTerm, 4, payload4);
// Verify the leader's last persisted snapshot (previous ones may not be purged yet).
List<Snapshot> persistedSnapshots = InMemorySnapshotStore.getSnapshots(leaderId, Snapshot.class);
Snapshot persistedSnapshot = persistedSnapshots.get(persistedSnapshots.size() - 1);
// The last (fourth) payload may or may not have been applied when the snapshot is captured depending on the
// timing when the async persistence completes.
List<ReplicatedLogEntry> unAppliedEntry = persistedSnapshot.getUnAppliedEntries();
long leadersSnapshotIndex;
if (unAppliedEntry.isEmpty()) {
leadersSnapshotIndex = 4;
expSnapshotState.add(payload4);
verifySnapshot("Persisted", persistedSnapshot, currentTerm, 4, currentTerm, 4);
} else {
leadersSnapshotIndex = 3;
verifySnapshot("Persisted", persistedSnapshot, currentTerm, 3, currentTerm, 4);
assertEquals("Persisted Snapshot getUnAppliedEntries size", 1, unAppliedEntry.size());
verifyReplicatedLogEntry(unAppliedEntry.get(0), currentTerm, 4, payload4);
expSnapshotState.add(payload4);
}
// Send a couple more payloads.
MockPayload payload5 = sendPayloadData(leaderActor, "five");
MockPayload payload6 = sendPayloadData(leaderActor, "six");
// Verify the leader applies the 2 log entries.
List<ApplyState> applyStates = MessageCollectorActor.expectMatching(leaderCollectorActor, ApplyState.class, 3);
verifyApplyState(applyStates.get(1), leaderCollectorActor, payload5.toString(), currentTerm, 5, payload5);
verifyApplyState(applyStates.get(2), leaderCollectorActor, payload6.toString(), currentTerm, 6, payload6);
// Verify the leader applies a log entry for at least the last entry index.
verifyApplyJournalEntries(leaderCollectorActor, 6);
// Ensure there's at least 1 more heartbeat to trim the log.
MessageCollectorActor.clearMessages(leaderCollectorActor);
MessageCollectorActor.expectFirstMatching(leaderCollectorActor, AppendEntriesReply.class);
// Verify the leader's final state.
verifyLeadersTrimmedLog(6);
InMemoryJournal.dumpJournal(leaderId);
// Verify the leaders's persisted journal log - it should only contain the last 2 ReplicatedLogEntries
// added after the snapshot as the persisted journal should've been purged to the snapshot
// sequence number.
verifyPersistedJournal(leaderId, Arrays.asList(new SimpleReplicatedLogEntry(5, currentTerm, payload5), new SimpleReplicatedLogEntry(6, currentTerm, payload6)));
// Verify the leaders's persisted journal contains an ApplyJournalEntries for at least the last entry index.
List<ApplyJournalEntries> persistedApplyJournalEntries = InMemoryJournal.get(leaderId, ApplyJournalEntries.class);
boolean found = false;
for (ApplyJournalEntries entry : persistedApplyJournalEntries) {
if (entry.getToIndex() == 6) {
found = true;
break;
}
}
Assert.assertTrue(String.format("ApplyJournalEntries with index %d not found in leader's persisted journal", 6), found);
// Verify follower 1 applies the 3 log entries.
applyStates = MessageCollectorActor.expectMatching(follower1CollectorActor, ApplyState.class, 3);
verifyApplyState(applyStates.get(0), null, null, currentTerm, 4, payload4);
verifyApplyState(applyStates.get(1), null, null, currentTerm, 5, payload5);
verifyApplyState(applyStates.get(2), null, null, currentTerm, 6, payload6);
// Verify follower 1's log state.
verifyFollowersTrimmedLog(1, follower1Actor, 6);
// Verify follower 2 applies the 3 log entries.
applyStates = MessageCollectorActor.expectMatching(follower2CollectorActor, ApplyState.class, 3);
verifyApplyState(applyStates.get(0), null, null, currentTerm, 4, payload4);
verifyApplyState(applyStates.get(1), null, null, currentTerm, 5, payload5);
verifyApplyState(applyStates.get(2), null, null, currentTerm, 6, payload6);
// Verify follower 2's log state.
verifyFollowersTrimmedLog(2, follower2Actor, 6);
expSnapshotState.add(payload5);
expSnapshotState.add(payload6);
testLog.info("verifyReplicationsAndSnapshotWithNoLaggingAfterInstallSnapshot ending");
return leadersSnapshotIndex;
}
Aggregations