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.behaviors.RaftActorBehavior;
40 import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
41 import org.slf4j.LoggerFactory;
43 public class SnapshotManagerTest extends AbstractActorTest {
46 private RaftActorContext mockRaftActorContext;
49 private ConfigParams mockConfigParams;
52 private ReplicatedLog mockReplicatedLog;
55 private DataPersistenceProvider mockDataPersistenceProvider;
58 private RaftActorBehavior mockRaftActorBehavior;
61 private Procedure<Void> mockProcedure;
64 private ElectionTerm mockElectionTerm;
66 private SnapshotManager snapshotManager;
68 private TestActorFactory factory;
70 private TestActorRef<MessageCollectorActor> actorRef;
74 MockitoAnnotations.initMocks(this);
76 doReturn(false).when(mockRaftActorContext).hasFollowers();
77 doReturn(mockConfigParams).when(mockRaftActorContext).getConfigParams();
78 doReturn(10L).when(mockConfigParams).getSnapshotBatchCount();
79 doReturn(70).when(mockConfigParams).getSnapshotDataThresholdPercentage();
80 doReturn(mockReplicatedLog).when(mockRaftActorContext).getReplicatedLog();
81 doReturn("123").when(mockRaftActorContext).getId();
82 doReturn(mockDataPersistenceProvider).when(mockRaftActorContext).getPersistenceProvider();
83 doReturn("123").when(mockRaftActorBehavior).getLeaderId();
85 doReturn(mockElectionTerm).when(mockRaftActorContext).getTermInformation();
86 doReturn(5L).when(mockElectionTerm).getCurrentTerm();
87 doReturn("member5").when(mockElectionTerm).getVotedFor();
89 snapshotManager = new SnapshotManager(mockRaftActorContext, LoggerFactory.getLogger(this.getClass()));
90 factory = new TestActorFactory(getSystem());
92 actorRef = factory.createTestActor(MessageCollectorActor.props(), factory.generateActorId("test-"));
93 doReturn(actorRef).when(mockRaftActorContext).getActor();
95 snapshotManager.setCreateSnapshotCallable(mockProcedure);
99 public void tearDown(){
104 public void testConstruction(){
105 assertEquals(false, snapshotManager.isCapturing());
109 public void testCaptureToInstall() throws Exception {
111 // Force capturing toInstall = true
112 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1, 0,
113 new MockRaftActorContext.MockPayload()), 0, "follower-1");
115 assertEquals(true, snapshotManager.isCapturing());
117 verify(mockProcedure).apply(null);
119 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
121 // LastIndex and LastTerm are picked up from the lastLogEntry
122 assertEquals(0L, captureSnapshot.getLastIndex());
123 assertEquals(1L, captureSnapshot.getLastTerm());
125 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
126 assertEquals(0L, captureSnapshot.getLastAppliedIndex());
127 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
130 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
131 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
132 actorRef.underlyingActor().clear();
136 public void testCapture() throws Exception {
137 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
138 new MockRaftActorContext.MockPayload()), 9);
142 assertEquals(true, snapshotManager.isCapturing());
144 verify(mockProcedure).apply(null);
146 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
148 // LastIndex and LastTerm are picked up from the lastLogEntry
149 assertEquals(9L, captureSnapshot.getLastIndex());
150 assertEquals(1L, captureSnapshot.getLastTerm());
152 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
153 assertEquals(9L, captureSnapshot.getLastAppliedIndex());
154 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
157 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
158 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
160 actorRef.underlyingActor().clear();
165 public void testCaptureWithNullLastLogEntry() throws Exception {
166 boolean capture = snapshotManager.capture(null, 1);
170 assertEquals(true, snapshotManager.isCapturing());
172 verify(mockProcedure).apply(null);
174 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
176 System.out.println(captureSnapshot);
178 // LastIndex and LastTerm are picked up from the lastLogEntry
179 assertEquals(-1L, captureSnapshot.getLastIndex());
180 assertEquals(-1L, captureSnapshot.getLastTerm());
182 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
183 assertEquals(-1L, captureSnapshot.getLastAppliedIndex());
184 assertEquals(-1L, captureSnapshot.getLastAppliedTerm());
187 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
188 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
189 actorRef.underlyingActor().clear();
194 public void testCaptureWithCreateProcedureError () throws Exception {
195 doThrow(new Exception("mock")).when(mockProcedure).apply(null);
197 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
198 new MockRaftActorContext.MockPayload()), 9);
200 assertFalse(capture);
202 assertEquals(false, snapshotManager.isCapturing());
204 verify(mockProcedure).apply(null);
208 public void testIllegalCapture() throws Exception {
209 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
210 new MockRaftActorContext.MockPayload()), 9);
214 verify(mockProcedure).apply(null);
216 reset(mockProcedure);
218 // This will not cause snapshot capture to start again
219 capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
220 new MockRaftActorContext.MockPayload()), 9);
222 assertFalse(capture);
224 verify(mockProcedure, never()).apply(null);
228 public void testPersistWhenReplicatedToAllIndexMinusOne(){
229 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
230 doReturn(1L).when(mockReplicatedLog).getSnapshotTerm();
232 doReturn(true).when(mockRaftActorContext).hasFollowers();
234 doReturn(8L).when(mockRaftActorContext).getLastApplied();
236 MockRaftActorContext.MockReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(
237 3L, 9L, new MockRaftActorContext.MockPayload());
239 MockRaftActorContext.MockReplicatedLogEntry lastAppliedEntry = new MockRaftActorContext.MockReplicatedLogEntry(
240 2L, 8L, new MockRaftActorContext.MockPayload());
242 doReturn(lastAppliedEntry).when(mockReplicatedLog).get(8L);
243 doReturn(Arrays.asList(lastLogEntry)).when(mockReplicatedLog).getFrom(9L);
245 // when replicatedToAllIndex = -1
246 snapshotManager.capture(lastLogEntry, -1);
248 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
249 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
251 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
252 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
254 Snapshot snapshot = snapshotArgumentCaptor.getValue();
256 assertEquals("getLastTerm", 3L, snapshot.getLastTerm());
257 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
258 assertEquals("getLastAppliedTerm", 2L, snapshot.getLastAppliedTerm());
259 assertEquals("getLastAppliedIndex", 8L, snapshot.getLastAppliedIndex());
260 assertArrayEquals("getState", bytes, snapshot.getState());
261 assertEquals("getUnAppliedEntries", Arrays.asList(lastLogEntry), snapshot.getUnAppliedEntries());
262 assertEquals("electionTerm", mockElectionTerm.getCurrentTerm(), snapshot.getElectionTerm());
263 assertEquals("electionVotedFor", mockElectionTerm.getVotedFor(), snapshot.getElectionVotedFor());
265 verify(mockReplicatedLog).snapshotPreCommit(7L, 1L);
269 public void testPersistWhenReplicatedToAllIndexNotMinus(){
270 doReturn(45L).when(mockReplicatedLog).getSnapshotIndex();
271 doReturn(6L).when(mockReplicatedLog).getSnapshotTerm();
272 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
273 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(9);
274 doReturn(6L).when(replicatedLogEntry).getTerm();
275 doReturn(9L).when(replicatedLogEntry).getIndex();
277 // when replicatedToAllIndex != -1
278 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
279 new MockRaftActorContext.MockPayload()), 9);
281 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
282 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
284 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
285 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
287 Snapshot snapshot = snapshotArgumentCaptor.getValue();
289 assertEquals("getLastTerm", 6L, snapshot.getLastTerm());
290 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
291 assertEquals("getLastAppliedTerm", 6L, snapshot.getLastAppliedTerm());
292 assertEquals("getLastAppliedIndex", 9L, snapshot.getLastAppliedIndex());
293 assertArrayEquals("getState", bytes, snapshot.getState());
294 assertEquals("getUnAppliedEntries size", 0, snapshot.getUnAppliedEntries().size());
296 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
298 verify(mockRaftActorBehavior).setReplicatedToAllIndex(9);
302 public void testPersistWhenReplicatedLogDataSizeGreaterThanThreshold(){
303 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
305 // when replicatedToAllIndex = -1
306 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
307 new MockRaftActorContext.MockPayload()), -1);
309 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
311 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
313 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
315 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
319 public void testPersistWhenReplicatedLogSizeExceedsSnapshotBatchCount() {
320 doReturn(10L).when(mockReplicatedLog).size(); // matches snapshotBatchCount
321 doReturn(100).when(mockReplicatedLog).dataSize();
323 doReturn(5L).when(mockReplicatedLog).getSnapshotIndex();
324 doReturn(5L).when(mockReplicatedLog).getSnapshotTerm();
326 long replicatedToAllIndex = 1;
327 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
328 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(replicatedToAllIndex);
329 doReturn(6L).when(replicatedLogEntry).getTerm();
330 doReturn(replicatedToAllIndex).when(replicatedLogEntry).getIndex();
332 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
333 new MockRaftActorContext.MockPayload()), replicatedToAllIndex);
335 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, 2000000L);
337 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
339 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
341 verify(mockRaftActorBehavior).setReplicatedToAllIndex(replicatedToAllIndex);
345 public void testPersistSendInstallSnapshot(){
346 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
348 // when replicatedToAllIndex = -1
349 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
350 new MockRaftActorContext.MockPayload()), -1, "follower-1");
354 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
356 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
358 assertEquals(true, snapshotManager.isCapturing());
360 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
362 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
364 ArgumentCaptor<SendInstallSnapshot> sendInstallSnapshotArgumentCaptor
365 = ArgumentCaptor.forClass(SendInstallSnapshot.class);
367 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), sendInstallSnapshotArgumentCaptor.capture());
369 SendInstallSnapshot sendInstallSnapshot = sendInstallSnapshotArgumentCaptor.getValue();
371 assertTrue(Arrays.equals(bytes, sendInstallSnapshot.getSnapshot().getState()));
375 public void testCallingPersistWithoutCaptureWillDoNothing(){
376 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
378 verify(mockDataPersistenceProvider, never()).saveSnapshot(any(Snapshot.class));
380 verify(mockReplicatedLog, never()).snapshotPreCommit(9L, 6L);
382 verify(mockRaftActorBehavior, never()).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
385 public void testCallingPersistTwiceWillDoNoHarm(){
386 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
388 // when replicatedToAllIndex = -1
389 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
390 new MockRaftActorContext.MockPayload()), -1, "follower-1");
392 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
394 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
396 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
398 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
400 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
404 public void testCommit(){
405 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
407 // when replicatedToAllIndex = -1
408 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
409 new MockRaftActorContext.MockPayload()), -1, "follower-1");
411 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
413 assertEquals(true, snapshotManager.isCapturing());
415 snapshotManager.commit(100L, mockRaftActorBehavior);
417 assertEquals(false, snapshotManager.isCapturing());
419 verify(mockReplicatedLog).snapshotCommit();
421 verify(mockDataPersistenceProvider).deleteMessages(50L);
423 ArgumentCaptor<SnapshotSelectionCriteria> criteriaCaptor = ArgumentCaptor.forClass(SnapshotSelectionCriteria.class);
425 verify(mockDataPersistenceProvider).deleteSnapshots(criteriaCaptor.capture());
427 assertEquals(90, criteriaCaptor.getValue().maxSequenceNr()); // sequenceNumber = 100
428 // config snapShotBatchCount = 10
429 // therefore maxSequenceNumber = 90
433 public void testCommitBeforePersist(){
434 // when replicatedToAllIndex = -1
435 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
436 new MockRaftActorContext.MockPayload()), -1, "follower-1");
438 snapshotManager.commit(100L, mockRaftActorBehavior);
440 verify(mockReplicatedLog, never()).snapshotCommit();
442 verify(mockDataPersistenceProvider, never()).deleteMessages(100L);
444 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
449 public void testCommitBeforeCapture(){
450 snapshotManager.commit(100L, mockRaftActorBehavior);
452 verify(mockReplicatedLog, never()).snapshotCommit();
454 verify(mockDataPersistenceProvider, never()).deleteMessages(anyLong());
456 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
461 public void testCallingCommitMultipleTimesCausesNoHarm(){
462 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
464 // when replicatedToAllIndex = -1
465 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
466 new MockRaftActorContext.MockPayload()), -1, "follower-1");
468 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
470 snapshotManager.commit(100L, mockRaftActorBehavior);
472 snapshotManager.commit(100L, mockRaftActorBehavior);
474 verify(mockReplicatedLog, times(1)).snapshotCommit();
476 verify(mockDataPersistenceProvider, times(1)).deleteMessages(50L);
478 verify(mockDataPersistenceProvider, times(1)).deleteSnapshots(any(SnapshotSelectionCriteria.class));
482 public void testRollback(){
483 // when replicatedToAllIndex = -1
484 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
485 new MockRaftActorContext.MockPayload()), -1, "follower-1");
487 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
489 snapshotManager.rollback();
491 verify(mockReplicatedLog).snapshotRollback();
496 public void testRollbackBeforePersist(){
497 // when replicatedToAllIndex = -1
498 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
499 new MockRaftActorContext.MockPayload()), -1, "follower-1");
501 snapshotManager.rollback();
503 verify(mockReplicatedLog, never()).snapshotRollback();
507 public void testRollbackBeforeCapture(){
508 snapshotManager.rollback();
510 verify(mockReplicatedLog, never()).snapshotRollback();
514 public void testCallingRollbackMultipleTimesCausesNoHarm(){
515 // when replicatedToAllIndex = -1
516 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
517 new MockRaftActorContext.MockPayload()), -1, "follower-1");
519 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
521 snapshotManager.rollback();
523 snapshotManager.rollback();
525 verify(mockReplicatedLog, times(1)).snapshotRollback();
529 public void testTrimLogWhenTrimIndexLessThanLastApplied() {
530 doReturn(20L).when(mockRaftActorContext).getLastApplied();
532 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
533 doReturn(true).when(mockReplicatedLog).isPresent(10);
534 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
535 doReturn(5L).when(replicatedLogEntry).getTerm();
537 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
538 assertEquals("return index", 10L, retIndex);
540 verify(mockReplicatedLog).snapshotPreCommit(10, 5);
541 verify(mockReplicatedLog).snapshotCommit();
543 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
547 public void testTrimLogWhenLastAppliedNotSet() {
548 doReturn(-1L).when(mockRaftActorContext).getLastApplied();
550 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
551 doReturn(true).when(mockReplicatedLog).isPresent(10);
552 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
553 doReturn(5L).when(replicatedLogEntry).getTerm();
555 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
556 assertEquals("return index", -1L, retIndex);
558 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
559 verify(mockReplicatedLog, never()).snapshotCommit();
561 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
565 public void testTrimLogWhenLastAppliedZero() {
566 doReturn(0L).when(mockRaftActorContext).getLastApplied();
568 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
569 doReturn(true).when(mockReplicatedLog).isPresent(10);
570 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
571 doReturn(5L).when(replicatedLogEntry).getTerm();
573 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
574 assertEquals("return index", -1L, retIndex);
576 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
577 verify(mockReplicatedLog, never()).snapshotCommit();
579 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
583 public void testTrimLogWhenTrimIndexNotPresent() {
584 doReturn(20L).when(mockRaftActorContext).getLastApplied();
586 doReturn(false).when(mockReplicatedLog).isPresent(10);
588 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
589 assertEquals("return index", -1L, retIndex);
591 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
592 verify(mockReplicatedLog, never()).snapshotCommit();
594 // Trim index is greater than replicatedToAllIndex so should update it.
595 verify(mockRaftActorBehavior).setReplicatedToAllIndex(10L);
599 public void testTrimLogAfterCapture(){
600 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
601 new MockRaftActorContext.MockPayload()), 9);
605 assertEquals(true, snapshotManager.isCapturing());
607 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
608 doReturn(20L).when(mockRaftActorContext).getLastApplied();
609 doReturn(true).when(mockReplicatedLog).isPresent(10);
610 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
611 doReturn(5L).when(replicatedLogEntry).getTerm();
613 snapshotManager.trimLog(10, mockRaftActorBehavior);
615 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
616 verify(mockReplicatedLog, never()).snapshotCommit();
621 public void testTrimLogAfterCaptureToInstall(){
622 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
623 new MockRaftActorContext.MockPayload()), 9, "follower-1");
627 assertEquals(true, snapshotManager.isCapturing());
629 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
630 doReturn(20L).when(mockRaftActorContext).getLastApplied();
631 doReturn(true).when(mockReplicatedLog).isPresent(10);
632 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
633 doReturn(5L).when(replicatedLogEntry).getTerm();
635 snapshotManager.trimLog(10, mockRaftActorBehavior);
637 verify(mockReplicatedLog, never()).snapshotPreCommit(10, 5);
638 verify(mockReplicatedLog, never()).snapshotCommit();
643 public void testLastAppliedTermInformationReader() {
645 LastAppliedTermInformationReader reader = new LastAppliedTermInformationReader();
647 doReturn(4L).when(mockReplicatedLog).getSnapshotTerm();
648 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
650 ReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(6L, 9L,
651 new MockRaftActorContext.MockPayload());
653 // No followers and valid lastLogEntry
654 reader.init(mockReplicatedLog, 1L, lastLogEntry, false);
656 assertEquals("getTerm", 6L, reader.getTerm());
657 assertEquals("getIndex", 9L, reader.getIndex());
659 // No followers and null lastLogEntry
660 reader.init(mockReplicatedLog, 1L, null, false);
662 assertEquals("getTerm", -1L, reader.getTerm());
663 assertEquals("getIndex", -1L, reader.getIndex());
665 // Followers and valid originalIndex entry
666 doReturn(new MockRaftActorContext.MockReplicatedLogEntry(5L, 8L,
667 new MockRaftActorContext.MockPayload())).when(mockReplicatedLog).get(8L);
668 reader.init(mockReplicatedLog, 8L, lastLogEntry, true);
670 assertEquals("getTerm", 5L, reader.getTerm());
671 assertEquals("getIndex", 8L, reader.getIndex());
673 // Followers and null originalIndex entry and valid snapshot index
674 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
676 assertEquals("getTerm", 4L, reader.getTerm());
677 assertEquals("getIndex", 7L, reader.getIndex());
679 // Followers and null originalIndex entry and invalid snapshot index
680 doReturn(-1L).when(mockReplicatedLog).getSnapshotIndex();
681 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
683 assertEquals("getTerm", -1L, reader.getTerm());
684 assertEquals("getIndex", -1L, reader.getIndex());