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("123").when(mockRaftActorBehavior).getLeaderId();
86 doReturn(mockElectionTerm).when(mockRaftActorContext).getTermInformation();
87 doReturn(5L).when(mockElectionTerm).getCurrentTerm();
88 doReturn("member5").when(mockElectionTerm).getVotedFor();
90 snapshotManager = new SnapshotManager(mockRaftActorContext, LoggerFactory.getLogger(this.getClass()));
91 factory = new TestActorFactory(getSystem());
93 actorRef = factory.createTestActor(MessageCollectorActor.props(), factory.generateActorId("test-"));
94 doReturn(actorRef).when(mockRaftActorContext).getActor();
96 snapshotManager.setCreateSnapshotCallable(mockProcedure);
100 public void tearDown(){
105 public void testConstruction(){
106 assertEquals(false, snapshotManager.isCapturing());
110 public void testCaptureToInstall() throws Exception {
112 // Force capturing toInstall = true
113 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1, 0,
114 new MockRaftActorContext.MockPayload()), 0, "follower-1");
116 assertEquals(true, snapshotManager.isCapturing());
118 verify(mockProcedure).apply(null);
120 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
122 // LastIndex and LastTerm are picked up from the lastLogEntry
123 assertEquals(0L, captureSnapshot.getLastIndex());
124 assertEquals(1L, captureSnapshot.getLastTerm());
126 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
127 assertEquals(0L, captureSnapshot.getLastAppliedIndex());
128 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
131 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
132 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
133 actorRef.underlyingActor().clear();
137 public void testCapture() throws Exception {
138 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
139 new MockRaftActorContext.MockPayload()), 9);
143 assertEquals(true, snapshotManager.isCapturing());
145 verify(mockProcedure).apply(null);
147 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
149 // LastIndex and LastTerm are picked up from the lastLogEntry
150 assertEquals(9L, captureSnapshot.getLastIndex());
151 assertEquals(1L, captureSnapshot.getLastTerm());
153 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
154 assertEquals(9L, captureSnapshot.getLastAppliedIndex());
155 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
158 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
159 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
161 actorRef.underlyingActor().clear();
166 public void testCaptureWithNullLastLogEntry() throws Exception {
167 boolean capture = snapshotManager.capture(null, 1);
171 assertEquals(true, snapshotManager.isCapturing());
173 verify(mockProcedure).apply(null);
175 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
177 System.out.println(captureSnapshot);
179 // LastIndex and LastTerm are picked up from the lastLogEntry
180 assertEquals(-1L, captureSnapshot.getLastIndex());
181 assertEquals(-1L, captureSnapshot.getLastTerm());
183 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
184 assertEquals(-1L, captureSnapshot.getLastAppliedIndex());
185 assertEquals(-1L, captureSnapshot.getLastAppliedTerm());
188 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
189 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
190 actorRef.underlyingActor().clear();
195 public void testCaptureWithCreateProcedureError () throws Exception {
196 doThrow(new Exception("mock")).when(mockProcedure).apply(null);
198 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
199 new MockRaftActorContext.MockPayload()), 9);
201 assertFalse(capture);
203 assertEquals(false, snapshotManager.isCapturing());
205 verify(mockProcedure).apply(null);
209 public void testIllegalCapture() throws Exception {
210 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
211 new MockRaftActorContext.MockPayload()), 9);
215 verify(mockProcedure).apply(null);
217 reset(mockProcedure);
219 // This will not cause snapshot capture to start again
220 capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
221 new MockRaftActorContext.MockPayload()), 9);
223 assertFalse(capture);
225 verify(mockProcedure, never()).apply(null);
229 public void testPersistWhenReplicatedToAllIndexMinusOne(){
230 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
231 doReturn(1L).when(mockReplicatedLog).getSnapshotTerm();
233 doReturn(true).when(mockRaftActorContext).hasFollowers();
235 doReturn(8L).when(mockRaftActorContext).getLastApplied();
237 MockRaftActorContext.MockReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(
238 3L, 9L, new MockRaftActorContext.MockPayload());
240 MockRaftActorContext.MockReplicatedLogEntry lastAppliedEntry = new MockRaftActorContext.MockReplicatedLogEntry(
241 2L, 8L, new MockRaftActorContext.MockPayload());
243 doReturn(lastAppliedEntry).when(mockReplicatedLog).get(8L);
244 doReturn(Arrays.asList(lastLogEntry)).when(mockReplicatedLog).getFrom(9L);
246 // when replicatedToAllIndex = -1
247 snapshotManager.capture(lastLogEntry, -1);
249 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
250 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
252 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
253 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
255 Snapshot snapshot = snapshotArgumentCaptor.getValue();
257 assertEquals("getLastTerm", 3L, snapshot.getLastTerm());
258 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
259 assertEquals("getLastAppliedTerm", 2L, snapshot.getLastAppliedTerm());
260 assertEquals("getLastAppliedIndex", 8L, snapshot.getLastAppliedIndex());
261 assertArrayEquals("getState", bytes, snapshot.getState());
262 assertEquals("getUnAppliedEntries", Arrays.asList(lastLogEntry), snapshot.getUnAppliedEntries());
263 assertEquals("electionTerm", mockElectionTerm.getCurrentTerm(), snapshot.getElectionTerm());
264 assertEquals("electionVotedFor", mockElectionTerm.getVotedFor(), snapshot.getElectionVotedFor());
266 verify(mockReplicatedLog).snapshotPreCommit(7L, 1L);
270 public void testPersistWhenReplicatedToAllIndexNotMinus(){
271 doReturn(45L).when(mockReplicatedLog).getSnapshotIndex();
272 doReturn(6L).when(mockReplicatedLog).getSnapshotTerm();
273 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
274 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(9);
275 doReturn(6L).when(replicatedLogEntry).getTerm();
276 doReturn(9L).when(replicatedLogEntry).getIndex();
278 // when replicatedToAllIndex != -1
279 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
280 new MockRaftActorContext.MockPayload()), 9);
282 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
283 snapshotManager.persist(bytes, mockRaftActorBehavior, 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);
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.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
312 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
314 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
316 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
320 public void testPersistWhenReplicatedLogSizeExceedsSnapshotBatchCount() {
321 doReturn(10L).when(mockReplicatedLog).size(); // matches snapshotBatchCount
322 doReturn(100).when(mockReplicatedLog).dataSize();
324 doReturn(5L).when(mockReplicatedLog).getSnapshotIndex();
325 doReturn(5L).when(mockReplicatedLog).getSnapshotTerm();
327 long replicatedToAllIndex = 1;
328 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
329 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(replicatedToAllIndex);
330 doReturn(6L).when(replicatedLogEntry).getTerm();
331 doReturn(replicatedToAllIndex).when(replicatedLogEntry).getIndex();
333 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
334 new MockRaftActorContext.MockPayload()), replicatedToAllIndex);
336 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, 2000000L);
338 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
340 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
342 verify(mockRaftActorBehavior).setReplicatedToAllIndex(replicatedToAllIndex);
346 public void testPersistSendInstallSnapshot(){
347 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
349 // when replicatedToAllIndex = -1
350 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
351 new MockRaftActorContext.MockPayload()), -1, "follower-1");
355 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
357 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
359 assertEquals(true, snapshotManager.isCapturing());
361 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
363 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
365 ArgumentCaptor<SendInstallSnapshot> sendInstallSnapshotArgumentCaptor
366 = ArgumentCaptor.forClass(SendInstallSnapshot.class);
368 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), sendInstallSnapshotArgumentCaptor.capture());
370 SendInstallSnapshot sendInstallSnapshot = sendInstallSnapshotArgumentCaptor.getValue();
372 assertTrue(Arrays.equals(bytes, sendInstallSnapshot.getSnapshot().getState()));
376 public void testCallingPersistWithoutCaptureWillDoNothing(){
377 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
379 verify(mockDataPersistenceProvider, never()).saveSnapshot(any(Snapshot.class));
381 verify(mockReplicatedLog, never()).snapshotPreCommit(9L, 6L);
383 verify(mockRaftActorBehavior, never()).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
386 public void testCallingPersistTwiceWillDoNoHarm(){
387 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
389 // when replicatedToAllIndex = -1
390 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
391 new MockRaftActorContext.MockPayload()), -1, "follower-1");
393 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
395 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
397 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
399 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
401 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
405 public void testCommit(){
406 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
408 // when replicatedToAllIndex = -1
409 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
410 new MockRaftActorContext.MockPayload()), -1, "follower-1");
412 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
414 assertEquals(true, snapshotManager.isCapturing());
416 snapshotManager.commit(100L, mockRaftActorBehavior);
418 assertEquals(false, snapshotManager.isCapturing());
420 verify(mockReplicatedLog).snapshotCommit();
422 verify(mockDataPersistenceProvider).deleteMessages(50L);
424 ArgumentCaptor<SnapshotSelectionCriteria> criteriaCaptor = ArgumentCaptor.forClass(SnapshotSelectionCriteria.class);
426 verify(mockDataPersistenceProvider).deleteSnapshots(criteriaCaptor.capture());
428 assertEquals(90, criteriaCaptor.getValue().maxSequenceNr()); // sequenceNumber = 100
429 // config snapShotBatchCount = 10
430 // therefore maxSequenceNumber = 90
432 MessageCollectorActor.expectFirstMatching(actorRef, SnapshotComplete.class);
436 public void testCommitBeforePersist(){
437 // when replicatedToAllIndex = -1
438 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
439 new MockRaftActorContext.MockPayload()), -1, "follower-1");
441 snapshotManager.commit(100L, mockRaftActorBehavior);
443 verify(mockReplicatedLog, never()).snapshotCommit();
445 verify(mockDataPersistenceProvider, never()).deleteMessages(100L);
447 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
452 public void testCommitBeforeCapture(){
453 snapshotManager.commit(100L, mockRaftActorBehavior);
455 verify(mockReplicatedLog, never()).snapshotCommit();
457 verify(mockDataPersistenceProvider, never()).deleteMessages(anyLong());
459 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
464 public void testCallingCommitMultipleTimesCausesNoHarm(){
465 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
467 // when replicatedToAllIndex = -1
468 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
469 new MockRaftActorContext.MockPayload()), -1, "follower-1");
471 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
473 snapshotManager.commit(100L, mockRaftActorBehavior);
475 snapshotManager.commit(100L, mockRaftActorBehavior);
477 verify(mockReplicatedLog, times(1)).snapshotCommit();
479 verify(mockDataPersistenceProvider, times(1)).deleteMessages(50L);
481 verify(mockDataPersistenceProvider, times(1)).deleteSnapshots(any(SnapshotSelectionCriteria.class));
485 public void testRollback(){
486 // when replicatedToAllIndex = -1
487 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
488 new MockRaftActorContext.MockPayload()), -1, "follower-1");
490 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
492 snapshotManager.rollback();
494 verify(mockReplicatedLog).snapshotRollback();
496 MessageCollectorActor.expectFirstMatching(actorRef, SnapshotComplete.class);
501 public void testRollbackBeforePersist(){
502 // when replicatedToAllIndex = -1
503 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
504 new MockRaftActorContext.MockPayload()), -1, "follower-1");
506 snapshotManager.rollback();
508 verify(mockReplicatedLog, never()).snapshotRollback();
512 public void testRollbackBeforeCapture(){
513 snapshotManager.rollback();
515 verify(mockReplicatedLog, never()).snapshotRollback();
519 public void testCallingRollbackMultipleTimesCausesNoHarm(){
520 // when replicatedToAllIndex = -1
521 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
522 new MockRaftActorContext.MockPayload()), -1, "follower-1");
524 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
526 snapshotManager.rollback();
528 snapshotManager.rollback();
530 verify(mockReplicatedLog, times(1)).snapshotRollback();
534 public void testTrimLogWhenTrimIndexLessThanLastApplied() {
535 doReturn(20L).when(mockRaftActorContext).getLastApplied();
537 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
538 doReturn(true).when(mockReplicatedLog).isPresent(10);
539 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
540 doReturn(5L).when(replicatedLogEntry).getTerm();
542 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
543 assertEquals("return index", 10L, retIndex);
545 verify(mockReplicatedLog).snapshotPreCommit(10, 5);
546 verify(mockReplicatedLog).snapshotCommit();
548 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
552 public void testTrimLogWhenLastAppliedNotSet() {
553 doReturn(-1L).when(mockRaftActorContext).getLastApplied();
555 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
556 doReturn(true).when(mockReplicatedLog).isPresent(10);
557 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
558 doReturn(5L).when(replicatedLogEntry).getTerm();
560 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
561 assertEquals("return index", -1L, retIndex);
563 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
564 verify(mockReplicatedLog, never()).snapshotCommit();
566 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
570 public void testTrimLogWhenLastAppliedZero() {
571 doReturn(0L).when(mockRaftActorContext).getLastApplied();
573 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
574 doReturn(true).when(mockReplicatedLog).isPresent(10);
575 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
576 doReturn(5L).when(replicatedLogEntry).getTerm();
578 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
579 assertEquals("return index", -1L, retIndex);
581 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
582 verify(mockReplicatedLog, never()).snapshotCommit();
584 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
588 public void testTrimLogWhenTrimIndexNotPresent() {
589 doReturn(20L).when(mockRaftActorContext).getLastApplied();
591 doReturn(false).when(mockReplicatedLog).isPresent(10);
593 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
594 assertEquals("return index", -1L, retIndex);
596 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
597 verify(mockReplicatedLog, never()).snapshotCommit();
599 // Trim index is greater than replicatedToAllIndex so should update it.
600 verify(mockRaftActorBehavior).setReplicatedToAllIndex(10L);
604 public void testTrimLogAfterCapture(){
605 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
606 new MockRaftActorContext.MockPayload()), 9);
610 assertEquals(true, snapshotManager.isCapturing());
612 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
613 doReturn(20L).when(mockRaftActorContext).getLastApplied();
614 doReturn(true).when(mockReplicatedLog).isPresent(10);
615 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
616 doReturn(5L).when(replicatedLogEntry).getTerm();
618 snapshotManager.trimLog(10, mockRaftActorBehavior);
620 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
621 verify(mockReplicatedLog, never()).snapshotCommit();
626 public void testTrimLogAfterCaptureToInstall(){
627 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
628 new MockRaftActorContext.MockPayload()), 9, "follower-1");
632 assertEquals(true, snapshotManager.isCapturing());
634 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
635 doReturn(20L).when(mockRaftActorContext).getLastApplied();
636 doReturn(true).when(mockReplicatedLog).isPresent(10);
637 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
638 doReturn(5L).when(replicatedLogEntry).getTerm();
640 snapshotManager.trimLog(10, mockRaftActorBehavior);
642 verify(mockReplicatedLog, never()).snapshotPreCommit(10, 5);
643 verify(mockReplicatedLog, never()).snapshotCommit();
648 public void testLastAppliedTermInformationReader() {
650 LastAppliedTermInformationReader reader = new LastAppliedTermInformationReader();
652 doReturn(4L).when(mockReplicatedLog).getSnapshotTerm();
653 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
655 ReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(6L, 9L,
656 new MockRaftActorContext.MockPayload());
658 // No followers and valid lastLogEntry
659 reader.init(mockReplicatedLog, 1L, lastLogEntry, false);
661 assertEquals("getTerm", 6L, reader.getTerm());
662 assertEquals("getIndex", 9L, reader.getIndex());
664 // No followers and null lastLogEntry
665 reader.init(mockReplicatedLog, 1L, null, false);
667 assertEquals("getTerm", -1L, reader.getTerm());
668 assertEquals("getIndex", -1L, reader.getIndex());
670 // Followers and valid originalIndex entry
671 doReturn(new MockRaftActorContext.MockReplicatedLogEntry(5L, 8L,
672 new MockRaftActorContext.MockPayload())).when(mockReplicatedLog).get(8L);
673 reader.init(mockReplicatedLog, 8L, lastLogEntry, true);
675 assertEquals("getTerm", 5L, reader.getTerm());
676 assertEquals("getIndex", 8L, reader.getIndex());
678 // Followers and null originalIndex entry and valid snapshot index
679 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
681 assertEquals("getTerm", 4L, reader.getTerm());
682 assertEquals("getIndex", 7L, reader.getIndex());
684 // Followers and null originalIndex entry and invalid snapshot index
685 doReturn(-1L).when(mockReplicatedLog).getSnapshotIndex();
686 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
688 assertEquals("getTerm", -1L, reader.getTerm());
689 assertEquals("getIndex", -1L, reader.getIndex());