1 package org.opendaylight.controller.cluster.raft;
3 import static org.junit.Assert.assertArrayEquals;
4 import static org.junit.Assert.assertEquals;
5 import static org.junit.Assert.assertFalse;
6 import static org.junit.Assert.assertTrue;
7 import static org.mockito.Matchers.any;
8 import static org.mockito.Matchers.anyLong;
9 import static org.mockito.Mockito.doReturn;
10 import static org.mockito.Mockito.mock;
11 import static org.mockito.Mockito.never;
12 import static org.mockito.Mockito.reset;
13 import static org.mockito.Mockito.times;
14 import static org.mockito.Mockito.verify;
15 import akka.actor.ActorRef;
16 import akka.japi.Procedure;
17 import akka.persistence.SnapshotSelectionCriteria;
18 import akka.testkit.TestActorRef;
19 import com.google.common.collect.ImmutableMap;
20 import java.util.Arrays;
21 import java.util.HashMap;
22 import java.util.List;
23 import org.junit.After;
24 import org.junit.Before;
25 import org.junit.Test;
26 import org.mockito.ArgumentCaptor;
27 import org.mockito.Mock;
28 import org.mockito.MockitoAnnotations;
29 import org.opendaylight.controller.cluster.DataPersistenceProvider;
30 import org.opendaylight.controller.cluster.raft.SnapshotManager.LastAppliedTermInformationReader;
31 import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot;
32 import org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot;
33 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
34 import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
35 import org.slf4j.LoggerFactory;
37 public class SnapshotManagerTest extends AbstractActorTest {
40 private RaftActorContext mockRaftActorContext;
43 private ConfigParams mockConfigParams;
46 private ReplicatedLog mockReplicatedLog;
49 private DataPersistenceProvider mockDataPersistenceProvider;
52 private RaftActorBehavior mockRaftActorBehavior;
55 private Procedure<Void> mockProcedure;
57 private SnapshotManager snapshotManager;
59 private TestActorFactory factory;
61 private TestActorRef<MessageCollectorActor> actorRef;
65 MockitoAnnotations.initMocks(this);
67 doReturn(new HashMap<>()).when(mockRaftActorContext).getPeerAddresses();
68 doReturn(mockConfigParams).when(mockRaftActorContext).getConfigParams();
69 doReturn(10L).when(mockConfigParams).getSnapshotBatchCount();
70 doReturn(mockReplicatedLog).when(mockRaftActorContext).getReplicatedLog();
71 doReturn("123").when(mockRaftActorContext).getId();
72 doReturn("123").when(mockRaftActorBehavior).getLeaderId();
74 ElectionTerm mockElectionTerm = mock(ElectionTerm.class);
75 doReturn(mockElectionTerm).when(mockRaftActorContext).getTermInformation();
76 doReturn(5L).when(mockElectionTerm).getCurrentTerm();
78 snapshotManager = new SnapshotManager(mockRaftActorContext, LoggerFactory.getLogger(this.getClass()));
79 factory = new TestActorFactory(getSystem());
81 actorRef = factory.createTestActor(MessageCollectorActor.props(), factory.generateActorId("test-"));
82 doReturn(actorRef).when(mockRaftActorContext).getActor();
87 public void tearDown(){
92 public void testConstruction(){
93 assertEquals(false, snapshotManager.isCapturing());
97 public void testCaptureToInstall(){
99 // Force capturing toInstall = true
100 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1, 0,
101 new MockRaftActorContext.MockPayload()), 0, "follower-1");
103 assertEquals(true, snapshotManager.isCapturing());
105 CaptureSnapshot captureSnapshot = MessageCollectorActor.expectFirstMatching(actorRef, CaptureSnapshot.class);
107 // LastIndex and LastTerm are picked up from the lastLogEntry
108 assertEquals(0L, captureSnapshot.getLastIndex());
109 assertEquals(1L, captureSnapshot.getLastTerm());
111 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
112 assertEquals(0L, captureSnapshot.getLastAppliedIndex());
113 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
116 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
117 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
118 actorRef.underlyingActor().clear();
122 public void testCapture(){
123 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
124 new MockRaftActorContext.MockPayload()), 9);
128 assertEquals(true, snapshotManager.isCapturing());
130 CaptureSnapshot captureSnapshot = MessageCollectorActor.expectFirstMatching(actorRef, CaptureSnapshot.class);
131 // LastIndex and LastTerm are picked up from the lastLogEntry
132 assertEquals(9L, captureSnapshot.getLastIndex());
133 assertEquals(1L, captureSnapshot.getLastTerm());
135 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
136 assertEquals(9L, captureSnapshot.getLastAppliedIndex());
137 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
140 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
141 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
143 actorRef.underlyingActor().clear();
148 public void testIllegalCapture() throws Exception {
149 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
150 new MockRaftActorContext.MockPayload()), 9);
154 List<CaptureSnapshot> allMatching = MessageCollectorActor.getAllMatching(actorRef, CaptureSnapshot.class);
156 assertEquals(1, allMatching.size());
158 // This will not cause snapshot capture to start again
159 capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
160 new MockRaftActorContext.MockPayload()), 9);
162 assertFalse(capture);
164 allMatching = MessageCollectorActor.getAllMatching(actorRef, CaptureSnapshot.class);
166 assertEquals(1, allMatching.size());
170 public void testPersistWhenReplicatedToAllIndexMinusOne(){
171 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
172 doReturn(1L).when(mockReplicatedLog).getSnapshotTerm();
174 doReturn(ImmutableMap.builder().put("follower-1", "").build()).when(mockRaftActorContext).getPeerAddresses();
176 doReturn(8L).when(mockRaftActorContext).getLastApplied();
178 MockRaftActorContext.MockReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(
179 3L, 9L, new MockRaftActorContext.MockPayload());
181 MockRaftActorContext.MockReplicatedLogEntry lastAppliedEntry = new MockRaftActorContext.MockReplicatedLogEntry(
182 2L, 8L, new MockRaftActorContext.MockPayload());
184 doReturn(lastAppliedEntry).when(mockReplicatedLog).get(8L);
185 doReturn(Arrays.asList(lastLogEntry)).when(mockReplicatedLog).getFrom(9L);
187 // when replicatedToAllIndex = -1
188 snapshotManager.capture(lastLogEntry, -1);
190 snapshotManager.create(mockProcedure);
192 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
193 snapshotManager.persist(mockDataPersistenceProvider, bytes, mockRaftActorBehavior
194 , Runtime.getRuntime().totalMemory());
196 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
197 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
199 Snapshot snapshot = snapshotArgumentCaptor.getValue();
201 assertEquals("getLastTerm", 3L, snapshot.getLastTerm());
202 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
203 assertEquals("getLastAppliedTerm", 2L, snapshot.getLastAppliedTerm());
204 assertEquals("getLastAppliedIndex", 8L, snapshot.getLastAppliedIndex());
205 assertArrayEquals("getState", bytes, snapshot.getState());
206 assertEquals("getUnAppliedEntries", Arrays.asList(lastLogEntry), snapshot.getUnAppliedEntries());
208 verify(mockReplicatedLog).snapshotPreCommit(7L, 1L);
213 public void testCreate() throws Exception {
214 // when replicatedToAllIndex = -1
215 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
216 new MockRaftActorContext.MockPayload()), -1);
218 snapshotManager.create(mockProcedure);
220 verify(mockProcedure).apply(null);
222 assertEquals("isCapturing", true, snapshotManager.isCapturing());
226 public void testCallingCreateMultipleTimesCausesNoHarm() throws Exception {
227 // when replicatedToAllIndex = -1
228 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
229 new MockRaftActorContext.MockPayload()), -1);
231 snapshotManager.create(mockProcedure);
233 snapshotManager.create(mockProcedure);
235 verify(mockProcedure, times(1)).apply(null);
239 public void testCallingCreateBeforeCapture() throws Exception {
240 snapshotManager.create(mockProcedure);
242 verify(mockProcedure, times(0)).apply(null);
246 public void testCallingCreateAfterPersist() throws Exception {
247 // when replicatedToAllIndex = -1
248 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
249 new MockRaftActorContext.MockPayload()), -1);
251 snapshotManager.create(mockProcedure);
253 verify(mockProcedure, times(1)).apply(null);
255 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
256 , Runtime.getRuntime().totalMemory());
258 reset(mockProcedure);
260 snapshotManager.create(mockProcedure);
262 verify(mockProcedure, never()).apply(null);
266 public void testPersistWhenReplicatedToAllIndexNotMinus(){
267 doReturn(45L).when(mockReplicatedLog).getSnapshotIndex();
268 doReturn(6L).when(mockReplicatedLog).getSnapshotTerm();
269 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
270 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(9);
271 doReturn(6L).when(replicatedLogEntry).getTerm();
272 doReturn(9L).when(replicatedLogEntry).getIndex();
274 // when replicatedToAllIndex != -1
275 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
276 new MockRaftActorContext.MockPayload()), 9);
278 snapshotManager.create(mockProcedure);
280 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
281 snapshotManager.persist(mockDataPersistenceProvider, bytes, mockRaftActorBehavior
282 , Runtime.getRuntime().totalMemory());
284 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
285 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
287 Snapshot snapshot = snapshotArgumentCaptor.getValue();
289 assertEquals("getLastTerm", 6L, snapshot.getLastTerm());
290 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
291 assertEquals("getLastAppliedTerm", 6L, snapshot.getLastAppliedTerm());
292 assertEquals("getLastAppliedIndex", 9L, snapshot.getLastAppliedIndex());
293 assertArrayEquals("getState", bytes, snapshot.getState());
294 assertEquals("getUnAppliedEntries size", 0, snapshot.getUnAppliedEntries().size());
296 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
298 verify(mockRaftActorBehavior).setReplicatedToAllIndex(9);
303 public void testPersistWhenReplicatedLogDataSizeGreaterThanThreshold(){
304 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
306 // when replicatedToAllIndex = -1
307 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
308 new MockRaftActorContext.MockPayload()), -1);
310 snapshotManager.create(mockProcedure);
312 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
313 , Runtime.getRuntime().totalMemory());
315 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
317 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
321 public void testPersistSendInstallSnapshot(){
322 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
324 // when replicatedToAllIndex = -1
325 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
326 new MockRaftActorContext.MockPayload()), -1, "follower-1");
330 snapshotManager.create(mockProcedure);
332 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
334 snapshotManager.persist(mockDataPersistenceProvider, bytes, mockRaftActorBehavior
335 , Runtime.getRuntime().totalMemory());
337 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
339 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
341 ArgumentCaptor<SendInstallSnapshot> sendInstallSnapshotArgumentCaptor
342 = ArgumentCaptor.forClass(SendInstallSnapshot.class);
344 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), sendInstallSnapshotArgumentCaptor.capture());
346 SendInstallSnapshot sendInstallSnapshot = sendInstallSnapshotArgumentCaptor.getValue();
348 assertTrue(Arrays.equals(bytes, sendInstallSnapshot.getSnapshot().toByteArray()));
352 public void testCallingPersistWithoutCaptureWillDoNothing(){
353 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
354 , Runtime.getRuntime().totalMemory());
356 verify(mockDataPersistenceProvider, never()).saveSnapshot(any(Snapshot.class));
358 verify(mockReplicatedLog, never()).snapshotPreCommit(9L, 6L);
360 verify(mockRaftActorBehavior, never()).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
363 public void testCallingPersistTwiceWillDoNoHarm(){
364 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
366 // when replicatedToAllIndex = -1
367 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
368 new MockRaftActorContext.MockPayload()), -1, "follower-1");
370 snapshotManager.create(mockProcedure);
372 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
373 , Runtime.getRuntime().totalMemory());
375 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
376 , Runtime.getRuntime().totalMemory());
378 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
380 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
382 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
386 public void testCommit(){
387 // when replicatedToAllIndex = -1
388 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
389 new MockRaftActorContext.MockPayload()), -1, "follower-1");
391 snapshotManager.create(mockProcedure);
393 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
394 , Runtime.getRuntime().totalMemory());
396 snapshotManager.commit(mockDataPersistenceProvider, 100L);
398 verify(mockReplicatedLog).snapshotCommit();
400 verify(mockDataPersistenceProvider).deleteMessages(100L);
402 ArgumentCaptor<SnapshotSelectionCriteria> criteriaCaptor = ArgumentCaptor.forClass(SnapshotSelectionCriteria.class);
404 verify(mockDataPersistenceProvider).deleteSnapshots(criteriaCaptor.capture());
406 assertEquals(90, criteriaCaptor.getValue().maxSequenceNr()); // sequenceNumber = 100
407 // config snapShotBatchCount = 10
408 // therefore maxSequenceNumber = 90
412 public void testCommitBeforePersist(){
413 // when replicatedToAllIndex = -1
414 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
415 new MockRaftActorContext.MockPayload()), -1, "follower-1");
417 snapshotManager.commit(mockDataPersistenceProvider, 100L);
419 verify(mockReplicatedLog, never()).snapshotCommit();
421 verify(mockDataPersistenceProvider, never()).deleteMessages(100L);
423 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
428 public void testCommitBeforeCapture(){
429 snapshotManager.commit(mockDataPersistenceProvider, 100L);
431 verify(mockReplicatedLog, never()).snapshotCommit();
433 verify(mockDataPersistenceProvider, never()).deleteMessages(anyLong());
435 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
440 public void testCallingCommitMultipleTimesCausesNoHarm(){
441 // when replicatedToAllIndex = -1
442 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
443 new MockRaftActorContext.MockPayload()), -1, "follower-1");
445 snapshotManager.create(mockProcedure);
447 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
448 , Runtime.getRuntime().totalMemory());
450 snapshotManager.commit(mockDataPersistenceProvider, 100L);
452 snapshotManager.commit(mockDataPersistenceProvider, 100L);
454 verify(mockReplicatedLog, times(1)).snapshotCommit();
456 verify(mockDataPersistenceProvider, times(1)).deleteMessages(100L);
458 verify(mockDataPersistenceProvider, times(1)).deleteSnapshots(any(SnapshotSelectionCriteria.class));
462 public void testRollback(){
463 // when replicatedToAllIndex = -1
464 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
465 new MockRaftActorContext.MockPayload()), -1, "follower-1");
467 snapshotManager.create(mockProcedure);
469 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
470 , Runtime.getRuntime().totalMemory());
472 snapshotManager.rollback();
474 verify(mockReplicatedLog).snapshotRollback();
479 public void testRollbackBeforePersist(){
480 // when replicatedToAllIndex = -1
481 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
482 new MockRaftActorContext.MockPayload()), -1, "follower-1");
484 snapshotManager.rollback();
486 verify(mockReplicatedLog, never()).snapshotRollback();
490 public void testRollbackBeforeCapture(){
491 snapshotManager.rollback();
493 verify(mockReplicatedLog, never()).snapshotRollback();
497 public void testCallingRollbackMultipleTimesCausesNoHarm(){
498 // when replicatedToAllIndex = -1
499 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
500 new MockRaftActorContext.MockPayload()), -1, "follower-1");
502 snapshotManager.create(mockProcedure);
504 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
505 , Runtime.getRuntime().totalMemory());
507 snapshotManager.rollback();
509 snapshotManager.rollback();
511 verify(mockReplicatedLog, times(1)).snapshotRollback();
515 public void testTrimLogWhenTrimIndexLessThanLastApplied() {
516 doReturn(20L).when(mockRaftActorContext).getLastApplied();
518 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
519 doReturn(true).when(mockReplicatedLog).isPresent(10);
520 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
521 doReturn(5L).when(replicatedLogEntry).getTerm();
523 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
524 assertEquals("return index", 10L, retIndex);
526 verify(mockReplicatedLog).snapshotPreCommit(10, 5);
527 verify(mockReplicatedLog).snapshotCommit();
529 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
533 public void testTrimLogWhenLastAppliedNotSet() {
534 doReturn(-1L).when(mockRaftActorContext).getLastApplied();
536 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
537 doReturn(true).when(mockReplicatedLog).isPresent(10);
538 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
539 doReturn(5L).when(replicatedLogEntry).getTerm();
541 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
542 assertEquals("return index", -1L, retIndex);
544 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
545 verify(mockReplicatedLog, never()).snapshotCommit();
547 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
551 public void testTrimLogWhenLastAppliedZero() {
552 doReturn(0L).when(mockRaftActorContext).getLastApplied();
554 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
555 doReturn(true).when(mockReplicatedLog).isPresent(10);
556 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
557 doReturn(5L).when(replicatedLogEntry).getTerm();
559 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
560 assertEquals("return index", -1L, retIndex);
562 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
563 verify(mockReplicatedLog, never()).snapshotCommit();
565 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
569 public void testTrimLogWhenTrimIndexNotPresent() {
570 doReturn(20L).when(mockRaftActorContext).getLastApplied();
572 doReturn(false).when(mockReplicatedLog).isPresent(10);
574 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
575 assertEquals("return index", -1L, retIndex);
577 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
578 verify(mockReplicatedLog, never()).snapshotCommit();
580 // Trim index is greater than replicatedToAllIndex so should update it.
581 verify(mockRaftActorBehavior).setReplicatedToAllIndex(10L);
585 public void testTrimLogAfterCapture(){
586 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
587 new MockRaftActorContext.MockPayload()), 9);
591 assertEquals(true, snapshotManager.isCapturing());
593 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
594 doReturn(20L).when(mockRaftActorContext).getLastApplied();
595 doReturn(true).when(mockReplicatedLog).isPresent(10);
596 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
597 doReturn(5L).when(replicatedLogEntry).getTerm();
599 snapshotManager.trimLog(10, mockRaftActorBehavior);
601 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
602 verify(mockReplicatedLog, never()).snapshotCommit();
607 public void testTrimLogAfterCaptureToInstall(){
608 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
609 new MockRaftActorContext.MockPayload()), 9, "follower-1");
613 assertEquals(true, snapshotManager.isCapturing());
615 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
616 doReturn(20L).when(mockRaftActorContext).getLastApplied();
617 doReturn(true).when(mockReplicatedLog).isPresent(10);
618 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
619 doReturn(5L).when(replicatedLogEntry).getTerm();
621 snapshotManager.trimLog(10, mockRaftActorBehavior);
623 verify(mockReplicatedLog, never()).snapshotPreCommit(10, 5);
624 verify(mockReplicatedLog, never()).snapshotCommit();
629 public void testLastAppliedTermInformationReader() {
631 LastAppliedTermInformationReader reader = new LastAppliedTermInformationReader();
633 doReturn(4L).when(mockReplicatedLog).getSnapshotTerm();
634 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
636 ReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(6L, 9L,
637 new MockRaftActorContext.MockPayload());
639 // No followers and valid lastLogEntry
640 reader.init(mockReplicatedLog, 1L, lastLogEntry, false);
642 assertEquals("getTerm", 6L, reader.getTerm());
643 assertEquals("getIndex", 9L, reader.getIndex());
645 // No followers and null lastLogEntry
646 reader.init(mockReplicatedLog, 1L, null, false);
648 assertEquals("getTerm", -1L, reader.getTerm());
649 assertEquals("getIndex", -1L, reader.getIndex());
651 // Followers and valid originalIndex entry
652 doReturn(new MockRaftActorContext.MockReplicatedLogEntry(5L, 8L,
653 new MockRaftActorContext.MockPayload())).when(mockReplicatedLog).get(8L);
654 reader.init(mockReplicatedLog, 8L, lastLogEntry, true);
656 assertEquals("getTerm", 5L, reader.getTerm());
657 assertEquals("getIndex", 8L, reader.getIndex());
659 // Followers and null originalIndex entry and valid snapshot index
660 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
662 assertEquals("getTerm", 4L, reader.getTerm());
663 assertEquals("getIndex", 7L, reader.getIndex());
665 // Followers and null originalIndex entry and invalid snapshot index
666 doReturn(-1L).when(mockReplicatedLog).getSnapshotIndex();
667 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
669 assertEquals("getTerm", -1L, reader.getTerm());
670 assertEquals("getIndex", -1L, reader.getIndex());