import static org.mockito.Mockito.mock;
import akka.actor.ActorRef;
import akka.actor.Props;
-import akka.japi.Creator;
import com.google.common.base.Optional;
import com.google.common.util.concurrent.Uninterruptibles;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.ObjectInputStream;
import java.util.ArrayList;
+import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CountDownLatch;
volatile RaftActorSnapshotCohort snapshotCohortDelegate;
private final CountDownLatch recoveryComplete = new CountDownLatch(1);
private final List<Object> state;
- private ActorRef roleChangeNotifier;
+ private final ActorRef roleChangeNotifier;
protected final CountDownLatch initializeBehaviorComplete = new CountDownLatch(1);
private RaftActorRecoverySupport raftActorRecoverySupport;
private RaftActorSnapshotMessageSupport snapshotMessageSupport;
+ private final byte[] restoreFromSnapshot;
+ final CountDownLatch snapshotCommitted = new CountDownLatch(1);
- public static final class MockRaftActorCreator implements Creator<MockRaftActor> {
- private static final long serialVersionUID = 1L;
- private final Map<String, String> peerAddresses;
- private final String id;
- private final Optional<ConfigParams> config;
- private final DataPersistenceProvider dataPersistenceProvider;
- private final ActorRef roleChangeNotifier;
- private RaftActorSnapshotMessageSupport snapshotMessageSupport;
-
- private MockRaftActorCreator(Map<String, String> peerAddresses, String id,
- Optional<ConfigParams> config, DataPersistenceProvider dataPersistenceProvider,
- ActorRef roleChangeNotifier) {
- this.peerAddresses = peerAddresses;
- this.id = id;
- this.config = config;
- this.dataPersistenceProvider = dataPersistenceProvider;
- this.roleChangeNotifier = roleChangeNotifier;
- }
-
- @Override
- public MockRaftActor create() throws Exception {
- MockRaftActor mockRaftActor = new MockRaftActor(id, peerAddresses, config,
- dataPersistenceProvider);
- mockRaftActor.roleChangeNotifier = this.roleChangeNotifier;
- mockRaftActor.snapshotMessageSupport = snapshotMessageSupport;
- return mockRaftActor;
- }
- }
-
- public MockRaftActor(String id, Map<String, String> peerAddresses, Optional<ConfigParams> config,
- DataPersistenceProvider dataPersistenceProvider) {
- super(id, peerAddresses, config, PAYLOAD_VERSION);
+ protected MockRaftActor(Builder builder) {
+ super(builder.id, builder.peerAddresses, Optional.fromNullable(builder.config), PAYLOAD_VERSION);
state = new ArrayList<>();
this.actorDelegate = mock(RaftActor.class);
this.recoveryCohortDelegate = mock(RaftActorRecoveryCohort.class);
this.snapshotCohortDelegate = mock(RaftActorSnapshotCohort.class);
- if(dataPersistenceProvider == null){
- setPersistence(true);
+
+ if(builder.dataPersistenceProvider == null){
+ setPersistence(builder.persistent.isPresent() ? builder.persistent.get() : true);
} else {
- setPersistence(dataPersistenceProvider);
+ setPersistence(builder.dataPersistenceProvider);
}
+
+ roleChangeNotifier = builder.roleChangeNotifier;
+ snapshotMessageSupport = builder.snapshotMessageSupport;
+ restoreFromSnapshot = builder.restoreFromSnapshot;
}
public void setRaftActorRecoverySupport(RaftActorRecoverySupport support) {
return state;
}
- public static Props props(final String id, final Map<String, String> peerAddresses,
- Optional<ConfigParams> config){
- return Props.create(new MockRaftActorCreator(peerAddresses, id, config, null, null));
- }
-
- public static Props props(final String id, final Map<String, String> peerAddresses,
- Optional<ConfigParams> config, RaftActorSnapshotMessageSupport snapshotMessageSupport){
- MockRaftActorCreator creator = new MockRaftActorCreator(peerAddresses, id, config, null, null);
- creator.snapshotMessageSupport = snapshotMessageSupport;
- return Props.create(creator);
- }
-
- public static Props props(final String id, final Map<String, String> peerAddresses,
- Optional<ConfigParams> config, DataPersistenceProvider dataPersistenceProvider){
- return Props.create(new MockRaftActorCreator(peerAddresses, id, config, dataPersistenceProvider, null));
- }
-
- public static Props props(final String id, final Map<String, String> peerAddresses,
- Optional<ConfigParams> config, ActorRef roleChangeNotifier){
- return Props.create(new MockRaftActorCreator(peerAddresses, id, config, null, roleChangeNotifier));
- }
-
- public static Props props(final String id, final Map<String, String> peerAddresses,
- Optional<ConfigParams> config, ActorRef roleChangeNotifier,
- DataPersistenceProvider dataPersistenceProvider){
- return Props.create(new MockRaftActorCreator(peerAddresses, id, config, dataPersistenceProvider, roleChangeNotifier));
- }
@Override protected void applyState(ActorRef clientActor, String identifier, Object data) {
actorDelegate.applyState(clientActor, identifier, data);
@Override
public void applySnapshot(byte [] snapshot) {
LOG.info("{}: applySnapshot called", persistenceId());
- snapshotCohortDelegate.applySnapshot(snapshot);
applySnapshotBytes(snapshot);
+ snapshotCohortDelegate.applySnapshot(snapshot);
}
@Override
super.changeCurrentBehavior((RaftActorBehavior)message);
} else {
super.handleCommand(message);
+
+ if(RaftActorSnapshotMessageSupport.COMMIT_SNAPSHOT.equals(message)) {
+ snapshotCommitted.countDown();
+ }
}
}
public ReplicatedLog getReplicatedLog(){
return this.getRaftActorContext().getReplicatedLog();
}
+
+ @Override
+ public byte[] getRestoreFromSnapshot() {
+ return restoreFromSnapshot;
+ }
+
+ public static Props props(final String id, final Map<String, String> peerAddresses,
+ ConfigParams config){
+ return builder().id(id).peerAddresses(peerAddresses).config(config).props();
+ }
+
+ public static Props props(final String id, final Map<String, String> peerAddresses,
+ ConfigParams config, DataPersistenceProvider dataPersistenceProvider){
+ return builder().id(id).peerAddresses(peerAddresses).config(config).
+ dataPersistenceProvider(dataPersistenceProvider).props();
+ }
+
+ public static Builder builder() {
+ return new Builder();
+ }
+
+ public static class Builder {
+ private Map<String, String> peerAddresses = Collections.emptyMap();
+ private String id;
+ private ConfigParams config;
+ private DataPersistenceProvider dataPersistenceProvider;
+ private ActorRef roleChangeNotifier;
+ private RaftActorSnapshotMessageSupport snapshotMessageSupport;
+ private byte[] restoreFromSnapshot;
+ private Optional<Boolean> persistent = Optional.absent();
+
+ public Builder id(String id) {
+ this.id = id;
+ return this;
+ }
+
+ public Builder peerAddresses(Map<String, String> peerAddresses) {
+ this.peerAddresses = peerAddresses;
+ return this;
+ }
+
+ public Builder config(ConfigParams config) {
+ this.config = config;
+ return this;
+ }
+
+ public Builder dataPersistenceProvider(DataPersistenceProvider dataPersistenceProvider) {
+ this.dataPersistenceProvider = dataPersistenceProvider;
+ return this;
+ }
+
+ public Builder roleChangeNotifier(ActorRef roleChangeNotifier) {
+ this.roleChangeNotifier = roleChangeNotifier;
+ return this;
+ }
+
+ public Builder snapshotMessageSupport(RaftActorSnapshotMessageSupport snapshotMessageSupport) {
+ this.snapshotMessageSupport = snapshotMessageSupport;
+ return this;
+ }
+
+ public Builder restoreFromSnapshot(byte[] restoreFromSnapshot) {
+ this.restoreFromSnapshot = restoreFromSnapshot;
+ return this;
+ }
+
+ public Builder persistent(Optional<Boolean> persistent) {
+ this.persistent = persistent;
+ return this;
+ }
+
+ public Props props() {
+ return Props.create(MockRaftActor.class, this);
+ }
+ }
}
import org.opendaylight.controller.cluster.PersistentDataProvider;
import org.opendaylight.controller.cluster.notifications.LeaderStateChanged;
import org.opendaylight.controller.cluster.notifications.RoleChanged;
+import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload;
import org.opendaylight.controller.cluster.raft.base.messages.ApplyJournalEntries;
import org.opendaylight.controller.cluster.raft.base.messages.ApplyLogEntries;
import org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot;
ImmutableMap<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
ActorRef followerActor = factory.createActor(MockRaftActor.props(persistenceId,
- peerAddresses, Optional.<ConfigParams>of(config)), persistenceId);
+ peerAddresses, config), persistenceId);
watch(followerActor);
//reinstate the actor
TestActorRef<MockRaftActor> ref = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses, Optional.<ConfigParams>of(config)));
+ MockRaftActor.props(persistenceId, peerAddresses, config));
MockRaftActor mockRaftActor = ref.underlyingActor();
TestActorRef<MockRaftActor> ref = factory.createTestActor(MockRaftActor.props(persistenceId,
ImmutableMap.<String, String>builder().put("member1", "address").build(),
- Optional.<ConfigParams>of(config), new NonPersistentDataProvider()), persistenceId);
+ config, new NonPersistentDataProvider()), persistenceId);
MockRaftActor mockRaftActor = ref.underlyingActor();
TestActorRef<MockRaftActor> ref = factory.createTestActor(MockRaftActor.props(persistenceId,
ImmutableMap.<String, String>builder().put("member1", "address").build(),
- Optional.<ConfigParams>of(config), new NonPersistentDataProvider()).
+ config, new NonPersistentDataProvider()).
withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
InMemoryJournal.waitForWriteMessagesComplete(persistenceId);
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
ref = factory.createTestActor(MockRaftActor.props(persistenceId,
- ImmutableMap.<String, String>builder().put("member1", "address").build(),
- Optional.<ConfigParams>of(config), new NonPersistentDataProvider()).
+ ImmutableMap.<String, String>builder().put("member1", "address").build(), config,
+ new NonPersistentDataProvider()).
withDispatcher(Dispatchers.DefaultDispatcherId()),
factory.generateActorId("follower-"));
config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS));
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
- Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config)), persistenceId);
+ Collections.<String, String>emptyMap(), config), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
RaftActorSnapshotMessageSupport mockSupport = mock(RaftActorSnapshotMessageSupport.class);
- TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
- Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), mockSupport), persistenceId);
+ TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.builder().id(persistenceId).
+ config(config).snapshotMessageSupport(mockSupport).props());
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
- Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ Collections.<String, String>emptyMap(), config, dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
- Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ Collections.<String, String>emptyMap(), config, dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = mockActorRef.underlyingActor();
String persistenceId = factory.generateActorId("notifier-");
- TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
- Collections.<String, String>emptyMap(), Optional.<ConfigParams>of(config), notifierActor,
- new NonPersistentDataProvider()).withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
+ TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.builder().id(persistenceId).
+ config(config).roleChangeNotifier(notifierActor).dataPersistenceProvider(
+ new NonPersistentDataProvider()).props().withDispatcher(Dispatchers.DefaultDispatcherId()),
+ persistenceId);
List<RoleChanged> matches = MessageCollectorActor.expectMatching(notifierActor, RoleChanged.class, 3);
String persistenceId = factory.generateActorId("notifier-");
- factory.createActor(MockRaftActor.props(persistenceId,
- ImmutableMap.of("leader", "fake/path"), Optional.<ConfigParams>of(config), notifierActor), persistenceId);
+ factory.createActor(MockRaftActor.builder().id(persistenceId).
+ peerAddresses(ImmutableMap.of("leader", "fake/path")).
+ config(config).roleChangeNotifier(notifierActor).props());
List<RoleChanged> matches = null;
for(int i = 0; i < 5000 / heartBeatInterval; i++) {
peerAddresses.put(follower1Id, followerActor1.path().toString());
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses,
- Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor leaderActor = mockActorRef.underlyingActor();
peerAddresses.put(leaderId, leaderActor1.path().toString());
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses,
- Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor followerActor = mockActorRef.underlyingActor();
followerActor.getRaftActorContext().setCommitIndex(4);
peerAddresses.put(follower2Id, followerActor2.path().toString());
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses,
- Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor leaderActor = mockActorRef.underlyingActor();
leaderActor.getRaftActorContext().setCommitIndex(9);
Map<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses,
- Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor leaderActor = mockActorRef.underlyingActor();
leaderActor.getRaftActorContext().setCommitIndex(3);
Map<String, String> peerAddresses = ImmutableMap.<String, String>builder().put("member1", "address").build();
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses,
- Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor leaderActor = mockActorRef.underlyingActor();
leaderActor.getRaftActorContext().setCommitIndex(3);
InMemoryJournal.addEntry(persistenceId, 1, replLogEntry);
TestActorRef<MockRaftActor> ref = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses, Optional.<ConfigParams>of(config)));
+ MockRaftActor.props(persistenceId, peerAddresses, config));
MockRaftActor mockRaftActor = ref.underlyingActor();
Map<String, String> peerAddresses = ImmutableMap.<String, String>builder().build();
TestActorRef<MockRaftActor> mockActorRef = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses,
- Optional.<ConfigParams>of(config), dataPersistenceProvider), persistenceId);
+ MockRaftActor.props(persistenceId, peerAddresses, config, dataPersistenceProvider), persistenceId);
MockRaftActor leaderActor = mockActorRef.underlyingActor();
DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class);
TestActorRef<MockRaftActor> actorRef = factory.createTestActor(
- MockRaftActor.props(persistenceId, peerAddresses,
- Optional.<ConfigParams>of(emptyConfig), dataPersistenceProvider), persistenceId);
+ MockRaftActor.props(persistenceId, peerAddresses, emptyConfig, dataPersistenceProvider), persistenceId);
MockRaftActor mockRaftActor = actorRef.underlyingActor();
mockRaftActor.waitForInitializeBehaviorComplete();
new MockRaftActorContext.MockPayload("C")));
TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.props(persistenceId,
- ImmutableMap.<String, String>builder().put("member1", "address").build(), Optional.<ConfigParams>of(config)).
+ ImmutableMap.<String, String>builder().put("member1", "address").build(), config).
withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
MockRaftActor mockRaftActor = raftActorRef.underlyingActor();
TEST_LOG.info("testGetSnapshot ending");
}
+
+ @Test
+ public void testRestoreFromSnapshot() throws Exception {
+ TEST_LOG.info("testRestoreFromSnapshot starting");
+
+ String persistenceId = factory.generateActorId("test-actor-");
+ DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
+ config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
+
+ List<ReplicatedLogEntry> snapshotUnappliedEntries = new ArrayList<>();
+ snapshotUnappliedEntries.add(new MockRaftActorContext.MockReplicatedLogEntry(1, 4,
+ new MockRaftActorContext.MockPayload("E")));
+
+ int snapshotLastApplied = 3;
+ int snapshotLastIndex = 4;
+
+ List<MockPayload> state = Arrays.asList(
+ new MockRaftActorContext.MockPayload("A"),
+ new MockRaftActorContext.MockPayload("B"),
+ new MockRaftActorContext.MockPayload("C"),
+ new MockRaftActorContext.MockPayload("D"));
+ ByteString stateBytes = fromObject(state);
+
+ Snapshot snapshot = Snapshot.create(stateBytes.toByteArray(), snapshotUnappliedEntries,
+ snapshotLastIndex, 1, snapshotLastApplied, 1, 1, "member-1");
+
+ InMemorySnapshotStore.addSnapshotSavedLatch(persistenceId);
+
+ TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.builder().id(persistenceId).
+ config(config).restoreFromSnapshot(SerializationUtils.serialize(snapshot)).props().
+ withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
+ MockRaftActor mockRaftActor = raftActorRef.underlyingActor();
+
+ mockRaftActor.waitForRecoveryComplete();
+
+ Snapshot savedSnapshot = InMemorySnapshotStore.waitForSavedSnapshot(persistenceId, Snapshot.class);
+ assertEquals("getElectionTerm", snapshot.getElectionTerm(), savedSnapshot.getElectionTerm());
+ assertEquals("getElectionVotedFor", snapshot.getElectionVotedFor(), savedSnapshot.getElectionVotedFor());
+ assertEquals("getLastAppliedIndex", snapshot.getLastAppliedIndex(), savedSnapshot.getLastAppliedIndex());
+ assertEquals("getLastAppliedTerm", snapshot.getLastAppliedTerm(), savedSnapshot.getLastAppliedTerm());
+ assertEquals("getLastIndex", snapshot.getLastIndex(), savedSnapshot.getLastIndex());
+ assertEquals("getLastTerm", snapshot.getLastTerm(), savedSnapshot.getLastTerm());
+ assertArrayEquals("getState", snapshot.getState(), savedSnapshot.getState());
+ assertEquals("getUnAppliedEntries", snapshot.getUnAppliedEntries(), savedSnapshot.getUnAppliedEntries());
+
+ verify(mockRaftActor.snapshotCohortDelegate, timeout(5000)).applySnapshot(any(byte[].class));
+
+ RaftActorContext context = mockRaftActor.getRaftActorContext();
+ assertEquals("Journal log size", 1, context.getReplicatedLog().size());
+ assertEquals("Last index", snapshotLastIndex, context.getReplicatedLog().lastIndex());
+ assertEquals("Last applied", snapshotLastApplied, context.getLastApplied());
+ assertEquals("Commit index", snapshotLastApplied, context.getCommitIndex());
+ assertEquals("Recovered state", state, mockRaftActor.getState());
+ assertEquals("Current term", 1L, context.getTermInformation().getCurrentTerm());
+ assertEquals("Voted for", "member-1", context.getTermInformation().getVotedFor());
+
+ // Test with data persistence disabled
+
+ snapshot = Snapshot.create(new byte[0], Collections.<ReplicatedLogEntry>emptyList(),
+ -1, -1, -1, -1, 5, "member-1");
+
+ persistenceId = factory.generateActorId("test-actor-");
+
+ raftActorRef = factory.createTestActor(MockRaftActor.builder().id(persistenceId).
+ config(config).restoreFromSnapshot(SerializationUtils.serialize(snapshot)).
+ persistent(Optional.of(Boolean.FALSE)).props().
+ withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
+ mockRaftActor = raftActorRef.underlyingActor();
+
+ mockRaftActor.waitForRecoveryComplete();
+ assertEquals("snapshot committed", true,
+ Uninterruptibles.awaitUninterruptibly(mockRaftActor.snapshotCommitted, 5, TimeUnit.SECONDS));
+
+ context = mockRaftActor.getRaftActorContext();
+ assertEquals("Current term", 5L, context.getTermInformation().getCurrentTerm());
+ assertEquals("Voted for", "member-1", context.getTermInformation().getVotedFor());
+
+ TEST_LOG.info("testRestoreFromSnapshot ending");
+ }
+
+ @Test
+ public void testRestoreFromSnapshotWithRecoveredData() throws Exception {
+ TEST_LOG.info("testRestoreFromSnapshotWithRecoveredData starting");
+
+ String persistenceId = factory.generateActorId("test-actor-");
+ DefaultConfigParamsImpl config = new DefaultConfigParamsImpl();
+ config.setCustomRaftPolicyImplementationClass(DisableElectionsRaftPolicy.class.getName());
+
+ List<MockPayload> state = Arrays.asList(new MockRaftActorContext.MockPayload("A"));
+ Snapshot snapshot = Snapshot.create(fromObject(state).toByteArray(), Arrays.<ReplicatedLogEntry>asList(),
+ 5, 2, 5, 2, 2, "member-1");
+
+ InMemoryJournal.addEntry(persistenceId, 1, new MockRaftActorContext.MockReplicatedLogEntry(1, 0,
+ new MockRaftActorContext.MockPayload("B")));
+
+ TestActorRef<MockRaftActor> raftActorRef = factory.createTestActor(MockRaftActor.builder().id(persistenceId).
+ config(config).restoreFromSnapshot(SerializationUtils.serialize(snapshot)).props().
+ withDispatcher(Dispatchers.DefaultDispatcherId()), persistenceId);
+ MockRaftActor mockRaftActor = raftActorRef.underlyingActor();
+
+ mockRaftActor.waitForRecoveryComplete();
+
+ verify(mockRaftActor.snapshotCohortDelegate, timeout(500).never()).applySnapshot(any(byte[].class));
+
+ RaftActorContext context = mockRaftActor.getRaftActorContext();
+ assertEquals("Journal log size", 1, context.getReplicatedLog().size());
+ assertEquals("Last index", 0, context.getReplicatedLog().lastIndex());
+ assertEquals("Last applied", -1, context.getLastApplied());
+ assertEquals("Commit index", -1, context.getCommitIndex());
+ assertEquals("Current term", 0, context.getTermInformation().getCurrentTerm());
+ assertEquals("Voted for", null, context.getTermInformation().getVotedFor());
+
+ TEST_LOG.info("testRestoreFromSnapshotWithRecoveredData ending");
+ }
}