Fix issue when AE leader differs from prior install snapshot leader
[controller.git] / opendaylight / md-sal / sal-akka-raft / src / test / java / org / opendaylight / controller / cluster / raft / LeadershipTransferIntegrationTest.java
index 3cc330a96aa101cab3c5b7c54462f3a8369b427d..acffda731f609f295707e3d6cca8b7610ccec574 100644 (file)
@@ -28,6 +28,7 @@ import org.opendaylight.controller.cluster.raft.client.messages.GetOnDemandRaftS
 import org.opendaylight.controller.cluster.raft.client.messages.OnDemandRaftState;
 import org.opendaylight.controller.cluster.raft.client.messages.Shutdown;
 import org.opendaylight.controller.cluster.raft.messages.AppendEntries;
+import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply;
 import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor;
 import scala.concurrent.Await;
 import scala.concurrent.Future;
@@ -40,9 +41,13 @@ import scala.concurrent.duration.FiniteDuration;
  */
 public class LeadershipTransferIntegrationTest extends AbstractRaftActorIntegrationTest {
 
+    private final String follower3Id = factory.generateActorId("follower");
     private TestActorRef<MessageCollectorActor> leaderNotifierActor;
     private TestActorRef<MessageCollectorActor> follower1NotifierActor;
     private TestActorRef<MessageCollectorActor> follower2NotifierActor;
+    private TestActorRef<MessageCollectorActor> follower3NotifierActor;
+    private TestActorRef<TestRaftActor> follower3Actor;
+    private ActorRef follower3CollectorActor;
 
     @Test
     public void testLeaderTransferOnShutDown() throws Throwable {
@@ -63,7 +68,7 @@ public class LeadershipTransferIntegrationTest extends AbstractRaftActorIntegrat
         testLog.info("sendShutDown for {} starting", actor.path());
 
         FiniteDuration duration = FiniteDuration.create(5, TimeUnit.SECONDS);
-        Future<Boolean> stopFuture = Patterns.gracefulStop(actor, duration, new Shutdown());
+        Future<Boolean> stopFuture = Patterns.gracefulStop(actor, duration, Shutdown.INSTANCE);
 
         Boolean stopped = Await.result(stopFuture, duration);
         assertEquals("Stopped", Boolean.TRUE, stopped);
@@ -77,13 +82,15 @@ public class LeadershipTransferIntegrationTest extends AbstractRaftActorIntegrat
         clearMessages(leaderNotifierActor);
         clearMessages(follower1NotifierActor);
         clearMessages(follower2NotifierActor);
+        clearMessages(follower3NotifierActor);
 
         FiniteDuration duration = FiniteDuration.create(5, TimeUnit.SECONDS);
-        Future<Boolean> stopFuture = Patterns.gracefulStop(leaderActor, duration, new Shutdown());
+        Future<Boolean> stopFuture = Patterns.gracefulStop(leaderActor, duration, Shutdown.INSTANCE);
 
         assertNullLeaderIdChange(leaderNotifierActor);
         assertNullLeaderIdChange(follower1NotifierActor);
         assertNullLeaderIdChange(follower2NotifierActor);
+        assertNullLeaderIdChange(follower3NotifierActor);
 
         verifyRaftState(follower1Actor, RaftState.Leader);
 
@@ -106,6 +113,7 @@ public class LeadershipTransferIntegrationTest extends AbstractRaftActorIntegrat
 
         expectFirstMatching(leaderCollectorActor, ApplyState.class);
         expectFirstMatching(follower1CollectorActor, ApplyState.class);
+        expectFirstMatching(follower3CollectorActor, ApplyState.class);
 
         testLog.info("sendPayloadWithFollower2Lagging ending");
     }
@@ -116,18 +124,28 @@ public class LeadershipTransferIntegrationTest extends AbstractRaftActorIntegrat
         follower1NotifierActor = factory.createTestActor(Props.create(MessageCollectorActor.class),
                 factory.generateActorId(follower1Id + "-notifier"));
         follower1Actor = newTestRaftActor(follower1Id, TestRaftActor.newBuilder().peerAddresses(
-                ImmutableMap.of(leaderId, testActorPath(leaderId), follower2Id, testActorPath(follower2Id))).
-                    config(newFollowerConfigParams()).roleChangeNotifier(follower1NotifierActor));
+                ImmutableMap.of(leaderId, testActorPath(leaderId), follower2Id, testActorPath(follower2Id),
+                        follower3Id, testActorPath(follower3Id))).
+                config(newFollowerConfigParams()).roleChangeNotifier(follower1NotifierActor));
 
         follower2NotifierActor = factory.createTestActor(Props.create(MessageCollectorActor.class),
                 factory.generateActorId(follower2Id + "-notifier"));
         follower2Actor = newTestRaftActor(follower2Id,TestRaftActor.newBuilder().peerAddresses(
-                ImmutableMap.of(leaderId, testActorPath(leaderId), follower1Id, follower1Actor.path().toString())).
-                    config(newFollowerConfigParams()).roleChangeNotifier(follower2NotifierActor));
+                ImmutableMap.of(leaderId, testActorPath(leaderId), follower1Id, follower1Actor.path().toString(),
+                        follower3Id, testActorPath(follower3Id))).
+                config(newFollowerConfigParams()).roleChangeNotifier(follower2NotifierActor));
+
+        follower3NotifierActor = factory.createTestActor(Props.create(MessageCollectorActor.class),
+                factory.generateActorId(follower3Id + "-notifier"));
+        follower3Actor = newTestRaftActor(follower3Id,TestRaftActor.newBuilder().peerAddresses(
+                ImmutableMap.of(leaderId, testActorPath(leaderId), follower1Id, follower1Actor.path().toString(),
+                        follower2Id, follower2Actor.path().toString())).
+                config(newFollowerConfigParams()).roleChangeNotifier(follower3NotifierActor));
 
         peerAddresses = ImmutableMap.<String, String>builder().
                 put(follower1Id, follower1Actor.path().toString()).
-                put(follower2Id, follower2Actor.path().toString()).build();
+                put(follower2Id, follower2Actor.path().toString()).
+                put(follower3Id, follower3Actor.path().toString()).build();
 
         leaderConfigParams = newLeaderConfigParams();
         leaderConfigParams.setElectionTimeoutFactor(3);
@@ -138,16 +156,18 @@ public class LeadershipTransferIntegrationTest extends AbstractRaftActorIntegrat
 
         follower1CollectorActor = follower1Actor.underlyingActor().collectorActor();
         follower2CollectorActor = follower2Actor.underlyingActor().collectorActor();
+        follower3CollectorActor = follower3Actor.underlyingActor().collectorActor();
         leaderCollectorActor = leaderActor.underlyingActor().collectorActor();
 
         leaderContext = leaderActor.underlyingActor().getRaftActorContext();
+        leaderContext.getPeerInfo(follower3Id).setVotingState(VotingState.NON_VOTING);
 
         waitUntilLeader(leaderActor);
 
         testLog.info("createRaftActors starting");
     }
 
-    private void verifyRaftState(ActorRef raftActor, final RaftState expState) throws Throwable {
+    private static void verifyRaftState(ActorRef raftActor, final RaftState expState) throws Throwable {
         Timeout timeout = new Timeout(500, TimeUnit.MILLISECONDS);
         Throwable lastError = null;
         Stopwatch sw = Stopwatch.createStarted();
@@ -166,7 +186,7 @@ public class LeadershipTransferIntegrationTest extends AbstractRaftActorIntegrat
         throw lastError;
     }
 
-    private void assertNullLeaderIdChange(TestActorRef<MessageCollectorActor> notifierActor) {
+    private static void assertNullLeaderIdChange(TestActorRef<MessageCollectorActor> notifierActor) {
         LeaderStateChanged change = expectFirstMatching(notifierActor, LeaderStateChanged.class);
         assertNull("Expected null leader Id", change.getLeaderId());
     }
@@ -177,11 +197,14 @@ public class LeadershipTransferIntegrationTest extends AbstractRaftActorIntegrat
 
         createRaftActors();
 
-        follower1Actor.underlyingActor().startDropMessages(AppendEntries.class);
-        follower2Actor.underlyingActor().startDropMessages(AppendEntries.class);
+        leaderActor.underlyingActor().startDropMessages(AppendEntriesReply.class);
 
         sendShutDown(leaderActor);
 
+        verifyRaftState(follower1Actor, RaftState.Follower);
+        verifyRaftState(follower2Actor, RaftState.Follower);
+        verifyRaftState(follower3Actor, RaftState.Follower);
+
         testLog.info("testLeaderTransferOnShutDown ending");
     }