Skip to content

Commit

Permalink
tests: Introduce prevote with check quorum test.
Browse files Browse the repository at this point in the history
We discovered some instances where prevote and check quorum interact
poorly. This commit introduces a test showcasing this.

Related to etcd-io/etcd#8334.
  • Loading branch information
Hoverbear committed Jul 3, 2018
1 parent b8d746a commit 4e6377a
Showing 1 changed file with 97 additions and 0 deletions.
97 changes: 97 additions & 0 deletions tests/cases/test_raft.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4132,3 +4132,100 @@ fn test_election_tick_range() {
assert_eq!(randomized_timeout, cfg.election_tick);
}
}
// ensure that after a node become pre-candidate, it will checkQuorum correctly.
#[test]
fn test_prevote_with_check_quorum() {
let bootstrap = |id| {
let mut cfg = new_test_config(id, vec![1, 2, 3], 10, 1);
cfg.pre_vote = true;
cfg.check_quorum = true;
let mut raft = Raft::new(&cfg, new_storage());
raft.become_follower(1, INVALID_ID);
Interface::new(raft)
};
let (peer1, peer2, peer3) = (bootstrap(1), bootstrap(2), bootstrap(3));

let mut network = Network::new(vec![Some(peer1), Some(peer2), Some(peer3)]);
network.send(vec![new_message(1, 1, MessageType::MsgHup, 0)]);

// cause a network partition to isolate node 3. node 3 has leader info
network.cut(1, 3);
network.cut(2, 3);

assert_eq!(
network.peers[&1].state,
StateRole::Leader,
"peer 1 state",
);
assert_eq!(
network.peers[&2].state,
StateRole::Follower,
"peer 2 state",
);

network.send(vec![new_message(3, 3, MessageType::MsgHup, 0)]);

assert_eq!(
network.peers[&3].state,
StateRole::PreCandidate,
"peer 3 state",
);

// term + 2, so that node 2 will ignore node 3's PreVote
network.send(vec![new_message(2, 1, MessageType::MsgTransferLeader, 0)]);
network.send(vec![new_message(1, 2, MessageType::MsgTransferLeader, 0)]);

// check whether the term values are expected
assert_eq!(
network.peers[&1].term, 4,
"peer 1 term",
);
assert_eq!(
network.peers[&2].term, 4,
"peer 2 term",
);
assert_eq!(
network.peers[&3].term, 2,
"peer 3 term",
);

// check state
assert_eq!(
network.peers[&1].state,
StateRole::Leader,
"peer 1 state",
);
assert_eq!(
network.peers[&2].state,
StateRole::Follower,
"peer 2 state",
);
assert_eq!(
network.peers[&3].state,
StateRole::PreCandidate,
"peer 3 state",
);

// recover the network then immediately isolate node 1 which is currently
// the leader, this is to emulate the crash of node 1.
network.recover();
network.cut(1, 2);
network.cut(1, 3);

// call for election. node 3 shouldn't ignore node 2's PreVote
network.send(vec![new_message(3, 3, MessageType::MsgHup, 0)]);
network.send(vec![new_message(2, 2, MessageType::MsgHup, 0)]);

// check state
assert_eq!(
network.peers[&2].state,
StateRole::Leader,
"peer 2 state",
);
assert_eq!(
network.peers[&3].state,
StateRole::Follower,
"peer 3 state",
);

}

0 comments on commit 4e6377a

Please sign in to comment.