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 com.google.common.collect.ImmutableMap;
29 import java.util.Arrays;
30 import java.util.HashMap;
31 import org.junit.After;
32 import org.junit.Before;
33 import org.junit.Test;
34 import org.mockito.ArgumentCaptor;
35 import org.mockito.Mock;
36 import org.mockito.MockitoAnnotations;
37 import org.opendaylight.controller.cluster.DataPersistenceProvider;
38 import org.opendaylight.controller.cluster.raft.SnapshotManager.LastAppliedTermInformationReader;
39 import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot;
40 import org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot;
41 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
42 import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
43 import org.slf4j.LoggerFactory;
45 public class SnapshotManagerTest extends AbstractActorTest {
48 private RaftActorContext mockRaftActorContext;
51 private ConfigParams mockConfigParams;
54 private ReplicatedLog mockReplicatedLog;
57 private DataPersistenceProvider mockDataPersistenceProvider;
60 private RaftActorBehavior mockRaftActorBehavior;
63 private Procedure<Void> mockProcedure;
65 private SnapshotManager snapshotManager;
67 private TestActorFactory factory;
69 private TestActorRef<MessageCollectorActor> actorRef;
73 MockitoAnnotations.initMocks(this);
75 doReturn(new HashMap<>()).when(mockRaftActorContext).getPeerAddresses();
76 doReturn(mockConfigParams).when(mockRaftActorContext).getConfigParams();
77 doReturn(10L).when(mockConfigParams).getSnapshotBatchCount();
78 doReturn(70).when(mockConfigParams).getSnapshotDataThresholdPercentage();
79 doReturn(mockReplicatedLog).when(mockRaftActorContext).getReplicatedLog();
80 doReturn("123").when(mockRaftActorContext).getId();
81 doReturn(mockDataPersistenceProvider).when(mockRaftActorContext).getPersistenceProvider();
82 doReturn("123").when(mockRaftActorBehavior).getLeaderId();
84 ElectionTerm mockElectionTerm = mock(ElectionTerm.class);
85 doReturn(mockElectionTerm).when(mockRaftActorContext).getTermInformation();
86 doReturn(5L).when(mockElectionTerm).getCurrentTerm();
88 snapshotManager = new SnapshotManager(mockRaftActorContext, LoggerFactory.getLogger(this.getClass()));
89 factory = new TestActorFactory(getSystem());
91 actorRef = factory.createTestActor(MessageCollectorActor.props(), factory.generateActorId("test-"));
92 doReturn(actorRef).when(mockRaftActorContext).getActor();
94 snapshotManager.setCreateSnapshotCallable(mockProcedure);
98 public void tearDown(){
103 public void testConstruction(){
104 assertEquals(false, snapshotManager.isCapturing());
108 public void testCaptureToInstall() throws Exception {
110 // Force capturing toInstall = true
111 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1, 0,
112 new MockRaftActorContext.MockPayload()), 0, "follower-1");
114 assertEquals(true, snapshotManager.isCapturing());
116 verify(mockProcedure).apply(null);
118 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
120 // LastIndex and LastTerm are picked up from the lastLogEntry
121 assertEquals(0L, captureSnapshot.getLastIndex());
122 assertEquals(1L, captureSnapshot.getLastTerm());
124 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
125 assertEquals(0L, captureSnapshot.getLastAppliedIndex());
126 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
129 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
130 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
131 actorRef.underlyingActor().clear();
135 public void testCapture() throws Exception {
136 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
137 new MockRaftActorContext.MockPayload()), 9);
141 assertEquals(true, snapshotManager.isCapturing());
143 verify(mockProcedure).apply(null);
145 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
147 // LastIndex and LastTerm are picked up from the lastLogEntry
148 assertEquals(9L, captureSnapshot.getLastIndex());
149 assertEquals(1L, captureSnapshot.getLastTerm());
151 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
152 assertEquals(9L, captureSnapshot.getLastAppliedIndex());
153 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
156 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
157 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
159 actorRef.underlyingActor().clear();
164 public void testCaptureWithNullLastLogEntry() throws Exception {
165 boolean capture = snapshotManager.capture(null, 1);
169 assertEquals(true, snapshotManager.isCapturing());
171 verify(mockProcedure).apply(null);
173 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
175 System.out.println(captureSnapshot);
177 // LastIndex and LastTerm are picked up from the lastLogEntry
178 assertEquals(-1L, captureSnapshot.getLastIndex());
179 assertEquals(-1L, captureSnapshot.getLastTerm());
181 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
182 assertEquals(-1L, captureSnapshot.getLastAppliedIndex());
183 assertEquals(-1L, captureSnapshot.getLastAppliedTerm());
186 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
187 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
188 actorRef.underlyingActor().clear();
193 public void testCaptureWithCreateProcedureError () throws Exception {
194 doThrow(new Exception("mock")).when(mockProcedure).apply(null);
196 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
197 new MockRaftActorContext.MockPayload()), 9);
199 assertFalse(capture);
201 assertEquals(false, snapshotManager.isCapturing());
203 verify(mockProcedure).apply(null);
207 public void testIllegalCapture() throws Exception {
208 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
209 new MockRaftActorContext.MockPayload()), 9);
213 verify(mockProcedure).apply(null);
215 reset(mockProcedure);
217 // This will not cause snapshot capture to start again
218 capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
219 new MockRaftActorContext.MockPayload()), 9);
221 assertFalse(capture);
223 verify(mockProcedure, never()).apply(null);
227 public void testPersistWhenReplicatedToAllIndexMinusOne(){
228 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
229 doReturn(1L).when(mockReplicatedLog).getSnapshotTerm();
231 doReturn(ImmutableMap.builder().put("follower-1", "").build()).when(mockRaftActorContext).getPeerAddresses();
233 doReturn(8L).when(mockRaftActorContext).getLastApplied();
235 MockRaftActorContext.MockReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(
236 3L, 9L, new MockRaftActorContext.MockPayload());
238 MockRaftActorContext.MockReplicatedLogEntry lastAppliedEntry = new MockRaftActorContext.MockReplicatedLogEntry(
239 2L, 8L, new MockRaftActorContext.MockPayload());
241 doReturn(lastAppliedEntry).when(mockReplicatedLog).get(8L);
242 doReturn(Arrays.asList(lastLogEntry)).when(mockReplicatedLog).getFrom(9L);
244 // when replicatedToAllIndex = -1
245 snapshotManager.capture(lastLogEntry, -1);
247 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
248 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
250 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
251 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
253 Snapshot snapshot = snapshotArgumentCaptor.getValue();
255 assertEquals("getLastTerm", 3L, snapshot.getLastTerm());
256 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
257 assertEquals("getLastAppliedTerm", 2L, snapshot.getLastAppliedTerm());
258 assertEquals("getLastAppliedIndex", 8L, snapshot.getLastAppliedIndex());
259 assertArrayEquals("getState", bytes, snapshot.getState());
260 assertEquals("getUnAppliedEntries", Arrays.asList(lastLogEntry), snapshot.getUnAppliedEntries());
262 verify(mockReplicatedLog).snapshotPreCommit(7L, 1L);
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 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
279 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
281 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
282 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
284 Snapshot snapshot = snapshotArgumentCaptor.getValue();
286 assertEquals("getLastTerm", 6L, snapshot.getLastTerm());
287 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
288 assertEquals("getLastAppliedTerm", 6L, snapshot.getLastAppliedTerm());
289 assertEquals("getLastAppliedIndex", 9L, snapshot.getLastAppliedIndex());
290 assertArrayEquals("getState", bytes, snapshot.getState());
291 assertEquals("getUnAppliedEntries size", 0, snapshot.getUnAppliedEntries().size());
293 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
295 verify(mockRaftActorBehavior).setReplicatedToAllIndex(9);
299 public void testPersistWhenReplicatedLogDataSizeGreaterThanThreshold(){
300 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
302 // when replicatedToAllIndex = -1
303 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
304 new MockRaftActorContext.MockPayload()), -1);
306 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
308 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
310 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
312 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
316 public void testPersistWhenReplicatedLogSizeExceedsSnapshotBatchCount() {
317 doReturn(10L).when(mockReplicatedLog).size(); // matches snapshotBatchCount
318 doReturn(100).when(mockReplicatedLog).dataSize();
320 doReturn(5L).when(mockReplicatedLog).getSnapshotIndex();
321 doReturn(5L).when(mockReplicatedLog).getSnapshotTerm();
323 long replicatedToAllIndex = 1;
324 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
325 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(replicatedToAllIndex);
326 doReturn(6L).when(replicatedLogEntry).getTerm();
327 doReturn(replicatedToAllIndex).when(replicatedLogEntry).getIndex();
329 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
330 new MockRaftActorContext.MockPayload()), replicatedToAllIndex);
332 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, 2000000L);
334 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
336 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
338 verify(mockRaftActorBehavior).setReplicatedToAllIndex(replicatedToAllIndex);
342 public void testPersistSendInstallSnapshot(){
343 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
345 // when replicatedToAllIndex = -1
346 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
347 new MockRaftActorContext.MockPayload()), -1, "follower-1");
351 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
353 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
355 assertEquals(true, snapshotManager.isCapturing());
357 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
359 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
361 ArgumentCaptor<SendInstallSnapshot> sendInstallSnapshotArgumentCaptor
362 = ArgumentCaptor.forClass(SendInstallSnapshot.class);
364 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), sendInstallSnapshotArgumentCaptor.capture());
366 SendInstallSnapshot sendInstallSnapshot = sendInstallSnapshotArgumentCaptor.getValue();
368 assertTrue(Arrays.equals(bytes, sendInstallSnapshot.getSnapshot().getState()));
372 public void testCallingPersistWithoutCaptureWillDoNothing(){
373 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
375 verify(mockDataPersistenceProvider, never()).saveSnapshot(any(Snapshot.class));
377 verify(mockReplicatedLog, never()).snapshotPreCommit(9L, 6L);
379 verify(mockRaftActorBehavior, never()).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
382 public void testCallingPersistTwiceWillDoNoHarm(){
383 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
385 // when replicatedToAllIndex = -1
386 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
387 new MockRaftActorContext.MockPayload()), -1, "follower-1");
389 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
391 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
393 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
395 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
397 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
401 public void testCommit(){
402 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
404 // when replicatedToAllIndex = -1
405 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
406 new MockRaftActorContext.MockPayload()), -1, "follower-1");
408 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
410 assertEquals(true, snapshotManager.isCapturing());
412 snapshotManager.commit(100L, mockRaftActorBehavior);
414 assertEquals(false, snapshotManager.isCapturing());
416 verify(mockReplicatedLog).snapshotCommit();
418 verify(mockDataPersistenceProvider).deleteMessages(50L);
420 ArgumentCaptor<SnapshotSelectionCriteria> criteriaCaptor = ArgumentCaptor.forClass(SnapshotSelectionCriteria.class);
422 verify(mockDataPersistenceProvider).deleteSnapshots(criteriaCaptor.capture());
424 assertEquals(90, criteriaCaptor.getValue().maxSequenceNr()); // sequenceNumber = 100
425 // config snapShotBatchCount = 10
426 // therefore maxSequenceNumber = 90
430 public void testCommitBeforePersist(){
431 // when replicatedToAllIndex = -1
432 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
433 new MockRaftActorContext.MockPayload()), -1, "follower-1");
435 snapshotManager.commit(100L, mockRaftActorBehavior);
437 verify(mockReplicatedLog, never()).snapshotCommit();
439 verify(mockDataPersistenceProvider, never()).deleteMessages(100L);
441 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
446 public void testCommitBeforeCapture(){
447 snapshotManager.commit(100L, mockRaftActorBehavior);
449 verify(mockReplicatedLog, never()).snapshotCommit();
451 verify(mockDataPersistenceProvider, never()).deleteMessages(anyLong());
453 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
458 public void testCallingCommitMultipleTimesCausesNoHarm(){
459 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
461 // when replicatedToAllIndex = -1
462 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
463 new MockRaftActorContext.MockPayload()), -1, "follower-1");
465 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
467 snapshotManager.commit(100L, mockRaftActorBehavior);
469 snapshotManager.commit(100L, mockRaftActorBehavior);
471 verify(mockReplicatedLog, times(1)).snapshotCommit();
473 verify(mockDataPersistenceProvider, times(1)).deleteMessages(50L);
475 verify(mockDataPersistenceProvider, times(1)).deleteSnapshots(any(SnapshotSelectionCriteria.class));
479 public void testRollback(){
480 // when replicatedToAllIndex = -1
481 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
482 new MockRaftActorContext.MockPayload()), -1, "follower-1");
484 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
486 snapshotManager.rollback();
488 verify(mockReplicatedLog).snapshotRollback();
493 public void testRollbackBeforePersist(){
494 // when replicatedToAllIndex = -1
495 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
496 new MockRaftActorContext.MockPayload()), -1, "follower-1");
498 snapshotManager.rollback();
500 verify(mockReplicatedLog, never()).snapshotRollback();
504 public void testRollbackBeforeCapture(){
505 snapshotManager.rollback();
507 verify(mockReplicatedLog, never()).snapshotRollback();
511 public void testCallingRollbackMultipleTimesCausesNoHarm(){
512 // when replicatedToAllIndex = -1
513 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
514 new MockRaftActorContext.MockPayload()), -1, "follower-1");
516 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
518 snapshotManager.rollback();
520 snapshotManager.rollback();
522 verify(mockReplicatedLog, times(1)).snapshotRollback();
526 public void testTrimLogWhenTrimIndexLessThanLastApplied() {
527 doReturn(20L).when(mockRaftActorContext).getLastApplied();
529 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
530 doReturn(true).when(mockReplicatedLog).isPresent(10);
531 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
532 doReturn(5L).when(replicatedLogEntry).getTerm();
534 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
535 assertEquals("return index", 10L, retIndex);
537 verify(mockReplicatedLog).snapshotPreCommit(10, 5);
538 verify(mockReplicatedLog).snapshotCommit();
540 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
544 public void testTrimLogWhenLastAppliedNotSet() {
545 doReturn(-1L).when(mockRaftActorContext).getLastApplied();
547 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
548 doReturn(true).when(mockReplicatedLog).isPresent(10);
549 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
550 doReturn(5L).when(replicatedLogEntry).getTerm();
552 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
553 assertEquals("return index", -1L, retIndex);
555 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
556 verify(mockReplicatedLog, never()).snapshotCommit();
558 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
562 public void testTrimLogWhenLastAppliedZero() {
563 doReturn(0L).when(mockRaftActorContext).getLastApplied();
565 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
566 doReturn(true).when(mockReplicatedLog).isPresent(10);
567 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
568 doReturn(5L).when(replicatedLogEntry).getTerm();
570 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
571 assertEquals("return index", -1L, retIndex);
573 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
574 verify(mockReplicatedLog, never()).snapshotCommit();
576 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
580 public void testTrimLogWhenTrimIndexNotPresent() {
581 doReturn(20L).when(mockRaftActorContext).getLastApplied();
583 doReturn(false).when(mockReplicatedLog).isPresent(10);
585 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
586 assertEquals("return index", -1L, retIndex);
588 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
589 verify(mockReplicatedLog, never()).snapshotCommit();
591 // Trim index is greater than replicatedToAllIndex so should update it.
592 verify(mockRaftActorBehavior).setReplicatedToAllIndex(10L);
596 public void testTrimLogAfterCapture(){
597 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
598 new MockRaftActorContext.MockPayload()), 9);
602 assertEquals(true, snapshotManager.isCapturing());
604 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
605 doReturn(20L).when(mockRaftActorContext).getLastApplied();
606 doReturn(true).when(mockReplicatedLog).isPresent(10);
607 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
608 doReturn(5L).when(replicatedLogEntry).getTerm();
610 snapshotManager.trimLog(10, mockRaftActorBehavior);
612 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
613 verify(mockReplicatedLog, never()).snapshotCommit();
618 public void testTrimLogAfterCaptureToInstall(){
619 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
620 new MockRaftActorContext.MockPayload()), 9, "follower-1");
624 assertEquals(true, snapshotManager.isCapturing());
626 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
627 doReturn(20L).when(mockRaftActorContext).getLastApplied();
628 doReturn(true).when(mockReplicatedLog).isPresent(10);
629 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
630 doReturn(5L).when(replicatedLogEntry).getTerm();
632 snapshotManager.trimLog(10, mockRaftActorBehavior);
634 verify(mockReplicatedLog, never()).snapshotPreCommit(10, 5);
635 verify(mockReplicatedLog, never()).snapshotCommit();
640 public void testLastAppliedTermInformationReader() {
642 LastAppliedTermInformationReader reader = new LastAppliedTermInformationReader();
644 doReturn(4L).when(mockReplicatedLog).getSnapshotTerm();
645 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
647 ReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(6L, 9L,
648 new MockRaftActorContext.MockPayload());
650 // No followers and valid lastLogEntry
651 reader.init(mockReplicatedLog, 1L, lastLogEntry, false);
653 assertEquals("getTerm", 6L, reader.getTerm());
654 assertEquals("getIndex", 9L, reader.getIndex());
656 // No followers and null lastLogEntry
657 reader.init(mockReplicatedLog, 1L, null, false);
659 assertEquals("getTerm", -1L, reader.getTerm());
660 assertEquals("getIndex", -1L, reader.getIndex());
662 // Followers and valid originalIndex entry
663 doReturn(new MockRaftActorContext.MockReplicatedLogEntry(5L, 8L,
664 new MockRaftActorContext.MockPayload())).when(mockReplicatedLog).get(8L);
665 reader.init(mockReplicatedLog, 8L, lastLogEntry, true);
667 assertEquals("getTerm", 5L, reader.getTerm());
668 assertEquals("getIndex", 8L, reader.getIndex());
670 // Followers and null originalIndex entry and valid snapshot index
671 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
673 assertEquals("getTerm", 4L, reader.getTerm());
674 assertEquals("getIndex", 7L, reader.getIndex());
676 // Followers and null originalIndex entry and invalid snapshot index
677 doReturn(-1L).when(mockReplicatedLog).getSnapshotIndex();
678 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
680 assertEquals("getTerm", -1L, reader.getTerm());
681 assertEquals("getIndex", -1L, reader.getIndex());