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 testCaptureWithCreateProcedureError () throws Exception {
165 doThrow(new Exception("mock")).when(mockProcedure).apply(null);
167 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
168 new MockRaftActorContext.MockPayload()), 9);
170 assertFalse(capture);
172 assertEquals(false, snapshotManager.isCapturing());
174 verify(mockProcedure).apply(null);
178 public void testIllegalCapture() throws Exception {
179 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
180 new MockRaftActorContext.MockPayload()), 9);
184 verify(mockProcedure).apply(null);
186 reset(mockProcedure);
188 // This will not cause snapshot capture to start again
189 capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
190 new MockRaftActorContext.MockPayload()), 9);
192 assertFalse(capture);
194 verify(mockProcedure, never()).apply(null);
198 public void testPersistWhenReplicatedToAllIndexMinusOne(){
199 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
200 doReturn(1L).when(mockReplicatedLog).getSnapshotTerm();
202 doReturn(ImmutableMap.builder().put("follower-1", "").build()).when(mockRaftActorContext).getPeerAddresses();
204 doReturn(8L).when(mockRaftActorContext).getLastApplied();
206 MockRaftActorContext.MockReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(
207 3L, 9L, new MockRaftActorContext.MockPayload());
209 MockRaftActorContext.MockReplicatedLogEntry lastAppliedEntry = new MockRaftActorContext.MockReplicatedLogEntry(
210 2L, 8L, new MockRaftActorContext.MockPayload());
212 doReturn(lastAppliedEntry).when(mockReplicatedLog).get(8L);
213 doReturn(Arrays.asList(lastLogEntry)).when(mockReplicatedLog).getFrom(9L);
215 // when replicatedToAllIndex = -1
216 snapshotManager.capture(lastLogEntry, -1);
218 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
219 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
221 ArgumentCaptor<Snapshot> snapshotArgumentCaptor = ArgumentCaptor.forClass(Snapshot.class);
222 verify(mockDataPersistenceProvider).saveSnapshot(snapshotArgumentCaptor.capture());
224 Snapshot snapshot = snapshotArgumentCaptor.getValue();
226 assertEquals("getLastTerm", 3L, snapshot.getLastTerm());
227 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
228 assertEquals("getLastAppliedTerm", 2L, snapshot.getLastAppliedTerm());
229 assertEquals("getLastAppliedIndex", 8L, snapshot.getLastAppliedIndex());
230 assertArrayEquals("getState", bytes, snapshot.getState());
231 assertEquals("getUnAppliedEntries", Arrays.asList(lastLogEntry), snapshot.getUnAppliedEntries());
233 verify(mockReplicatedLog).snapshotPreCommit(7L, 1L);
237 public void testPersistWhenReplicatedToAllIndexNotMinus(){
238 doReturn(45L).when(mockReplicatedLog).getSnapshotIndex();
239 doReturn(6L).when(mockReplicatedLog).getSnapshotTerm();
240 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
241 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(9);
242 doReturn(6L).when(replicatedLogEntry).getTerm();
243 doReturn(9L).when(replicatedLogEntry).getIndex();
245 // when replicatedToAllIndex != -1
246 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
247 new MockRaftActorContext.MockPayload()), 9);
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", 6L, snapshot.getLastTerm());
258 assertEquals("getLastIndex", 9L, snapshot.getLastIndex());
259 assertEquals("getLastAppliedTerm", 6L, snapshot.getLastAppliedTerm());
260 assertEquals("getLastAppliedIndex", 9L, snapshot.getLastAppliedIndex());
261 assertArrayEquals("getState", bytes, snapshot.getState());
262 assertEquals("getUnAppliedEntries size", 0, snapshot.getUnAppliedEntries().size());
264 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
266 verify(mockRaftActorBehavior).setReplicatedToAllIndex(9);
270 public void testPersistWhenReplicatedLogDataSizeGreaterThanThreshold(){
271 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
273 // when replicatedToAllIndex = -1
274 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6,9,
275 new MockRaftActorContext.MockPayload()), -1);
277 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
279 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
281 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
283 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
287 public void testPersistWhenReplicatedLogSizeExceedsSnapshotBatchCount() {
288 doReturn(10L).when(mockReplicatedLog).size(); // matches snapshotBatchCount
289 doReturn(100).when(mockReplicatedLog).dataSize();
291 doReturn(5L).when(mockReplicatedLog).getSnapshotIndex();
292 doReturn(5L).when(mockReplicatedLog).getSnapshotTerm();
294 long replicatedToAllIndex = 1;
295 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
296 doReturn(replicatedLogEntry).when(mockReplicatedLog).get(replicatedToAllIndex);
297 doReturn(6L).when(replicatedLogEntry).getTerm();
298 doReturn(replicatedToAllIndex).when(replicatedLogEntry).getIndex();
300 snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
301 new MockRaftActorContext.MockPayload()), replicatedToAllIndex);
303 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, 2000000L);
305 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
307 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
309 verify(mockRaftActorBehavior).setReplicatedToAllIndex(replicatedToAllIndex);
313 public void testPersistSendInstallSnapshot(){
314 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
316 // when replicatedToAllIndex = -1
317 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
318 new MockRaftActorContext.MockPayload()), -1, "follower-1");
322 byte[] bytes = new byte[] {1,2,3,4,5,6,7,8,9,10};
324 snapshotManager.persist(bytes, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
326 assertEquals(true, snapshotManager.isCapturing());
328 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
330 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
332 ArgumentCaptor<SendInstallSnapshot> sendInstallSnapshotArgumentCaptor
333 = ArgumentCaptor.forClass(SendInstallSnapshot.class);
335 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), sendInstallSnapshotArgumentCaptor.capture());
337 SendInstallSnapshot sendInstallSnapshot = sendInstallSnapshotArgumentCaptor.getValue();
339 assertTrue(Arrays.equals(bytes, sendInstallSnapshot.getSnapshot().getState()));
343 public void testCallingPersistWithoutCaptureWillDoNothing(){
344 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
346 verify(mockDataPersistenceProvider, never()).saveSnapshot(any(Snapshot.class));
348 verify(mockReplicatedLog, never()).snapshotPreCommit(9L, 6L);
350 verify(mockRaftActorBehavior, never()).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
353 public void testCallingPersistTwiceWillDoNoHarm(){
354 doReturn(Integer.MAX_VALUE).when(mockReplicatedLog).dataSize();
356 // when replicatedToAllIndex = -1
357 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
358 new MockRaftActorContext.MockPayload()), -1, "follower-1");
360 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
362 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
364 verify(mockDataPersistenceProvider).saveSnapshot(any(Snapshot.class));
366 verify(mockReplicatedLog).snapshotPreCommit(9L, 6L);
368 verify(mockRaftActorBehavior).handleMessage(any(ActorRef.class), any(SendInstallSnapshot.class));
372 public void testCommit(){
373 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
375 // when replicatedToAllIndex = -1
376 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
377 new MockRaftActorContext.MockPayload()), -1, "follower-1");
379 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
381 assertEquals(true, snapshotManager.isCapturing());
383 snapshotManager.commit(100L, mockRaftActorBehavior);
385 assertEquals(false, snapshotManager.isCapturing());
387 verify(mockReplicatedLog).snapshotCommit();
389 verify(mockDataPersistenceProvider).deleteMessages(50L);
391 ArgumentCaptor<SnapshotSelectionCriteria> criteriaCaptor = ArgumentCaptor.forClass(SnapshotSelectionCriteria.class);
393 verify(mockDataPersistenceProvider).deleteSnapshots(criteriaCaptor.capture());
395 assertEquals(90, criteriaCaptor.getValue().maxSequenceNr()); // sequenceNumber = 100
396 // config snapShotBatchCount = 10
397 // therefore maxSequenceNumber = 90
401 public void testCommitBeforePersist(){
402 // when replicatedToAllIndex = -1
403 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
404 new MockRaftActorContext.MockPayload()), -1, "follower-1");
406 snapshotManager.commit(100L, mockRaftActorBehavior);
408 verify(mockReplicatedLog, never()).snapshotCommit();
410 verify(mockDataPersistenceProvider, never()).deleteMessages(100L);
412 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
417 public void testCommitBeforeCapture(){
418 snapshotManager.commit(100L, mockRaftActorBehavior);
420 verify(mockReplicatedLog, never()).snapshotCommit();
422 verify(mockDataPersistenceProvider, never()).deleteMessages(anyLong());
424 verify(mockDataPersistenceProvider, never()).deleteSnapshots(any(SnapshotSelectionCriteria.class));
429 public void testCallingCommitMultipleTimesCausesNoHarm(){
430 doReturn(50L).when(mockDataPersistenceProvider).getLastSequenceNumber();
432 // when replicatedToAllIndex = -1
433 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
434 new MockRaftActorContext.MockPayload()), -1, "follower-1");
436 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
438 snapshotManager.commit(100L, mockRaftActorBehavior);
440 snapshotManager.commit(100L, mockRaftActorBehavior);
442 verify(mockReplicatedLog, times(1)).snapshotCommit();
444 verify(mockDataPersistenceProvider, times(1)).deleteMessages(50L);
446 verify(mockDataPersistenceProvider, times(1)).deleteSnapshots(any(SnapshotSelectionCriteria.class));
450 public void testRollback(){
451 // when replicatedToAllIndex = -1
452 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
453 new MockRaftActorContext.MockPayload()), -1, "follower-1");
455 snapshotManager.persist(new byte[]{}, mockRaftActorBehavior, Runtime.getRuntime().totalMemory());
457 snapshotManager.rollback();
459 verify(mockReplicatedLog).snapshotRollback();
464 public void testRollbackBeforePersist(){
465 // when replicatedToAllIndex = -1
466 snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(6, 9,
467 new MockRaftActorContext.MockPayload()), -1, "follower-1");
469 snapshotManager.rollback();
471 verify(mockReplicatedLog, never()).snapshotRollback();
475 public void testRollbackBeforeCapture(){
476 snapshotManager.rollback();
478 verify(mockReplicatedLog, never()).snapshotRollback();
482 public void testCallingRollbackMultipleTimesCausesNoHarm(){
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 snapshotManager.rollback();
493 verify(mockReplicatedLog, times(1)).snapshotRollback();
497 public void testTrimLogWhenTrimIndexLessThanLastApplied() {
498 doReturn(20L).when(mockRaftActorContext).getLastApplied();
500 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
501 doReturn(true).when(mockReplicatedLog).isPresent(10);
502 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
503 doReturn(5L).when(replicatedLogEntry).getTerm();
505 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
506 assertEquals("return index", 10L, retIndex);
508 verify(mockReplicatedLog).snapshotPreCommit(10, 5);
509 verify(mockReplicatedLog).snapshotCommit();
511 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
515 public void testTrimLogWhenLastAppliedNotSet() {
516 doReturn(-1L).when(mockRaftActorContext).getLastApplied();
518 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
519 doReturn(true).when(mockReplicatedLog).isPresent(10);
520 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
521 doReturn(5L).when(replicatedLogEntry).getTerm();
523 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
524 assertEquals("return index", -1L, retIndex);
526 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
527 verify(mockReplicatedLog, never()).snapshotCommit();
529 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
533 public void testTrimLogWhenLastAppliedZero() {
534 doReturn(0L).when(mockRaftActorContext).getLastApplied();
536 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
537 doReturn(true).when(mockReplicatedLog).isPresent(10);
538 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
539 doReturn(5L).when(replicatedLogEntry).getTerm();
541 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
542 assertEquals("return index", -1L, retIndex);
544 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
545 verify(mockReplicatedLog, never()).snapshotCommit();
547 verify(mockRaftActorBehavior, never()).setReplicatedToAllIndex(anyLong());
551 public void testTrimLogWhenTrimIndexNotPresent() {
552 doReturn(20L).when(mockRaftActorContext).getLastApplied();
554 doReturn(false).when(mockReplicatedLog).isPresent(10);
556 long retIndex = snapshotManager.trimLog(10, mockRaftActorBehavior);
557 assertEquals("return index", -1L, retIndex);
559 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
560 verify(mockReplicatedLog, never()).snapshotCommit();
562 // Trim index is greater than replicatedToAllIndex so should update it.
563 verify(mockRaftActorBehavior).setReplicatedToAllIndex(10L);
567 public void testTrimLogAfterCapture(){
568 boolean capture = snapshotManager.capture(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
569 new MockRaftActorContext.MockPayload()), 9);
573 assertEquals(true, snapshotManager.isCapturing());
575 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
576 doReturn(20L).when(mockRaftActorContext).getLastApplied();
577 doReturn(true).when(mockReplicatedLog).isPresent(10);
578 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
579 doReturn(5L).when(replicatedLogEntry).getTerm();
581 snapshotManager.trimLog(10, mockRaftActorBehavior);
583 verify(mockReplicatedLog, never()).snapshotPreCommit(anyLong(), anyLong());
584 verify(mockReplicatedLog, never()).snapshotCommit();
589 public void testTrimLogAfterCaptureToInstall(){
590 boolean capture = snapshotManager.captureToInstall(new MockRaftActorContext.MockReplicatedLogEntry(1,9,
591 new MockRaftActorContext.MockPayload()), 9, "follower-1");
595 assertEquals(true, snapshotManager.isCapturing());
597 ReplicatedLogEntry replicatedLogEntry = mock(ReplicatedLogEntry.class);
598 doReturn(20L).when(mockRaftActorContext).getLastApplied();
599 doReturn(true).when(mockReplicatedLog).isPresent(10);
600 doReturn(replicatedLogEntry).when((mockReplicatedLog)).get(10);
601 doReturn(5L).when(replicatedLogEntry).getTerm();
603 snapshotManager.trimLog(10, mockRaftActorBehavior);
605 verify(mockReplicatedLog, never()).snapshotPreCommit(10, 5);
606 verify(mockReplicatedLog, never()).snapshotCommit();
611 public void testLastAppliedTermInformationReader() {
613 LastAppliedTermInformationReader reader = new LastAppliedTermInformationReader();
615 doReturn(4L).when(mockReplicatedLog).getSnapshotTerm();
616 doReturn(7L).when(mockReplicatedLog).getSnapshotIndex();
618 ReplicatedLogEntry lastLogEntry = new MockRaftActorContext.MockReplicatedLogEntry(6L, 9L,
619 new MockRaftActorContext.MockPayload());
621 // No followers and valid lastLogEntry
622 reader.init(mockReplicatedLog, 1L, lastLogEntry, false);
624 assertEquals("getTerm", 6L, reader.getTerm());
625 assertEquals("getIndex", 9L, reader.getIndex());
627 // No followers and null lastLogEntry
628 reader.init(mockReplicatedLog, 1L, null, false);
630 assertEquals("getTerm", -1L, reader.getTerm());
631 assertEquals("getIndex", -1L, reader.getIndex());
633 // Followers and valid originalIndex entry
634 doReturn(new MockRaftActorContext.MockReplicatedLogEntry(5L, 8L,
635 new MockRaftActorContext.MockPayload())).when(mockReplicatedLog).get(8L);
636 reader.init(mockReplicatedLog, 8L, lastLogEntry, true);
638 assertEquals("getTerm", 5L, reader.getTerm());
639 assertEquals("getIndex", 8L, reader.getIndex());
641 // Followers and null originalIndex entry and valid snapshot index
642 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
644 assertEquals("getTerm", 4L, reader.getTerm());
645 assertEquals("getIndex", 7L, reader.getIndex());
647 // Followers and null originalIndex entry and invalid snapshot index
648 doReturn(-1L).when(mockReplicatedLog).getSnapshotIndex();
649 reader.init(mockReplicatedLog, 7L, lastLogEntry, true);
651 assertEquals("getTerm", -1L, reader.getTerm());
652 assertEquals("getIndex", -1L, reader.getIndex());