use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorTest method testGetSnapshot.
@Test
public void testGetSnapshot() throws Exception {
TEST_LOG.info("testGetSnapshot starting");
final TestKit kit = new TestKit(getSystem());
String persistenceId = factory.generateActorId("test-actor-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
long term = 3;
long seqN = 1;
InMemoryJournal.addEntry(persistenceId, seqN++, new UpdateElectionTerm(term, "member-1"));
InMemoryJournal.addEntry(persistenceId, seqN++, new SimpleReplicatedLogEntry(0, term, new MockRaftActorContext.MockPayload("A")));
InMemoryJournal.addEntry(persistenceId, seqN++, new SimpleReplicatedLogEntry(1, term, new MockRaftActorContext.MockPayload("B")));
InMemoryJournal.addEntry(persistenceId, seqN++, new ApplyJournalEntries(1));
InMemoryJournal.addEntry(persistenceId, seqN++, new SimpleReplicatedLogEntry(2, term, new MockRaftActorContext.MockPayload("C")));
TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, ImmutableMap.<String, String>builder().put("member1", "address").build(), config).withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
MockRaftActor mockRaftActor = raftActorRef.underlyingActor();
mockRaftActor.waitForRecoveryComplete();
mockRaftActor.snapshotCohortDelegate = mock(RaftActorSnapshotCohort.class);
raftActorRef.tell(GetSnapshot.INSTANCE, kit.getRef());
ArgumentCaptor<ActorRef> replyActor = ArgumentCaptor.forClass(ActorRef.class);
verify(mockRaftActor.snapshotCohortDelegate, timeout(5000)).createSnapshot(replyActor.capture(), eq(java.util.Optional.empty()));
byte[] stateSnapshot = new byte[] { 1, 2, 3 };
replyActor.getValue().tell(new CaptureSnapshotReply(ByteState.of(stateSnapshot), java.util.Optional.empty()), ActorRef.noSender());
GetSnapshotReply reply = kit.expectMsgClass(GetSnapshotReply.class);
assertEquals("getId", persistenceId, reply.getId());
Snapshot replySnapshot = reply.getSnapshot();
assertEquals("getElectionTerm", term, replySnapshot.getElectionTerm());
assertEquals("getElectionVotedFor", "member-1", replySnapshot.getElectionVotedFor());
assertEquals("getLastAppliedIndex", 1L, replySnapshot.getLastAppliedIndex());
assertEquals("getLastAppliedTerm", term, replySnapshot.getLastAppliedTerm());
assertEquals("getLastIndex", 2L, replySnapshot.getLastIndex());
assertEquals("getLastTerm", term, replySnapshot.getLastTerm());
assertEquals("getState", ByteState.of(stateSnapshot), replySnapshot.getState());
assertEquals("getUnAppliedEntries size", 1, replySnapshot.getUnAppliedEntries().size());
assertEquals("UnApplied entry index ", 2L, replySnapshot.getUnAppliedEntries().get(0).getIndex());
// Test with timeout
mockRaftActor.getSnapshotMessageSupport().setSnapshotReplyActorTimeout(Duration.create(200, TimeUnit.MILLISECONDS));
reset(mockRaftActor.snapshotCohortDelegate);
raftActorRef.tell(GetSnapshot.INSTANCE, kit.getRef());
Failure failure = kit.expectMsgClass(akka.actor.Status.Failure.class);
assertEquals("Failure cause type", TimeoutException.class, failure.cause().getClass());
mockRaftActor.getSnapshotMessageSupport().setSnapshotReplyActorTimeout(Duration.create(30, TimeUnit.SECONDS));
// Test with persistence disabled.
mockRaftActor.setPersistence(false);
reset(mockRaftActor.snapshotCohortDelegate);
raftActorRef.tell(GetSnapshot.INSTANCE, kit.getRef());
reply = kit.expectMsgClass(GetSnapshotReply.class);
verify(mockRaftActor.snapshotCohortDelegate, never()).createSnapshot(anyObject(), anyObject());
assertEquals("getId", persistenceId, reply.getId());
replySnapshot = reply.getSnapshot();
assertEquals("getElectionTerm", term, replySnapshot.getElectionTerm());
assertEquals("getElectionVotedFor", "member-1", replySnapshot.getElectionVotedFor());
assertEquals("getLastAppliedIndex", -1L, replySnapshot.getLastAppliedIndex());
assertEquals("getLastAppliedTerm", -1L, replySnapshot.getLastAppliedTerm());
assertEquals("getLastIndex", -1L, replySnapshot.getLastIndex());
assertEquals("getLastTerm", -1L, replySnapshot.getLastTerm());
assertEquals("getState type", EmptyState.INSTANCE, replySnapshot.getState());
assertEquals("getUnAppliedEntries size", 0, replySnapshot.getUnAppliedEntries().size());
TEST_LOG.info("testGetSnapshot ending");
}
use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testChangeToVotingWithNoLeaderAndOtherLeaderElected.
@Test
public void testChangeToVotingWithNoLeaderAndOtherLeaderElected() {
LOG.info("testChangeToVotingWithNoLeaderAndOtherLeaderElected starting");
DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
configParams.setHeartBeatInterval(new FiniteDuration(100, TimeUnit.MILLISECONDS));
configParams.setElectionTimeoutFactor(100000);
final String node1ID = "node1";
final String node2ID = "node2";
configParams.setPeerAddressResolver(peerId -> peerId.equals(node1ID) ? actorFactory.createTestActorPath(node1ID) : peerId.equals(node2ID) ? actorFactory.createTestActorPath(node2ID) : null);
ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(new ServerInfo(node1ID, false), new ServerInfo(node2ID, true)));
SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, 1, persistedServerConfig);
InMemoryJournal.addEntry(node1ID, 1, new UpdateElectionTerm(1, "node1"));
InMemoryJournal.addEntry(node1ID, 2, persistedServerConfigEntry);
InMemoryJournal.addEntry(node2ID, 1, new UpdateElectionTerm(1, "node1"));
InMemoryJournal.addEntry(node2ID, 2, persistedServerConfigEntry);
ActorRef node1Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
TestActorRef<CollectingMockRaftActor> node1RaftActorRef = actorFactory.createTestActor(CollectingMockRaftActor.props(node1ID, ImmutableMap.<String, String>of(), configParams, PERSISTENT, node1Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), node1ID);
final CollectingMockRaftActor node1RaftActor = node1RaftActorRef.underlyingActor();
ActorRef node2Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
TestActorRef<CollectingMockRaftActor> node2RaftActorRef = actorFactory.createTestActor(CollectingMockRaftActor.props(node2ID, ImmutableMap.<String, String>of(), configParams, PERSISTENT, node2Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), node2ID);
CollectingMockRaftActor node2RaftActor = node2RaftActorRef.underlyingActor();
// Send a ChangeServersVotingStatus message to node1 to change node1 to voting. This should cause
// node1 to try to elect itself as leader in order to apply the new server config. But we'll drop
// RequestVote messages in node2 and make it the leader so node1 should forward the server change
// request to node2 when node2 is elected.
node2RaftActor.setDropMessageOfType(RequestVote.class);
ChangeServersVotingStatus changeServers = new ChangeServersVotingStatus(ImmutableMap.of(node1ID, true, node2ID, true));
node1RaftActorRef.tell(changeServers, testKit.getRef());
MessageCollectorActor.expectFirstMatching(node2Collector, RequestVote.class);
node2RaftActorRef.tell(TimeoutNow.INSTANCE, ActorRef.noSender());
ServerChangeReply reply = testKit.expectMsgClass(testKit.duration("5 seconds"), ServerChangeReply.class);
assertEquals("getStatus", ServerChangeStatus.OK, reply.getStatus());
MessageCollectorActor.expectFirstMatching(node1Collector, ApplyJournalEntries.class);
verifyServerConfigurationPayloadEntry(node1RaftActor.getRaftActorContext().getReplicatedLog(), votingServer(node1ID), votingServer(node2ID));
assertEquals("isVotingMember", true, node1RaftActor.getRaftActorContext().isVotingMember());
assertEquals("getRaftState", RaftState.Follower, node1RaftActor.getRaftState());
MessageCollectorActor.expectFirstMatching(node2Collector, ApplyJournalEntries.class);
verifyServerConfigurationPayloadEntry(node2RaftActor.getRaftActorContext().getReplicatedLog(), votingServer(node1ID), votingServer(node2ID));
assertEquals("getRaftState", RaftState.Leader, node2RaftActor.getRaftState());
LOG.info("testChangeToVotingWithNoLeaderAndOtherLeaderElected ending");
}
use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServersAsNonVoting.
@Test
public void testAddServersAsNonVoting() throws Exception {
LOG.info("testAddServersAsNonVoting 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();
final ActorRef leaderCollectorActor = newLeaderCollectorActor(leaderRaftActor);
leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), false), testKit.getRef());
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);
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), nonVotingServer(NEW_SERVER_ID));
// Verify ServerConfigurationPayload entry in the new follower
expectFirstMatching(newFollowerCollectorActor, ApplyState.class);
assertEquals("New follower journal last index", 0, newFollowerActorContext.getReplicatedLog().lastIndex());
verifyServerConfigurationPayloadEntry(newFollowerActorContext.getReplicatedLog(), votingServer(LEADER_ID), nonVotingServer(NEW_SERVER_ID));
// Verify new server config was applied in the new follower
assertEquals("New follower peers", Sets.newHashSet(LEADER_ID), newFollowerActorContext.getPeerIds());
assertNoneMatching(newFollowerCollectorActor, InstallSnapshot.class, 500);
// Add another non-voting server.
clearMessages(leaderCollectorActor);
RaftActorContext follower2ActorContext = newFollowerContext(NEW_SERVER_ID2, followerActor);
Follower newFollower2 = new Follower(follower2ActorContext);
followerActor.underlyingActor().setBehavior(newFollower2);
leaderActor.tell(new AddServer(NEW_SERVER_ID2, followerActor.path().toString(), false), testKit.getRef());
addServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), AddServerReply.class);
assertEquals("getStatus", ServerChangeStatus.OK, addServerReply.getStatus());
assertEquals("getLeaderHint", java.util.Optional.of(LEADER_ID), addServerReply.getLeaderHint());
expectFirstMatching(leaderCollectorActor, ApplyState.class);
assertEquals("Leader journal last index", 1, leaderActorContext.getReplicatedLog().lastIndex());
assertEquals("Leader commit index", 1, leaderActorContext.getCommitIndex());
assertEquals("Leader last applied index", 1, leaderActorContext.getLastApplied());
verifyServerConfigurationPayloadEntry(leaderActorContext.getReplicatedLog(), votingServer(LEADER_ID), nonVotingServer(NEW_SERVER_ID), nonVotingServer(NEW_SERVER_ID2));
LOG.info("testAddServersAsNonVoting ending");
}
use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testRemoveServer.
@Test
public void testRemoveServer() throws Exception {
LOG.info("testRemoveServer starting");
DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
configParams.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
configParams.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
final String follower1ActorId = actorFactory.generateActorId(FOLLOWER_ID);
final String follower1ActorPath = actorFactory.createTestActorPath(follower1ActorId);
final String follower2ActorId = actorFactory.generateActorId(FOLLOWER_ID2);
final String follower2ActorPath = actorFactory.createTestActorPath(follower2ActorId);
RaftActorContext initialActorContext = new MockRaftActorContext();
final String downNodeId = "downNode";
TestActorRef<MockLeaderRaftActor> leaderActor = actorFactory.createTestActor(MockLeaderRaftActor.props(ImmutableMap.of(FOLLOWER_ID, follower1ActorPath, FOLLOWER_ID2, follower2ActorPath, downNodeId, ""), initialActorContext).withDispatcher(Dispatchers.DefaultDispatcherId()), actorFactory.generateActorId(LEADER_ID));
final ActorRef leaderCollector = newLeaderCollectorActor(leaderActor.underlyingActor());
ActorRef follower1Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
final TestActorRef<CollectingMockRaftActor> follower1Actor = actorFactory.createTestActor(CollectingMockRaftActor.props(FOLLOWER_ID, ImmutableMap.of(LEADER_ID, leaderActor.path().toString(), FOLLOWER_ID2, follower2ActorPath, downNodeId, ""), configParams, NO_PERSISTENCE, follower1Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), follower1ActorId);
ActorRef follower2Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
final TestActorRef<CollectingMockRaftActor> follower2Actor = actorFactory.createTestActor(CollectingMockRaftActor.props(FOLLOWER_ID2, ImmutableMap.of(LEADER_ID, leaderActor.path().toString(), FOLLOWER_ID, follower1ActorPath, downNodeId, ""), configParams, NO_PERSISTENCE, follower2Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), follower2ActorId);
leaderActor.underlyingActor().waitForInitializeBehaviorComplete();
follower1Actor.underlyingActor().waitForInitializeBehaviorComplete();
follower2Actor.underlyingActor().waitForInitializeBehaviorComplete();
leaderActor.tell(new RemoveServer(FOLLOWER_ID), testKit.getRef());
RemoveServerReply removeServerReply = testKit.expectMsgClass(testKit.duration("5 seconds"), RemoveServerReply.class);
assertEquals("getStatus", ServerChangeStatus.OK, removeServerReply.getStatus());
ApplyState applyState = MessageCollectorActor.expectFirstMatching(leaderCollector, ApplyState.class);
assertEquals(0L, applyState.getReplicatedLogEntry().getIndex());
verifyServerConfigurationPayloadEntry(leaderActor.underlyingActor().getRaftActorContext().getReplicatedLog(), votingServer(LEADER_ID), votingServer(FOLLOWER_ID2), votingServer(downNodeId));
applyState = MessageCollectorActor.expectFirstMatching(follower2Collector, ApplyState.class);
assertEquals(0L, applyState.getReplicatedLogEntry().getIndex());
verifyServerConfigurationPayloadEntry(leaderActor.underlyingActor().getRaftActorContext().getReplicatedLog(), votingServer(LEADER_ID), votingServer(FOLLOWER_ID2), votingServer(downNodeId));
RaftActorBehavior currentBehavior = leaderActor.underlyingActor().getCurrentBehavior();
assertTrue("Expected Leader", currentBehavior instanceof Leader);
assertEquals("Follower ids size", 2, ((Leader) currentBehavior).getFollowerIds().size());
MessageCollectorActor.expectFirstMatching(follower1Collector, ServerRemoved.class);
LOG.info("testRemoveServer ending");
}
use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorServerConfigurationSupportTest method testAddServerWithLeaderChangeBeforePriorSnapshotComplete.
@Test
public void testAddServerWithLeaderChangeBeforePriorSnapshotComplete() throws Exception {
LOG.info("testAddServerWithLeaderChangeBeforePriorSnapshotComplete 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(100);
final ActorRef leaderCollectorActor = newLeaderCollectorActor(leaderRaftActor);
// Drop the commit message so the snapshot doesn't complete yet.
leaderRaftActor.setDropMessageOfType(COMMIT_MESSAGE_CLASS);
leaderActor.tell(new InitiateCaptureSnapshot(), leaderActor);
leaderActor.tell(new AddServer(NEW_SERVER_ID, newFollowerRaftActor.path().toString(), true), testKit.getRef());
Object commitMsg = expectFirstMatching(leaderCollectorActor, COMMIT_MESSAGE_CLASS);
// Change the leader behavior to follower
leaderActor.tell(new Follower(leaderActorContext), leaderActor);
// Drop CaptureSnapshotReply in case install snapshot is incorrectly initiated after the prior
// snapshot completes. This will prevent the invalid snapshot from completing and fail the
// isCapturing assertion below.
leaderRaftActor.setDropMessageOfType(CaptureSnapshotReply.class);
// Complete the prior snapshot - this should be a no-op b/c it's no longer the leader
leaderActor.tell(commitMsg, leaderActor);
leaderActor.tell(new RaftActorServerConfigurationSupport.ServerOperationTimeout(NEW_SERVER_ID), 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());
assertEquals("isCapturing", false, leaderActorContext.getSnapshotManager().isCapturing());
LOG.info("testAddServerWithLeaderChangeBeforePriorSnapshotComplete ending");
}
Aggregations