use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorTest method testRaftActorRecoveryWithPersistenceEnabled.
@Test
public void testRaftActorRecoveryWithPersistenceEnabled() throws Exception {
TEST_LOG.info("testRaftActorRecoveryWithPersistenceEnabled starting");
TestKit kit = new TestKit(getSystem());
String persistenceId = factory.generateActorId("follower-");
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
// Set the heartbeat interval high to essentially disable election otherwise the test
// may fail if the actor is switched to Leader and the commitIndex is set to the last
// log entry.
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
ImmutableMap<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
ActorRef followerActor = factory.createActor(MockRaftActor.props(persistenceId, peerAddresses, config), persistenceId);
kit.watch(followerActor);
List<ReplicatedLogEntry> snapshotUnappliedEntries = new ArrayList<>();
ReplicatedLogEntry entry1 = new SimpleReplicatedLogEntry(4, 1, new MockRaftActorContext.MockPayload("E"));
snapshotUnappliedEntries.add(entry1);
int lastAppliedDuringSnapshotCapture = 3;
int lastIndexDuringSnapshotCapture = 4;
// 4 messages as part of snapshot, which are applied to state
MockSnapshotState snapshotState = new MockSnapshotState(Arrays.asList(new MockRaftActorContext.MockPayload("A"), new MockRaftActorContext.MockPayload("B"), new MockRaftActorContext.MockPayload("C"), new MockRaftActorContext.MockPayload("D")));
Snapshot snapshot = Snapshot.create(snapshotState, snapshotUnappliedEntries, lastIndexDuringSnapshotCapture, 1, lastAppliedDuringSnapshotCapture, 1, -1, null, null);
InMemorySnapshotStore.addSnapshot(persistenceId, snapshot);
// add more entries after snapshot is taken
List<ReplicatedLogEntry> entries = new ArrayList<>();
ReplicatedLogEntry entry2 = new SimpleReplicatedLogEntry(5, 1, new MockRaftActorContext.MockPayload("F", 2));
ReplicatedLogEntry entry3 = new SimpleReplicatedLogEntry(6, 1, new MockRaftActorContext.MockPayload("G", 3));
ReplicatedLogEntry entry4 = new SimpleReplicatedLogEntry(7, 1, new MockRaftActorContext.MockPayload("H", 4));
entries.add(entry2);
entries.add(entry3);
entries.add(entry4);
final int lastAppliedToState = 5;
final int lastIndex = 7;
InMemoryJournal.addEntry(persistenceId, 5, entry2);
// 2 entries are applied to state besides the 4 entries in snapshot
InMemoryJournal.addEntry(persistenceId, 6, new ApplyJournalEntries(lastAppliedToState));
InMemoryJournal.addEntry(persistenceId, 7, entry3);
InMemoryJournal.addEntry(persistenceId, 8, entry4);
// kill the actor
followerActor.tell(PoisonPill.getInstance(), null);
kit.expectMsgClass(kit.duration("5 seconds"), Terminated.class);
kit.unwatch(followerActor);
// reinstate the actor
TestActorRef<MockRaftActor> ref = factory.createTestActor(MockRaftActor.props(persistenceId, peerAddresses, config));
MockRaftActor mockRaftActor = ref.underlyingActor();
mockRaftActor.waitForRecoveryComplete();
RaftActorContext context = mockRaftActor.getRaftActorContext();
assertEquals("Journal log size", snapshotUnappliedEntries.size() + entries.size(), context.getReplicatedLog().size());
assertEquals("Journal data size", 10, context.getReplicatedLog().dataSize());
assertEquals("Last index", lastIndex, context.getReplicatedLog().lastIndex());
assertEquals("Last applied", lastAppliedToState, context.getLastApplied());
assertEquals("Commit index", lastAppliedToState, context.getCommitIndex());
assertEquals("Recovered state size", 6, mockRaftActor.getState().size());
mockRaftActor.waitForInitializeBehaviorComplete();
assertEquals("getRaftState", RaftState.Follower, mockRaftActor.getRaftState());
TEST_LOG.info("testRaftActorRecoveryWithPersistenceEnabled ending");
}
use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorTest method testLeaderTransitioning.
@Test
public void testLeaderTransitioning() throws Exception {
TEST_LOG.info("testLeaderTransitioning starting");
ActorRef notifierActor = factory.createActor(MessageCollectorActor.props());
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
String persistenceId = factory.generateActorId("test-actor-");
TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.builder().id(persistenceId).config(config).roleChangeNotifier(notifierActor).props().withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
MockRaftActor mockRaftActor = raftActorRef.underlyingActor();
mockRaftActor.waitForInitializeBehaviorComplete();
raftActorRef.tell(new AppendEntries(1L, "leader", 0L, 1L, Collections.<ReplicatedLogEntry>emptyList(), 0L, -1L, (short) 1), ActorRef.noSender());
LeaderStateChanged leaderStateChange = MessageCollectorActor.expectFirstMatching(notifierActor, LeaderStateChanged.class);
assertEquals("getLeaderId", "leader", leaderStateChange.getLeaderId());
MessageCollectorActor.clearMessages(notifierActor);
raftActorRef.tell(new LeaderTransitioning("leader"), ActorRef.noSender());
leaderStateChange = MessageCollectorActor.expectFirstMatching(notifierActor, LeaderStateChanged.class);
assertEquals("getMemberId", persistenceId, leaderStateChange.getMemberId());
assertEquals("getLeaderId", null, leaderStateChange.getLeaderId());
TEST_LOG.info("testLeaderTransitioning ending");
}
use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorTest method testReplicateWithBatchHint.
@Test
public void testReplicateWithBatchHint() throws Exception {
final String leaderId = factory.generateActorId("leader-");
final String followerId = factory.generateActorId("follower-");
final ActorRef followerActor = factory.createActor(MessageCollectorActor.props());
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
TestActorRef<MockRaftActor> leaderActorRef = factory.createTestActor(MockRaftActor.props(leaderId, ImmutableMap.of(followerId, followerActor.path().toString()), config), leaderId);
MockRaftActor leaderActor = leaderActorRef.underlyingActor();
leaderActor.waitForInitializeBehaviorComplete();
leaderActor.getRaftActorContext().getTermInformation().update(1, leaderId);
Leader leader = new Leader(leaderActor.getRaftActorContext());
leaderActor.setCurrentBehavior(leader);
MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
MessageCollectorActor.clearMessages(followerActor);
leaderActor.onReceiveCommand(new AppendEntriesReply(followerId, 1, true, -1, -1, (short) 0));
leaderActor.persistData(leaderActorRef, new MockIdentifier("1"), new MockPayload("1"), true);
MessageCollectorActor.assertNoneMatching(followerActor, AppendEntries.class, 500);
leaderActor.persistData(leaderActorRef, new MockIdentifier("2"), new MockPayload("2"), true);
MessageCollectorActor.assertNoneMatching(followerActor, AppendEntries.class, 500);
leaderActor.persistData(leaderActorRef, new MockIdentifier("3"), new MockPayload("3"), false);
AppendEntries appendEntries = MessageCollectorActor.expectFirstMatching(followerActor, AppendEntries.class);
assertEquals("AppendEntries size", 3, appendEntries.getEntries().size());
}
use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorTest method testRaftRoleChangeNotifierWhenRaftActorHasNoPeers.
@Test
public void testRaftRoleChangeNotifierWhenRaftActorHasNoPeers() throws Exception {
ActorRef notifierActor = factory.createActor(MessageCollectorActor.props());
MessageCollectorActor.waitUntilReady(notifierActor);
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
long heartBeatInterval = 100;
config.setHeartBeatInterval(FiniteDuration.create(heartBeatInterval, TimeUnit.MILLISECONDS));
config.setElectionTimeoutFactor(20);
String persistenceId = factory.generateActorId("notifier-");
final TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.builder().id(persistenceId).config(config).roleChangeNotifier(notifierActor).dataPersistenceProvider(createProvider()).props().withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
List<RoleChanged> matches = MessageCollectorActor.expectMatching(notifierActor, RoleChanged.class, 3);
// check if the notifier got a role change from null to Follower
RoleChanged raftRoleChanged = matches.get(0);
assertEquals(persistenceId, raftRoleChanged.getMemberId());
assertNull(raftRoleChanged.getOldRole());
assertEquals(RaftState.Follower.name(), raftRoleChanged.getNewRole());
// check if the notifier got a role change from Follower to Candidate
raftRoleChanged = matches.get(1);
assertEquals(persistenceId, raftRoleChanged.getMemberId());
assertEquals(RaftState.Follower.name(), raftRoleChanged.getOldRole());
assertEquals(RaftState.Candidate.name(), raftRoleChanged.getNewRole());
// check if the notifier got a role change from Candidate to Leader
raftRoleChanged = matches.get(2);
assertEquals(persistenceId, raftRoleChanged.getMemberId());
assertEquals(RaftState.Candidate.name(), raftRoleChanged.getOldRole());
assertEquals(RaftState.Leader.name(), raftRoleChanged.getNewRole());
LeaderStateChanged leaderStateChange = MessageCollectorActor.expectFirstMatching(notifierActor, LeaderStateChanged.class);
assertEquals(raftRoleChanged.getMemberId(), leaderStateChange.getLeaderId());
assertEquals(MockRaftActor.PAYLOAD_VERSION, leaderStateChange.getLeaderPayloadVersion());
MessageCollectorActor.clearMessages(notifierActor);
MockRaftActor raftActor = raftActorRef.underlyingActor();
final String newLeaderId = "new-leader";
final short newLeaderVersion = 6;
Follower follower = new Follower(raftActor.getRaftActorContext()) {
@Override
public RaftActorBehavior handleMessage(final ActorRef sender, final Object message) {
setLeaderId(newLeaderId);
setLeaderPayloadVersion(newLeaderVersion);
return this;
}
};
raftActor.newBehavior(follower);
leaderStateChange = MessageCollectorActor.expectFirstMatching(notifierActor, LeaderStateChanged.class);
assertEquals(persistenceId, leaderStateChange.getMemberId());
assertEquals(null, leaderStateChange.getLeaderId());
raftRoleChanged = MessageCollectorActor.expectFirstMatching(notifierActor, RoleChanged.class);
assertEquals(RaftState.Leader.name(), raftRoleChanged.getOldRole());
assertEquals(RaftState.Follower.name(), raftRoleChanged.getNewRole());
MessageCollectorActor.clearMessages(notifierActor);
raftActor.handleCommand("any");
leaderStateChange = MessageCollectorActor.expectFirstMatching(notifierActor, LeaderStateChanged.class);
assertEquals(persistenceId, leaderStateChange.getMemberId());
assertEquals(newLeaderId, leaderStateChange.getLeaderId());
assertEquals(newLeaderVersion, leaderStateChange.getLeaderPayloadVersion());
MessageCollectorActor.clearMessages(notifierActor);
raftActor.handleCommand("any");
Uninterruptibles.sleepUninterruptibly(505, TimeUnit.MILLISECONDS);
leaderStateChange = MessageCollectorActor.getFirstMatching(notifierActor, LeaderStateChanged.class);
assertNull(leaderStateChange);
}
use of akka.testkit.TestActorRef in project controller by opendaylight.
the class RaftActorTest method testReplicateWithPersistencePending.
@SuppressWarnings({ "unchecked", "rawtypes" })
@Test
public void testReplicateWithPersistencePending() throws Exception {
final String leaderId = factory.generateActorId("leader-");
final String followerId = factory.generateActorId("follower-");
final ActorRef followerActor = factory.createActor(MessageCollectorActor.props());
DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
config.setIsolatedLeaderCheckInterval(new FiniteDuration(1, TimeUnit.DAYS));
DataPersistenceProvider mockPersistenceProvider = mock(DataPersistenceProvider.class);
doReturn(true).when(mockPersistenceProvider).isRecoveryApplicable();
TestActorRef<MockRaftActor> leaderActorRef = factory.createTestActor(MockRaftActor.props(leaderId, ImmutableMap.of(followerId, followerActor.path().toString()), config, mockPersistenceProvider), leaderId);
MockRaftActor leaderActor = leaderActorRef.underlyingActor();
leaderActor.waitForInitializeBehaviorComplete();
leaderActor.getRaftActorContext().getTermInformation().update(1, leaderId);
Leader leader = new Leader(leaderActor.getRaftActorContext());
leaderActor.setCurrentBehavior(leader);
leaderActor.persistData(leaderActorRef, new MockIdentifier("1"), new MockRaftActorContext.MockPayload("1"), false);
ReplicatedLogEntry logEntry = leaderActor.getReplicatedLog().get(0);
assertNotNull("ReplicatedLogEntry not found", logEntry);
assertEquals("isPersistencePending", true, logEntry.isPersistencePending());
assertEquals("getCommitIndex", -1, leaderActor.getRaftActorContext().getCommitIndex());
leaderActor.onReceiveCommand(new AppendEntriesReply(followerId, 1, true, 0, 1, (short) 0));
assertEquals("getCommitIndex", -1, leaderActor.getRaftActorContext().getCommitIndex());
ArgumentCaptor<Procedure> callbackCaptor = ArgumentCaptor.forClass(Procedure.class);
verify(mockPersistenceProvider).persistAsync(eq(logEntry), callbackCaptor.capture());
callbackCaptor.getValue().apply(logEntry);
assertEquals("getCommitIndex", 0, leaderActor.getRaftActorContext().getCommitIndex());
assertEquals("getLastApplied", 0, leaderActor.getRaftActorContext().getLastApplied());
}
Aggregations