From dcf327e8c3a8a10e2a7a433e473157ed50395b99 Mon Sep 17 00:00:00 2001 From: Tom Pantelis Date: Sat, 28 Mar 2015 20:51:05 -0400 Subject: [PATCH] Add unit tests for RaftActorSnapshotMessageSupport Change-Id: Ic0f5be5c9741f62bae572953d89ac8800ee371af Signed-off-by: Tom Pantelis --- .../controller/cluster/raft/RaftActor.java | 8 +- .../raft/RaftActorSnapshotMessageSupport.java | 7 +- .../cluster/raft/MockRaftActor.java | 15 + .../RaftActorSnapshotMessageSupportTest.java | 177 ++++++++++++ .../cluster/raft/RaftActorTest.java | 258 ++++-------------- 5 files changed, 250 insertions(+), 215 deletions(-) create mode 100644 opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupportTest.java diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java index 030ab30339..e98b1f74c4 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActor.java @@ -193,8 +193,7 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { @Override public void handleCommand(Object message) { if(snapshotSupport == null) { - snapshotSupport = new RaftActorSnapshotMessageSupport(delegatingPersistenceProvider, context, - currentBehavior, getRaftActorSnapshotCohort(), self()); + snapshotSupport = newRaftActorSnapshotMessageSupport(); } boolean handled = snapshotSupport.handleSnapshotMessage(message); @@ -244,6 +243,11 @@ public abstract class RaftActor extends AbstractUntypedPersistentActor { } } + protected RaftActorSnapshotMessageSupport newRaftActorSnapshotMessageSupport() { + return new RaftActorSnapshotMessageSupport(delegatingPersistenceProvider, context, + currentBehavior, getRaftActorSnapshotCohort()); + } + private void onGetOnDemandRaftStats() { // Debugging message to retrieve raft stats. diff --git a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupport.java b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupport.java index 21c8ffa68e..790ff89510 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupport.java +++ b/opendaylight/md-sal/sal-akka-raft/src/main/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupport.java @@ -7,7 +7,6 @@ */ package org.opendaylight.controller.cluster.raft; -import akka.actor.ActorRef; import akka.japi.Procedure; import akka.persistence.SaveSnapshotFailure; import akka.persistence.SaveSnapshotSuccess; @@ -30,23 +29,21 @@ class RaftActorSnapshotMessageSupport { private final RaftActorContext context; private final RaftActorBehavior currentBehavior; private final RaftActorSnapshotCohort cohort; - private final ActorRef raftActorRef; private final Logger log; private final Procedure createSnapshotProcedure = new Procedure() { @Override public void apply(Void notUsed) throws Exception { - cohort.createSnapshot(raftActorRef); + cohort.createSnapshot(context.getActor()); } }; RaftActorSnapshotMessageSupport(DataPersistenceProvider persistence, RaftActorContext context, - RaftActorBehavior currentBehavior, RaftActorSnapshotCohort cohort, ActorRef raftActorRef) { + RaftActorBehavior currentBehavior, RaftActorSnapshotCohort cohort) { this.persistence = persistence; this.context = context; this.currentBehavior = currentBehavior; this.cohort = cohort; - this.raftActorRef = raftActorRef; this.log = context.getLogger(); } diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActor.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActor.java index 3275e8d6c4..53110b3583 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActor.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/MockRaftActor.java @@ -37,6 +37,7 @@ public class MockRaftActor extends RaftActor implements RaftActorRecoveryCohort, private ActorRef roleChangeNotifier; private final CountDownLatch initializeBehaviorComplete = new CountDownLatch(1); private RaftActorRecoverySupport raftActorRecoverySupport; + private RaftActorSnapshotMessageSupport snapshotMessageSupport; public static final class MockRaftActorCreator implements Creator { private static final long serialVersionUID = 1L; @@ -45,6 +46,7 @@ public class MockRaftActor extends RaftActor implements RaftActorRecoveryCohort, private final Optional config; private final DataPersistenceProvider dataPersistenceProvider; private final ActorRef roleChangeNotifier; + private RaftActorSnapshotMessageSupport snapshotMessageSupport; private MockRaftActorCreator(Map peerAddresses, String id, Optional config, DataPersistenceProvider dataPersistenceProvider, @@ -61,6 +63,7 @@ public class MockRaftActor extends RaftActor implements RaftActorRecoveryCohort, MockRaftActor mockRaftActor = new MockRaftActor(id, peerAddresses, config, dataPersistenceProvider); mockRaftActor.roleChangeNotifier = this.roleChangeNotifier; + mockRaftActor.snapshotMessageSupport = snapshotMessageSupport; return mockRaftActor; } } @@ -88,6 +91,11 @@ public class MockRaftActor extends RaftActor implements RaftActorRecoveryCohort, return raftActorRecoverySupport != null ? raftActorRecoverySupport : super.newRaftActorRecoverySupport(); } + @Override + protected RaftActorSnapshotMessageSupport newRaftActorSnapshotMessageSupport() { + return snapshotMessageSupport != null ? snapshotMessageSupport : super.newRaftActorSnapshotMessageSupport(); + } + public void waitForRecoveryComplete() { try { assertEquals("Recovery complete", true, recoveryComplete.await(5, TimeUnit.SECONDS)); @@ -123,6 +131,13 @@ public class MockRaftActor extends RaftActor implements RaftActorRecoveryCohort, return Props.create(new MockRaftActorCreator(peerAddresses, id, config, null, null)); } + public static Props props(final String id, final Map peerAddresses, + Optional config, RaftActorSnapshotMessageSupport snapshotMessageSupport){ + MockRaftActorCreator creator = new MockRaftActorCreator(peerAddresses, id, config, null, null); + creator.snapshotMessageSupport = snapshotMessageSupport; + return Props.create(creator); + } + public static Props props(final String id, final Map peerAddresses, Optional config, DataPersistenceProvider dataPersistenceProvider){ return Props.create(new MockRaftActorCreator(peerAddresses, id, config, dataPersistenceProvider, null)); diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupportTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupportTest.java new file mode 100644 index 0000000000..86b90d844d --- /dev/null +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorSnapshotMessageSupportTest.java @@ -0,0 +1,177 @@ +/* + * Copyright (c) 2015 Brocade Communications Systems, Inc. and others. All rights reserved. + * + * This program and the accompanying materials are made available under the + * terms of the Eclipse Public License v1.0 which accompanies this distribution, + * and is available at http://www.eclipse.org/legal/epl-v10.html + */ +package org.opendaylight.controller.cluster.raft; + +import static org.junit.Assert.assertEquals; +import static org.mockito.Matchers.anyLong; +import static org.mockito.Matchers.same; +import static org.mockito.Mockito.doReturn; +import static org.mockito.Mockito.verify; +import akka.actor.ActorRef; +import akka.japi.Procedure; +import akka.persistence.SaveSnapshotFailure; +import akka.persistence.SaveSnapshotSuccess; +import akka.persistence.SnapshotMetadata; +import java.util.Arrays; +import java.util.Collections; +import org.junit.Before; +import org.junit.Test; +import org.mockito.ArgumentCaptor; +import org.mockito.Mock; +import org.mockito.MockitoAnnotations; +import org.opendaylight.controller.cluster.DataPersistenceProvider; +import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockPayload; +import org.opendaylight.controller.cluster.raft.MockRaftActorContext.MockReplicatedLogEntry; +import org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot; +import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot; +import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply; +import org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; + +/** + * Unit tests for RaftActorSnapshotMessageSupport. + * + * @author Thomas Pantelis + */ +public class RaftActorSnapshotMessageSupportTest { + + private static final Logger LOG = LoggerFactory.getLogger(RaftActorRecoverySupportTest.class); + + @Mock + private DataPersistenceProvider mockPersistence; + + @Mock + private RaftActorBehavior mockBehavior; + + @Mock + private RaftActorSnapshotCohort mockCohort; + + @Mock + private SnapshotManager mockSnapshotManager; + + @Mock + ActorRef mockRaftActorRef; + + private RaftActorSnapshotMessageSupport support; + + private RaftActorContext context; + private final DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl(); + + @Before + public void setup() { + MockitoAnnotations.initMocks(this); + + context = new RaftActorContextImpl(mockRaftActorRef, null, "test", + new ElectionTermImpl(mockPersistence, "test", LOG), + -1, -1, Collections.emptyMap(), configParams, LOG) { + @Override + public SnapshotManager getSnapshotManager() { + return mockSnapshotManager; + } + }; + + support = new RaftActorSnapshotMessageSupport(mockPersistence, context, mockBehavior, mockCohort); + + doReturn(true).when(mockPersistence).isRecoveryApplicable(); + + context.setReplicatedLog(ReplicatedLogImpl.newInstance(context, mockPersistence, mockBehavior)); + } + + private void sendMessageToSupport(Object message) { + sendMessageToSupport(message, true); + } + + private void sendMessageToSupport(Object message, boolean expHandled) { + boolean handled = support.handleSnapshotMessage(message); + assertEquals("complete", expHandled, handled); + } + + @Test + public void testOnApplySnapshot() { + + ReplicatedLog replicatedLog = context.getReplicatedLog(); + replicatedLog.append(new MockReplicatedLogEntry(1, 1, new MockPayload("1"))); + + byte[] snapshotBytes = {1,2,3,4,5}; + + ReplicatedLogEntry unAppliedEntry = new MockReplicatedLogEntry(1, 2, new MockPayload("2")); + + long lastAppliedDuringSnapshotCapture = 1; + long lastIndexDuringSnapshotCapture = 2; + + Snapshot snapshot = Snapshot.create(snapshotBytes, Arrays.asList(unAppliedEntry), + lastIndexDuringSnapshotCapture, 1, lastAppliedDuringSnapshotCapture, 1); + + sendMessageToSupport(new ApplySnapshot(snapshot)); + + assertEquals("Journal log size", 1, context.getReplicatedLog().size()); + assertEquals("Last index", lastIndexDuringSnapshotCapture, context.getReplicatedLog().lastIndex()); + assertEquals("Last applied", lastAppliedDuringSnapshotCapture, context.getLastApplied()); + assertEquals("Commit index", -1, context.getCommitIndex()); + assertEquals("Snapshot term", 1, context.getReplicatedLog().getSnapshotTerm()); + assertEquals("Snapshot index", lastAppliedDuringSnapshotCapture, context.getReplicatedLog().getSnapshotIndex()); + + verify(mockCohort).applySnapshot(snapshotBytes); + } + + @SuppressWarnings({ "rawtypes", "unchecked" }) + @Test + public void testOnCaptureSnapshot() throws Exception { + + sendMessageToSupport(new CaptureSnapshot(3, 1, 2, 1, 2, 1)); + + ArgumentCaptor procedure = ArgumentCaptor.forClass(Procedure.class); + verify(mockSnapshotManager).create(procedure.capture()); + + procedure.getValue().apply(null); + + verify(mockCohort).createSnapshot(same(mockRaftActorRef)); + } + + @Test + public void testOnCaptureSnapshotReply() { + + byte[] snapshot = {1,2,3,4,5}; + sendMessageToSupport(new CaptureSnapshotReply(snapshot)); + + verify(mockSnapshotManager).persist(same(mockPersistence), same(snapshot), same(mockBehavior), anyLong()); + } + + @Test + public void testOnSaveSnapshotSuccess() { + + long sequenceNumber = 100; + sendMessageToSupport(new SaveSnapshotSuccess(new SnapshotMetadata("foo", sequenceNumber, 1234L))); + + verify(mockSnapshotManager).commit(mockPersistence, sequenceNumber); + } + + @Test + public void testOnSaveSnapshotFailure() { + + sendMessageToSupport(new SaveSnapshotFailure(new SnapshotMetadata("foo", 100, 1234L), + new Throwable("mock"))); + + verify(mockSnapshotManager).rollback(); + } + + @Test + public void testOnCommitSnapshot() { + + sendMessageToSupport(RaftActorSnapshotMessageSupport.COMMIT_SNAPSHOT); + + verify(mockSnapshotManager).commit(mockPersistence, -1); + } + + @Test + public void testUnhandledMessage() { + + sendMessageToSupport("unhandled", false); + } +} diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java index bc6257b67d..9187f36954 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/RaftActorTest.java @@ -4,7 +4,6 @@ import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertTrue; import static org.mockito.Matchers.any; import static org.mockito.Matchers.anyObject; import static org.mockito.Matchers.eq; @@ -22,7 +21,6 @@ import akka.persistence.SaveSnapshotFailure; import akka.persistence.SaveSnapshotSuccess; import akka.persistence.SnapshotMetadata; import akka.persistence.SnapshotOffer; -import akka.persistence.SnapshotSelectionCriteria; import akka.testkit.JavaTestKit; import akka.testkit.TestActorRef; import com.google.common.base.Optional; @@ -53,6 +51,7 @@ import org.opendaylight.controller.cluster.raft.base.messages.ApplyJournalEntrie import org.opendaylight.controller.cluster.raft.base.messages.ApplyLogEntries; import org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot; import org.opendaylight.controller.cluster.raft.base.messages.ApplyState; +import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot; import org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply; import org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat; import org.opendaylight.controller.cluster.raft.behaviors.Follower; @@ -252,6 +251,55 @@ public class RaftActorTest extends AbstractActorTest { verify(mockSupport).handleRecoveryMessage(same(updateElectionTerm)); } + @Test + public void testRaftActorForwardsToRaftActorSnapshotMessageSupport() { + String persistenceId = factory.generateActorId("leader-"); + + DefaultConfigParamsImpl config = new DefaultConfigParamsImpl(); + + config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS)); + + RaftActorSnapshotMessageSupport mockSupport = mock(RaftActorSnapshotMessageSupport.class); + + TestActorRef mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, + Collections.emptyMap(), Optional.of(config), mockSupport), persistenceId); + + MockRaftActor mockRaftActor = mockActorRef.underlyingActor(); + + // Wait for akka's recovery to complete so it doesn't interfere. + mockRaftActor.waitForRecoveryComplete(); + + ApplySnapshot applySnapshot = new ApplySnapshot(mock(Snapshot.class)); + doReturn(true).when(mockSupport).handleSnapshotMessage(same(applySnapshot)); + mockRaftActor.handleCommand(applySnapshot); + + CaptureSnapshot captureSnapshot = new CaptureSnapshot(1, 1, 1, 1, 0, 1); + doReturn(true).when(mockSupport).handleSnapshotMessage(same(captureSnapshot)); + mockRaftActor.handleCommand(captureSnapshot); + + CaptureSnapshotReply captureSnapshotReply = new CaptureSnapshotReply(new byte[0]); + doReturn(true).when(mockSupport).handleSnapshotMessage(same(captureSnapshotReply)); + mockRaftActor.handleCommand(captureSnapshotReply); + + SaveSnapshotSuccess saveSnapshotSuccess = new SaveSnapshotSuccess(mock(SnapshotMetadata.class)); + doReturn(true).when(mockSupport).handleSnapshotMessage(same(saveSnapshotSuccess)); + mockRaftActor.handleCommand(saveSnapshotSuccess); + + SaveSnapshotFailure saveSnapshotFailure = new SaveSnapshotFailure(mock(SnapshotMetadata.class), new Throwable()); + doReturn(true).when(mockSupport).handleSnapshotMessage(same(saveSnapshotFailure)); + mockRaftActor.handleCommand(saveSnapshotFailure); + + doReturn(true).when(mockSupport).handleSnapshotMessage(same(RaftActorSnapshotMessageSupport.COMMIT_SNAPSHOT)); + mockRaftActor.handleCommand(RaftActorSnapshotMessageSupport.COMMIT_SNAPSHOT); + + verify(mockSupport).handleSnapshotMessage(same(applySnapshot)); + verify(mockSupport).handleSnapshotMessage(same(captureSnapshot)); + verify(mockSupport).handleSnapshotMessage(same(captureSnapshotReply)); + verify(mockSupport).handleSnapshotMessage(same(saveSnapshotSuccess)); + verify(mockSupport).handleSnapshotMessage(same(saveSnapshotFailure)); + verify(mockSupport).handleSnapshotMessage(same(RaftActorSnapshotMessageSupport.COMMIT_SNAPSHOT)); + } + @Test public void testUpdatingElectionTermCallsDataPersistence() throws Exception { new JavaTestKit(getSystem()) { @@ -368,112 +416,6 @@ public class RaftActorTest extends AbstractActorTest { }; } - @Test - public void testCaptureSnapshotReplyCallsDataPersistence() throws Exception { - new JavaTestKit(getSystem()) { - { - String persistenceId = factory.generateActorId("leader-"); - - DefaultConfigParamsImpl config = new DefaultConfigParamsImpl(); - - config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS)); - - DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class); - - TestActorRef mockActorRef = factory.createTestActor( - MockRaftActor.props(persistenceId, Collections.emptyMap(), - Optional.of(config), dataPersistenceProvider), persistenceId); - - MockRaftActor mockRaftActor = mockActorRef.underlyingActor(); - - mockRaftActor.waitForInitializeBehaviorComplete(); - - ByteString snapshotBytes = fromObject(Arrays.asList( - new MockRaftActorContext.MockPayload("A"), - new MockRaftActorContext.MockPayload("B"), - new MockRaftActorContext.MockPayload("C"), - new MockRaftActorContext.MockPayload("D"))); - - RaftActorContext raftActorContext = mockRaftActor.getRaftActorContext(); - - raftActorContext.getSnapshotManager().capture( - new MockRaftActorContext.MockReplicatedLogEntry(1, -1, - new MockRaftActorContext.MockPayload("D")), -1); - - mockRaftActor.setCurrentBehavior(new Leader(raftActorContext)); - - mockRaftActor.onReceiveCommand(new CaptureSnapshotReply(snapshotBytes.toByteArray())); - - verify(dataPersistenceProvider).saveSnapshot(anyObject()); - - } - }; - } - - @Test - public void testSaveSnapshotSuccessCallsDataPersistence() throws Exception { - new JavaTestKit(getSystem()) { - { - String persistenceId = factory.generateActorId("leader-"); - - DefaultConfigParamsImpl config = new DefaultConfigParamsImpl(); - - config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS)); - - DataPersistenceProvider dataPersistenceProvider = mock(DataPersistenceProvider.class); - - TestActorRef mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, - ImmutableMap.of("leader", "fake/path"), Optional.of(config), dataPersistenceProvider), persistenceId); - - MockRaftActor mockRaftActor = mockActorRef.underlyingActor(); - - mockRaftActor.waitForInitializeBehaviorComplete(); - MockRaftActorContext.MockReplicatedLogEntry lastEntry = new MockRaftActorContext.MockReplicatedLogEntry(1, 4, mock(Payload.class)); - - mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 0, mock(Payload.class))); - mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 1, mock(Payload.class))); - mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 2, mock(Payload.class))); - mockRaftActor.getReplicatedLog().append(new MockRaftActorContext.MockReplicatedLogEntry(1, 3, mock(Payload.class))); - mockRaftActor.getReplicatedLog().append(lastEntry); - - ByteString snapshotBytes = fromObject(Arrays.asList( - new MockRaftActorContext.MockPayload("A"), - new MockRaftActorContext.MockPayload("B"), - new MockRaftActorContext.MockPayload("C"), - new MockRaftActorContext.MockPayload("D"))); - - RaftActorContext raftActorContext = mockRaftActor.getRaftActorContext(); - mockRaftActor.setCurrentBehavior(new Follower(raftActorContext)); - - long replicatedToAllIndex = 1; - - mockRaftActor.getRaftActorContext().getSnapshotManager().capture(lastEntry, replicatedToAllIndex); - - verify(mockRaftActor.snapshotCohortDelegate).createSnapshot(any(ActorRef.class)); - - mockRaftActor.onReceiveCommand(new CaptureSnapshotReply(snapshotBytes.toByteArray())); - - mockRaftActor.onReceiveCommand(new SaveSnapshotSuccess(new SnapshotMetadata("foo", 100, 100))); - - verify(dataPersistenceProvider).deleteSnapshots(any(SnapshotSelectionCriteria.class)); - - verify(dataPersistenceProvider).deleteMessages(100); - - assertEquals(3, mockRaftActor.getReplicatedLog().size()); - assertEquals(1, mockRaftActor.getCurrentBehavior().getReplicatedToAllIndex()); - - assertNotNull(mockRaftActor.getReplicatedLog().get(2)); - assertNotNull(mockRaftActor.getReplicatedLog().get(3)); - assertNotNull(mockRaftActor.getReplicatedLog().get(4)); - - // Index 2 will not be in the log because it was removed due to snapshotting - assertNull(mockRaftActor.getReplicatedLog().get(1)); - assertNull(mockRaftActor.getReplicatedLog().get(0)); - - } - }; - } - @Test public void testApplyState() throws Exception { @@ -505,106 +447,6 @@ public class RaftActorTest extends AbstractActorTest { }; } - @Test - public void testApplySnapshot() throws Exception { - new JavaTestKit(getSystem()) { - { - String persistenceId = factory.generateActorId("leader-"); - - DefaultConfigParamsImpl config = new DefaultConfigParamsImpl(); - - config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS)); - - DataPersistenceProviderMonitor dataPersistenceProviderMonitor = new DataPersistenceProviderMonitor(); - - TestActorRef mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, - Collections.emptyMap(), Optional.of(config), dataPersistenceProviderMonitor), persistenceId); - - MockRaftActor mockRaftActor = mockActorRef.underlyingActor(); - - mockRaftActor.waitForInitializeBehaviorComplete(); - - ReplicatedLog oldReplicatedLog = mockRaftActor.getReplicatedLog(); - - oldReplicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, 0, mock(Payload.class))); - oldReplicatedLog.append(new MockRaftActorContext.MockReplicatedLogEntry(1, 1, mock(Payload.class))); - oldReplicatedLog.append( - new MockRaftActorContext.MockReplicatedLogEntry(1, 2, - mock(Payload.class))); - - ByteString snapshotBytes = fromObject(Arrays.asList( - new MockRaftActorContext.MockPayload("A"), - new MockRaftActorContext.MockPayload("B"), - new MockRaftActorContext.MockPayload("C"), - new MockRaftActorContext.MockPayload("D"))); - - Snapshot snapshot = mock(Snapshot.class); - - doReturn(snapshotBytes.toByteArray()).when(snapshot).getState(); - - doReturn(3L).when(snapshot).getLastAppliedIndex(); - - mockRaftActor.onReceiveCommand(new ApplySnapshot(snapshot)); - - verify(mockRaftActor.snapshotCohortDelegate).applySnapshot(eq(snapshot.getState())); - - assertTrue("The replicatedLog should have changed", - oldReplicatedLog != mockRaftActor.getReplicatedLog()); - - assertEquals("lastApplied should be same as in the snapshot", - (Long) 3L, mockRaftActor.getLastApplied()); - - assertEquals(0, mockRaftActor.getReplicatedLog().size()); - - } - }; - } - - @Test - public void testSaveSnapshotFailure() throws Exception { - new JavaTestKit(getSystem()) { - { - String persistenceId = factory.generateActorId("leader-"); - - DefaultConfigParamsImpl config = new DefaultConfigParamsImpl(); - - config.setHeartBeatInterval(new FiniteDuration(1, TimeUnit.DAYS)); - - DataPersistenceProviderMonitor dataPersistenceProviderMonitor = new DataPersistenceProviderMonitor(); - - TestActorRef mockActorRef = factory.createTestActor(MockRaftActor.props(persistenceId, - Collections.emptyMap(), Optional.of(config), dataPersistenceProviderMonitor), persistenceId); - - MockRaftActor mockRaftActor = mockActorRef.underlyingActor(); - - mockRaftActor.waitForInitializeBehaviorComplete(); - - ByteString snapshotBytes = fromObject(Arrays.asList( - new MockRaftActorContext.MockPayload("A"), - new MockRaftActorContext.MockPayload("B"), - new MockRaftActorContext.MockPayload("C"), - new MockRaftActorContext.MockPayload("D"))); - - RaftActorContext raftActorContext = mockRaftActor.getRaftActorContext(); - - mockRaftActor.setCurrentBehavior(new Leader(raftActorContext)); - - raftActorContext.getSnapshotManager().capture( - new MockRaftActorContext.MockReplicatedLogEntry(1, 1, - new MockRaftActorContext.MockPayload("D")), 1); - - mockRaftActor.onReceiveCommand(new CaptureSnapshotReply(snapshotBytes.toByteArray())); - - mockRaftActor.onReceiveCommand(new SaveSnapshotFailure(new SnapshotMetadata("foobar", 10L, 1234L), - new Exception())); - - assertEquals("Snapshot index should not have advanced because save snapshot failed", -1, - mockRaftActor.getReplicatedLog().getSnapshotIndex()); - - } - }; - } - @Test public void testRaftRoleChangeNotifierWhenRaftActorHasNoPeers() throws Exception { new JavaTestKit(getSystem()) {{ -- 2.36.6