2 * Copyright (c) 2015 Cisco Systems, Inc. and others. All rights reserved.
4 * This program and the accompanying materials are made available under the
5 * terms of the Eclipse Public License v1.0 which accompanies this distribution,
6 * and is available at http://www.eclipse.org/legal/epl-v10.html
9 package org.opendaylight.controller.cluster.raft;
11 import static org.junit.Assert.assertArrayEquals;
12 import static org.junit.Assert.assertEquals;
13 import static org.junit.Assert.assertFalse;
14 import static org.junit.Assert.assertTrue;
15 import static org.mockito.Matchers.any;
16 import static org.mockito.Matchers.anyLong;
17 import static org.mockito.Mockito.doReturn;
18 import static org.mockito.Mockito.doThrow;
19 import static org.mockito.Mockito.mock;
20 import static org.mockito.Mockito.never;
21 import static org.mockito.Mockito.reset;
22 import static org.mockito.Mockito.times;
23 import static org.mockito.Mockito.verify;
24 import akka.actor.ActorRef;
25 import akka.japi.Procedure;
26 import akka.persistence.SnapshotSelectionCriteria;
27 import akka.testkit.TestActorRef;
28 import java.util.Arrays;
29 import org.junit.After;
30 import org.junit.Before;
31 import org.junit.Test;
32 import org.mockito.ArgumentCaptor;
33 import org.mockito.Mock;
34 import org.mockito.MockitoAnnotations;
35 import org.opendaylight.controller.cluster.DataPersistenceProvider;
36 import org.opendaylight.controller.cluster.raft.SnapshotManager.LastAppliedTermInformationReader;
37 import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot;
38 import org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot;
39 import org.opendaylight.controller.cluster.raft.base.messages.SnapshotComplete;
40 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
41 import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
42 import org.slf4j.LoggerFactory;
44 public class SnapshotManagerTest extends AbstractActorTest {
47 private RaftActorContext mockRaftActorContext;
50 private ConfigParams mockConfigParams;
53 private ReplicatedLog mockReplicatedLog;
56 private DataPersistenceProvider mockDataPersistenceProvider;
59 private RaftActorBehavior mockRaftActorBehavior;
62 private Procedure<Void> mockProcedure;
65 private ElectionTerm mockElectionTerm;
67 private SnapshotManager snapshotManager;
69 private TestActorFactory factory;
71 private TestActorRef<MessageCollectorActor> actorRef;
75 MockitoAnnotations.initMocks(this);
77 doReturn(false).when(mockRaftActorContext).hasFollowers();
78 doReturn(mockConfigParams).when(mockRaftActorContext).getConfigParams();
79 doReturn(10L).when(mockConfigParams).getSnapshotBatchCount();
80 doReturn(70).when(mockConfigParams).getSnapshotDataThresholdPercentage();
81 doReturn(mockReplicatedLog).when(mockRaftActorContext).getReplicatedLog();
82 doReturn("123").when(mockRaftActorContext).getId();
83 doReturn(mockDataPersistenceProvider).when(mockRaftActorContext).getPersistenceProvider();
84 doReturn(mockRaftActorBehavior).when(mockRaftActorContext).getCurrentBehavior();
85 doReturn("123").when(mockRaftActorBehavior).getLeaderId();
87 doReturn(mockElectionTerm).when(mockRaftActorContext).getTermInformation();
88 doReturn(5L).when(mockElectionTerm).getCurrentTerm();
89 doReturn("member5").when(mockElectionTerm).getVotedFor();
91 snapshotManager = new SnapshotManager(mockRaftActorContext, LoggerFactory.getLogger(this.getClass()));
92 factory = new TestActorFactory(getSystem());
94 actorRef = factory.createTestActor(MessageCollectorActor.props(), factory.generateActorId("test-"));
95 doReturn(actorRef).when(mockRaftActorContext).getActor();
97 snapshotManager.setCreateSnapshotCallable(mockProcedure);
101 public void tearDown(){
106 public void testConstruction(){
107 assertEquals(false, snapshotManager.isCapturing());
111 public void testCaptureToInstall() throws Exception {
113 // Force capturing toInstall = true
114 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1, 0,
115 new MockRaftActorContext.MockPayload()), 0, "follower-1");
117 assertEquals(true, snapshotManager.isCapturing());
119 verify(mockProcedure).apply(null);
121 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
123 // LastIndex and LastTerm are picked up from the lastLogEntry
124 assertEquals(0L, captureSnapshot.getLastIndex());
125 assertEquals(1L, captureSnapshot.getLastTerm());
127 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
128 assertEquals(0L, captureSnapshot.getLastAppliedIndex());
129 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
132 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
133 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
134 actorRef.underlyingActor().clear();
138 public void testCapture() throws Exception {
139 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
140 new MockRaftActorContext.MockPayload()), 9);
144 assertEquals(true, snapshotManager.isCapturing());
146 verify(mockProcedure).apply(null);
148 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
150 // LastIndex and LastTerm are picked up from the lastLogEntry
151 assertEquals(9L, captureSnapshot.getLastIndex());
152 assertEquals(1L, captureSnapshot.getLastTerm());
154 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
155 assertEquals(9L, captureSnapshot.getLastAppliedIndex());
156 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
159 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
160 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
162 actorRef.underlyingActor().clear();
167 public void testCaptureWithNullLastLogEntry() throws Exception {
168 boolean capture = snapshotManager.capture(null, 1);
172 assertEquals(true, snapshotManager.isCapturing());
174 verify(mockProcedure).apply(null);
176 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
178 System.out.println(captureSnapshot);
180 // LastIndex and LastTerm are picked up from the lastLogEntry
181 assertEquals(-1L, captureSnapshot.getLastIndex());
182 assertEquals(-1L, captureSnapshot.getLastTerm());
184 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
185 assertEquals(-1L, captureSnapshot.getLastAppliedIndex());
186 assertEquals(-1L, captureSnapshot.getLastAppliedTerm());
189 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
190 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
191 actorRef.underlyingActor().clear();
196 public void testCaptureWithCreateProcedureError () throws Exception {
197 doThrow(new Exception("mock")).when(mockProcedure).apply(null);
199 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
200 new MockRaftActorContext.MockPayload()), 9);
202 assertFalse(capture);
204 assertEquals(false, snapshotManager.isCapturing());
206 verify(mockProcedure).apply(null);
210 public void testIllegalCapture() throws Exception {
211 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
212 new MockRaftActorContext.MockPayload()), 9);
216 verify(mockProcedure).apply(null);
218 reset(mockProcedure);
220 // This will not cause snapshot capture to start again
221 capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
222 new MockRaftActorContext.MockPayload()), 9);
224 assertFalse(capture);
226 verify(mockProcedure, never()).apply(null);
230 public void testPersistWhenReplicatedToAllIndexMinusOne(){
231 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
232 doReturn(1L).when(mockReplicatedLog).getSnapshotTerm();
234 doReturn(true).when(mockRaftActorContext).hasFollowers();
236 doReturn(8L).when(mockRaftActorContext).getLastApplied();
238 MockRaftActorContext.MockReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(
239 3L, 9L, new MockRaftActorContext.MockPayload());
241 MockRaftActorContext.MockReplicatedLogEntry lastAppliedEntry = new MockRaftActorContext.MockReplicatedLogEntry(
242 2L, 8L, new MockRaftActorContext.MockPayload());
244 doReturn(lastAppliedEntry).when(mockReplicatedLog).get(8L);
245 doReturn(Arrays.asList(lastLogEntry)).when(mockReplicatedLog).getFrom(9L);
247 // when replicatedToAllIndex = -1
248 snapshotManager.capture(lastLogEntry, -1);
250 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
251 snapshotManager.persist(bytes, Runtime.getRuntime().totalMemory());
253 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
254 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
256 Snapshot snapshot = snapshotArgumentCaptor.getValue();
258 assertEquals("getLastTerm", 3L, snapshot.getLastTerm());
259 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
260 assertEquals("getLastAppliedTerm", 2L, snapshot.getLastAppliedTerm());
261 assertEquals("getLastAppliedIndex", 8L, snapshot.getLastAppliedIndex());
262 assertArrayEquals("getState", bytes, snapshot.getState());
263 assertEquals("getUnAppliedEntries", Arrays.asList(lastLogEntry), snapshot.getUnAppliedEntries());
264 assertEquals("electionTerm", mockElectionTerm.getCurrentTerm(), snapshot.getElectionTerm());
265 assertEquals("electionVotedFor", mockElectionTerm.getVotedFor(), snapshot.getElectionVotedFor());
267 verify(mockReplicatedLog).snapshotPreCommit(7L, 1L);
271 public void testPersistWhenReplicatedToAllIndexNotMinus(){
272 doReturn(45L).when(mockReplicatedLog).getSnapshotIndex();
273 doReturn(6L).when(mockReplicatedLog).getSnapshotTerm();
274 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
275 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(9);
276 doReturn(6L).when(replicatedLogEntry).getTerm();
277 doReturn(9L).when(replicatedLogEntry).getIndex();
279 // when replicatedToAllIndex != -1
280 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
281 new MockRaftActorContext.MockPayload()), 9);
283 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
284 snapshotManager.persist(bytes, Runtime.getRuntime().totalMemory());
286 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
287 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
289 Snapshot snapshot = snapshotArgumentCaptor.getValue();
291 assertEquals("getLastTerm", 6L, snapshot.getLastTerm());
292 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
293 assertEquals("getLastAppliedTerm", 6L, snapshot.getLastAppliedTerm());
294 assertEquals("getLastAppliedIndex", 9L, snapshot.getLastAppliedIndex());
295 assertArrayEquals("getState", bytes, snapshot.getState());
296 assertEquals("getUnAppliedEntries size", 0, snapshot.getUnAppliedEntries().size());
298 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
300 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.persist(new byte[]{}, Runtime.getRuntime().totalMemory());
313 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
315 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
317 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
321 public void testPersistWhenReplicatedLogSizeExceedsSnapshotBatchCount() {
322 doReturn(10L).when(mockReplicatedLog).size(); // matches snapshotBatchCount
323 doReturn(100).when(mockReplicatedLog).dataSize();
325 doReturn(5L).when(mockReplicatedLog).getSnapshotIndex();
326 doReturn(5L).when(mockReplicatedLog).getSnapshotTerm();
328 long replicatedToAllIndex = 1;
329 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
330 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(replicatedToAllIndex);
331 doReturn(6L).when(replicatedLogEntry).getTerm();
332 doReturn(replicatedToAllIndex).when(replicatedLogEntry).getIndex();
334 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
335 new MockRaftActorContext.MockPayload()), replicatedToAllIndex);
337 snapshotManager.persist(new byte[]{}, 2000000L);
339 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
341 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
343 verify(mockRaftActorBehavior).setReplicatedToAllIndex(replicatedToAllIndex);
347 public void testPersistSendInstallSnapshot(){
348 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
350 // when replicatedToAllIndex = -1
351 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
352 new MockRaftActorContext.MockPayload()), -1, "follower-1");
356 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
358 snapshotManager.persist(bytes, Runtime.getRuntime().totalMemory());
360 assertEquals(true, snapshotManager.isCapturing());
362 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
364 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
366 ArgumentCaptor<SendInstallSnapshot> sendInstallSnapshotArgumentCaptor
367 = ArgumentCaptor.forClass(SendInstallSnapshot.class);
369 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), sendInstallSnapshotArgumentCaptor.capture());
371 SendInstallSnapshot sendInstallSnapshot = sendInstallSnapshotArgumentCaptor.getValue();
373 assertTrue(Arrays.equals(bytes, sendInstallSnapshot.getSnapshot().getState()));
377 public void testCallingPersistWithoutCaptureWillDoNothing(){
378 snapshotManager.persist(new byte[]{}, Runtime.getRuntime().totalMemory());
380 verify(mockDataPersistenceProvider, never()).saveSnapshot(any(Snapshot.class));
382 verify(mockReplicatedLog, never()).snapshotPreCommit(9L, 6L);
384 verify(mockRaftActorBehavior, never()).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
387 public void testCallingPersistTwiceWillDoNoHarm(){
388 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
390 // when replicatedToAllIndex = -1
391 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
392 new MockRaftActorContext.MockPayload()), -1, "follower-1");
394 snapshotManager.persist(new byte[]{}, Runtime.getRuntime().totalMemory());
396 snapshotManager.persist(new byte[]{}, Runtime.getRuntime().totalMemory());
398 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
400 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
402 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
406 public void testCommit(){
407 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
409 // when replicatedToAllIndex = -1
410 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
411 new MockRaftActorContext.MockPayload()), -1, "follower-1");
413 snapshotManager.persist(new byte[]{}, Runtime.getRuntime().totalMemory());
415 assertEquals(true, snapshotManager.isCapturing());
417 snapshotManager.commit(100L);
419 assertEquals(false, snapshotManager.isCapturing());
421 verify(mockReplicatedLog).snapshotCommit();
423 verify(mockDataPersistenceProvider).deleteMessages(50L);
425 ArgumentCaptor<SnapshotSelectionCriteria> criteriaCaptor = ArgumentCaptor.forClass(SnapshotSelectionCriteria.class);
427 verify(mockDataPersistenceProvider).deleteSnapshots(criteriaCaptor.capture());
429 assertEquals(90, criteriaCaptor.getValue().maxSequenceNr()); // sequenceNumber = 100
430 // config snapShotBatchCount = 10
431 // therefore maxSequenceNumber = 90
433 MessageCollectorActor.expectFirstMatching(actorRef, SnapshotComplete.class);
437 public void testCommitBeforePersist(){
438 // when replicatedToAllIndex = -1
439 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
440 new MockRaftActorContext.MockPayload()), -1, "follower-1");
442 snapshotManager.commit(100L);
444 verify(mockReplicatedLog, never()).snapshotCommit();
446 verify(mockDataPersistenceProvider, never()).deleteMessages(100L);
448 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
453 public void testCommitBeforeCapture(){
454 snapshotManager.commit(100L);
456 verify(mockReplicatedLog, never()).snapshotCommit();
458 verify(mockDataPersistenceProvider, never()).deleteMessages(anyLong());
460 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
465 public void testCallingCommitMultipleTimesCausesNoHarm(){
466 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
468 // when replicatedToAllIndex = -1
469 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
470 new MockRaftActorContext.MockPayload()), -1, "follower-1");
472 snapshotManager.persist(new byte[]{}, Runtime.getRuntime().totalMemory());
474 snapshotManager.commit(100L);
476 snapshotManager.commit(100L);
478 verify(mockReplicatedLog, times(1)).snapshotCommit();
480 verify(mockDataPersistenceProvider, times(1)).deleteMessages(50L);
482 verify(mockDataPersistenceProvider, times(1)).deleteSnapshots(any(SnapshotSelectionCriteria.class));
486 public void testRollback(){
487 // when replicatedToAllIndex = -1
488 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
489 new MockRaftActorContext.MockPayload()), -1, "follower-1");
491 snapshotManager.persist(new byte[]{}, Runtime.getRuntime().totalMemory());
493 snapshotManager.rollback();
495 verify(mockReplicatedLog).snapshotRollback();
497 MessageCollectorActor.expectFirstMatching(actorRef, SnapshotComplete.class);
502 public void testRollbackBeforePersist(){
503 // when replicatedToAllIndex = -1
504 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
505 new MockRaftActorContext.MockPayload()), -1, "follower-1");
507 snapshotManager.rollback();
509 verify(mockReplicatedLog, never()).snapshotRollback();
513 public void testRollbackBeforeCapture(){
514 snapshotManager.rollback();
516 verify(mockReplicatedLog, never()).snapshotRollback();
520 public void testCallingRollbackMultipleTimesCausesNoHarm(){
521 // when replicatedToAllIndex = -1
522 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
523 new MockRaftActorContext.MockPayload()), -1, "follower-1");
525 snapshotManager.persist(new byte[]{}, Runtime.getRuntime().totalMemory());
527 snapshotManager.rollback();
529 snapshotManager.rollback();
531 verify(mockReplicatedLog, times(1)).snapshotRollback();
535 public void testTrimLogWhenTrimIndexLessThanLastApplied() {
536 doReturn(20L).when(mockRaftActorContext).getLastApplied();
538 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
539 doReturn(true).when(mockReplicatedLog).isPresent(10);
540 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
541 doReturn(5L).when(replicatedLogEntry).getTerm();
543 long retIndex = snapshotManager.trimLog(10);
544 assertEquals("return index", 10L, retIndex);
546 verify(mockReplicatedLog).snapshotPreCommit(10, 5);
547 verify(mockReplicatedLog).snapshotCommit();
549 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
553 public void testTrimLogWhenLastAppliedNotSet() {
554 doReturn(-1L).when(mockRaftActorContext).getLastApplied();
556 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
557 doReturn(true).when(mockReplicatedLog).isPresent(10);
558 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
559 doReturn(5L).when(replicatedLogEntry).getTerm();
561 long retIndex = snapshotManager.trimLog(10);
562 assertEquals("return index", -1L, retIndex);
564 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
565 verify(mockReplicatedLog, never()).snapshotCommit();
567 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
571 public void testTrimLogWhenLastAppliedZero() {
572 doReturn(0L).when(mockRaftActorContext).getLastApplied();
574 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
575 doReturn(true).when(mockReplicatedLog).isPresent(10);
576 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
577 doReturn(5L).when(replicatedLogEntry).getTerm();
579 long retIndex = snapshotManager.trimLog(10);
580 assertEquals("return index", -1L, retIndex);
582 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
583 verify(mockReplicatedLog, never()).snapshotCommit();
585 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
589 public void testTrimLogWhenTrimIndexNotPresent() {
590 doReturn(20L).when(mockRaftActorContext).getLastApplied();
592 doReturn(false).when(mockReplicatedLog).isPresent(10);
594 long retIndex = snapshotManager.trimLog(10);
595 assertEquals("return index", -1L, retIndex);
597 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
598 verify(mockReplicatedLog, never()).snapshotCommit();
600 // Trim index is greater than replicatedToAllIndex so should update it.
601 verify(mockRaftActorBehavior).setReplicatedToAllIndex(10L);
605 public void testTrimLogAfterCapture(){
606 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
607 new MockRaftActorContext.MockPayload()), 9);
611 assertEquals(true, snapshotManager.isCapturing());
613 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
614 doReturn(20L).when(mockRaftActorContext).getLastApplied();
615 doReturn(true).when(mockReplicatedLog).isPresent(10);
616 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
617 doReturn(5L).when(replicatedLogEntry).getTerm();
619 snapshotManager.trimLog(10);
621 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
622 verify(mockReplicatedLog, never()).snapshotCommit();
627 public void testTrimLogAfterCaptureToInstall(){
628 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
629 new MockRaftActorContext.MockPayload()), 9, "follower-1");
633 assertEquals(true, snapshotManager.isCapturing());
635 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
636 doReturn(20L).when(mockRaftActorContext).getLastApplied();
637 doReturn(true).when(mockReplicatedLog).isPresent(10);
638 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
639 doReturn(5L).when(replicatedLogEntry).getTerm();
641 snapshotManager.trimLog(10);
643 verify(mockReplicatedLog, never()).snapshotPreCommit(10, 5);
644 verify(mockReplicatedLog, never()).snapshotCommit();
649 public void testLastAppliedTermInformationReader() {
651 LastAppliedTermInformationReader reader = new LastAppliedTermInformationReader();
653 doReturn(4L).when(mockReplicatedLog).getSnapshotTerm();
654 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
656 ReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(6L, 9L,
657 new MockRaftActorContext.MockPayload());
659 // No followers and valid lastLogEntry
660 reader.init(mockReplicatedLog, 1L, lastLogEntry, false);
662 assertEquals("getTerm", 6L, reader.getTerm());
663 assertEquals("getIndex", 9L, reader.getIndex());
665 // No followers and null lastLogEntry
666 reader.init(mockReplicatedLog, 1L, null, false);
668 assertEquals("getTerm", -1L, reader.getTerm());
669 assertEquals("getIndex", -1L, reader.getIndex());
671 // Followers and valid originalIndex entry
672 doReturn(new MockRaftActorContext.MockReplicatedLogEntry(5L, 8L,
673 new MockRaftActorContext.MockPayload())).when(mockReplicatedLog).get(8L);
674 reader.init(mockReplicatedLog, 8L, lastLogEntry, true);
676 assertEquals("getTerm", 5L, reader.getTerm());
677 assertEquals("getIndex", 8L, reader.getIndex());
679 // Followers and null originalIndex entry and valid snapshot index
680 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
682 assertEquals("getTerm", 4L, reader.getTerm());
683 assertEquals("getIndex", 7L, reader.getIndex());
685 // Followers and null originalIndex entry and invalid snapshot index
686 doReturn(-1L).when(mockReplicatedLog).getSnapshotIndex();
687 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
689 assertEquals("getTerm", -1L, reader.getTerm());
690 assertEquals("getIndex", -1L, reader.getIndex());