diff --git a/raft/raft_paper_test.go b/raft/raft_paper_test.go index 7b0cbfba0..0a45a0f89 100644 --- a/raft/raft_paper_test.go +++ b/raft/raft_paper_test.go @@ -36,6 +36,63 @@ import ( pb "github.com/coreos/etcd/raft/raftpb" ) +func TestFollowerUpdateTermFromMessage(t *testing.T) { + testUpdateTermFromMessage(t, StateFollower) +} +func TestCandidateUpdateTermFromMessage(t *testing.T) { + testUpdateTermFromMessage(t, StateCandidate) +} +func TestLeaderUpdateTermFromMessage(t *testing.T) { + testUpdateTermFromMessage(t, StateLeader) +} + +// testUpdateTermFromMessage tests that if one server’s current term is +// smaller than the other’s, then it updates its current term to the larger +// value. If a candidate or leader discovers that its term is out of date, +// it immediately reverts to follower state. +// Reference: section 5.1 +func testUpdateTermFromMessage(t *testing.T, state StateType) { + r := newRaft(1, []uint64{1, 2, 3}, 10, 1) + switch state { + case StateFollower: + r.becomeFollower(1, 2) + case StateCandidate: + r.becomeCandidate() + case StateLeader: + r.becomeCandidate() + r.becomeLeader() + } + + r.Step(pb.Message{Type: pb.MsgApp, Term: 2}) + + if r.Term != 2 { + t.Errorf("term = %d, want %d", r.Term, 2) + } + if r.state != StateFollower { + t.Errorf("state = %v, want %v", r.state, StateFollower) + } +} + +// TestRejectStaleTermMessage tests that if a server receives a request with +// a stale term number, it rejects the request. +// Our implementation ignores the request instead. +// Reference: section 5.1 +func TestRejectStaleTermMessage(t *testing.T) { + called := false + fakeStep := func(r *raft, m pb.Message) { + called = true + } + r := newRaft(1, []uint64{1, 2, 3}, 10, 1) + r.step = fakeStep + r.loadState(pb.HardState{Term: 2}) + + r.Step(pb.Message{Type: pb.MsgApp, Term: r.Term - 1}) + + if called == true { + t.Errorf("stepFunc called = %v, want %v", called, false) + } +} + // TestStartAsFollower tests that when servers start up, they begin as followers. // Reference: section 5.2 func TestStartAsFollower(t *testing.T) {