use of org.opendaylight.controller.cluster.raft.MockRaftActor.MockSnapshotState 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");
}
Aggregations