mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00
Merge pull request #8346 from javaforfun/shawnsli/reset-votes-when-become-pre-candidate
raft: reset votes when becomePreCandidate
This commit is contained in:
commit
033c0cbdd8
@ -611,6 +611,7 @@ func (r *raft) becomePreCandidate() {
|
||||
// but doesn't change anything else. In particular it does not increase
|
||||
// r.Term or change r.Vote.
|
||||
r.step = stepCandidate
|
||||
r.votes = make(map[uint64]bool)
|
||||
r.tick = r.tickElection
|
||||
r.state = StatePreCandidate
|
||||
r.logger.Infof("%x became pre-candidate at term %d", r.id, r.Term)
|
||||
|
@ -3209,6 +3209,83 @@ func TestNodeWithSmallerTermCanCompleteElection(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
// TestPreVoteWithSplitVote verifies that after split vote, cluster can complete
|
||||
// election in next round.
|
||||
func TestPreVoteWithSplitVote(t *testing.T) {
|
||||
n1 := newTestRaft(1, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
||||
n2 := newTestRaft(2, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
||||
n3 := newTestRaft(3, []uint64{1, 2, 3}, 10, 1, NewMemoryStorage())
|
||||
|
||||
n1.becomeFollower(1, None)
|
||||
n2.becomeFollower(1, None)
|
||||
n3.becomeFollower(1, None)
|
||||
|
||||
n1.preVote = true
|
||||
n2.preVote = true
|
||||
n3.preVote = true
|
||||
|
||||
nt := newNetwork(n1, n2, n3)
|
||||
nt.send(pb.Message{From: 1, To: 1, Type: pb.MsgHup})
|
||||
|
||||
// simulate leader down. followers start split vote.
|
||||
nt.isolate(1)
|
||||
nt.send([]pb.Message{
|
||||
{From: 2, To: 2, Type: pb.MsgHup},
|
||||
{From: 3, To: 3, Type: pb.MsgHup},
|
||||
}...)
|
||||
|
||||
// check whether the term values are expected
|
||||
// n2.Term == 3
|
||||
// n3.Term == 3
|
||||
sm := nt.peers[2].(*raft)
|
||||
if sm.Term != 3 {
|
||||
t.Errorf("peer 2 term: %d, want %d", sm.Term, 3)
|
||||
}
|
||||
sm = nt.peers[3].(*raft)
|
||||
if sm.Term != 3 {
|
||||
t.Errorf("peer 3 term: %d, want %d", sm.Term, 3)
|
||||
}
|
||||
|
||||
// check state
|
||||
// n2 == candidate
|
||||
// n3 == candidate
|
||||
sm = nt.peers[2].(*raft)
|
||||
if sm.state != StateCandidate {
|
||||
t.Errorf("peer 2 state: %s, want %s", sm.state, StateCandidate)
|
||||
}
|
||||
sm = nt.peers[3].(*raft)
|
||||
if sm.state != StateCandidate {
|
||||
t.Errorf("peer 3 state: %s, want %s", sm.state, StateCandidate)
|
||||
}
|
||||
|
||||
// node 2 election timeout first
|
||||
nt.send(pb.Message{From: 2, To: 2, Type: pb.MsgHup})
|
||||
|
||||
// check whether the term values are expected
|
||||
// n2.Term == 4
|
||||
// n3.Term == 4
|
||||
sm = nt.peers[2].(*raft)
|
||||
if sm.Term != 4 {
|
||||
t.Errorf("peer 2 term: %d, want %d", sm.Term, 4)
|
||||
}
|
||||
sm = nt.peers[3].(*raft)
|
||||
if sm.Term != 4 {
|
||||
t.Errorf("peer 3 term: %d, want %d", sm.Term, 4)
|
||||
}
|
||||
|
||||
// check state
|
||||
// n2 == leader
|
||||
// n3 == follower
|
||||
sm = nt.peers[2].(*raft)
|
||||
if sm.state != StateLeader {
|
||||
t.Errorf("peer 2 state: %s, want %s", sm.state, StateLeader)
|
||||
}
|
||||
sm = nt.peers[3].(*raft)
|
||||
if sm.state != StateFollower {
|
||||
t.Errorf("peer 3 state: %s, want %s", sm.state, StateFollower)
|
||||
}
|
||||
}
|
||||
|
||||
func entsWithConfig(configFunc func(*Config), terms ...uint64) *raft {
|
||||
storage := NewMemoryStorage()
|
||||
for i, term := range terms {
|
||||
|
Loading…
x
Reference in New Issue
Block a user