use of com.hazelcast.cp.internal.RaftTestApplyOp in project hazelcast by hazelcast.
the class RaftSessionServiceTest method testSnapshotRestore.
@Test
public void testSnapshotRestore() throws ExecutionException, InterruptedException, UnknownHostException {
HazelcastInstance leader = getLeaderInstance(instances, groupId);
HazelcastInstance follower = getRandomFollowerInstance(instances, groupId);
// the follower falls behind the leader. It neither append entries nor installs snapshots.
dropOperationsBetween(leader, follower, RaftServiceDataSerializerHook.F_ID, asList(RaftServiceDataSerializerHook.APPEND_REQUEST_OP, RaftServiceDataSerializerHook.INSTALL_SNAPSHOT_OP));
SessionResponse response = invocationManager.<SessionResponse>invoke(groupId, newCreateSessionOp()).get();
spawn(() -> {
for (int i = 0; i < 30; i++) {
invocationManager.invoke(groupId, new HeartbeatSessionOp(response.getSessionId())).joinInternal();
sleepAtLeastSeconds(5);
}
});
for (int i = 0; i < LOG_ENTRY_COUNT_TO_SNAPSHOT; i++) {
invocationManager.invoke(groupId, new RaftTestApplyOp("value" + i)).get();
}
RaftNodeImpl leaderRaftNode = (RaftNodeImpl) ((RaftService) getNodeEngineImpl(leader).getService(RaftService.SERVICE_NAME)).getRaftNode(groupId);
RaftNodeImpl followerRaftNode = (RaftNodeImpl) ((RaftService) getNodeEngineImpl(follower).getService(RaftService.SERVICE_NAME)).getRaftNode(groupId);
// the leader takes a snapshot
long[] leaderSnapshotIndex = new long[1];
assertTrueEventually(() -> {
long idx = getSnapshotEntry(leaderRaftNode).index();
assertTrue(idx > 0);
leaderSnapshotIndex[0] = idx;
});
// the follower doesn't have it since its raft log is still empty
assertTrueAllTheTime(() -> assertEquals(0, getSnapshotEntry(followerRaftNode).index()), 10);
resetPacketFiltersFrom(leader);
// the follower installs the snapshot after it hears from the leader
assertTrueEventually(() -> assertTrue(getSnapshotEntry(followerRaftNode).index() > 0));
assertTrueEventually(() -> {
RaftSessionService sessionService = getNodeEngineImpl(follower).getService(RaftSessionService.SERVICE_NAME);
RaftSessionRegistry registry = sessionService.getSessionRegistryOrNull(groupId);
assertNotNull(registry.getSession(response.getSessionId()));
});
// the follower disconnects from the leader again
dropOperationsBetween(leader, follower, RaftServiceDataSerializerHook.F_ID, asList(RaftServiceDataSerializerHook.APPEND_REQUEST_OP, RaftServiceDataSerializerHook.INSTALL_SNAPSHOT_OP));
for (int i = 0; i < LOG_ENTRY_COUNT_TO_SNAPSHOT; i++) {
invocationManager.invoke(groupId, new HeartbeatSessionOp(response.getSessionId())).get();
}
// the leader takes a new snapshot
assertTrueEventually(() -> assertTrue(getSnapshotEntry(leaderRaftNode).index() > leaderSnapshotIndex[0]));
resetPacketFiltersFrom(leader);
// the follower installs the new snapshot after it hears from the leader
assertTrueEventually(() -> {
CPSessionInfo leaderSession = getSession(leader, groupId, response.getSessionId());
CPSessionInfo followerSession = getSession(follower, groupId, response.getSessionId());
assertNotNull(leaderSession);
assertNotNull(followerSession);
assertEquals(leaderSession.version(), followerSession.version());
});
}
Aggregations