# This test verifies that a config change is not proposed if the leader has
# unapplied config changes. This ensures a safety requirement stated in
# https://github.com/etcd-io/etcd/issues/7625#issuecomment-489232411

# The check should be performed even if conf change validation is disabled.
add-nodes 4 voters=(1) index=2 disable-conf-change-validation=true
----
INFO 1 switched to configuration voters=(1)
INFO 1 became follower at term 0
DEBUG 1 reset election elapsed to 0
INFO newRaft 1 [peers: [1], term: 0, commit: 2, applied: 2, lastindex: 2, lastterm: 1]
INFO 2 switched to configuration voters=(1)
INFO 2 became follower at term 0
DEBUG 2 reset election elapsed to 0
INFO newRaft 2 [peers: [1], term: 0, commit: 2, applied: 2, lastindex: 2, lastterm: 1]
INFO 3 switched to configuration voters=(1)
INFO 3 became follower at term 0
DEBUG 3 reset election elapsed to 0
INFO newRaft 3 [peers: [1], term: 0, commit: 2, applied: 2, lastindex: 2, lastterm: 1]
INFO 4 switched to configuration voters=(1)
INFO 4 became follower at term 0
DEBUG 4 reset election elapsed to 0
INFO newRaft 4 [peers: [1], term: 0, commit: 2, applied: 2, lastindex: 2, lastterm: 1]

campaign 1
----
INFO 1 is starting a new election at term 0
INFO 1 became candidate at term 1

stabilize log-level=none
----
ok

# Propose one config change. It should be accepted.
propose-conf-change 1 transition=explicit
l2 l3
----
ok

# The first config change gets appended.
process-ready 1
----
Ready MustSync=true:
Entries:
1/4 EntryConfChangeV2 l2 l3

# Propose another config change. It should be rejected, because the first config
# change hasn't applied on the leader yet.
propose-conf-change 1
l4
----
INFO 1 ignoring conf change {ConfChangeTransitionAuto [{ConfChangeAddLearnerNode 4}] []} at config voters=(1): possible unapplied conf change at index 4 (applied to 3)

# The new config change is appended to the log as an empty entry.
stabilize 1
----
> 1 handling Ready
  Ready MustSync=true:
  HardState Term:1 Vote:1 Commit:4 Lead:1 LeadEpoch:1
  Entries:
  1/5 EntryNormal ""
  CommittedEntries:
  1/4 EntryConfChangeV2 l2 l3
  INFO 1 switched to configuration voters=(1)&&(1) learners=(2 3)
> 1 handling Ready
  Ready MustSync=true:
  HardState Term:1 Vote:1 Commit:5 Lead:1 LeadEpoch:1
  CommittedEntries:
  1/5 EntryNormal ""
  Messages:
  1->2 MsgFortifyLeader Term:1 Log:0/0
  1->3 MsgFortifyLeader Term:1 Log:0/0
  1->2 MsgApp Term:1 Log:1/4 Commit:4 Entries:[1/5 EntryNormal ""]
  1->3 MsgApp Term:1 Log:1/4 Commit:4 Entries:[1/5 EntryNormal ""]
