Search in sources :

Example 6 with RequestVote

use of org.opendaylight.controller.cluster.raft.messages.RequestVote in project controller by opendaylight.

the class RaftActorServerConfigurationSupportTest method testChangeToVotingWithNoLeaderAndElectionTimeout.

@Test
public void testChangeToVotingWithNoLeaderAndElectionTimeout() {
    LOG.info("testChangeToVotingWithNoLeaderAndElectionTimeout starting");
    final String node1ID = "node1";
    final String node2ID = "node2";
    final PeerAddressResolver peerAddressResolver = peerId -> peerId.equals(node1ID) ? actorFactory.createTestActorPath(node1ID) : peerId.equals(node2ID) ? actorFactory.createTestActorPath(node2ID) : null;
    ServerConfigurationPayload persistedServerConfig = new ServerConfigurationPayload(Arrays.asList(new ServerInfo(node1ID, false), new ServerInfo(node2ID, true)));
    SimpleReplicatedLogEntry persistedServerConfigEntry = new SimpleReplicatedLogEntry(0, 1, persistedServerConfig);
    InMemoryJournal.addEntry(node1ID, 1, new UpdateElectionTerm(1, "node1"));
    InMemoryJournal.addEntry(node1ID, 2, persistedServerConfigEntry);
    InMemoryJournal.addEntry(node2ID, 1, new UpdateElectionTerm(1, "node1"));
    InMemoryJournal.addEntry(node2ID, 2, persistedServerConfigEntry);
    DefaultConfigParamsImpl configParams1 = new DefaultConfigParamsImpl();
    configParams1.setHeartBeatInterval(new FiniteDuration(100, TimeUnit.MILLISECONDS));
    configParams1.setElectionTimeoutFactor(1);
    configParams1.setPeerAddressResolver(peerAddressResolver);
    ActorRef node1Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
    TestActorRef<CollectingMockRaftActor> node1RaftActorRef = actorFactory.createTestActor(CollectingMockRaftActor.props(node1ID, ImmutableMap.<String, String>of(), configParams1, PERSISTENT, node1Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), node1ID);
    final CollectingMockRaftActor node1RaftActor = node1RaftActorRef.underlyingActor();
    DefaultConfigParamsImpl configParams2 = new DefaultConfigParamsImpl();
    configParams2.setElectionTimeoutFactor(1000000);
    configParams2.setPeerAddressResolver(peerAddressResolver);
    ActorRef node2Collector = actorFactory.createActor(MessageCollectorActor.props(), actorFactory.generateActorId("collector"));
    TestActorRef<CollectingMockRaftActor> node2RaftActorRef = actorFactory.createTestActor(CollectingMockRaftActor.props(node2ID, ImmutableMap.<String, String>of(), configParams2, PERSISTENT, node2Collector).withDispatcher(Dispatchers.DefaultDispatcherId()), node2ID);
    CollectingMockRaftActor node2RaftActor = node2RaftActorRef.underlyingActor();
    // Send a ChangeServersVotingStatus message to node1 to change mode1 to voting. This should cause
    // node1 to try to elect itself as leader in order to apply the new server config. But we'll drop
    // RequestVote messages in node2 which should cause node1 to time out and revert back to the previous
    // server config and fail with NO_LEADER. Note that node1 shouldn't forward the request to node2 b/c
    // node2 was previously voting.
    node2RaftActor.setDropMessageOfType(RequestVote.class);
    ChangeServersVotingStatus changeServers = new ChangeServersVotingStatus(ImmutableMap.of(node1ID, true));
    node1RaftActorRef.tell(changeServers, testKit.getRef());
    ServerChangeReply reply = testKit.expectMsgClass(testKit.duration("5 seconds"), ServerChangeReply.class);
    assertEquals("getStatus", ServerChangeStatus.NO_LEADER, reply.getStatus());
    assertEquals("Server config", Sets.newHashSet(nonVotingServer(node1ID), votingServer(node2ID)), Sets.newHashSet(node1RaftActor.getRaftActorContext().getPeerServerInfo(true).getServerConfig()));
    assertEquals("getRaftState", RaftState.Follower, node1RaftActor.getRaftState());
    LOG.info("testChangeToVotingWithNoLeaderAndElectionTimeout ending");
}
Also used : UnInitializedFollowerSnapshotReply(org.opendaylight.controller.cluster.raft.messages.UnInitializedFollowerSnapshotReply) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) Arrays(java.util.Arrays) AddServerReply(org.opendaylight.controller.cluster.raft.messages.AddServerReply) ForwardMessageToBehaviorActor(org.opendaylight.controller.cluster.raft.utils.ForwardMessageToBehaviorActor) LoggerFactory(org.slf4j.LoggerFactory) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) ApplySnapshot(org.opendaylight.controller.cluster.raft.base.messages.ApplySnapshot) ActorRef(akka.actor.ActorRef) Optional(com.google.common.base.Optional) RemoveServer(org.opendaylight.controller.cluster.raft.messages.RemoveServer) RemoveServerReply(org.opendaylight.controller.cluster.raft.messages.RemoveServerReply) Map(java.util.Map) After(org.junit.After) Assert.fail(org.junit.Assert.fail) UntypedActor(akka.actor.UntypedActor) ApplyJournalEntries(org.opendaylight.controller.cluster.raft.persisted.ApplyJournalEntries) RaftActorBehavior(org.opendaylight.controller.cluster.raft.behaviors.RaftActorBehavior) Dispatchers(akka.dispatch.Dispatchers) AppendEntries(org.opendaylight.controller.cluster.raft.messages.AppendEntries) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) ImmutableMap(com.google.common.collect.ImmutableMap) AddServer(org.opendaylight.controller.cluster.raft.messages.AddServer) FiniteDuration(scala.concurrent.duration.FiniteDuration) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote) MessageCollectorActor.clearMessages(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.clearMessages) Sets(com.google.common.collect.Sets) List(java.util.List) AbstractLeader(org.opendaylight.controller.cluster.raft.behaviors.AbstractLeader) MessageCollectorActor(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor) MessageCollectorActor.expectMatching(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.expectMatching) Props(akka.actor.Props) CaptureSnapshotReply(org.opendaylight.controller.cluster.raft.base.messages.CaptureSnapshotReply) InstallSnapshot(org.opendaylight.controller.cluster.raft.messages.InstallSnapshot) Follower(org.opendaylight.controller.cluster.raft.behaviors.Follower) Stopwatch(com.google.common.base.Stopwatch) ApplyState(org.opendaylight.controller.cluster.raft.base.messages.ApplyState) ServerChangeStatus(org.opendaylight.controller.cluster.raft.messages.ServerChangeStatus) InMemoryJournal(org.opendaylight.controller.cluster.raft.utils.InMemoryJournal) SerializationUtils(org.apache.commons.lang3.SerializationUtils) InMemorySnapshotStore(org.opendaylight.controller.cluster.raft.utils.InMemorySnapshotStore) TimeoutNow(org.opendaylight.controller.cluster.raft.base.messages.TimeoutNow) ArrayList(java.util.ArrayList) InitiateCaptureSnapshot(org.opendaylight.controller.cluster.raft.base.messages.InitiateCaptureSnapshot) MessageCollectorActor.assertNoneMatching(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.assertNoneMatching) ChangeServersVotingStatus(org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus) ByteSource(com.google.common.io.ByteSource) Before(org.junit.Before) DisableElectionsRaftPolicy(org.opendaylight.controller.cluster.raft.policy.DisableElectionsRaftPolicy) OutputStream(java.io.OutputStream) MessageCollectorActor.expectFirstMatching(org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor.expectFirstMatching) Logger(org.slf4j.Logger) Assert.assertTrue(org.junit.Assert.assertTrue) ServerChangeReply(org.opendaylight.controller.cluster.raft.messages.ServerChangeReply) Test(org.junit.Test) TestKit(akka.testkit.javadsl.TestKit) TestActorRef(akka.testkit.TestActorRef) Maps(com.google.common.collect.Maps) TimeUnit(java.util.concurrent.TimeUnit) NonPersistentDataProvider(org.opendaylight.controller.cluster.NonPersistentDataProvider) ServerRemoved(org.opendaylight.controller.cluster.raft.messages.ServerRemoved) ByteState(org.opendaylight.controller.cluster.raft.persisted.ByteState) Leader(org.opendaylight.controller.cluster.raft.behaviors.Leader) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm) Collections(java.util.Collections) Assert.assertEquals(org.junit.Assert.assertEquals) ServerInfo(org.opendaylight.controller.cluster.raft.persisted.ServerInfo) ActorRef(akka.actor.ActorRef) TestActorRef(akka.testkit.TestActorRef) FiniteDuration(scala.concurrent.duration.FiniteDuration) ServerConfigurationPayload(org.opendaylight.controller.cluster.raft.persisted.ServerConfigurationPayload) SimpleReplicatedLogEntry(org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry) ChangeServersVotingStatus(org.opendaylight.controller.cluster.raft.messages.ChangeServersVotingStatus) ServerChangeReply(org.opendaylight.controller.cluster.raft.messages.ServerChangeReply) UpdateElectionTerm(org.opendaylight.controller.cluster.raft.persisted.UpdateElectionTerm) Test(org.junit.Test)

Example 7 with RequestVote

use of org.opendaylight.controller.cluster.raft.messages.RequestVote in project controller by opendaylight.

the class AbstractRaftActorBehaviorTest method testHandleRequestVoteWhenSenderTermLessThanCurrentTerm.

/**
 * This test verifies that the receiving RaftActor will not grant a vote
 * to a sender if the sender's term is lesser than the currentTerm of the
 * recipient RaftActor.
 */
@Test
public void testHandleRequestVoteWhenSenderTermLessThanCurrentTerm() {
    MockRaftActorContext context = createActorContext();
    context.getTermInformation().update(1000, null);
    behavior = createBehavior(context);
    behavior.handleMessage(behaviorActor, new RequestVote(999, "test", 10000, 999));
    RequestVoteReply reply = MessageCollectorActor.expectFirstMatching(behaviorActor, RequestVoteReply.class);
    assertEquals("isVoteGranted", false, reply.isVoteGranted());
}
Also used : MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote) AbstractActorTest(org.opendaylight.controller.cluster.raft.AbstractActorTest) Test(org.junit.Test)

Example 8 with RequestVote

use of org.opendaylight.controller.cluster.raft.messages.RequestVote in project controller by opendaylight.

the class AbstractRaftActorBehaviorTest method testHandleRequestVoteWhenSenderLogLessUptoDate.

/**
 * This test verifies that when a RaftActor receives a RequestVote message
 * with a term that is greater than it's currentTerm but a less up-to-date
 * log then the receiving RaftActor will not grant the vote to the sender.
 */
@Test
public void testHandleRequestVoteWhenSenderLogLessUptoDate() {
    MockRaftActorContext context = createActorContext();
    behavior = createBehavior(context);
    context.getTermInformation().update(1, "test");
    int index = 2000;
    setLastLogEntry(context, context.getTermInformation().getCurrentTerm(), index, new MockRaftActorContext.MockPayload(""));
    behavior.handleMessage(behaviorActor, new RequestVote(context.getTermInformation().getCurrentTerm(), "test", index - 1, context.getTermInformation().getCurrentTerm()));
    RequestVoteReply reply = MessageCollectorActor.expectFirstMatching(behaviorActor, RequestVoteReply.class);
    assertEquals("isVoteGranted", false, reply.isVoteGranted());
}
Also used : MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote) AbstractActorTest(org.opendaylight.controller.cluster.raft.AbstractActorTest) Test(org.junit.Test)

Example 9 with RequestVote

use of org.opendaylight.controller.cluster.raft.messages.RequestVote in project controller by opendaylight.

the class CandidateTest method testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForDoesNotMatch.

@Test
public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForDoesNotMatch() {
    MockRaftActorContext context = createActorContext();
    context.getTermInformation().update(1000, null);
    // Once a candidate is created it will immediately increment the current term so after
    // construction the currentTerm should be 1001
    candidate = new Candidate(context);
    setupPeers(1);
    // RequestVote candidate ID ("candidate2") does not match this candidate's votedFor
    // (it votes for itself)
    candidate.handleMessage(peerActors[0], new RequestVote(1001, "candidate2", 10000, 999));
    RequestVoteReply reply = MessageCollectorActor.expectFirstMatching(peerActors[0], RequestVoteReply.class);
    assertEquals("isVoteGranted", false, reply.isVoteGranted());
    assertEquals("getTerm", 1001, reply.getTerm());
}
Also used : MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote) Test(org.junit.Test)

Example 10 with RequestVote

use of org.opendaylight.controller.cluster.raft.messages.RequestVote in project controller by opendaylight.

the class FollowerTest method testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNull.

@Test
public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNull() {
    logStart("testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNull");
    MockRaftActorContext context = createActorContext();
    long term = 1000;
    context.getTermInformation().update(term, null);
    follower = createBehavior(context);
    follower.handleMessage(leaderActor, new RequestVote(term, "test", 10000, 999));
    RequestVoteReply reply = MessageCollectorActor.expectFirstMatching(leaderActor, RequestVoteReply.class);
    assertEquals("isVoteGranted", true, reply.isVoteGranted());
    assertEquals("getTerm", term, reply.getTerm());
    verify(follower).scheduleElection(any(FiniteDuration.class));
}
Also used : MockRaftActorContext(org.opendaylight.controller.cluster.raft.MockRaftActorContext) FiniteDuration(scala.concurrent.duration.FiniteDuration) RequestVoteReply(org.opendaylight.controller.cluster.raft.messages.RequestVoteReply) RequestVote(org.opendaylight.controller.cluster.raft.messages.RequestVote) Test(org.junit.Test)

Aggregations

RequestVote (org.opendaylight.controller.cluster.raft.messages.RequestVote)17 Test (org.junit.Test)11 RequestVoteReply (org.opendaylight.controller.cluster.raft.messages.RequestVoteReply)10 MockRaftActorContext (org.opendaylight.controller.cluster.raft.MockRaftActorContext)8 AbstractActorTest (org.opendaylight.controller.cluster.raft.AbstractActorTest)3 InstallSnapshot (org.opendaylight.controller.cluster.raft.messages.InstallSnapshot)3 RaftRPC (org.opendaylight.controller.cluster.raft.messages.RaftRPC)3 FiniteDuration (scala.concurrent.duration.FiniteDuration)3 ActorRef (akka.actor.ActorRef)2 TestActorRef (akka.testkit.TestActorRef)2 ElectionTimeout (org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout)2 TimeoutNow (org.opendaylight.controller.cluster.raft.base.messages.TimeoutNow)2 AppendEntries (org.opendaylight.controller.cluster.raft.messages.AppendEntries)2 ActorSelection (akka.actor.ActorSelection)1 Props (akka.actor.Props)1 UntypedActor (akka.actor.UntypedActor)1 Dispatchers (akka.dispatch.Dispatchers)1 TestKit (akka.testkit.javadsl.TestKit)1 Optional (com.google.common.base.Optional)1 Stopwatch (com.google.common.base.Stopwatch)1