Search in sources :

Example 11 with AddServerReply

use of org.opendaylight.controller.cluster.raft.messages.AddServerReply 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");
}
Also used : ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) UnInitializedFollowerSnapshotReply(org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply) Follower(org.opendaylight.controller.cluster.raft.behaviors.Follower) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) Test(org.junit.Test)

Example 12 with AddServerReply

use of org.opendaylight.controller.cluster.raft.messages.AddServerReply 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");
}
Also used : InitiateCaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) Test(org.junit.Test)

Example 13 with AddServerReply

use of org.opendaylight.controller.cluster.raft.messages.AddServerReply 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");
}
Also used : ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) ApplySnapshot(org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot) Follower(org.opendaylight.controller.cluster.raft.behaviors.Follower) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) Test(org.junit.Test)

Example 14 with AddServerReply

use of org.opendaylight.controller.cluster.raft.messages.AddServerReply 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");
}
Also used : InitiateCaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) Test(org.junit.Test)

Example 15 with AddServerReply

use of org.opendaylight.controller.cluster.raft.messages.AddServerReply in project controller by opendaylight.

the class RaftActorServerConfigurationSupportTest method testAddServerWithInstallSnapshotTimeout.

@Test
public void testAddServerWithInstallSnapshotTimeout() throws Exception {
    LOG.info("testAddServerWithInstallSnapshotTimeout 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 the InstallSnapshot message so it times out
    newFollowerRaftActor.underlyingActor().setDropMessageOfType(InstallSnapshot.class);
    leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
    leaderActor.tell(new UnInitializedFollowerSnapshotReply("bogus"), leaderActor);
    AddServerReply addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
    assertEquals("getStatus", ServerChangeStatus.TIMEOUT, addServerReply.getStatus());
    assertEquals("Leader peers size", 0, leaderActorContext.getPeerIds().size());
    assertEquals("Leader followers size", 0, ((AbstractLeader) leaderRaftActor.getCurrentBehavior()).getFollowerIds().size());
    LOG.info("testAddServerWithInstallSnapshotTimeout ending");
}
Also used : UnInitializedFollowerSnapshotReply(org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply) AbstractLeader(org.opendaylight.controller.cluster.raft.behaviors.AbstractLeader) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) Test(org.junit.Test)

Aggregations

Test (org.junit.Test)16 AddServerReply (org.opendaylight.controller.cluster.raft.messages.AddServerReply)16 AddServer (org.opendaylight.controller.cluster.raft.messages.AddServer)15 ActorRef (akka.actor.ActorRef)11 TestActorRef (akka.testkit.TestActorRef)11 TestKit (akka.testkit.javadsl.TestKit)5 Follower (org.opendaylight.controller.cluster.raft.behaviors.Follower)5 AddressFromURIString (akka.actor.AddressFromURIString)4 AbstractShardManagerTest (org.opendaylight.controller.cluster.datastore.AbstractShardManagerTest)4 AddShardReplica (org.opendaylight.controller.cluster.datastore.messages.AddShardReplica)4 UpdateSchemaContext (org.opendaylight.controller.cluster.datastore.messages.UpdateSchemaContext)4 Failure (akka.actor.Status.Failure)3 MockConfiguration (org.opendaylight.controller.cluster.datastore.utils.MockConfiguration)3 InitiateCaptureSnapshot (org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot)3 Status (akka.actor.Status)2 ActorInitialized (org.opendaylight.controller.cluster.datastore.messages.ActorInitialized)2 ChangeShardMembersVotingStatus (org.opendaylight.controller.cluster.datastore.messages.ChangeShardMembersVotingStatus)2 FindLocalShard (org.opendaylight.controller.cluster.datastore.messages.FindLocalShard)2 ShardLeaderStateChanged (org.opendaylight.controller.cluster.datastore.messages.ShardLeaderStateChanged)2 ShardManagerSnapshot (org.opendaylight.controller.cluster.datastore.persisted.ShardManagerSnapshot)2