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(mockDataPersistenceProvider).when(mockRaftActorContext).getPersistenceProvider();
73 doReturn("123").when(mockRaftActorBehavior).getLeaderId();
75 ElectionTerm mockElectionTerm = mock(ElectionTerm.class);
76 doReturn(mockElectionTerm).when(mockRaftActorContext).getTermInformation();
77 doReturn(5L).when(mockElectionTerm).getCurrentTerm();
79 snapshotManager = new SnapshotManager(mockRaftActorContext, LoggerFactory.getLogger(this.getClass()));
80 factory = new TestActorFactory(getSystem());
82 actorRef = factory.createTestActor(MessageCollectorActor.props(), factory.generateActorId("test-"));
83 doReturn(actorRef).when(mockRaftActorContext).getActor();
88 public void tearDown(){
93 public void testConstruction(){
94 assertEquals(false, snapshotManager.isCapturing());
98 public void testCaptureToInstall(){
100 // Force capturing toInstall = true
101 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1, 0,
102 new MockRaftActorContext.MockPayload()), 0, "follower-1");
104 assertEquals(true, snapshotManager.isCapturing());
106 CaptureSnapshot captureSnapshot = MessageCollectorActor.expectFirstMatching(actorRef, CaptureSnapshot.class);
108 // LastIndex and LastTerm are picked up from the lastLogEntry
109 assertEquals(0L, captureSnapshot.getLastIndex());
110 assertEquals(1L, captureSnapshot.getLastTerm());
112 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
113 assertEquals(0L, captureSnapshot.getLastAppliedIndex());
114 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
117 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
118 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
119 actorRef.underlyingActor().clear();
123 public void testCapture(){
124 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
125 new MockRaftActorContext.MockPayload()), 9);
129 assertEquals(true, snapshotManager.isCapturing());
131 CaptureSnapshot captureSnapshot = MessageCollectorActor.expectFirstMatching(actorRef, CaptureSnapshot.class);
132 // LastIndex and LastTerm are picked up from the lastLogEntry
133 assertEquals(9L, captureSnapshot.getLastIndex());
134 assertEquals(1L, captureSnapshot.getLastTerm());
136 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
137 assertEquals(9L, captureSnapshot.getLastAppliedIndex());
138 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
141 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
142 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
144 actorRef.underlyingActor().clear();
149 public void testIllegalCapture() throws Exception {
150 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
151 new MockRaftActorContext.MockPayload()), 9);
155 List<CaptureSnapshot> allMatching = MessageCollectorActor.getAllMatching(actorRef, CaptureSnapshot.class);
157 assertEquals(1, allMatching.size());
159 // This will not cause snapshot capture to start again
160 capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
161 new MockRaftActorContext.MockPayload()), 9);
163 assertFalse(capture);
165 allMatching = MessageCollectorActor.getAllMatching(actorRef, CaptureSnapshot.class);
167 assertEquals(1, allMatching.size());
171 public void testPersistWhenReplicatedToAllIndexMinusOne(){
172 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
173 doReturn(1L).when(mockReplicatedLog).getSnapshotTerm();
175 doReturn(ImmutableMap.builder().put("follower-1", "").build()).when(mockRaftActorContext).getPeerAddresses();
177 doReturn(8L).when(mockRaftActorContext).getLastApplied();
179 MockRaftActorContext.MockReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(
180 3L, 9L, new MockRaftActorContext.MockPayload());
182 MockRaftActorContext.MockReplicatedLogEntry lastAppliedEntry = new MockRaftActorContext.MockReplicatedLogEntry(
183 2L, 8L, new MockRaftActorContext.MockPayload());
185 doReturn(lastAppliedEntry).when(mockReplicatedLog).get(8L);
186 doReturn(Arrays.asList(lastLogEntry)).when(mockReplicatedLog).getFrom(9L);
188 // when replicatedToAllIndex = -1
189 snapshotManager.capture(lastLogEntry, -1);
191 snapshotManager.create(mockProcedure);
193 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
194 snapshotManager.persist(mockDataPersistenceProvider, bytes, mockRaftActorBehavior
195 , Runtime.getRuntime().totalMemory());
197 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
198 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
200 Snapshot snapshot = snapshotArgumentCaptor.getValue();
202 assertEquals("getLastTerm", 3L, snapshot.getLastTerm());
203 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
204 assertEquals("getLastAppliedTerm", 2L, snapshot.getLastAppliedTerm());
205 assertEquals("getLastAppliedIndex", 8L, snapshot.getLastAppliedIndex());
206 assertArrayEquals("getState", bytes, snapshot.getState());
207 assertEquals("getUnAppliedEntries", Arrays.asList(lastLogEntry), snapshot.getUnAppliedEntries());
209 verify(mockReplicatedLog).snapshotPreCommit(7L, 1L);
214 public void testCreate() throws Exception {
215 // when replicatedToAllIndex = -1
216 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
217 new MockRaftActorContext.MockPayload()), -1);
219 snapshotManager.create(mockProcedure);
221 verify(mockProcedure).apply(null);
223 assertEquals("isCapturing", true, snapshotManager.isCapturing());
227 public void testCallingCreateMultipleTimesCausesNoHarm() throws Exception {
228 // when replicatedToAllIndex = -1
229 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
230 new MockRaftActorContext.MockPayload()), -1);
232 snapshotManager.create(mockProcedure);
234 snapshotManager.create(mockProcedure);
236 verify(mockProcedure, times(1)).apply(null);
240 public void testCallingCreateBeforeCapture() throws Exception {
241 snapshotManager.create(mockProcedure);
243 verify(mockProcedure, times(0)).apply(null);
247 public void testCallingCreateAfterPersist() throws Exception {
248 // when replicatedToAllIndex = -1
249 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
250 new MockRaftActorContext.MockPayload()), -1);
252 snapshotManager.create(mockProcedure);
254 verify(mockProcedure, times(1)).apply(null);
256 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
257 , Runtime.getRuntime().totalMemory());
259 reset(mockProcedure);
261 snapshotManager.create(mockProcedure);
263 verify(mockProcedure, never()).apply(null);
267 public void testPersistWhenReplicatedToAllIndexNotMinus(){
268 doReturn(45L).when(mockReplicatedLog).getSnapshotIndex();
269 doReturn(6L).when(mockReplicatedLog).getSnapshotTerm();
270 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
271 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(9);
272 doReturn(6L).when(replicatedLogEntry).getTerm();
273 doReturn(9L).when(replicatedLogEntry).getIndex();
275 // when replicatedToAllIndex != -1
276 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
277 new MockRaftActorContext.MockPayload()), 9);
279 snapshotManager.create(mockProcedure);
281 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
282 snapshotManager.persist(mockDataPersistenceProvider, bytes, mockRaftActorBehavior
283 , Runtime.getRuntime().totalMemory());
285 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
286 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
288 Snapshot snapshot = snapshotArgumentCaptor.getValue();
290 assertEquals("getLastTerm", 6L, snapshot.getLastTerm());
291 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
292 assertEquals("getLastAppliedTerm", 6L, snapshot.getLastAppliedTerm());
293 assertEquals("getLastAppliedIndex", 9L, snapshot.getLastAppliedIndex());
294 assertArrayEquals("getState", bytes, snapshot.getState());
295 assertEquals("getUnAppliedEntries size", 0, snapshot.getUnAppliedEntries().size());
297 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
299 verify(mockRaftActorBehavior).setReplicatedToAllIndex(9);
304 public void testPersistWhenReplicatedLogDataSizeGreaterThanThreshold(){
305 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
307 // when replicatedToAllIndex = -1
308 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
309 new MockRaftActorContext.MockPayload()), -1);
311 snapshotManager.create(mockProcedure);
313 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
314 , Runtime.getRuntime().totalMemory());
316 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
318 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
322 public void testPersistSendInstallSnapshot(){
323 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
325 // when replicatedToAllIndex = -1
326 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
327 new MockRaftActorContext.MockPayload()), -1, "follower-1");
331 snapshotManager.create(mockProcedure);
333 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
335 snapshotManager.persist(mockDataPersistenceProvider, bytes, mockRaftActorBehavior
336 , Runtime.getRuntime().totalMemory());
338 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
340 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
342 ArgumentCaptor<SendInstallSnapshot> sendInstallSnapshotArgumentCaptor
343 = ArgumentCaptor.forClass(SendInstallSnapshot.class);
345 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), sendInstallSnapshotArgumentCaptor.capture());
347 SendInstallSnapshot sendInstallSnapshot = sendInstallSnapshotArgumentCaptor.getValue();
349 assertTrue(Arrays.equals(bytes, sendInstallSnapshot.getSnapshot().toByteArray()));
353 public void testCallingPersistWithoutCaptureWillDoNothing(){
354 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
355 , Runtime.getRuntime().totalMemory());
357 verify(mockDataPersistenceProvider, never()).saveSnapshot(any(Snapshot.class));
359 verify(mockReplicatedLog, never()).snapshotPreCommit(9L, 6L);
361 verify(mockRaftActorBehavior, never()).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
364 public void testCallingPersistTwiceWillDoNoHarm(){
365 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
367 // when replicatedToAllIndex = -1
368 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
369 new MockRaftActorContext.MockPayload()), -1, "follower-1");
371 snapshotManager.create(mockProcedure);
373 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
374 , Runtime.getRuntime().totalMemory());
376 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
377 , Runtime.getRuntime().totalMemory());
379 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
381 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
383 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
387 public void testCommit(){
388 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
390 // when replicatedToAllIndex = -1
391 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
392 new MockRaftActorContext.MockPayload()), -1, "follower-1");
394 snapshotManager.create(mockProcedure);
396 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
397 , Runtime.getRuntime().totalMemory());
399 snapshotManager.commit(mockDataPersistenceProvider, 100L);
401 verify(mockReplicatedLog).snapshotCommit();
403 verify(mockDataPersistenceProvider).deleteMessages(50L);
405 ArgumentCaptor<SnapshotSelectionCriteria> criteriaCaptor = ArgumentCaptor.forClass(SnapshotSelectionCriteria.class);
407 verify(mockDataPersistenceProvider).deleteSnapshots(criteriaCaptor.capture());
409 assertEquals(90, criteriaCaptor.getValue().maxSequenceNr()); // sequenceNumber = 100
410 // config snapShotBatchCount = 10
411 // therefore maxSequenceNumber = 90
415 public void testCommitBeforePersist(){
416 // when replicatedToAllIndex = -1
417 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
418 new MockRaftActorContext.MockPayload()), -1, "follower-1");
420 snapshotManager.commit(mockDataPersistenceProvider, 100L);
422 verify(mockReplicatedLog, never()).snapshotCommit();
424 verify(mockDataPersistenceProvider, never()).deleteMessages(100L);
426 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
431 public void testCommitBeforeCapture(){
432 snapshotManager.commit(mockDataPersistenceProvider, 100L);
434 verify(mockReplicatedLog, never()).snapshotCommit();
436 verify(mockDataPersistenceProvider, never()).deleteMessages(anyLong());
438 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
443 public void testCallingCommitMultipleTimesCausesNoHarm(){
444 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
446 // when replicatedToAllIndex = -1
447 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
448 new MockRaftActorContext.MockPayload()), -1, "follower-1");
450 snapshotManager.create(mockProcedure);
452 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
453 , Runtime.getRuntime().totalMemory());
455 snapshotManager.commit(mockDataPersistenceProvider, 100L);
457 snapshotManager.commit(mockDataPersistenceProvider, 100L);
459 verify(mockReplicatedLog, times(1)).snapshotCommit();
461 verify(mockDataPersistenceProvider, times(1)).deleteMessages(50L);
463 verify(mockDataPersistenceProvider, times(1)).deleteSnapshots(any(SnapshotSelectionCriteria.class));
467 public void testRollback(){
468 // when replicatedToAllIndex = -1
469 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
470 new MockRaftActorContext.MockPayload()), -1, "follower-1");
472 snapshotManager.create(mockProcedure);
474 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
475 , Runtime.getRuntime().totalMemory());
477 snapshotManager.rollback();
479 verify(mockReplicatedLog).snapshotRollback();
484 public void testRollbackBeforePersist(){
485 // when replicatedToAllIndex = -1
486 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
487 new MockRaftActorContext.MockPayload()), -1, "follower-1");
489 snapshotManager.rollback();
491 verify(mockReplicatedLog, never()).snapshotRollback();
495 public void testRollbackBeforeCapture(){
496 snapshotManager.rollback();
498 verify(mockReplicatedLog, never()).snapshotRollback();
502 public void testCallingRollbackMultipleTimesCausesNoHarm(){
503 // when replicatedToAllIndex = -1
504 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
505 new MockRaftActorContext.MockPayload()), -1, "follower-1");
507 snapshotManager.create(mockProcedure);
509 snapshotManager.persist(mockDataPersistenceProvider, new byte[]{}, mockRaftActorBehavior
510 , Runtime.getRuntime().totalMemory());
512 snapshotManager.rollback();
514 snapshotManager.rollback();
516 verify(mockReplicatedLog, times(1)).snapshotRollback();
520 public void testTrimLogWhenTrimIndexLessThanLastApplied() {
521 doReturn(20L).when(mockRaftActorContext).getLastApplied();
523 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
524 doReturn(true).when(mockReplicatedLog).isPresent(10);
525 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
526 doReturn(5L).when(replicatedLogEntry).getTerm();
528 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
529 assertEquals("return index", 10L, retIndex);
531 verify(mockReplicatedLog).snapshotPreCommit(10, 5);
532 verify(mockReplicatedLog).snapshotCommit();
534 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
538 public void testTrimLogWhenLastAppliedNotSet() {
539 doReturn(-1L).when(mockRaftActorContext).getLastApplied();
541 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
542 doReturn(true).when(mockReplicatedLog).isPresent(10);
543 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
544 doReturn(5L).when(replicatedLogEntry).getTerm();
546 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
547 assertEquals("return index", -1L, retIndex);
549 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
550 verify(mockReplicatedLog, never()).snapshotCommit();
552 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
556 public void testTrimLogWhenLastAppliedZero() {
557 doReturn(0L).when(mockRaftActorContext).getLastApplied();
559 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
560 doReturn(true).when(mockReplicatedLog).isPresent(10);
561 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
562 doReturn(5L).when(replicatedLogEntry).getTerm();
564 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
565 assertEquals("return index", -1L, retIndex);
567 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
568 verify(mockReplicatedLog, never()).snapshotCommit();
570 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
574 public void testTrimLogWhenTrimIndexNotPresent() {
575 doReturn(20L).when(mockRaftActorContext).getLastApplied();
577 doReturn(false).when(mockReplicatedLog).isPresent(10);
579 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
580 assertEquals("return index", -1L, retIndex);
582 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
583 verify(mockReplicatedLog, never()).snapshotCommit();
585 // Trim index is greater than replicatedToAllIndex so should update it.
586 verify(mockRaftActorBehavior).setReplicatedToAllIndex(10L);
590 public void testTrimLogAfterCapture(){
591 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
592 new MockRaftActorContext.MockPayload()), 9);
596 assertEquals(true, snapshotManager.isCapturing());
598 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
599 doReturn(20L).when(mockRaftActorContext).getLastApplied();
600 doReturn(true).when(mockReplicatedLog).isPresent(10);
601 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
602 doReturn(5L).when(replicatedLogEntry).getTerm();
604 snapshotManager.trimLog(10, mockRaftActorBehavior);
606 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
607 verify(mockReplicatedLog, never()).snapshotCommit();
612 public void testTrimLogAfterCaptureToInstall(){
613 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
614 new MockRaftActorContext.MockPayload()), 9, "follower-1");
618 assertEquals(true, snapshotManager.isCapturing());
620 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
621 doReturn(20L).when(mockRaftActorContext).getLastApplied();
622 doReturn(true).when(mockReplicatedLog).isPresent(10);
623 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
624 doReturn(5L).when(replicatedLogEntry).getTerm();
626 snapshotManager.trimLog(10, mockRaftActorBehavior);
628 verify(mockReplicatedLog, never()).snapshotPreCommit(10, 5);
629 verify(mockReplicatedLog, never()).snapshotCommit();
634 public void testLastAppliedTermInformationReader() {
636 LastAppliedTermInformationReader reader = new LastAppliedTermInformationReader();
638 doReturn(4L).when(mockReplicatedLog).getSnapshotTerm();
639 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
641 ReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(6L, 9L,
642 new MockRaftActorContext.MockPayload());
644 // No followers and valid lastLogEntry
645 reader.init(mockReplicatedLog, 1L, lastLogEntry, false);
647 assertEquals("getTerm", 6L, reader.getTerm());
648 assertEquals("getIndex", 9L, reader.getIndex());
650 // No followers and null lastLogEntry
651 reader.init(mockReplicatedLog, 1L, null, false);
653 assertEquals("getTerm", -1L, reader.getTerm());
654 assertEquals("getIndex", -1L, reader.getIndex());
656 // Followers and valid originalIndex entry
657 doReturn(new MockRaftActorContext.MockReplicatedLogEntry(5L, 8L,
658 new MockRaftActorContext.MockPayload())).when(mockReplicatedLog).get(8L);
659 reader.init(mockReplicatedLog, 8L, lastLogEntry, true);
661 assertEquals("getTerm", 5L, reader.getTerm());
662 assertEquals("getIndex", 8L, reader.getIndex());
664 // Followers and null originalIndex entry and valid snapshot index
665 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
667 assertEquals("getTerm", 4L, reader.getTerm());
668 assertEquals("getIndex", 7L, reader.getIndex());
670 // Followers and null originalIndex entry and invalid snapshot index
671 doReturn(-1L).when(mockReplicatedLog).getSnapshotIndex();
672 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
674 assertEquals("getTerm", -1L, reader.getTerm());
675 assertEquals("getIndex", -1L, reader.getIndex());