X-Git-Url: https://git.opendaylight.org/gerrit/gitweb?p=controller.git;a=blobdiff_plain;f=opendaylight%2Fmd-sal%2Fsal-akka-raft%2Fsrc%2Ftest%2Fjava%2Forg%2Fopendaylight%2Fcontroller%2Fcluster%2Fraft%2Fbehaviors%2FCandidateTest.java;h=88a261328ade2700077121ecfb765edfb311f2fd;hp=c76368370506af15ab4b7b567672514514e41690;hb=fe8352361d49c76a0ecc80162a2b8258d35198b5;hpb=5ffd4b46ca00fc8f3d801050670c890117dc0811 diff --git a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java index c763683705..88a261328a 100644 --- a/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java +++ b/opendaylight/md-sal/sal-akka-raft/src/test/java/org/opendaylight/controller/cluster/raft/behaviors/CandidateTest.java @@ -1,299 +1,378 @@ +/* + * Copyright (c) 2014, 2015 Cisco 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.behaviors; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + import akka.actor.ActorRef; import akka.actor.Props; -import akka.testkit.JavaTestKit; -import junit.framework.Assert; +import akka.testkit.TestActorRef; +import com.google.common.base.Stopwatch; +import java.util.ArrayList; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.concurrent.TimeUnit; +import org.junit.After; import org.junit.Before; import org.junit.Test; +import org.mockito.Mockito; +import org.opendaylight.controller.cluster.NonPersistentDataProvider; +import org.opendaylight.controller.cluster.raft.DefaultConfigParamsImpl; +import org.opendaylight.controller.cluster.raft.ElectionTerm; import org.opendaylight.controller.cluster.raft.MockRaftActorContext; import org.opendaylight.controller.cluster.raft.RaftActorContext; +import org.opendaylight.controller.cluster.raft.RaftActorContextImpl; import org.opendaylight.controller.cluster.raft.RaftState; +import org.opendaylight.controller.cluster.raft.ReplicatedLogEntry; +import org.opendaylight.controller.cluster.raft.VotingState; import org.opendaylight.controller.cluster.raft.base.messages.ElectionTimeout; import org.opendaylight.controller.cluster.raft.messages.AppendEntries; import org.opendaylight.controller.cluster.raft.messages.AppendEntriesReply; +import org.opendaylight.controller.cluster.raft.messages.RaftRPC; import org.opendaylight.controller.cluster.raft.messages.RequestVote; import org.opendaylight.controller.cluster.raft.messages.RequestVoteReply; -import org.opendaylight.controller.cluster.raft.utils.DoNothingActor; - -import java.util.Collections; -import java.util.HashMap; -import java.util.Map; - -import static org.junit.Assert.assertEquals; +import org.opendaylight.controller.cluster.raft.persisted.SimpleReplicatedLogEntry; +import org.opendaylight.controller.cluster.raft.utils.MessageCollectorActor; +import org.slf4j.Logger; +import org.slf4j.LoggerFactory; -public class CandidateTest extends AbstractRaftActorBehaviorTest { +public class CandidateTest extends AbstractRaftActorBehaviorTest { + static final Logger LOG = LoggerFactory.getLogger(CandidateTest.class); - private final ActorRef candidateActor = getSystem().actorOf(Props.create( - DoNothingActor.class)); + private final TestActorRef candidateActor = actorFactory.createTestActor( + Props.create(MessageCollectorActor.class), actorFactory.generateActorId("candidate")); - private final ActorRef peerActor1 = getSystem().actorOf(Props.create( - DoNothingActor.class)); + private TestActorRef[] peerActors; - private final ActorRef peerActor2 = getSystem().actorOf(Props.create( - DoNothingActor.class)); + private RaftActorBehavior candidate; - private final ActorRef peerActor3 = getSystem().actorOf(Props.create( - DoNothingActor.class)); + @Before + public void setUp(){ + } - private final ActorRef peerActor4 = getSystem().actorOf(Props.create( - DoNothingActor.class)); + @Override + @After + public void tearDown() throws Exception { + if (candidate != null) { + candidate.close(); + } - private final Map onePeer = new HashMap<>(); - private final Map twoPeers = new HashMap<>(); - private final Map fourPeers = new HashMap<>(); + super.tearDown(); + } - @Before - public void setUp(){ - onePeer.put(peerActor1.path().toString(), - peerActor1.path().toString()); + @Test + public void testWhenACandidateIsCreatedItIncrementsTheCurrentTermAndVotesForItself() { + RaftActorContext raftActorContext = createActorContext(); + long expectedTerm = raftActorContext.getTermInformation().getCurrentTerm(); - twoPeers.put(peerActor1.path().toString(), - peerActor1.path().toString()); - twoPeers.put(peerActor2.path().toString(), - peerActor2.path().toString()); + candidate = new Candidate(raftActorContext); - fourPeers.put(peerActor1.path().toString(), - peerActor1.path().toString()); - fourPeers.put(peerActor2.path().toString(), - peerActor2.path().toString()); - fourPeers.put(peerActor3.path().toString(), - peerActor3.path().toString()); - fourPeers.put(peerActor4.path().toString(), - peerActor3.path().toString()); + assertEquals("getCurrentTerm", expectedTerm + 1, raftActorContext.getTermInformation().getCurrentTerm()); + assertEquals("getVotedFor", raftActorContext.getId(), raftActorContext.getTermInformation().getVotedFor()); + } + @Test + public void testThatAnElectionTimeoutIsTriggered() { + MockRaftActorContext actorContext = createActorContext(); + candidate = new Candidate(actorContext); + MessageCollectorActor.expectFirstMatching(candidateActor, ElectionTimeout.class, + actorContext.getConfigParams().getElectionTimeOutInterval().$times(6).toMillis()); } @Test - public void testWhenACandidateIsCreatedItIncrementsTheCurrentTermAndVotesForItself(){ + public void testHandleElectionTimeoutWhenThereAreZeroPeers() { RaftActorContext raftActorContext = createActorContext(); - long expectedTerm = raftActorContext.getTermInformation().getCurrentTerm(); + candidate = new Candidate(raftActorContext); - new Candidate(raftActorContext); + RaftActorBehavior newBehavior = + candidate.handleMessage(candidateActor, ElectionTimeout.INSTANCE); - assertEquals(expectedTerm+1, raftActorContext.getTermInformation().getCurrentTerm()); - assertEquals(raftActorContext.getId(), raftActorContext.getTermInformation().getVotedFor()); + assertEquals("Behavior", RaftState.Leader, newBehavior.state()); } @Test - public void testThatAnElectionTimeoutIsTriggered(){ - new JavaTestKit(getSystem()) {{ - - new Within(duration("1 seconds")) { - protected void run() { - - Candidate candidate = new Candidate(createActorContext(getTestActor())); - - final Boolean out = new ExpectMsg(duration("1 seconds"), "ElectionTimeout") { - // do not put code outside this method, will run afterwards - protected Boolean match(Object in) { - if (in instanceof ElectionTimeout) { - return true; - } else { - throw noMatch(); - } - } - }.get(); - - assertEquals(true, out); - } - }; - }}; + public void testHandleElectionTimeoutWhenThereAreTwoNodeCluster() { + MockRaftActorContext raftActorContext = createActorContext(); + raftActorContext.setPeerAddresses(setupPeers(1)); + candidate = new Candidate(raftActorContext); + + candidate = candidate.handleMessage(candidateActor, ElectionTimeout.INSTANCE); + + assertEquals("Behavior", RaftState.Candidate, candidate.state()); } @Test - public void testHandleElectionTimeoutWhenThereAreZeroPeers(){ - RaftActorContext raftActorContext = createActorContext(); - Candidate candidate = - new Candidate(raftActorContext); + public void testBecomeLeaderOnReceivingMajorityVotesInThreeNodeCluster() { + MockRaftActorContext raftActorContext = createActorContext(); + raftActorContext.setLastApplied(raftActorContext.getReplicatedLog().lastIndex()); + raftActorContext.setPeerAddresses(setupPeers(2)); + candidate = new Candidate(raftActorContext); - RaftState raftState = - candidate.handleMessage(candidateActor, new ElectionTimeout()); + candidate = candidate.handleMessage(peerActors[0], new RequestVoteReply(1, true)); - Assert.assertEquals(RaftState.Leader, raftState); + assertEquals("Behavior", RaftState.Leader, candidate.state()); } @Test - public void testHandleElectionTimeoutWhenThereAreTwoNodesInCluster(){ - MockRaftActorContext raftActorContext = - (MockRaftActorContext) createActorContext(); - raftActorContext.setPeerAddresses(onePeer); - Candidate candidate = - new Candidate(raftActorContext); + public void testBecomePreLeaderOnReceivingMajorityVotesInThreeNodeCluster() { + MockRaftActorContext raftActorContext = createActorContext(); + raftActorContext.setLastApplied(-1); + raftActorContext.setPeerAddresses(setupPeers(2)); + candidate = new Candidate(raftActorContext); - RaftState raftState = - candidate.handleMessage(candidateActor, new ElectionTimeout()); + candidate = candidate.handleMessage(peerActors[0], new RequestVoteReply(1, true)); - Assert.assertEquals(RaftState.Candidate, raftState); + // LastApplied is -1 and behind the last index. + assertEquals("Behavior", RaftState.PreLeader, candidate.state()); } @Test - public void testBecomeLeaderOnReceivingMajorityVotesInThreeNodesInCluster(){ - MockRaftActorContext raftActorContext = - (MockRaftActorContext) createActorContext(); - raftActorContext.setPeerAddresses(twoPeers); - Candidate candidate = - new Candidate(raftActorContext); + public void testBecomeLeaderOnReceivingMajorityVotesInFiveNodeCluster() { + MockRaftActorContext raftActorContext = createActorContext(); + raftActorContext.getTermInformation().update(2L, "other"); + raftActorContext.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder() + .createEntries(0, 5, 1).build()); + raftActorContext.setCommitIndex(raftActorContext.getReplicatedLog().lastIndex()); + raftActorContext.setLastApplied(raftActorContext.getReplicatedLog().lastIndex()); + raftActorContext.setPeerAddresses(setupPeers(4)); + candidate = new Candidate(raftActorContext); - RaftState stateOnFirstVote = candidate.handleMessage(peerActor1, new RequestVoteReply(0, true)); + RequestVote requestVote = MessageCollectorActor.expectFirstMatching(peerActors[0], RequestVote.class); + assertEquals("getTerm", 3L, requestVote.getTerm()); + assertEquals("getCandidateId", raftActorContext.getId(), requestVote.getCandidateId()); + assertEquals("getLastLogTerm", 1L, requestVote.getLastLogTerm()); + assertEquals("getLastLogIndex", 4L, requestVote.getLastLogIndex()); - Assert.assertEquals(RaftState.Leader, stateOnFirstVote); + MessageCollectorActor.expectFirstMatching(peerActors[1], RequestVote.class); + MessageCollectorActor.expectFirstMatching(peerActors[2], RequestVote.class); + MessageCollectorActor.expectFirstMatching(peerActors[3], RequestVote.class); + // First peers denies the vote. + candidate = candidate.handleMessage(peerActors[0], new RequestVoteReply(1, false)); + + assertEquals("Behavior", RaftState.Candidate, candidate.state()); + + candidate = candidate.handleMessage(peerActors[1], new RequestVoteReply(1, true)); + + assertEquals("Behavior", RaftState.Candidate, candidate.state()); + + candidate = candidate.handleMessage(peerActors[2], new RequestVoteReply(1, true)); + + assertEquals("Behavior", RaftState.Leader, candidate.state()); } @Test - public void testBecomeLeaderOnReceivingMajorityVotesInFiveNodesInCluster(){ - MockRaftActorContext raftActorContext = - (MockRaftActorContext) createActorContext(); - raftActorContext.setPeerAddresses(fourPeers); - Candidate candidate = - new Candidate(raftActorContext); + public void testBecomeLeaderOnReceivingMajorityVotesWithNonVotingPeers() { + ElectionTerm mockElectionTerm = Mockito.mock(ElectionTerm.class); + Mockito.doReturn(1L).when(mockElectionTerm).getCurrentTerm(); + RaftActorContext raftActorContext = new RaftActorContextImpl(candidateActor, candidateActor.actorContext(), + "candidate", mockElectionTerm, -1, -1, setupPeers(4), new DefaultConfigParamsImpl(), + new NonPersistentDataProvider(), LOG); + raftActorContext.setReplicatedLog(new MockRaftActorContext.MockReplicatedLogBuilder().build()); + raftActorContext.getPeerInfo("peer1").setVotingState(VotingState.NON_VOTING); + raftActorContext.getPeerInfo("peer4").setVotingState(VotingState.NON_VOTING); + candidate = new Candidate(raftActorContext); + + MessageCollectorActor.expectFirstMatching(peerActors[1], RequestVote.class); + MessageCollectorActor.expectFirstMatching(peerActors[2], RequestVote.class); + MessageCollectorActor.assertNoneMatching(peerActors[0], RequestVote.class, 300); + MessageCollectorActor.assertNoneMatching(peerActors[3], RequestVote.class, 100); - RaftState stateOnFirstVote = candidate.handleMessage(peerActor1, new RequestVoteReply(0, true)); + candidate = candidate.handleMessage(peerActors[1], new RequestVoteReply(1, false)); - RaftState stateOnSecondVote = candidate.handleMessage(peerActor2, new RequestVoteReply(0, true)); + assertEquals("Behavior", RaftState.Candidate, candidate.state()); - Assert.assertEquals(RaftState.Candidate, stateOnFirstVote); - Assert.assertEquals(RaftState.Leader, stateOnSecondVote); + candidate = candidate.handleMessage(peerActors[2], new RequestVoteReply(1, true)); + assertEquals("Behavior", RaftState.Leader, candidate.state()); } @Test - public void testResponseToAppendEntriesWithLowerTerm(){ - new JavaTestKit(getSystem()) {{ - - new Within(duration("1 seconds")) { - protected void run() { - - Candidate candidate = new Candidate(createActorContext(getTestActor())); - - candidate.handleMessage(getTestActor(), new AppendEntries(0, "test", 0,0,Collections.EMPTY_LIST, 0)); - - final Boolean out = new ExpectMsg(duration("1 seconds"), "AppendEntriesResponse") { - // do not put code outside this method, will run afterwards - protected Boolean match(Object in) { - if (in instanceof AppendEntriesReply) { - AppendEntriesReply reply = (AppendEntriesReply) in; - return reply.isSuccess(); - } else { - throw noMatch(); - } - } - }.get(); - - assertEquals(false, out); - } - }; - }}; + public void testResponseToHandleAppendEntriesWithLowerTerm() { + candidate = new Candidate(createActorContext()); + + setupPeers(1); + RaftActorBehavior newBehavior = candidate.handleMessage(peerActors[0], new AppendEntries(1, "test", 0, 0, + Collections.emptyList(), 0, -1, (short) 0)); + + AppendEntriesReply reply = MessageCollectorActor.expectFirstMatching( + peerActors[0], AppendEntriesReply.class); + assertEquals("isSuccess", false, reply.isSuccess()); + assertEquals("getTerm", 2, reply.getTerm()); + assertTrue("New Behavior : " + newBehavior, newBehavior instanceof Candidate); } @Test - public void testResponseToRequestVoteWithLowerTerm(){ - new JavaTestKit(getSystem()) {{ - - new Within(duration("1 seconds")) { - protected void run() { - - Candidate candidate = new Candidate(createActorContext(getTestActor())); - - candidate.handleMessage(getTestActor(), new RequestVote(0, "test", 0, 0)); - - final Boolean out = new ExpectMsg(duration("1 seconds"), "AppendEntriesResponse") { - // do not put code outside this method, will run afterwards - protected Boolean match(Object in) { - if (in instanceof RequestVoteReply) { - RequestVoteReply reply = (RequestVoteReply) in; - return reply.isVoteGranted(); - } else { - throw noMatch(); - } - } - }.get(); - - assertEquals(false, out); - } - }; - }}; + public void testResponseToHandleAppendEntriesWithHigherTerm() { + candidate = new Candidate(createActorContext()); + + setupPeers(1); + RaftActorBehavior newBehavior = candidate.handleMessage(peerActors[0], new AppendEntries(5, "test", 0, 0, + Collections.emptyList(), 0, -1, (short) 0)); + + assertTrue("New Behavior : " + newBehavior, newBehavior instanceof Follower); } @Test - public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNull(){ - new JavaTestKit(getSystem()) {{ - - new Within(duration("1 seconds")) { - protected void run() { - - RaftActorContext context = createActorContext(getTestActor()); - - 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 - RaftActorBehavior follower = createBehavior(context); - - follower.handleMessage(getTestActor(), new RequestVote(1001, "test", 10000, 999)); - - final Boolean out = new ExpectMsg(duration("1 seconds"), "RequestVoteReply") { - // do not put code outside this method, will run afterwards - protected Boolean match(Object in) { - if (in instanceof RequestVoteReply) { - RequestVoteReply reply = (RequestVoteReply) in; - return reply.isVoteGranted(); - } else { - throw noMatch(); - } - } - }.get(); - - assertEquals(true, out); - } - }; - }}; + public void testResponseToHandleAppendEntriesWithEqualTerm() { + MockRaftActorContext actorContext = createActorContext(); + + candidate = new Candidate(actorContext); + + setupPeers(1); + RaftActorBehavior newBehavior = candidate.handleMessage(peerActors[0], new AppendEntries(2, "test", 0, 0, + Collections.emptyList(), 0, -1, (short) 0)); + + assertTrue("New Behavior : " + newBehavior + " term = " + actorContext.getTermInformation().getCurrentTerm(), + newBehavior instanceof Follower); + } + + + @Test + public void testResponseToRequestVoteWithLowerTerm() { + candidate = new Candidate(createActorContext()); + + setupPeers(1); + candidate.handleMessage(peerActors[0], new RequestVote(1, "test", 0, 0)); + + RequestVoteReply reply = MessageCollectorActor.expectFirstMatching( + peerActors[0], RequestVoteReply.class); + assertEquals("isVoteGranted", false, reply.isVoteGranted()); + assertEquals("getTerm", 2, reply.getTerm()); } @Test - public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForIsNotTheSameAsCandidateId(){ - new JavaTestKit(getSystem()) {{ + public void testHandleRequestVoteWhenSenderTermEqualToCurrentTermAndVotedForMatches() { + 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); + candidate.handleMessage(peerActors[0], new RequestVote(1001, context.getId(), 10000, 999)); + + RequestVoteReply reply = MessageCollectorActor.expectFirstMatching( + peerActors[0], RequestVoteReply.class); + assertEquals("isVoteGranted", true, reply.isVoteGranted()); + assertEquals("getTerm", 1001, reply.getTerm()); + } + + @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); - new Within(duration("1 seconds")) { - protected void run() { + // 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)); - RaftActorContext context = createActorContext(getTestActor()); + RequestVoteReply reply = MessageCollectorActor.expectFirstMatching( + peerActors[0], RequestVoteReply.class); + assertEquals("isVoteGranted", false, reply.isVoteGranted()); + assertEquals("getTerm", 1001, reply.getTerm()); + } + + @Test + public void testCandidateSchedulesElectionTimeoutImmediatelyWhenItHasNoPeers() { + MockRaftActorContext context = createActorContext(); - context.getTermInformation().update(1000, "test"); + Stopwatch stopwatch = Stopwatch.createStarted(); - RaftActorBehavior follower = createBehavior(context); + candidate = createBehavior(context); - follower.handleMessage(getTestActor(), new RequestVote(1001, "candidate", 10000, 999)); + MessageCollectorActor.expectFirstMatching(candidateActor, ElectionTimeout.class); - final Boolean out = new ExpectMsg(duration("1 seconds"), "RequestVoteReply") { - // do not put code outside this method, will run afterwards - protected Boolean match(Object in) { - if (in instanceof RequestVoteReply) { - RequestVoteReply reply = (RequestVoteReply) in; - return reply.isVoteGranted(); - } else { - throw noMatch(); - } - } - }.get(); + long elapsed = stopwatch.elapsed(TimeUnit.MILLISECONDS); - assertEquals(false, out); - } - }; - }}; + assertTrue(elapsed < context.getConfigParams().getElectionTimeOutInterval().toMillis()); } + @Test + @Override + public void testHandleAppendEntriesAddSameEntryToLog() throws Exception { + 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 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); + // Resetting the Candidates term to make sure it will match + // the term sent by AppendEntries. If this was not done then + // the test will fail because the Candidate will assume that + // the message was sent to it from a lower term peer and will + // thus respond with a failure + context.getTermInformation().update(2, "test"); - @Override protected RaftActorBehavior createBehavior(RaftActorContext actorContext) { + // Send an unknown message so that the state of the RaftActor remains unchanged + behavior.handleMessage(candidateActor, "unknown"); + + RaftActorBehavior raftBehavior = behavior.handleMessage(candidateActor, appendEntries); + + assertEquals("Raft state", RaftState.Follower, raftBehavior.state()); + + assertEquals("ReplicatedLog size", 1, context.getReplicatedLog().size()); + + handleAppendEntriesAddSameEntryToLogReply(candidateActor); + } + + @Override + protected Candidate createBehavior(final RaftActorContext actorContext) { return new Candidate(actorContext); } - @Override protected RaftActorContext createActorContext() { - return new MockRaftActorContext("test", getSystem(), candidateActor); + @Override protected MockRaftActorContext createActorContext() { + return new MockRaftActorContext("candidate", getSystem(), candidateActor); } + @SuppressWarnings("unchecked") + private Map setupPeers(final int count) { + Map peerMap = new HashMap<>(); + peerActors = new TestActorRef[count]; + for (int i = 0; i < count; i++) { + peerActors[i] = actorFactory.createTestActor(Props.create(MessageCollectorActor.class), + actorFactory.generateActorId("peer")); + peerMap.put("peer" + (i + 1), peerActors[i].path().toString()); + } + + return peerMap; + } + @Override + protected void assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(final MockRaftActorContext actorContext, + final ActorRef actorRef, final RaftRPC rpc) throws Exception { + super.assertStateChangesToFollowerWhenRaftRPCHasNewerTerm(actorContext, actorRef, rpc); + if (rpc instanceof RequestVote) { + assertEquals("New votedFor", ((RequestVote)rpc).getCandidateId(), + actorContext.getTermInformation().getVotedFor()); + } else { + assertEquals("New votedFor", null, actorContext.getTermInformation().getVotedFor()); + } + } }