Search in sources :

Example 31 with DefaultConfigParamsImpl

use of org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl in project controller by opendaylight.

the class LeaderTest method testHandleAppendEntriesReplyWithNewerTerm.

@Test
public void testHandleAppendEntriesReplyWithNewerTerm() {
    logStart("testHandleAppendEntriesReplyWithNewerTerm");
    MockRaftActorContext leaderActorContext = createActorContext();
    ((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setHeartBeatInterval(new FiniteDuration(10000, TimeUnit.SECONDS));
    leaderActorContext.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 2, 2).build());
    leader = new Leader(leaderActorContext);
    leaderActor.underlyingActor().setBehavior(leader);
    leaderActor.tell(new AppendEntriesReply("foo", 20, false, 1000, 10, (short) 1), ActorRef.noSender());
    AppendEntriesReply appendEntriesReply = MessageCollectorActor.expectFirstMatching(leaderActor, AppendEntriesReply.class);
    assertEquals(false, appendEntriesReply.isSuccess());
    assertEquals(RaftState.Follower, leaderActor.underlyingActor().getFirstBehaviorChange().state());
    MessageCollectorActor.clearMessages(leaderActor);
}
Also used : AppendEntriesReply(org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) FiniteDuration(scala.concurrent.duration.FiniteDuration) DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl) Test(org.junit.Test)

Example 32 with DefaultConfigParamsImpl

use of org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl in project controller by opendaylight.

the class LeaderTest method testReplicationWithPayloadSizeThatExceedsThreshold.

@Test
public void testReplicationWithPayloadSizeThatExceedsThreshold() {
    logStart("testReplicationWithPayloadSizeThatExceedsThreshold");
    final int serializedSize = SerializationUtils.serialize(new AppendEntries(1, LEADER_ID, -1, -1, Arrays.asList(new SimpleReplicatedLogEntry(0, 1, new MockRaftActorContext.MockPayload("large"))), 0, -1, (short) 0)).length;
    final MockRaftActorContext.MockPayload largePayload = new MockRaftActorContext.MockPayload("large", serializedSize);
    MockRaftActorContext leaderActorContext = createActorContextWithFollower();
    ((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setHeartBeatInterval(new FiniteDuration(300, TimeUnit.MILLISECONDS));
    ((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setSnapshotChunkSize(serializedSize - 50);
    leaderActorContext.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().build());
    leaderActorContext.setCommitIndex(-1);
    leaderActorContext.setLastApplied(-1);
    leader = new Leader(leaderActorContext);
    leaderActorContext.setCurrentBehavior(leader);
    // Send initial heartbeat reply so follower is marked active
    MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
    leader.handleMessage(followerActor, new AppendEntriesReply(FOLLOWER_ID, -1, true, -1, -1, (short) 0));
    MessageCollectorActor.clearMessages(followerActor);
    // Send normal payload first to prime commit index.
    final long term = leaderActorContext.getTermInformation().getCurrentTerm();
    sendReplicate(leaderActorContext, term, 0);
    AppendEntries appendEntries = MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
    assertEquals("Entries size", 1, appendEntries.getEntries().size());
    assertEquals("Entry getIndex", 0, appendEntries.getEntries().get(0).getIndex());
    leader.handleMessage(followerActor, new AppendEntriesReply(FOLLOWER_ID, term, true, 0, term, (short) 0));
    assertEquals("getCommitIndex", 0, leaderActorContext.getCommitIndex());
    MessageCollectorActor.clearMessages(followerActor);
    // Now send a large payload that exceeds the maximum size for a single AppendEntries - it should be sliced.
    sendReplicate(leaderActorContext, term, 1, largePayload);
    MessageSlice messageSlice = MessageCollectorActor.expectFirstMatching(followerActor, MessageSlice.class);
    assertEquals("getSliceIndex", 1, messageSlice.getSliceIndex());
    assertEquals("getTotalSlices", 2, messageSlice.getTotalSlices());
    final Identifier slicingId = messageSlice.getIdentifier();
    appendEntries = MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
    assertEquals("getPrevLogIndex", 0, appendEntries.getPrevLogIndex());
    assertEquals("getPrevLogTerm", term, appendEntries.getPrevLogTerm());
    assertEquals("getLeaderCommit", -1, appendEntries.getLeaderCommit());
    assertEquals("Entries size", 0, appendEntries.getEntries().size());
    MessageCollectorActor.clearMessages(followerActor);
    // Initiate a heartbeat - it should send an empty AppendEntries since slicing is in progress.
    // Sleep for the heartbeat interval so AppendEntries is sent.
    Uninterruptibles.sleepUninterruptibly(leaderActorContext.getConfigParams().getHeartBeatInterval().toMillis(), TimeUnit.MILLISECONDS);
    leader.handleMessage(leaderActor, SendHeartBeat.INSTANCE);
    appendEntries = MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
    assertEquals("getLeaderCommit", -1, appendEntries.getLeaderCommit());
    assertEquals("Entries size", 0, appendEntries.getEntries().size());
    MessageCollectorActor.clearMessages(followerActor);
    // Simulate the MessageSliceReply's and AppendEntriesReply from the follower.
    leader.handleMessage(followerActor, MessageSliceReply.success(slicingId, 1, followerActor));
    messageSlice = MessageCollectorActor.expectFirstMatching(followerActor, MessageSlice.class);
    assertEquals("getSliceIndex", 2, messageSlice.getSliceIndex());
    leader.handleMessage(followerActor, MessageSliceReply.success(slicingId, 2, followerActor));
    leader.handleMessage(followerActor, new AppendEntriesReply(FOLLOWER_ID, term, true, 1, term, (short) 0));
    MessageCollectorActor.clearMessages(followerActor);
    // Send another normal payload.
    sendReplicate(leaderActorContext, term, 2);
    appendEntries = MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
    assertEquals("Entries size", 1, appendEntries.getEntries().size());
    assertEquals("Entry getIndex", 2, appendEntries.getEntries().get(0).getIndex());
    assertEquals("getLeaderCommit", 1, appendEntries.getLeaderCommit());
}
Also used : MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) FiniteDuration(scala.concurrent.duration.FiniteDuration) DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl) AppendEntries(org.opendaylight.controller.cluster.raft.messages.AppendEntries) Identifier(org.opendaylight.yangtools.concepts.Identifier) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) AppendEntriesReply(org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply) MessageSlice(org.opendaylight.controller.cluster.messaging.MessageSlice) Test(org.junit.Test)

Example 33 with DefaultConfigParamsImpl

use of org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl in project controller by opendaylight.

the class LeaderTest method testHandleSnapshotSendsPreviousChunksHashCodeWhenSendingNextChunk.

@Test
public void testHandleSnapshotSendsPreviousChunksHashCodeWhenSendingNextChunk() throws Exception {
    logStart("testHandleSnapshotSendsPreviousChunksHashCodeWhenSendingNextChunk");
    MockRaftActorContext actorContext = createActorContextWithFollower();
    final int commitIndex = 3;
    final int snapshotIndex = 2;
    final int snapshotTerm = 1;
    final int currentTerm = 2;
    actorContext.setConfigParams(new DefaultConfigParamsImpl() {

        @Override
        public int getSnapshotChunkSize() {
            return 50;
        }
    });
    actorContext.setCommitIndex(commitIndex);
    leader = new Leader(actorContext);
    leader.getFollower(FOLLOWER_ID).setMatchIndex(-1);
    leader.getFollower(FOLLOWER_ID).setNextIndex(0);
    Map<String, String> leadersSnapshot = new HashMap<>();
    leadersSnapshot.put("1", "A");
    leadersSnapshot.put("2", "B");
    leadersSnapshot.put("3", "C");
    // set the snapshot variables in replicatedlog
    actorContext.getReplicatedLog().setSnapshotIndex(snapshotIndex);
    actorContext.getReplicatedLog().setSnapshotTerm(snapshotTerm);
    actorContext.getTermInformation().update(currentTerm, leaderActor.path().toString());
    ByteString bs = toByteString(leadersSnapshot);
    Snapshot snapshot = Snapshot.create(ByteState.of(bs.toByteArray()), Collections.<ReplicatedLogEntry>emptyList(), commitIndex, snapshotTerm, commitIndex, snapshotTerm, -1, null, null);
    leader.handleMessage(leaderActor, new SendInstallSnapshot(snapshot, ByteSource.wrap(bs.toByteArray())));
    InstallSnapshot installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    assertEquals(1, installSnapshot.getChunkIndex());
    assertEquals(3, installSnapshot.getTotalChunks());
    assertEquals(LeaderInstallSnapshotState.INITIAL_LAST_CHUNK_HASH_CODE, installSnapshot.getLastChunkHashCode().get().intValue());
    final int hashCode = Arrays.hashCode(installSnapshot.getData());
    followerActor.underlyingActor().clear();
    leader.handleMessage(followerActor, new InstallSnapshotReply(installSnapshot.getTerm(), FOLLOWER_ID, 1, true));
    installSnapshot = MessageCollectorActor.expectFirstMatching(followerActor, InstallSnapshot.class);
    assertEquals(2, installSnapshot.getChunkIndex());
    assertEquals(3, installSnapshot.getTotalChunks());
    assertEquals(hashCode, installSnapshot.getLastChunkHashCode().get().intValue());
}
Also used : SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) HashMap(java.util.HashMap) InstallSnapshotReply(org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply) ByteString(com.google.protobuf.ByteString) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl) ByteString(com.google.protobuf.ByteString) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Snapshot(org.opendaylight.controller.cluster.raft.persisted.Snapshot) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) CaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot) SendInstallSnapshot(org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot) Test(org.junit.Test)

Example 34 with DefaultConfigParamsImpl

use of org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl in project controller by opendaylight.

the class PartitionedCandidateOnStartupElectionScenarioTest method setupInitialMember1AndMember2Behaviors.

private void setupInitialMember1AndMember2Behaviors() {
    testLog.info("setupInitialMember1AndMember2Behaviors starting");
    // Initialize the ReplicatedLog and election term info for member 1 and 2. The current term
    // will be 3 and the last term will be 2.
    SimpleReplicatedLog replicatedLog = new SimpleReplicatedLog();
    replicatedLog.append(new SimpleReplicatedLogEntry(0, 2, new MockPayload("")));
    replicatedLog.append(new SimpleReplicatedLogEntry(1, 3, new MockPayload("")));
    // Create member 2's behavior as Follower.
    member2Context = newRaftActorContext("member2", member2ActorRef, ImmutableMap.<String, String>builder().put("member1", member1ActorRef.path().toString()).put("member3", member3ActorRef.path().toString()).build());
    DefaultConfigParamsImpl member2ConfigParams = newConfigParams();
    member2Context.setConfigParams(member2ConfigParams);
    member2Context.setReplicatedLog(replicatedLog);
    member2Context.setCommitIndex(replicatedLog.lastIndex());
    member2Context.setLastApplied(replicatedLog.lastIndex());
    member2Context.getTermInformation().update(3, "member1");
    member2Actor.self().tell(new SetBehavior(new Follower(member2Context), member2Context), ActorRef.noSender());
    // Create member 1's behavior as Leader.
    member1Context = newRaftActorContext("member1", member1ActorRef, ImmutableMap.<String, String>builder().put("member2", member2ActorRef.path().toString()).put("member3", member3ActorRef.path().toString()).build());
    DefaultConfigParamsImpl member1ConfigParams = newConfigParams();
    member1Context.setConfigParams(member1ConfigParams);
    member1Context.setReplicatedLog(replicatedLog);
    member1Context.setCommitIndex(replicatedLog.lastIndex());
    member1Context.setLastApplied(replicatedLog.lastIndex());
    member1Context.getTermInformation().update(3, "member1");
    initializeLeaderBehavior(member1Actor, member1Context, 1);
    member2Actor.clear();
    member3Actor.clear();
    testLog.info("setupInitialMember1AndMember2Behaviors 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 35 with DefaultConfigParamsImpl

use of org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl in project controller by opendaylight.

the class PartitionedLeadersElectionScenarioTest method setupInitialMemberBehaviors.

private void setupInitialMemberBehaviors() throws Exception {
    testLog.info("setupInitialMemberBehaviors starting");
    // Create member 2's behavior initially as Follower
    member2Context = newRaftActorContext("member2", member2ActorRef, ImmutableMap.<String, String>builder().put("member1", member1ActorRef.path().toString()).put("member3", member3ActorRef.path().toString()).build());
    DefaultConfigParamsImpl member2ConfigParams = newConfigParams();
    member2Context.setConfigParams(member2ConfigParams);
    member2Actor.self().tell(new SetBehavior(new Follower(member2Context), member2Context), ActorRef.noSender());
    // Create member 3's behavior initially as Follower
    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);
    member3Actor.self().tell(new SetBehavior(new Follower(member3Context), member3Context), ActorRef.noSender());
    // Create member 1's behavior initially as Leader
    member1Context = newRaftActorContext("member1", member1ActorRef, ImmutableMap.<String, String>builder().put("member2", member2ActorRef.path().toString()).put("member3", member3ActorRef.path().toString()).build());
    DefaultConfigParamsImpl member1ConfigParams = newConfigParams();
    member1Context.setConfigParams(member1ConfigParams);
    initializeLeaderBehavior(member1Actor, member1Context, 2);
    member2Actor.clear();
    member3Actor.clear();
    testLog.info("setupInitialMemberBehaviors ending");
}
Also used : DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl)

Aggregations

DefaultConfigParamsImpl (org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl)39 Test (org.junit.Test)31 MockRaftActorContext (org.opendaylight.controller.cluster.raft.MockRaftActorContext)31 FiniteDuration (scala.concurrent.duration.FiniteDuration)26 AppendEntriesReply (org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply)22 AppendEntries (org.opendaylight.controller.cluster.raft.messages.AppendEntries)17 SimpleReplicatedLogEntry (org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry)10 ByteString (com.google.protobuf.ByteString)8 ReplicatedLogEntry (org.opendaylight.controller.cluster.raft.ReplicatedLogEntry)7 InstallSnapshot (org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)6 Snapshot (org.opendaylight.controller.cluster.raft.persisted.Snapshot)6 HashMap (java.util.HashMap)5 FollowerLogInformation (org.opendaylight.controller.cluster.raft.FollowerLogInformation)4 RaftActorLeadershipTransferCohort (org.opendaylight.controller.cluster.raft.RaftActorLeadershipTransferCohort)4 ActorRef (akka.actor.ActorRef)3 TestActorRef (akka.testkit.TestActorRef)3 AtomicReference (java.util.concurrent.atomic.AtomicReference)3 MockRaftActor (org.opendaylight.controller.cluster.raft.MockRaftActor)3 Builder (org.opendaylight.controller.cluster.raft.MockRaftActor.Builder)3 RaftActorSnapshotCohort (org.opendaylight.controller.cluster.raft.RaftActorSnapshotCohort)3