use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServerWithLeaderChangeDuringInstallSnapshot.
@Test
public void testAddServerWithLeaderChangeDuringInstallSnapshot() throws Exception {
LOG.info("testAddServerWithLeaderChangeDuringInstallSnapshot starting");
setupNewFollower();
RaftActorContext initialActorContext = new MockRaftActorContext();
TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.<String, String>of(), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
MockLeaderRaftActor leaderRaftActor = leaderActor.underlyingActor();
RaftActorContext leaderActorContext = leaderRaftActor.getRaftActorContext();
((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setElectionTimeoutFactor(8);
ActorRef leaderCollectorActor = newLeaderCollectorActor(leaderRaftActor);
// Drop the UnInitializedFollowerSnapshotReply to delay it.
leaderRaftActor.setDropMessageOfType(UnInitializedFollowerSnapshotReply.class);
leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
final UnInitializedFollowerSnapshotReply snapshotReply = expectFirstMatching(leaderCollectorActor, UnInitializedFollowerSnapshotReply.class);
// Prevent election timeout when the leader switches to follower
((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setElectionTimeoutFactor(100);
// Change the leader behavior to follower
leaderActor.tell(new Follower(leaderActorContext), leaderActor);
// Send the captured UnInitializedFollowerSnapshotReply - should be a no-op
leaderRaftActor.setDropMessageOfType(null);
leaderActor.tell(snapshotReply, leaderActor);
AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
assertEquals("getStatus", ServerChangeStatus.NO_LEADER, addServerReply.getStatus());
assertEquals("Leader peers size", 0, leaderActorContext.getPeerIds().size());
LOG.info("testAddServerWithLeaderChangeDuringInstallSnapshot ending");
}
use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServerWithPriorSnapshotCompleteTimeout.
@Test
public void testAddServerWithPriorSnapshotCompleteTimeout() throws Exception {
LOG.info("testAddServerWithPriorSnapshotCompleteTimeout starting");
setupNewFollower();
RaftActorContext initialActorContext = new MockRaftActorContext();
TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.<String, String>of(), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
MockLeaderRaftActor leaderRaftActor = leaderActor.underlyingActor();
RaftActorContext leaderActorContext = leaderRaftActor.getRaftActorContext();
((DefaultConfigParamsImpl) leaderActorContext.getConfigParams()).setElectionTimeoutFactor(1);
// Drop commit message so the snapshot doesn't complete.
leaderRaftActor.setDropMessageOfType(COMMIT_MESSAGE_CLASS);
leaderActor.tell(new InitiateCaptureSnapshot(), leaderActor);
leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
assertEquals("getStatus", ServerChangeStatus.TIMEOUT, addServerReply.getStatus());
assertEquals("Leader peers size", 0, leaderActorContext.getPeerIds().size());
LOG.info("testAddServerWithPriorSnapshotCompleteTimeout ending");
}
use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServerForwardedToLeader.
@Test
public void testAddServerForwardedToLeader() {
LOG.info("testAddServerForwardedToLeader starting");
setupNewFollower();
DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
configParams.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
ActorRef leaderActor = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId(LEADER_ID));
TestActorRef<MockRaftActor> followerRaftActor = actorFactory.createTestActor(MockRaftActor.builder().id(FOLLOWER_ID).peerAddresses(ImmutableMap.of(LEADER_ID, leaderActor.path().toString())).config(configParams).persistent(Optional.of(false)).props().withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(FOLLOWER_ID));
followerRaftActor.underlyingActor().waitForInitializeBehaviorComplete();
followerRaftActor.tell(new AppendEntries(1, LEADER_ID, 0, 1, Collections.<ReplicatedLogEntry>emptyList(), -1, -1, (short) 0), leaderActor);
followerRaftActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
expectFirstMatching(leaderActor, AddServer.class);
LOG.info("testAddServerForwardedToLeader ending");
}
use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServerWithExistingFollower.
@Test
public void testAddServerWithExistingFollower() throws Exception {
LOG.info("testAddServerWithExistingFollower starting");
setupNewFollower();
RaftActorContextImpl followerActorContext = newFollowerContext(FOLLOWER_ID, followerActor);
followerActorContext.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 3, 1).build());
followerActorContext.setCommitIndex(2);
followerActorContext.setLastApplied(2);
Follower follower = new Follower(followerActorContext);
followerActor.underlyingActor().setBehavior(follower);
followerActorContext.setCurrentBehavior(follower);
TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.of(FOLLOWER_ID, followerActor.path().toString()), followerActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
// Expect initial heartbeat from the leader.
expectFirstMatching(followerActor, AppendEntries.class);
clearMessages(followerActor);
MockLeaderRaftActor leaderRaftActor = leaderActor.underlyingActor();
final ActorRef leaderCollectorActor = newLeaderCollectorActor(leaderRaftActor);
leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
// Leader should install snapshot - capture and verify ApplySnapshot contents
ApplySnapshot applySnapshot = expectFirstMatching(newFollowerCollectorActor, ApplySnapshot.class);
List<Object> snapshotState = MockRaftActor.fromState(applySnapshot.getSnapshot().getState());
assertEquals("Snapshot state", snapshotState, leaderRaftActor.getState());
AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
assertEquals("getStatus", ServerChangeStatus.OK, addServerReply.getStatus());
assertEquals("getLeaderHint", LEADER_ID, addServerReply.getLeaderHint().get());
// Verify ServerConfigurationPayload entry in leader's log
expectFirstMatching(leaderCollectorActor, ApplyState.class);
RaftActorContext leaderActorContext = leaderRaftActor.getRaftActorContext();
assertEquals("Leader journal last index", 3, leaderActorContext.getReplicatedLog().lastIndex());
assertEquals("Leader commit index", 3, leaderActorContext.getCommitIndex());
assertEquals("Leader last applied index", 3, leaderActorContext.getLastApplied());
verifyServerConfigurationPayloadEntry(leaderActorContext.getReplicatedLog(), votingServer(LEADER_ID), votingServer(FOLLOWER_ID), votingServer(NEW_SERVER_ID));
// Verify ServerConfigurationPayload entry in both followers
expectFirstMatching(followerActor, ApplyState.class);
assertEquals("Follower journal last index", 3, followerActorContext.getReplicatedLog().lastIndex());
verifyServerConfigurationPayloadEntry(followerActorContext.getReplicatedLog(), votingServer(LEADER_ID), votingServer(FOLLOWER_ID), votingServer(NEW_SERVER_ID));
expectFirstMatching(newFollowerCollectorActor, ApplyState.class);
assertEquals("New follower journal last index", 3, newFollowerActorContext.getReplicatedLog().lastIndex());
verifyServerConfigurationPayloadEntry(newFollowerActorContext.getReplicatedLog(), votingServer(LEADER_ID), votingServer(FOLLOWER_ID), votingServer(NEW_SERVER_ID));
// Verify new server config was applied in both followers
assertEquals("Follower peers", Sets.newHashSet(LEADER_ID, NEW_SERVER_ID), followerActorContext.getPeerIds());
assertEquals("New follower peers", Sets.newHashSet(LEADER_ID, FOLLOWER_ID), newFollowerActorContext.getPeerIds());
assertEquals("Follower commit index", 3, followerActorContext.getCommitIndex());
assertEquals("Follower last applied index", 3, followerActorContext.getLastApplied());
assertEquals("New follower commit index", 3, newFollowerActorContext.getCommitIndex());
assertEquals("New follower last applied index", 3, newFollowerActorContext.getLastApplied());
assertEquals("Leader persisted ReplicatedLogImplEntry entries", 0, InMemoryJournal.get(LEADER_ID, SimpleReplicatedLogEntry.class).size());
assertEquals("Leader persisted ServerConfigurationPayload entries", 1, InMemoryJournal.get(LEADER_ID, ServerConfigurationPayload.class).size());
assertEquals("New follower persisted ReplicatedLogImplEntry entries", 0, InMemoryJournal.get(NEW_SERVER_ID, SimpleReplicatedLogEntry.class).size());
assertEquals("New follower persisted ServerConfigurationPayload entries", 1, InMemoryJournal.get(NEW_SERVER_ID, ServerConfigurationPayload.class).size());
LOG.info("testAddServerWithExistingFollower ending");
}
use of org.opendaylight.controller.cluster.raft.messages.AddServer in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServerWithPriorSnapshotInProgress.
@Test
public void testAddServerWithPriorSnapshotInProgress() throws Exception {
LOG.info("testAddServerWithPriorSnapshotInProgress starting");
setupNewFollower();
RaftActorContext initialActorContext = new MockRaftActorContext();
TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.<String, String>of(), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
MockLeaderRaftActor leaderRaftActor = leaderActor.underlyingActor();
final RaftActorContext leaderActorContext = leaderRaftActor.getRaftActorContext();
ActorRef leaderCollectorActor = newLeaderCollectorActor(leaderRaftActor);
// Drop commit message for now to delay snapshot completion
leaderRaftActor.setDropMessageOfType(String.class);
leaderActor.tell(new InitiateCaptureSnapshot(), leaderActor);
Object commitMsg = expectFirstMatching(leaderCollectorActor, COMMIT_MESSAGE_CLASS);
leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
leaderRaftActor.setDropMessageOfType(null);
leaderActor.tell(commitMsg, leaderActor);
AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
assertEquals("getStatus", ServerChangeStatus.OK, addServerReply.getStatus());
assertEquals("getLeaderHint", LEADER_ID, addServerReply.getLeaderHint().get());
expectFirstMatching(newFollowerCollectorActor, ApplySnapshot.class);
// Verify ServerConfigurationPayload entry in leader's log
expectFirstMatching(leaderCollectorActor, ApplyState.class);
assertEquals("Leader journal last index", 0, leaderActorContext.getReplicatedLog().lastIndex());
assertEquals("Leader commit index", 0, leaderActorContext.getCommitIndex());
assertEquals("Leader last applied index", 0, leaderActorContext.getLastApplied());
verifyServerConfigurationPayloadEntry(leaderActorContext.getReplicatedLog(), votingServer(LEADER_ID), votingServer(NEW_SERVER_ID));
LOG.info("testAddServerWithPriorSnapshotInProgress ending");
}
Aggregations