From 23731bf9ba556867089a9cc8db5e492ca6035fe8 Mon Sep 17 00:00:00 2001 From: shawnli Date: Fri, 28 Dec 2018 19:57:26 +0800 Subject: [PATCH] raft: set lead to none when becomePreCandidate --- raft/raft.go | 1 + raft/raft_test.go | 49 +++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 50 insertions(+) diff --git a/raft/raft.go b/raft/raft.go index 211a3b0e2..e1e6a16d4 100644 --- a/raft/raft.go +++ b/raft/raft.go @@ -736,6 +736,7 @@ func (r *raft) becomePreCandidate() { r.step = stepCandidate r.votes = make(map[uint64]bool) r.tick = r.tickElection + r.lead = None r.state = StatePreCandidate r.logger.Infof("%x became pre-candidate at term %d", r.id, r.Term) } diff --git a/raft/raft_test.go b/raft/raft_test.go index 227581bf3..12a127dd1 100644 --- a/raft/raft_test.go +++ b/raft/raft_test.go @@ -3981,6 +3981,55 @@ func TestPreVoteWithSplitVote(t *testing.T) { } } +// TestPreVoteWithCheckQuorum ensures that after a node become pre-candidate, +// it will checkQuorum correctly. +func TestPreVoteWithCheckQuorum(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 + + n1.checkQuorum = true + n2.checkQuorum = true + n3.checkQuorum = true + + nt := newNetwork(n1, n2, n3) + nt.send(pb.Message{From: 1, To: 1, Type: pb.MsgHup}) + + // isolate node 1. node 2 and node 3 have leader info + nt.isolate(1) + + // check state + sm := nt.peers[1].(*raft) + if sm.state != StateLeader { + t.Fatalf("peer 1 state: %s, want %s", sm.state, StateLeader) + } + sm = nt.peers[2].(*raft) + if sm.state != StateFollower { + t.Fatalf("peer 2 state: %s, want %s", sm.state, StateFollower) + } + sm = nt.peers[3].(*raft) + if sm.state != StateFollower { + t.Fatalf("peer 3 state: %s, want %s", sm.state, StateFollower) + } + + // node 2 will ignore node 3's PreVote + nt.send(pb.Message{From: 3, To: 3, Type: pb.MsgHup}) + nt.send(pb.Message{From: 2, To: 2, Type: pb.MsgHup}) + + // Do we have a leader? + if n2.state != StateLeader && n3.state != StateFollower { + t.Errorf("no leader") + } +} + // simulate rolling update a cluster for Pre-Vote. cluster has 3 nodes [n1, n2, n3]. // n1 is leader with term 2 // n2 is follower with term 2