# Tests that CheckQuorum causes a leader to step down if it hasn't heard from a
# quorum of followers in the past election timeout interval.
#
# Also tests that votes are rejected when there is a current leader. In the Raft
# thesis this is part of PreVote, but etcd/raft enables this via CheckQuorum.

log-level none
----
ok

add-nodes 3 voters=(1,2,3) index=10 checkquorum=true
----
ok

campaign 1
----
ok

stabilize
----
ok

log-level debug
----
ok

# Campaigning will fail when there is an active leader.
campaign 2
----
INFO 2 is starting a new election at term 1
INFO 2 became candidate at term 2
INFO 2 [logterm: 1, index: 11] sent MsgVote request to 1 at term 2
INFO 2 [logterm: 1, index: 11] sent MsgVote request to 3 at term 2

stabilize
----
> 2 handling Ready
  Ready MustSync=true:
  Lead:0 State:StateCandidate
  HardState Term:2 Vote:2 Commit:11
  Messages:
  2->1 MsgVote Term:2 Log:1/11
  2->3 MsgVote Term:2 Log:1/11
  INFO 2 received MsgVoteResp from 2 at term 2
  INFO 2 has received 1 MsgVoteResp votes and 0 vote rejections
> 1 receiving messages
  2->1 MsgVote Term:2 Log:1/11
  INFO 1 [logterm: 1, index: 11, vote: 1] ignored MsgVote from 2 [logterm: 1, index: 11] at term 1: lease is not expired (remaining ticks: 3)
> 3 receiving messages
  2->3 MsgVote Term:2 Log:1/11
  INFO 3 [logterm: 1, index: 11, vote: 1] ignored MsgVote from 2 [logterm: 1, index: 11] at term 1: lease is not expired (remaining ticks: 3)

# Tick the leader without processing any messages from followers. We have to
# tick 2 election timeouts, since the followers were active in the current
# interval (see messages above).
tick-election 1
----
ok

tick-election 1
----
WARN 1 stepped down to follower since quorum is not active
INFO 1 became follower at term 1

# We'll now send all of the heartbeats that were buffered during the ticks
# above. Conceptually, "the network was slow".
stabilize
----
> 1 handling Ready
  Ready MustSync=false:
  Lead:0 State:StateFollower
  Messages:
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
> 2 receiving messages
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->2 MsgHeartbeat Term:1 Log:0/0 Commit:11
> 3 receiving messages
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
  1->3 MsgHeartbeat Term:1 Log:0/0 Commit:11
> 2 handling Ready
  Ready MustSync=false:
  Messages:
  2->1 MsgAppResp Term:2 Log:0/0
  2->1 MsgAppResp Term:2 Log:0/0
  2->1 MsgAppResp Term:2 Log:0/0
  2->1 MsgAppResp Term:2 Log:0/0
  2->1 MsgAppResp Term:2 Log:0/0
> 3 handling Ready
  Ready MustSync=false:
  Messages:
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  3->1 MsgHeartbeatResp Term:1 Log:0/0
> 1 receiving messages
  2->1 MsgAppResp Term:2 Log:0/0
  INFO 1 [term: 1] received a MsgAppResp message with higher term from 2 [term: 2]
  INFO 1 became follower at term 2
  2->1 MsgAppResp Term:2 Log:0/0
  2->1 MsgAppResp Term:2 Log:0/0
  2->1 MsgAppResp Term:2 Log:0/0
  2->1 MsgAppResp Term:2 Log:0/0
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  INFO 1 [term: 2] ignored a MsgHeartbeatResp message with lower term from 3 [term: 1]
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  INFO 1 [term: 2] ignored a MsgHeartbeatResp message with lower term from 3 [term: 1]
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  INFO 1 [term: 2] ignored a MsgHeartbeatResp message with lower term from 3 [term: 1]
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  INFO 1 [term: 2] ignored a MsgHeartbeatResp message with lower term from 3 [term: 1]
  3->1 MsgHeartbeatResp Term:1 Log:0/0
  INFO 1 [term: 2] ignored a MsgHeartbeatResp message with lower term from 3 [term: 1]
> 1 handling Ready
  Ready MustSync=true:
  HardState Term:2 Commit:11

# Other nodes can now successfully campaign. Note that we haven't ticked 3, so
# it won't grant votes.
campaign 2
----
INFO 2 is starting a new election at term 2
INFO 2 became candidate at term 3
INFO 2 [logterm: 1, index: 11] sent MsgVote request to 1 at term 3
INFO 2 [logterm: 1, index: 11] sent MsgVote request to 3 at term 3

process-ready 2
----
Ready MustSync=true:
HardState Term:3 Vote:2 Commit:11
Messages:
2->1 MsgVote Term:3 Log:1/11
2->3 MsgVote Term:3 Log:1/11
INFO 2 received MsgVoteResp from 2 at term 3
INFO 2 has received 1 MsgVoteResp votes and 0 vote rejections

deliver-msgs 1
----
2->1 MsgVote Term:3 Log:1/11
INFO 1 [term: 2] received a MsgVote message with higher term from 2 [term: 3]
INFO 1 became follower at term 3
INFO 1 [logterm: 1, index: 11, vote: 0] cast MsgVote for 2 [logterm: 1, index: 11] at term 3

deliver-msgs 3
----
2->3 MsgVote Term:3 Log:1/11
INFO 3 [logterm: 1, index: 11, vote: 1] ignored MsgVote from 2 [logterm: 1, index: 11] at term 1: lease is not expired (remaining ticks: 3)

stabilize
----
> 1 handling Ready
  Ready MustSync=true:
  HardState Term:3 Vote:2 Commit:11
  Messages:
  1->2 MsgVoteResp Term:3 Log:0/0
> 2 receiving messages
  1->2 MsgVoteResp Term:3 Log:0/0
  INFO 2 received MsgVoteResp from 1 at term 3
  INFO 2 has received 2 MsgVoteResp votes and 0 vote rejections
  INFO 2 became leader at term 3
> 2 handling Ready
  Ready MustSync=true:
  Lead:2 State:StateLeader
  Entries:
  3/12 EntryNormal ""
  Messages:
  2->1 MsgApp Term:3 Log:1/11 Commit:11 Entries:[3/12 EntryNormal ""]
  2->3 MsgApp Term:3 Log:1/11 Commit:11 Entries:[3/12 EntryNormal ""]
> 1 receiving messages
  2->1 MsgApp Term:3 Log:1/11 Commit:11 Entries:[3/12 EntryNormal ""]
> 3 receiving messages
  2->3 MsgApp Term:3 Log:1/11 Commit:11 Entries:[3/12 EntryNormal ""]
  INFO 3 [term: 1] received a MsgApp message with higher term from 2 [term: 3]
  INFO 3 became follower at term 3
> 1 handling Ready
  Ready MustSync=true:
  Lead:2 State:StateFollower
  Entries:
  3/12 EntryNormal ""
  Messages:
  1->2 MsgAppResp Term:3 Log:0/12
> 3 handling Ready
  Ready MustSync=true:
  Lead:2 State:StateFollower
  HardState Term:3 Commit:11
  Entries:
  3/12 EntryNormal ""
  Messages:
  3->2 MsgAppResp Term:3 Log:0/12
> 2 receiving messages
  1->2 MsgAppResp Term:3 Log:0/12
  3->2 MsgAppResp Term:3 Log:0/12
> 2 handling Ready
  Ready MustSync=false:
  HardState Term:3 Vote:2 Commit:12
  CommittedEntries:
  3/12 EntryNormal ""
  Messages:
  2->1 MsgApp Term:3 Log:3/12 Commit:12
  2->3 MsgApp Term:3 Log:3/12 Commit:12
> 1 receiving messages
  2->1 MsgApp Term:3 Log:3/12 Commit:12
> 3 receiving messages
  2->3 MsgApp Term:3 Log:3/12 Commit:12
> 1 handling Ready
  Ready MustSync=false:
  HardState Term:3 Vote:2 Commit:12
  CommittedEntries:
  3/12 EntryNormal ""
  Messages:
  1->2 MsgAppResp Term:3 Log:0/12
> 3 handling Ready
  Ready MustSync=false:
  HardState Term:3 Commit:12
  CommittedEntries:
  3/12 EntryNormal ""
  Messages:
  3->2 MsgAppResp Term:3 Log:0/12
> 2 receiving messages
  1->2 MsgAppResp Term:3 Log:0/12
  3->2 MsgAppResp Term:3 Log:0/12
