use of org.opendaylight.controller.cluster.raft.MockRaftActorContext in project controller by opendaylight.
the class LeaderTest method testIsolatedLeaderCheckNoFollowers.
@Test
public void testIsolatedLeaderCheckNoFollowers() {
logStart("testIsolatedLeaderCheckNoFollowers");
MockRaftActorContext leaderActorContext = createActorContext();
leader = new Leader(leaderActorContext);
RaftActorBehavior newBehavior = leader.handleMessage(leaderActor, Leader.ISOLATED_LEADER_CHECK);
assertTrue(newBehavior instanceof Leader);
}
use of org.opendaylight.controller.cluster.raft.MockRaftActorContext 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);
}
use of org.opendaylight.controller.cluster.raft.MockRaftActorContext in project controller by opendaylight.
the class LeaderTest method testHandleRequestVoteReply.
@Test
public void testHandleRequestVoteReply() {
logStart("testHandleRequestVoteReply");
MockRaftActorContext leaderActorContext = createActorContext();
leader = new Leader(leaderActorContext);
// Should be a no-op.
RaftActorBehavior raftActorBehavior = leader.handleRequestVoteReply(followerActor, new RequestVoteReply(1, true));
assertEquals(RaftState.Leader, raftActorBehavior.state());
raftActorBehavior = leader.handleRequestVoteReply(followerActor, new RequestVoteReply(1, false));
assertEquals(RaftState.Leader, raftActorBehavior.state());
}
use of org.opendaylight.controller.cluster.raft.MockRaftActorContext 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());
}
use of org.opendaylight.controller.cluster.raft.MockRaftActorContext 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());
}
Aggregations