X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2Fbehaviors%2FFollowerTest.java;h=4dd2b9b5363b41b7d56bcc7adb912a753526bf76;hb=c77c163d54872612b47f0f2550931fa408ed596b;hp=15fca0cb8d80696393e30ea465d5263ba339fa91;hpb=283929615619b09a664fd46bd13e19cdb163ec4d;p=controller.git diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java index 15fca0cb8d..4dd2b9b536 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/FollowerTest.java @@ -14,24 +14,22 @@ import static org.junit.Assert.assertNotNull; import static org.junit.Assert.assertNull; import static org.junit.Assert.assertSame; import static org.junit.Assert.assertTrue; -import static org.mockito.Matchers.any; +import static org.mockito.ArgumentMatchers.any; import static org.mockito.Mockito.never; import static org.mockito.Mockito.spy; import static org.mockito.Mockito.verify; import akka.actor.ActorRef; -import akka.actor.Props; import akka.dispatch.Dispatchers; -import akka.testkit.JavaTestKit; +import akka.protobuf.ByteString; import akka.testkit.TestActorRef; +import akka.testkit.javadsl.TestKit; import com.google.common.base.Optional; import com.google.common.base.Stopwatch; -import com.google.common.base.Throwables; import com.google.common.collect.ImmutableList; import com.google.common.collect.ImmutableMap; import com.google.common.io.ByteSource; import com.google.common.util.concurrent.Uninterruptibles; -import com.google.protobuf.ByteString; import java.io.OutputStream; import java.util.ArrayList; import java.util.Arrays; @@ -79,11 +77,11 @@ import scala.concurrent.duration.FiniteDuration; public class FollowerTest extends AbstractRaftActorBehaviorTest { - private final TestActorRef followerActor = actorFactory.createTestActor( - Props.create(MessageCollectorActor.class), actorFactory.generateActorId("follower")); + private final ActorRef followerActor = actorFactory.createActor( + MessageCollectorActor.props(), actorFactory.generateActorId("follower")); - private final TestActorRef leaderActor = actorFactory.createTestActor( - Props.create(MessageCollectorActor.class), actorFactory.generateActorId("leader")); + private final ActorRef leaderActor = actorFactory.createActor( + MessageCollectorActor.props(), actorFactory.generateActorId("leader")); private Follower follower; @@ -91,7 +89,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { @Override @After - public void tearDown() throws Exception { + public void tearDown() { if (follower != null) { follower.close(); } @@ -100,7 +98,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Override - protected Follower createBehavior(RaftActorContext actorContext) { + protected Follower createBehavior(final RaftActorContext actorContext) { return spy(new Follower(actorContext)); } @@ -110,7 +108,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Override - protected MockRaftActorContext createActorContext(ActorRef actorRef) { + protected MockRaftActorContext createActorContext(final ActorRef actorRef) { MockRaftActorContext context = new MockRaftActorContext("follower", getSystem(), actorRef); context.setPayloadVersion(payloadVersion); return context; @@ -209,7 +207,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { @Test - public void testHandleFirstAppendEntries() throws Exception { + public void testHandleFirstAppendEntries() { logStart("testHandleFirstAppendEntries"); MockRaftActorContext context = createActorContext(); @@ -237,7 +235,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testHandleFirstAppendEntriesWithPrevIndexMinusOne() throws Exception { + public void testHandleFirstAppendEntriesWithPrevIndexMinusOne() { logStart("testHandleFirstAppendEntries"); MockRaftActorContext context = createActorContext(); @@ -260,9 +258,8 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testHandleFirstAppendEntriesWithPrevIndexMinusOneAndReplicatedToAllIndexPresentInLog() - throws Exception { - logStart("testHandleFirstAppendEntries"); + public void testHandleFirstAppendEntriesWithPrevIndexMinusOneAndReplicatedToAllIndexPresentInLog() { + logStart("testHandleFirstAppendEntriesWithPrevIndexMinusOneAndReplicatedToAllIndexPresentInLog"); MockRaftActorContext context = createActorContext(); context.getReplicatedLog().clear(0,2); @@ -287,9 +284,8 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testHandleFirstAppendEntriesWithPrevIndexMinusOneAndReplicatedToAllIndexPresentInSnapshot() - throws Exception { - logStart("testHandleFirstAppendEntries"); + public void testHandleFirstAppendEntriesWithPrevIndexMinusOneAndReplicatedToAllIndexPresentInSnapshot() { + logStart("testHandleFirstAppendEntriesWithPrevIndexMinusOneAndReplicatedToAllIndexPresentInSnapshot"); MockRaftActorContext context = createActorContext(); context.getReplicatedLog().clear(0,2); @@ -313,8 +309,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testFirstAppendEntriesWithNoPrevIndexAndReplicatedToAllPresentInSnapshotButCalculatedPrevEntryMissing() - throws Exception { + public void testFirstAppendEntriesWithNoPrevIndexAndReplToAllPresentInSnapshotButCalculatedPrevEntryMissing() { logStart( "testFirstAppendEntriesWithNoPrevIndexAndReplicatedToAllPresentInSnapshotButCalculatedPrevEntryMissing"); @@ -340,7 +335,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testHandleSyncUpAppendEntries() throws Exception { + public void testHandleSyncUpAppendEntries() { logStart("testHandleSyncUpAppendEntries"); MockRaftActorContext context = createActorContext(); @@ -360,15 +355,13 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { assertFalse(syncStatus.isInitialSyncDone()); // Clear all the messages - followerActor.underlyingActor().clear(); + MessageCollectorActor.clearMessages(followerActor); context.setLastApplied(101); context.setCommitIndex(101); - setLastLogEntry(context, 1, 101, - new MockRaftActorContext.MockPayload("")); + setLastLogEntry(context, 1, 101, new MockRaftActorContext.MockPayload("")); - entries = Arrays.asList( - newReplicatedLogEntry(2, 101, "foo")); + entries = Arrays.asList(newReplicatedLogEntry(2, 101, "foo")); // The new commitIndex is 101 appendEntries = new AppendEntries(2, "leader-1", 101, 1, entries, 102, 101, (short)0); @@ -378,7 +371,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { assertTrue(syncStatus.isInitialSyncDone()); - followerActor.underlyingActor().clear(); + MessageCollectorActor.clearMessages(followerActor); // Sending the same message again should not generate another message @@ -387,11 +380,10 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { syncStatus = MessageCollectorActor.getFirstMatching(followerActor, FollowerInitialSyncUpStatus.class); assertNull(syncStatus); - } @Test - public void testHandleAppendEntriesLeaderChangedBeforeSyncUpComplete() throws Exception { + public void testHandleAppendEntriesLeaderChangedBeforeSyncUpComplete() { logStart("testHandleAppendEntriesLeaderChangedBeforeSyncUpComplete"); MockRaftActorContext context = createActorContext(); @@ -411,7 +403,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { assertFalse(syncStatus.isInitialSyncDone()); // Clear all the messages - followerActor.underlyingActor().clear(); + MessageCollectorActor.clearMessages(followerActor); context.setLastApplied(100); setLastLogEntry(context, 1, 100, @@ -428,12 +420,10 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { // We get a new message saying initial status is not done assertFalse(syncStatus.isInitialSyncDone()); - } - @Test - public void testHandleAppendEntriesLeaderChangedAfterSyncUpComplete() throws Exception { + public void testHandleAppendEntriesLeaderChangedAfterSyncUpComplete() { logStart("testHandleAppendEntriesLeaderChangedAfterSyncUpComplete"); MockRaftActorContext context = createActorContext(); @@ -453,7 +443,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { assertFalse(syncStatus.isInitialSyncDone()); // Clear all the messages - followerActor.underlyingActor().clear(); + MessageCollectorActor.clearMessages(followerActor); context.setLastApplied(101); context.setCommitIndex(101); @@ -472,7 +462,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { assertTrue(syncStatus.isInitialSyncDone()); // Clear all the messages - followerActor.underlyingActor().clear(); + MessageCollectorActor.clearMessages(followerActor); context.setLastApplied(100); setLastLogEntry(context, 1, 100, @@ -489,10 +479,8 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { // We get a new message saying initial status is not done assertFalse(syncStatus.isInitialSyncDone()); - } - /** * This test verifies that when an AppendEntries RPC is received by a RaftActor * with a commitIndex that is greater than what has been applied to the @@ -500,7 +488,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { * sets it current applied state to the commitIndex of the sender. */ @Test - public void testHandleAppendEntriesWithNewerCommitIndex() throws Exception { + public void testHandleAppendEntriesWithNewerCommitIndex() { logStart("testHandleAppendEntriesWithNewerCommitIndex"); MockRaftActorContext context = createActorContext(); @@ -523,7 +511,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } /** - * This test verifies that when an AppendEntries is received a specific prevLogTerm + * This test verifies that when an AppendEntries is received with a prevLogTerm * which does not match the term that is in RaftActors log entry at prevLogIndex * then the RaftActor does not change it's state and it returns a failure. */ @@ -533,12 +521,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { MockRaftActorContext context = createActorContext(); - // First set the receivers term to lower number - context.getTermInformation().update(95, "test"); - - // AppendEntries is now sent with a bigger term - // this will set the receivers term to be the same as the sender's term - AppendEntries appendEntries = new AppendEntries(100, "leader", 0, 0, null, 101, -1, (short)0); + AppendEntries appendEntries = new AppendEntries(2, "leader", 0, 2, Collections.emptyList(), 101, -1, (short)0); follower = createBehavior(context); @@ -552,6 +535,28 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { assertEquals("isSuccess", false, reply.isSuccess()); } + @Test + public void testHandleAppendEntriesSenderPrevLogIndexIsInTheSnapshot() { + logStart("testHandleAppendEntriesSenderPrevLogIndexIsInTheSnapshot"); + + MockRaftActorContext context = createActorContext(); + context.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(5, 8, 3).build()); + context.getReplicatedLog().setSnapshotIndex(4); + context.getReplicatedLog().setSnapshotTerm(3); + + AppendEntries appendEntries = new AppendEntries(3, "leader", 1, 3, Collections.emptyList(), 8, -1, (short)0); + + follower = createBehavior(context); + + RaftActorBehavior newBehavior = follower.handleMessage(leaderActor, appendEntries); + + Assert.assertSame(follower, newBehavior); + + AppendEntriesReply reply = MessageCollectorActor.expectFirstMatching(leaderActor, AppendEntriesReply.class); + + assertEquals("isSuccess", true, reply.isSuccess()); + } + /** * This test verifies that when a new AppendEntries message is received with * new entries and the logs of the sender and receiver match that the new @@ -759,7 +764,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { entries = Arrays.asList(newReplicatedLogEntry(1, 1, "one"), newReplicatedLogEntry(1, 2, "two")); - leaderActor.underlyingActor().clear(); + MessageCollectorActor.clearMessages(leaderActor); follower.handleMessage(leaderActor, new AppendEntries(1, "leader", 0, 1, entries, 2, -1, (short)0)); assertEquals("Next index", 3, log.last().getIndex() + 1); @@ -805,7 +810,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { * the follower its applied correctly. */ @Test - public void testHandleInstallSnapshot() throws Exception { + public void testHandleInstallSnapshot() { logStart("testHandleInstallSnapshot"); MockRaftActorContext context = createActorContext(); @@ -863,13 +868,12 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { assertNull("Expected null SnapshotTracker", follower.getSnapshotTracker()); } - /** * Verify that when an AppendEntries is sent to a follower during a snapshot install * the Follower short-circuits the processing of the AppendEntries message. */ @Test - public void testReceivingAppendEntriesDuringInstallSnapshot() throws Exception { + public void testReceivingAppendEntriesDuringInstallSnapshot() { logStart("testReceivingAppendEntriesDuringInstallSnapshot"); MockRaftActorContext context = createActorContext(); @@ -912,7 +916,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testReceivingAppendEntriesDuringInstallSnapshotFromDifferentLeader() throws Exception { + public void testReceivingAppendEntriesDuringInstallSnapshotFromDifferentLeader() { logStart("testReceivingAppendEntriesDuringInstallSnapshotFromDifferentLeader"); MockRaftActorContext context = createActorContext(); @@ -955,7 +959,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testInitialSyncUpWithHandleInstallSnapshotFollowedByAppendEntries() throws Exception { + public void testInitialSyncUpWithHandleInstallSnapshotFollowedByAppendEntries() { logStart("testInitialSyncUpWithHandleInstallSnapshot"); MockRaftActorContext context = createActorContext(); @@ -988,7 +992,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { assertFalse(syncStatus.isInitialSyncDone()); // Clear all the messages - followerActor.underlyingActor().clear(); + MessageCollectorActor.clearMessages(followerActor); context.setLastApplied(101); context.setCommitIndex(101); @@ -1008,7 +1012,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testHandleOutOfSequenceInstallSnapshot() throws Exception { + public void testHandleOutOfSequenceInstallSnapshot() { logStart("testHandleOutOfSequenceInstallSnapshot"); MockRaftActorContext context = createActorContext(); @@ -1110,7 +1114,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testCaptureSnapshotOnLastEntryInAppendEntries() throws Exception { + public void testCaptureSnapshotOnLastEntryInAppendEntries() { String id = "testCaptureSnapshotOnLastEntryInAppendEntries"; logStart(id); @@ -1165,7 +1169,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testCaptureSnapshotOnMiddleEntryInAppendEntries() throws Exception { + public void testCaptureSnapshotOnMiddleEntryInAppendEntries() { String id = "testCaptureSnapshotOnMiddleEntryInAppendEntries"; logStart(id); @@ -1224,7 +1228,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { // Reinstate the actor from persistence - actorFactory.killActor(followerActorRef, new JavaTestKit(getSystem())); + actorFactory.killActor(followerActorRef, new TestKit(getSystem())); followerActorRef = actorFactory.createTestActor(builder.props() .withDispatcher(Dispatchers.DefaultDispatcherId()), id); @@ -1240,7 +1244,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Test - public void testCaptureSnapshotOnAppendEntriesWithUnapplied() throws Exception { + public void testCaptureSnapshotOnAppendEntriesWithUnapplied() { String id = "testCaptureSnapshotOnAppendEntriesWithUnapplied"; logStart(id); @@ -1298,31 +1302,35 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @SuppressWarnings("checkstyle:IllegalCatch") - private RaftActorSnapshotCohort newRaftActorSnapshotCohort(final AtomicReference followerRaftActor) { + private static RaftActorSnapshotCohort newRaftActorSnapshotCohort( + final AtomicReference followerRaftActor) { RaftActorSnapshotCohort snapshotCohort = new RaftActorSnapshotCohort() { @Override - public void createSnapshot(ActorRef actorRef, java.util.Optional installSnapshotStream) { + public void createSnapshot(final ActorRef actorRef, + final java.util.Optional installSnapshotStream) { try { actorRef.tell(new CaptureSnapshotReply(new MockSnapshotState(followerRaftActor.get().getState()), installSnapshotStream), actorRef); + } catch (RuntimeException e) { + throw e; } catch (Exception e) { - Throwables.propagate(e); + throw new RuntimeException(e); } } @Override - public void applySnapshot(State snapshotState) { + public void applySnapshot(final State snapshotState) { } @Override - public State deserializeSnapshot(ByteSource snapshotBytes) { + public State deserializeSnapshot(final ByteSource snapshotBytes) { throw new UnsupportedOperationException(); } }; return snapshotCohort; } - public byte[] getNextChunk(ByteString bs, int offset, int chunkSize) { + public byte[] getNextChunk(final ByteString bs, final int offset, final int chunkSize) { int snapshotLength = bs.size(); int start = offset; int size = chunkSize; @@ -1339,14 +1347,14 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { return nextChunk; } - private void expectAndVerifyAppendEntriesReply(int expTerm, boolean expSuccess, - String expFollowerId, long expLogLastTerm, long expLogLastIndex) { + private void expectAndVerifyAppendEntriesReply(final int expTerm, final boolean expSuccess, + final String expFollowerId, final long expLogLastTerm, final long expLogLastIndex) { expectAndVerifyAppendEntriesReply(expTerm, expSuccess, expFollowerId, expLogLastTerm, expLogLastIndex, false); } - private void expectAndVerifyAppendEntriesReply(int expTerm, boolean expSuccess, - String expFollowerId, long expLogLastTerm, long expLogLastIndex, - boolean expForceInstallSnapshot) { + private void expectAndVerifyAppendEntriesReply(final int expTerm, final boolean expSuccess, + final String expFollowerId, final long expLogLastTerm, final long expLogLastIndex, + final boolean expForceInstallSnapshot) { AppendEntriesReply reply = MessageCollectorActor.expectFirstMatching(leaderActor, AppendEntriesReply.class); @@ -1361,7 +1369,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } - private static ReplicatedLogEntry newReplicatedLogEntry(long term, long index, String data) { + private static ReplicatedLogEntry newReplicatedLogEntry(final long term, final long index, final String data) { return new SimpleReplicatedLogEntry(index, term, new MockRaftActorContext.MockPayload(data)); } @@ -1376,8 +1384,8 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Override - protected void assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(MockRaftActorContext actorContext, - ActorRef actorRef, RaftRPC rpc) throws Exception { + protected void assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(final MockRaftActorContext actorContext, + final ActorRef actorRef, final RaftRPC rpc) { super.assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(actorContext, actorRef, rpc); String expVotedFor = rpc instanceof RequestVote ? ((RequestVote)rpc).getCandidateId() : null; @@ -1385,8 +1393,7 @@ public class FollowerTest extends AbstractRaftActorBehaviorTest { } @Override - protected void handleAppendEntriesAddSameEntryToLogReply(final TestActorRef replyActor) - throws Exception { + protected void handleAppendEntriesAddSameEntryToLogReply(final ActorRef replyActor) { AppendEntriesReply reply = MessageCollectorActor.expectFirstMatching(replyActor, AppendEntriesReply.class); assertEquals("isSuccess", true, reply.isSuccess()); }