Search in sources :

Example 1 with MockPayload

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.

the class PartitionedCandidateOnStartupElectionScenarioTest method setupPartitionedCandidateMember3AndSendElectionTimeouts.

private void setupPartitionedCandidateMember3AndSendElectionTimeouts() {
    testLog.info("setupPartitionedCandidateMember3AndSendElectionTimeouts starting");
    // Create member 3's behavior initially as a Candidate.
    member3Context = newRaftActorContext("member3", member3ActorRef, ImmutableMap.<String, String>builder().put("member1", member1ActorRef.path().toString()).put("member2", member2ActorRef.path().toString()).build());
    DefaultConfigParamsImpl member3ConfigParams = newConfigParams();
    member3Context.setConfigParams(member3ConfigParams);
    // Initialize the ReplicatedLog and election term info for Candidate member 3. The current term
    // will be 2 and the last term will be 1 so it is behind the leader's log.
    SimpleReplicatedLog candidateReplicatedLog = new SimpleReplicatedLog();
    candidateReplicatedLog.append(new SimpleReplicatedLogEntry(0, 2, new MockPayload("")));
    member3Context.setReplicatedLog(candidateReplicatedLog);
    member3Context.setCommitIndex(candidateReplicatedLog.lastIndex());
    member3Context.setLastApplied(candidateReplicatedLog.lastIndex());
    member3Context.getTermInformation().update(2, member1Context.getId());
    // The member 3 Candidate will start a new term and send RequestVotes. However it will be
    // partitioned from the cluster by having member 1 and 2 drop its RequestVote messages.
    candidateElectionTerm = member3Context.getTermInformation().getCurrentTerm() + numCandidateElections;
    member1Actor.dropMessagesToBehavior(RequestVote.class, numCandidateElections);
    member2Actor.dropMessagesToBehavior(RequestVote.class, numCandidateElections);
    member3Actor.self().tell(new SetBehavior(new Candidate(member3Context), member3Context), ActorRef.noSender());
    for (int i = 0; i < numCandidateElections - 1; i++) {
        member3ActorRef.tell(ElectionTimeout.INSTANCE, ActorRef.noSender());
    }
    member1Actor.waitForExpectedMessages(RequestVote.class);
    member2Actor.waitForExpectedMessages(RequestVote.class);
    verifyBehaviorState("member 1", member1Actor, RaftState.Leader);
    verifyBehaviorState("member 2", member2Actor, RaftState.Follower);
    verifyBehaviorState("member 3", member3Actor, RaftState.Candidate);
    assertEquals("member 1 election term", 3, member1Context.getTermInformation().getCurrentTerm());
    assertEquals("member 2 election term", 3, member2Context.getTermInformation().getCurrentTerm());
    assertEquals("member 3 election term", candidateElectionTerm, member3Context.getTermInformation().getCurrentTerm());
    testLog.info("setupPartitionedCandidateMember3AndSendElectionTimeouts ending");
}
Also used : SimpleReplicatedLog(org.opendaylight.controller.cluster.raft.MockRaftActorContext.SimpleReplicatedLog) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload)

Example 2 with MockPayload

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.

the class RecoveryIntegrationTest method testStatePersistedAfterSnapshotPersisted.

@Test
public void testStatePersistedAfterSnapshotPersisted() {
    send2InitialPayloads();
    // Block these messages initially so we can control the sequence.
    follower1Actor.underlyingActor().startDropMessages(AppendEntries.class);
    final MockPayload payload2 = sendPayloadData(leaderActor, "two");
    // This should trigger a snapshot.
    final MockPayload payload3 = sendPayloadData(leaderActor, "three");
    // Send another payload.
    final MockPayload payload4 = sendPayloadData(leaderActor, "four");
    MessageCollectorActor.expectMatching(follower1CollectorActor, AppendEntries.class, 3);
    // Wait for snapshot complete.
    MessageCollectorActor.expectFirstMatching(leaderCollectorActor, SaveSnapshotSuccess.class);
    // Now deliver the AppendEntries to the follower
    follower1Actor.underlyingActor().stopDropMessages(AppendEntries.class);
    MessageCollectorActor.expectMatching(leaderCollectorActor, ApplyJournalEntries.class, 1);
    reinstateLeaderActor();
    assertEquals("Leader snapshot term", currentTerm, leaderContext.getReplicatedLog().getSnapshotTerm());
    assertEquals("Leader snapshot index", 1, leaderContext.getReplicatedLog().getSnapshotIndex());
    assertEquals("Leader journal log size", 3, leaderContext.getReplicatedLog().size());
    assertEquals("Leader journal last index", 4, leaderContext.getReplicatedLog().lastIndex());
    assertEquals("Leader commit index", 4, leaderContext.getCommitIndex());
    assertEquals("Leader last applied", 4, leaderContext.getLastApplied());
    assertEquals("Leader state", Arrays.asList(payload0, payload1, payload2, payload3, payload4), leaderActor.underlyingActor().getState());
}
Also used : MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) Test(org.junit.Test)

Example 3 with MockPayload

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.

the class RecoveryIntegrationTest method testStatePersistedBetweenSnapshotCaptureAndPersist.

@Test
public void testStatePersistedBetweenSnapshotCaptureAndPersist() {
    send2InitialPayloads();
    // Block these messages initially so we can control the sequence.
    leaderActor.underlyingActor().startDropMessages(CaptureSnapshotReply.class);
    follower1Actor.underlyingActor().startDropMessages(AppendEntries.class);
    final MockPayload payload2 = sendPayloadData(leaderActor, "two");
    // This should trigger a snapshot.
    final MockPayload payload3 = sendPayloadData(leaderActor, "three");
    MessageCollectorActor.expectMatching(follower1CollectorActor, AppendEntries.class, 3);
    // Send another payload.
    final MockPayload payload4 = sendPayloadData(leaderActor, "four");
    // Now deliver the AppendEntries to the follower
    follower1Actor.underlyingActor().stopDropMessages(AppendEntries.class);
    MessageCollectorActor.expectMatching(leaderCollectorActor, ApplyJournalEntries.class, 1);
    // Now deliver the CaptureSnapshotReply to the leader.
    CaptureSnapshotReply captureSnapshotReply = MessageCollectorActor.expectFirstMatching(leaderCollectorActor, CaptureSnapshotReply.class);
    leaderActor.underlyingActor().stopDropMessages(CaptureSnapshotReply.class);
    leaderActor.tell(captureSnapshotReply, leaderActor);
    // Wait for snapshot complete.
    MessageCollectorActor.expectFirstMatching(leaderCollectorActor, SaveSnapshotSuccess.class);
    reinstateLeaderActor();
    assertEquals("Leader snapshot term", currentTerm, leaderContext.getReplicatedLog().getSnapshotTerm());
    assertEquals("Leader snapshot index", 1, leaderContext.getReplicatedLog().getSnapshotIndex());
    assertEquals("Leader journal log size", 3, leaderContext.getReplicatedLog().size());
    assertEquals("Leader journal last index", 4, leaderContext.getReplicatedLog().lastIndex());
    assertEquals("Leader commit index", 4, leaderContext.getCommitIndex());
    assertEquals("Leader last applied", 4, leaderContext.getLastApplied());
    assertEquals("Leader state", Arrays.asList(payload0, payload1, payload2, payload3, payload4), leaderActor.underlyingActor().getState());
}
Also used : CaptureSnapshotReply(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) Test(org.junit.Test)

Example 4 with MockPayload

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.

the class RecoveryIntegrationTest method testFollowerRecoveryAfterInstallSnapshot.

@Test
public void testFollowerRecoveryAfterInstallSnapshot() throws Exception {
    send2InitialPayloads();
    leader = leaderActor.underlyingActor().getCurrentBehavior();
    follower2Actor = newTestRaftActor(follower2Id, ImmutableMap.of(leaderId, testActorPath(leaderId)), newFollowerConfigParams());
    follower2CollectorActor = follower2Actor.underlyingActor().collectorActor();
    leaderActor.tell(new SetPeerAddress(follower2Id, follower2Actor.path().toString()), ActorRef.noSender());
    final MockPayload payload2 = sendPayloadData(leaderActor, "two");
    // Verify the leader applies the 3rd payload state.
    MessageCollectorActor.expectMatching(leaderCollectorActor, ApplyJournalEntries.class, 1);
    MessageCollectorActor.expectMatching(follower2CollectorActor, ApplyJournalEntries.class, 1);
    assertEquals("Leader commit index", 2, leaderContext.getCommitIndex());
    assertEquals("Leader last applied", 2, leaderContext.getLastApplied());
    assertEquals("Leader snapshot index", 1, leaderContext.getReplicatedLog().getSnapshotIndex());
    assertEquals("Leader replicatedToAllIndex", 1, leader.getReplicatedToAllIndex());
    killActor(follower2Actor);
    InMemoryJournal.clear();
    follower2Actor = newTestRaftActor(follower2Id, ImmutableMap.of(leaderId, testActorPath(leaderId)), newFollowerConfigParams());
    TestRaftActor follower2Underlying = follower2Actor.underlyingActor();
    follower2CollectorActor = follower2Underlying.collectorActor();
    follower2Context = follower2Underlying.getRaftActorContext();
    leaderActor.tell(new SetPeerAddress(follower2Id, follower2Actor.path().toString()), ActorRef.noSender());
    // The leader should install a snapshot so wait for the follower to receive ApplySnapshot.
    MessageCollectorActor.expectFirstMatching(follower2CollectorActor, ApplySnapshot.class);
    // Wait for the follower to persist the snapshot.
    MessageCollectorActor.expectFirstMatching(follower2CollectorActor, SaveSnapshotSuccess.class);
    final List<MockPayload> expFollowerState = Arrays.asList(payload0, payload1, payload2);
    assertEquals("Follower commit index", 2, follower2Context.getCommitIndex());
    assertEquals("Follower last applied", 2, follower2Context.getLastApplied());
    assertEquals("Follower snapshot index", 2, follower2Context.getReplicatedLog().getSnapshotIndex());
    assertEquals("Follower state", expFollowerState, follower2Underlying.getState());
    killActor(follower2Actor);
    follower2Actor = newTestRaftActor(follower2Id, ImmutableMap.of(leaderId, testActorPath(leaderId)), newFollowerConfigParams());
    follower2Underlying = follower2Actor.underlyingActor();
    follower2Underlying.waitForRecoveryComplete();
    follower2Context = follower2Underlying.getRaftActorContext();
    assertEquals("Follower commit index", 2, follower2Context.getCommitIndex());
    assertEquals("Follower last applied", 2, follower2Context.getLastApplied());
    assertEquals("Follower snapshot index", 2, follower2Context.getReplicatedLog().getSnapshotIndex());
    assertEquals("Follower state", expFollowerState, follower2Underlying.getState());
}
Also used : MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) Test(org.junit.Test)

Example 5 with MockPayload

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload in project controller by opendaylight.

the class ReplicatedLogImplTest method testAppendAndPersistExpectingCaptureDueToDataSize.

@Test
public void testAppendAndPersistExpectingCaptureDueToDataSize() throws Exception {
    doReturn(1L).when(mockBehavior).getReplicatedToAllIndex();
    context.setTotalMemoryRetriever(() -> 100);
    ReplicatedLog log = ReplicatedLogImpl.newInstance(context);
    int dataSize = 600;
    ReplicatedLogEntry logEntry = new SimpleReplicatedLogEntry(2, 1, new MockPayload("2", dataSize));
    log.appendAndPersist(logEntry, null, true);
    verifyPersist(logEntry);
    reset(mockPersistence);
    logEntry = new SimpleReplicatedLogEntry(3, 1, new MockPayload("3", 5));
    log.appendAndPersist(logEntry, null, true);
    verifyPersist(logEntry);
    assertEquals("size", 2, log.size());
}
Also used : SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) MockPayload(org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload) Test(org.junit.Test)

Aggregations

MockPayload (org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload)37 Test (org.junit.Test)30 SimpleReplicatedLogEntry (org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry)22 ApplyState (org.opendaylight.controller.cluster.raft.base.messages.ApplyState)11 Snapshot (org.opendaylight.controller.cluster.raft.persisted.Snapshot)8 ApplySnapshot (org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot)5 CaptureSnapshot (org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot)5 InstallSnapshot (org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)5 MockSnapshotState (org.opendaylight.controller.cluster.raft.MockRaftActor.MockSnapshotState)4 AppendEntries (org.opendaylight.controller.cluster.raft.messages.AppendEntries)4 SnapshotMetadata (akka.persistence.SnapshotMetadata)3 SnapshotOffer (akka.persistence.SnapshotOffer)3 ApplyJournalEntries (org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries)3 ByteString (com.google.protobuf.ByteString)2 DefaultConfigParamsImpl (org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl)2 SimpleReplicatedLog (org.opendaylight.controller.cluster.raft.MockRaftActorContext.SimpleReplicatedLog)2 DeleteEntries (org.opendaylight.controller.cluster.raft.persisted.DeleteEntries)2 ServerConfigurationPayload (org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload)2 ServerInfo (org.opendaylight.controller.cluster.raft.persisted.ServerInfo)2 UpdateElectionTerm (org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm)2