Search in sources :

Example 81 with MockRaftActorContext

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext in project controller by opendaylight.

the class AbstractLeaderElectionScenarioTest method newRaftActorContext.

MockRaftActorContext newRaftActorContext(final String id, final ActorRef actor, final Map<String, String> peerAddresses) {
    MockRaftActorContext context = new MockRaftActorContext(id, system, actor);
    context.setPeerAddresses(peerAddresses);
    context.getTermInformation().updateAndPersist(1, "");
    return context;
}
Also used : MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext)

Example 82 with MockRaftActorContext

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext in project controller by opendaylight.

the class AbstractLeaderTest method testLeaderSchedulesHeartbeatsEvenWhenNoFollowersRespondToInitialAppendEntries.

/**
 * When we removed scheduling of heartbeat in the AbstractLeader constructor we ended up with a situation where
 * if no follower responded to an initial AppendEntries heartbeats would not be sent to it. This test verifies
 * that regardless of whether followers respond or not we schedule heartbeats.
 */
@Test
public void testLeaderSchedulesHeartbeatsEvenWhenNoFollowersRespondToInitialAppendEntries() throws Exception {
    logStart("testLeaderSchedulesHeartbeatsEvenWhenNoFollowersRespondToInitialAppendEntries");
    String leaderActorId = actorFactory.generateActorId("leader");
    String follower1ActorId = actorFactory.generateActorId("follower");
    String follower2ActorId = actorFactory.generateActorId("follower");
    TestActorRef<ForwardMessageToBehaviorActor> leaderActor = actorFactory.createTestActor(ForwardMessageToBehaviorActor.props(), leaderActorId);
    final ActorRef follower1Actor = actorFactory.createActor(MessageCollectorActor.props(), follower1ActorId);
    final ActorRef follower2Actor = actorFactory.createActor(MessageCollectorActor.props(), follower2ActorId);
    MockRaftActorContext leaderActorContext = new MockRaftActorContext(leaderActorId, getSystem(), leaderActor);
    DefaultConfigParamsImpl configParams = new DefaultConfigParamsImpl();
    configParams.setHeartBeatInterval(new FiniteDuration(200, TimeUnit.MILLISECONDS));
    configParams.setIsolatedLeaderCheckInterval(new FiniteDuration(10, TimeUnit.SECONDS));
    leaderActorContext.setConfigParams(configParams);
    leaderActorContext.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(1, 5, 1).build());
    Map<String, String> peerAddresses = new HashMap<>();
    peerAddresses.put(follower1ActorId, follower1Actor.path().toString());
    peerAddresses.put(follower2ActorId, follower2Actor.path().toString());
    leaderActorContext.setPeerAddresses(peerAddresses);
    RaftActorBehavior leader = createBehavior(leaderActorContext);
    leaderActor.underlyingActor().setBehavior(leader);
    Uninterruptibles.sleepUninterruptibly(1, TimeUnit.SECONDS);
    List<SendHeartBeat> allMessages = MessageCollectorActor.getAllMatching(leaderActor, SendHeartBeat.class);
    // Need more than 1 heartbeat to be delivered because we waited for 1 second with heartbeat interval 200ms
    assertTrue(String.format("%s messages is less than expected", allMessages.size()), allMessages.size() > 1);
}
Also used : HashMap(java.util.HashMap) TestActorRef(akka.testkit.TestActorRef) ActorRef(akka.actor.ActorRef) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) FiniteDuration(scala.concurrent.duration.FiniteDuration) DefaultConfigParamsImpl(org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl) SendHeartBeat(org.opendaylight.controller.cluster.raft.base.messages.SendHeartBeat) ForwardMessageToBehaviorActor(org.opendaylight.controller.cluster.raft.utils.ForwardMessageToBehaviorActor) Test(org.junit.Test)

Example 83 with MockRaftActorContext

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext in project controller by opendaylight.

the class AbstractRaftActorBehaviorTest method testHandleAppendEntriesAddSameEntryToLog.

@Test
public void testHandleAppendEntriesAddSameEntryToLog() {
    MockRaftActorContext context = createActorContext();
    context.getTermInformation().update(2, "test");
    // Prepare the receivers log
    MockRaftActorContext.MockPayload payload = new MockRaftActorContext.MockPayload("zero");
    setLastLogEntry(context, 2, 0, payload);
    List<ReplicatedLogEntry> entries = new ArrayList<>();
    entries.add(new SimpleReplicatedLogEntry(0, 2, payload));
    final AppendEntries appendEntries = new AppendEntries(2, "leader-1", -1, -1, entries, 2, -1, (short) 0);
    behavior = createBehavior(context);
    assertFalse("This test should be overridden when testing Candidate", behavior instanceof Candidate);
    RaftState expected = behavior.state();
    // Check that the behavior does not handle unknwon message
    assertNull(behavior.handleMessage(behaviorActor, "unknown"));
    RaftActorBehavior raftBehavior = behavior.handleMessage(behaviorActor, appendEntries);
    assertEquals("Raft state", expected, raftBehavior.state());
    assertEquals("ReplicatedLog size", 1, context.getReplicatedLog().size());
    handleAppendEntriesAddSameEntryToLogReply(behaviorActor);
}
Also used : SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ReplicatedLogEntry(org.opendaylight.controller.cluster.raft.ReplicatedLogEntry) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) RaftState(org.opendaylight.controller.cluster.raft.RaftState) ArrayList(java.util.ArrayList) AppendEntries(org.opendaylight.controller.cluster.raft.messages.AppendEntries) AbstractActorTest(org.opendaylight.controller.cluster.raft.AbstractActorTest) Test(org.junit.Test)

Example 84 with MockRaftActorContext

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext in project controller by opendaylight.

the class AbstractRaftActorBehaviorTest method testPerformSnapshot.

@Test
public void testPerformSnapshot() {
    MockRaftActorContext context = new MockRaftActorContext("test", getSystem(), behaviorActor);
    AbstractRaftActorBehavior abstractBehavior = (AbstractRaftActorBehavior) createBehavior(context);
    if (abstractBehavior instanceof Candidate) {
        return;
    }
    context.getTermInformation().update(1, "test");
    // log has 1 entry with replicatedToAllIndex = 0, does not do anything, returns the
    context.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 1, 1).build());
    context.setLastApplied(0);
    abstractBehavior.performSnapshotWithoutCapture(0);
    assertEquals(-1, abstractBehavior.getReplicatedToAllIndex());
    assertEquals(1, context.getReplicatedLog().size());
    // 2 entries, lastApplied still 0, no purging.
    context.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 2, 1).build());
    context.setLastApplied(0);
    abstractBehavior.performSnapshotWithoutCapture(0);
    assertEquals(-1, abstractBehavior.getReplicatedToAllIndex());
    assertEquals(2, context.getReplicatedLog().size());
    // 2 entries, lastApplied still 0, no purging.
    context.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 2, 1).build());
    context.setLastApplied(1);
    abstractBehavior.performSnapshotWithoutCapture(0);
    assertEquals(0, abstractBehavior.getReplicatedToAllIndex());
    assertEquals(1, context.getReplicatedLog().size());
    // 5 entries, lastApplied =2 and replicatedIndex = 3, but since we want to keep the lastapplied, indices 0 and
    // 1 will only get purged
    context.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 5, 1).build());
    context.setLastApplied(2);
    abstractBehavior.performSnapshotWithoutCapture(3);
    assertEquals(1, abstractBehavior.getReplicatedToAllIndex());
    assertEquals(3, context.getReplicatedLog().size());
    // scenario where Last applied > Replicated to all index (becoz of a slow follower)
    context.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().createEntries(0, 3, 1).build());
    context.setLastApplied(2);
    abstractBehavior.performSnapshotWithoutCapture(1);
    assertEquals(1, abstractBehavior.getReplicatedToAllIndex());
    assertEquals(1, context.getReplicatedLog().size());
}
Also used : MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) AbstractActorTest(org.opendaylight.controller.cluster.raft.AbstractActorTest) Test(org.junit.Test)

Example 85 with MockRaftActorContext

use of org.opendaylight.controller.cluster.raft.MockRaftActorContext in project controller by opendaylight.

the class AbstractRaftActorBehaviorTest method testHandleAppendEntriesSenderTermLessThanReceiverTerm.

/**
 * This test verifies that when an AppendEntries is received with a term that
 * is less that the currentTerm of the RaftActor then the RaftActor does not
 * change it's state and it responds back with a failure.
 */
@Test
public void testHandleAppendEntriesSenderTermLessThanReceiverTerm() {
    MockRaftActorContext context = createActorContext();
    short payloadVersion = 5;
    context.setPayloadVersion(payloadVersion);
    // First set the receivers term to a high number (1000)
    context.getTermInformation().update(1000, "test");
    AppendEntries appendEntries = new AppendEntries(100, "leader-1", 0, 0, Collections.emptyList(), 101, -1, (short) 4);
    behavior = createBehavior(context);
    RaftState expected = behavior.state();
    RaftActorBehavior raftBehavior = behavior.handleMessage(behaviorActor, appendEntries);
    assertEquals("Raft state", expected, raftBehavior.state());
    // Also expect an AppendEntriesReply to be sent where success is false
    AppendEntriesReply reply = MessageCollectorActor.expectFirstMatching(behaviorActor, AppendEntriesReply.class);
    assertEquals("isSuccess", false, reply.isSuccess());
    assertEquals("getPayloadVersion", payloadVersion, reply.getPayloadVersion());
}
Also used : AppendEntriesReply(org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply) MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) RaftState(org.opendaylight.controller.cluster.raft.RaftState) AppendEntries(org.opendaylight.controller.cluster.raft.messages.AppendEntries) AbstractActorTest(org.opendaylight.controller.cluster.raft.AbstractActorTest) Test(org.junit.Test)

Aggregations

MockRaftActorContext (org.opendaylight.controller.cluster.raft.MockRaftActorContext)100 Test (org.junit.Test)93 AppendEntries (org.opendaylight.controller.cluster.raft.messages.AppendEntries)44 AppendEntriesReply (org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply)40 DefaultConfigParamsImpl (org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl)30 FiniteDuration (scala.concurrent.duration.FiniteDuration)29 SimpleReplicatedLogEntry (org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry)28 ReplicatedLogEntry (org.opendaylight.controller.cluster.raft.ReplicatedLogEntry)24 ByteString (com.google.protobuf.ByteString)19 HashMap (java.util.HashMap)16 InstallSnapshot (org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)11 RequestVoteReply (org.opendaylight.controller.cluster.raft.messages.RequestVoteReply)11 FollowerInitialSyncUpStatus (org.opendaylight.controller.cluster.raft.base.messages.FollowerInitialSyncUpStatus)9 RequestVote (org.opendaylight.controller.cluster.raft.messages.RequestVote)8 ArrayList (java.util.ArrayList)7 AbstractActorTest (org.opendaylight.controller.cluster.raft.AbstractActorTest)7 CaptureSnapshot (org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshot)7 FollowerLogInformation (org.opendaylight.controller.cluster.raft.FollowerLogInformation)6 SendInstallSnapshot (org.opendaylight.controller.cluster.raft.base.messages.SendInstallSnapshot)6 InstallSnapshotReply (org.opendaylight.controller.cluster.raft.messages.InstallSnapshotReply)6