Skip to content

Commit cf5ec0d

Browse files
author
Taichi Yamakawa
committed
Test candidate's state after receiving RequestVoteResponse
1 parent c4233cc commit cf5ec0d

File tree

1 file changed

+30
-6
lines changed

1 file changed

+30
-6
lines changed

src/test/scala/lerna/akka/entityreplication/raft/RaftActorCandidateSpec.scala

Lines changed: 30 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,9 @@ import lerna.akka.entityreplication.raft.RaftProtocol.{ Command, ForwardedComman
88
import lerna.akka.entityreplication.raft.model._
99
import lerna.akka.entityreplication.raft.protocol.RaftCommands._
1010
import lerna.akka.entityreplication.raft.routing.MemberIndex
11+
import org.scalatest.Inside
1112

12-
class RaftActorCandidateSpec extends TestKit(ActorSystem()) with RaftActorSpecBase {
13+
class RaftActorCandidateSpec extends TestKit(ActorSystem()) with RaftActorSpecBase with Inside {
1314

1415
import RaftActor._
1516

@@ -164,17 +165,40 @@ class RaftActorCandidateSpec extends TestKit(ActorSystem()) with RaftActorSpecBa
164165
}
165166

166167
"メンバーの過半数に Accept されると Leader になる" in {
168+
val selfMemberIndex = createUniqueMemberIndex()
167169
val follower1MemberIndex = createUniqueMemberIndex()
168170
val follower2MemberIndex = createUniqueMemberIndex()
169171
val candidate = createRaftActor(
172+
selfMemberIndex = selfMemberIndex,
170173
otherMemberIndexes = Set(follower1MemberIndex, follower2MemberIndex),
171174
)
172-
val term = Term.initial()
173-
setState(candidate, Candidate, createCandidateData(term))
175+
val currentTerm = Term(1)
176+
setState(candidate, Candidate, createCandidateData(currentTerm))
177+
inside(getState(candidate)) { state =>
178+
state.stateData.acceptedMembers should be(Set.empty)
179+
}
174180

175-
candidate ! RequestVoteAccepted(term, follower1MemberIndex)
176-
candidate ! RequestVoteAccepted(term, follower2MemberIndex)
177-
getState(candidate).stateName should be(Leader)
181+
// The candidate will vote for itself.
182+
candidate ! RequestVoteAccepted(currentTerm, selfMemberIndex)
183+
inside(getState(candidate)) { state =>
184+
state.stateName should be(Candidate)
185+
state.stateData.currentTerm should be(currentTerm)
186+
state.stateData.acceptedMembers should be(Set(selfMemberIndex))
187+
}
188+
189+
// Denied from follower1, this situation could happen by a split vote.
190+
candidate ! RequestVoteDenied(currentTerm)
191+
inside(getState(candidate)) { state =>
192+
state.stateName should be(Candidate)
193+
state.stateData.currentTerm should be(currentTerm)
194+
state.stateData.acceptedMembers should be(Set(selfMemberIndex))
195+
}
196+
197+
candidate ! RequestVoteAccepted(currentTerm, follower2MemberIndex)
198+
inside(getState(candidate)) { state =>
199+
state.stateName should be(Leader)
200+
state.stateData.currentTerm should be(currentTerm)
201+
}
178202
}
179203

180204
"become a Follower and agree to a Term if it receives RequestVoteDenied with newer Term" in {

0 commit comments

Comments
 (0)