1 package org.opendaylight.controller.cluster.raft;
3 import static org.junit.Assert.assertArrayEquals;
4 import static org.junit.Assert.assertEquals;
5 import static org.junit.Assert.assertFalse;
6 import static org.junit.Assert.assertTrue;
7 import static org.mockito.Matchers.any;
8 import static org.mockito.Matchers.anyLong;
9 import static org.mockito.Mockito.doReturn;
10 import static org.mockito.Mockito.doThrow;
11 import static org.mockito.Mockito.mock;
12 import static org.mockito.Mockito.never;
13 import static org.mockito.Mockito.reset;
14 import static org.mockito.Mockito.times;
15 import static org.mockito.Mockito.verify;
16 import akka.actor.ActorRef;
17 import akka.japi.Procedure;
18 import akka.persistence.SnapshotSelectionCriteria;
19 import akka.testkit.TestActorRef;
20 import com.google.common.collect.ImmutableMap;
21 import java.util.Arrays;
22 import java.util.HashMap;
23 import org.junit.After;
24 import org.junit.Before;
25 import org.junit.Test;
26 import org.mockito.ArgumentCaptor;
27 import org.mockito.Mock;
28 import org.mockito.MockitoAnnotations;
29 import org.opendaylight.controller.cluster.DataPersistenceProvider;
30 import org.opendaylight.controller.cluster.raft.SnapshotManager.LastAppliedTermInformationReader;
31 import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot;
32 import org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot;
33 import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior;
34 import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
35 import org.slf4j.LoggerFactory;
37 public class SnapshotManagerTest extends AbstractActorTest {
40 private RaftActorContext mockRaftActorContext;
43 private ConfigParams mockConfigParams;
46 private ReplicatedLog mockReplicatedLog;
49 private DataPersistenceProvider mockDataPersistenceProvider;
52 private RaftActorBehavior mockRaftActorBehavior;
55 private Procedure<Void> mockProcedure;
57 private SnapshotManager snapshotManager;
59 private TestActorFactory factory;
61 private TestActorRef<MessageCollectorActor> actorRef;
65 MockitoAnnotations.initMocks(this);
67 doReturn(new HashMap<>()).when(mockRaftActorContext).getPeerAddresses();
68 doReturn(mockConfigParams).when(mockRaftActorContext).getConfigParams();
69 doReturn(10L).when(mockConfigParams).getSnapshotBatchCount();
70 doReturn(70).when(mockConfigParams).getSnapshotDataThresholdPercentage();
71 doReturn(mockReplicatedLog).when(mockRaftActorContext).getReplicatedLog();
72 doReturn("123").when(mockRaftActorContext).getId();
73 doReturn(mockDataPersistenceProvider).when(mockRaftActorContext).getPersistenceProvider();
74 doReturn("123").when(mockRaftActorBehavior).getLeaderId();
76 ElectionTerm mockElectionTerm = mock(ElectionTerm.class);
77 doReturn(mockElectionTerm).when(mockRaftActorContext).getTermInformation();
78 doReturn(5L).when(mockElectionTerm).getCurrentTerm();
80 snapshotManager = new SnapshotManager(mockRaftActorContext, LoggerFactory.getLogger(this.getClass()));
81 factory = new TestActorFactory(getSystem());
83 actorRef = factory.createTestActor(MessageCollectorActor.props(), factory.generateActorId("test-"));
84 doReturn(actorRef).when(mockRaftActorContext).getActor();
86 snapshotManager.setCreateSnapshotCallable(mockProcedure);
90 public void tearDown(){
95 public void testConstruction(){
96 assertEquals(false, snapshotManager.isCapturing());
100 public void testCaptureToInstall() throws Exception {
102 // Force capturing toInstall = true
103 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1, 0,
104 new MockRaftActorContext.MockPayload()), 0, "follower-1");
106 assertEquals(true, snapshotManager.isCapturing());
108 verify(mockProcedure).apply(null);
110 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
112 // LastIndex and LastTerm are picked up from the lastLogEntry
113 assertEquals(0L, captureSnapshot.getLastIndex());
114 assertEquals(1L, captureSnapshot.getLastTerm());
116 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
117 assertEquals(0L, captureSnapshot.getLastAppliedIndex());
118 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
121 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
122 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
123 actorRef.underlyingActor().clear();
127 public void testCapture() throws Exception {
128 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
129 new MockRaftActorContext.MockPayload()), 9);
133 assertEquals(true, snapshotManager.isCapturing());
135 verify(mockProcedure).apply(null);
137 CaptureSnapshot captureSnapshot = snapshotManager.getCaptureSnapshot();
139 // LastIndex and LastTerm are picked up from the lastLogEntry
140 assertEquals(9L, captureSnapshot.getLastIndex());
141 assertEquals(1L, captureSnapshot.getLastTerm());
143 // Since the actor does not have any followers (no peer addresses) lastApplied will be from lastLogEntry
144 assertEquals(9L, captureSnapshot.getLastAppliedIndex());
145 assertEquals(1L, captureSnapshot.getLastAppliedTerm());
148 assertEquals(-1L, captureSnapshot.getReplicatedToAllIndex());
149 assertEquals(-1L, captureSnapshot.getReplicatedToAllTerm());
151 actorRef.underlyingActor().clear();
156 public void testCaptureWithCreateProcedureError () throws Exception {
157 doThrow(new Exception("mock")).when(mockProcedure).apply(null);
159 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
160 new MockRaftActorContext.MockPayload()), 9);
162 assertFalse(capture);
164 assertEquals(false, snapshotManager.isCapturing());
166 verify(mockProcedure).apply(null);
170 public void testIllegalCapture() throws Exception {
171 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
172 new MockRaftActorContext.MockPayload()), 9);
176 verify(mockProcedure).apply(null);
178 reset(mockProcedure);
180 // This will not cause snapshot capture to start again
181 capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
182 new MockRaftActorContext.MockPayload()), 9);
184 assertFalse(capture);
186 verify(mockProcedure, never()).apply(null);
190 public void testPersistWhenReplicatedToAllIndexMinusOne(){
191 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
192 doReturn(1L).when(mockReplicatedLog).getSnapshotTerm();
194 doReturn(ImmutableMap.builder().put("follower-1", "").build()).when(mockRaftActorContext).getPeerAddresses();
196 doReturn(8L).when(mockRaftActorContext).getLastApplied();
198 MockRaftActorContext.MockReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(
199 3L, 9L, new MockRaftActorContext.MockPayload());
201 MockRaftActorContext.MockReplicatedLogEntry lastAppliedEntry = new MockRaftActorContext.MockReplicatedLogEntry(
202 2L, 8L, new MockRaftActorContext.MockPayload());
204 doReturn(lastAppliedEntry).when(mockReplicatedLog).get(8L);
205 doReturn(Arrays.asList(lastLogEntry)).when(mockReplicatedLog).getFrom(9L);
207 // when replicatedToAllIndex = -1
208 snapshotManager.capture(lastLogEntry, -1);
210 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
211 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
213 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
214 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
216 Snapshot snapshot = snapshotArgumentCaptor.getValue();
218 assertEquals("getLastTerm", 3L, snapshot.getLastTerm());
219 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
220 assertEquals("getLastAppliedTerm", 2L, snapshot.getLastAppliedTerm());
221 assertEquals("getLastAppliedIndex", 8L, snapshot.getLastAppliedIndex());
222 assertArrayEquals("getState", bytes, snapshot.getState());
223 assertEquals("getUnAppliedEntries", Arrays.asList(lastLogEntry), snapshot.getUnAppliedEntries());
225 verify(mockReplicatedLog).snapshotPreCommit(7L, 1L);
229 public void testPersistWhenReplicatedToAllIndexNotMinus(){
230 doReturn(45L).when(mockReplicatedLog).getSnapshotIndex();
231 doReturn(6L).when(mockReplicatedLog).getSnapshotTerm();
232 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
233 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(9);
234 doReturn(6L).when(replicatedLogEntry).getTerm();
235 doReturn(9L).when(replicatedLogEntry).getIndex();
237 // when replicatedToAllIndex != -1
238 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
239 new MockRaftActorContext.MockPayload()), 9);
241 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
242 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
244 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
245 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
247 Snapshot snapshot = snapshotArgumentCaptor.getValue();
249 assertEquals("getLastTerm", 6L, snapshot.getLastTerm());
250 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
251 assertEquals("getLastAppliedTerm", 6L, snapshot.getLastAppliedTerm());
252 assertEquals("getLastAppliedIndex", 9L, snapshot.getLastAppliedIndex());
253 assertArrayEquals("getState", bytes, snapshot.getState());
254 assertEquals("getUnAppliedEntries size", 0, snapshot.getUnAppliedEntries().size());
256 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
258 verify(mockRaftActorBehavior).setReplicatedToAllIndex(9);
262 public void testPersistWhenReplicatedLogDataSizeGreaterThanThreshold(){
263 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
265 // when replicatedToAllIndex = -1
266 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
267 new MockRaftActorContext.MockPayload()), -1);
269 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
271 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
273 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
275 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
279 public void testPersistWhenReplicatedLogSizeExceedsSnapshotBatchCount() {
280 doReturn(10L).when(mockReplicatedLog).size(); // matches snapshotBatchCount
281 doReturn(100).when(mockReplicatedLog).dataSize();
283 doReturn(5L).when(mockReplicatedLog).getSnapshotIndex();
284 doReturn(5L).when(mockReplicatedLog).getSnapshotTerm();
286 long replicatedToAllIndex = 1;
287 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
288 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(replicatedToAllIndex);
289 doReturn(6L).when(replicatedLogEntry).getTerm();
290 doReturn(replicatedToAllIndex).when(replicatedLogEntry).getIndex();
292 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
293 new MockRaftActorContext.MockPayload()), replicatedToAllIndex);
295 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, 2000000L);
297 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
299 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
301 verify(mockRaftActorBehavior).setReplicatedToAllIndex(replicatedToAllIndex);
305 public void testPersistSendInstallSnapshot(){
306 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
308 // when replicatedToAllIndex = -1
309 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
310 new MockRaftActorContext.MockPayload()), -1, "follower-1");
314 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
316 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
318 assertEquals(true, snapshotManager.isCapturing());
320 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
322 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
324 ArgumentCaptor<SendInstallSnapshot> sendInstallSnapshotArgumentCaptor
325 = ArgumentCaptor.forClass(SendInstallSnapshot.class);
327 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), sendInstallSnapshotArgumentCaptor.capture());
329 SendInstallSnapshot sendInstallSnapshot = sendInstallSnapshotArgumentCaptor.getValue();
331 assertTrue(Arrays.equals(bytes, sendInstallSnapshot.getSnapshot().getState()));
335 public void testCallingPersistWithoutCaptureWillDoNothing(){
336 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
338 verify(mockDataPersistenceProvider, never()).saveSnapshot(any(Snapshot.class));
340 verify(mockReplicatedLog, never()).snapshotPreCommit(9L, 6L);
342 verify(mockRaftActorBehavior, never()).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
345 public void testCallingPersistTwiceWillDoNoHarm(){
346 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
348 // when replicatedToAllIndex = -1
349 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
350 new MockRaftActorContext.MockPayload()), -1, "follower-1");
352 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
354 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
356 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
358 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
360 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
364 public void testCommit(){
365 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
367 // when replicatedToAllIndex = -1
368 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
369 new MockRaftActorContext.MockPayload()), -1, "follower-1");
371 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
373 assertEquals(true, snapshotManager.isCapturing());
375 snapshotManager.commit(100L, mockRaftActorBehavior);
377 assertEquals(false, snapshotManager.isCapturing());
379 verify(mockReplicatedLog).snapshotCommit();
381 verify(mockDataPersistenceProvider).deleteMessages(50L);
383 ArgumentCaptor<SnapshotSelectionCriteria> criteriaCaptor = ArgumentCaptor.forClass(SnapshotSelectionCriteria.class);
385 verify(mockDataPersistenceProvider).deleteSnapshots(criteriaCaptor.capture());
387 assertEquals(90, criteriaCaptor.getValue().maxSequenceNr()); // sequenceNumber = 100
388 // config snapShotBatchCount = 10
389 // therefore maxSequenceNumber = 90
393 public void testCommitBeforePersist(){
394 // when replicatedToAllIndex = -1
395 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
396 new MockRaftActorContext.MockPayload()), -1, "follower-1");
398 snapshotManager.commit(100L, mockRaftActorBehavior);
400 verify(mockReplicatedLog, never()).snapshotCommit();
402 verify(mockDataPersistenceProvider, never()).deleteMessages(100L);
404 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
409 public void testCommitBeforeCapture(){
410 snapshotManager.commit(100L, mockRaftActorBehavior);
412 verify(mockReplicatedLog, never()).snapshotCommit();
414 verify(mockDataPersistenceProvider, never()).deleteMessages(anyLong());
416 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
421 public void testCallingCommitMultipleTimesCausesNoHarm(){
422 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
424 // when replicatedToAllIndex = -1
425 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
426 new MockRaftActorContext.MockPayload()), -1, "follower-1");
428 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
430 snapshotManager.commit(100L, mockRaftActorBehavior);
432 snapshotManager.commit(100L, mockRaftActorBehavior);
434 verify(mockReplicatedLog, times(1)).snapshotCommit();
436 verify(mockDataPersistenceProvider, times(1)).deleteMessages(50L);
438 verify(mockDataPersistenceProvider, times(1)).deleteSnapshots(any(SnapshotSelectionCriteria.class));
442 public void testRollback(){
443 // when replicatedToAllIndex = -1
444 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
445 new MockRaftActorContext.MockPayload()), -1, "follower-1");
447 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
449 snapshotManager.rollback();
451 verify(mockReplicatedLog).snapshotRollback();
456 public void testRollbackBeforePersist(){
457 // when replicatedToAllIndex = -1
458 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
459 new MockRaftActorContext.MockPayload()), -1, "follower-1");
461 snapshotManager.rollback();
463 verify(mockReplicatedLog, never()).snapshotRollback();
467 public void testRollbackBeforeCapture(){
468 snapshotManager.rollback();
470 verify(mockReplicatedLog, never()).snapshotRollback();
474 public void testCallingRollbackMultipleTimesCausesNoHarm(){
475 // when replicatedToAllIndex = -1
476 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
477 new MockRaftActorContext.MockPayload()), -1, "follower-1");
479 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
481 snapshotManager.rollback();
483 snapshotManager.rollback();
485 verify(mockReplicatedLog, times(1)).snapshotRollback();
489 public void testTrimLogWhenTrimIndexLessThanLastApplied() {
490 doReturn(20L).when(mockRaftActorContext).getLastApplied();
492 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
493 doReturn(true).when(mockReplicatedLog).isPresent(10);
494 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
495 doReturn(5L).when(replicatedLogEntry).getTerm();
497 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
498 assertEquals("return index", 10L, retIndex);
500 verify(mockReplicatedLog).snapshotPreCommit(10, 5);
501 verify(mockReplicatedLog).snapshotCommit();
503 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
507 public void testTrimLogWhenLastAppliedNotSet() {
508 doReturn(-1L).when(mockRaftActorContext).getLastApplied();
510 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
511 doReturn(true).when(mockReplicatedLog).isPresent(10);
512 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
513 doReturn(5L).when(replicatedLogEntry).getTerm();
515 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
516 assertEquals("return index", -1L, retIndex);
518 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
519 verify(mockReplicatedLog, never()).snapshotCommit();
521 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
525 public void testTrimLogWhenLastAppliedZero() {
526 doReturn(0L).when(mockRaftActorContext).getLastApplied();
528 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
529 doReturn(true).when(mockReplicatedLog).isPresent(10);
530 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
531 doReturn(5L).when(replicatedLogEntry).getTerm();
533 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
534 assertEquals("return index", -1L, retIndex);
536 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
537 verify(mockReplicatedLog, never()).snapshotCommit();
539 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
543 public void testTrimLogWhenTrimIndexNotPresent() {
544 doReturn(20L).when(mockRaftActorContext).getLastApplied();
546 doReturn(false).when(mockReplicatedLog).isPresent(10);
548 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
549 assertEquals("return index", -1L, retIndex);
551 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
552 verify(mockReplicatedLog, never()).snapshotCommit();
554 // Trim index is greater than replicatedToAllIndex so should update it.
555 verify(mockRaftActorBehavior).setReplicatedToAllIndex(10L);
559 public void testTrimLogAfterCapture(){
560 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
561 new MockRaftActorContext.MockPayload()), 9);
565 assertEquals(true, snapshotManager.isCapturing());
567 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
568 doReturn(20L).when(mockRaftActorContext).getLastApplied();
569 doReturn(true).when(mockReplicatedLog).isPresent(10);
570 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
571 doReturn(5L).when(replicatedLogEntry).getTerm();
573 snapshotManager.trimLog(10, mockRaftActorBehavior);
575 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
576 verify(mockReplicatedLog, never()).snapshotCommit();
581 public void testTrimLogAfterCaptureToInstall(){
582 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
583 new MockRaftActorContext.MockPayload()), 9, "follower-1");
587 assertEquals(true, snapshotManager.isCapturing());
589 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
590 doReturn(20L).when(mockRaftActorContext).getLastApplied();
591 doReturn(true).when(mockReplicatedLog).isPresent(10);
592 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
593 doReturn(5L).when(replicatedLogEntry).getTerm();
595 snapshotManager.trimLog(10, mockRaftActorBehavior);
597 verify(mockReplicatedLog, never()).snapshotPreCommit(10, 5);
598 verify(mockReplicatedLog, never()).snapshotCommit();
603 public void testLastAppliedTermInformationReader() {
605 LastAppliedTermInformationReader reader = new LastAppliedTermInformationReader();
607 doReturn(4L).when(mockReplicatedLog).getSnapshotTerm();
608 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
610 ReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(6L, 9L,
611 new MockRaftActorContext.MockPayload());
613 // No followers and valid lastLogEntry
614 reader.init(mockReplicatedLog, 1L, lastLogEntry, false);
616 assertEquals("getTerm", 6L, reader.getTerm());
617 assertEquals("getIndex", 9L, reader.getIndex());
619 // No followers and null lastLogEntry
620 reader.init(mockReplicatedLog, 1L, null, false);
622 assertEquals("getTerm", -1L, reader.getTerm());
623 assertEquals("getIndex", -1L, reader.getIndex());
625 // Followers and valid originalIndex entry
626 doReturn(new MockRaftActorContext.MockReplicatedLogEntry(5L, 8L,
627 new MockRaftActorContext.MockPayload())).when(mockReplicatedLog).get(8L);
628 reader.init(mockReplicatedLog, 8L, lastLogEntry, true);
630 assertEquals("getTerm", 5L, reader.getTerm());
631 assertEquals("getIndex", 8L, reader.getIndex());
633 // Followers and null originalIndex entry and valid snapshot index
634 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
636 assertEquals("getTerm", 4L, reader.getTerm());
637 assertEquals("getIndex", 7L, reader.getIndex());
639 // Followers and null originalIndex entry and invalid snapshot index
640 doReturn(-1L).when(mockReplicatedLog).getSnapshotIndex();
641 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
643 assertEquals("getTerm", -1L, reader.getTerm());
644 assertEquals("getIndex", -1L, reader.getIndex());