mirror of
https://github.com/etcd-io/etcd.git
synced 2024-09-27 06:25:44 +00:00

The quorum package contains logic to reason about committed indexes as well as vote outcomes for both majority and joint quorums. The package is oblivious to the existence of learner replicas. The plan is to hook this up to etcd/raft in subsequent commits.
482 lines
9.0 KiB
Plaintext
482 lines
9.0 KiB
Plaintext
# No difference between a simple majority quorum and a simple majority quorum
|
|
# joint with an empty majority quorum. (This is asserted for all datadriven tests
|
|
# by the framework, so we don't dwell on it more).
|
|
#
|
|
# Note that by specifying cfgj explicitly we tell the test harness to treat the
|
|
# input as a joint quorum and not a majority quorum. If we didn't specify
|
|
# cfgj=zero the test would pass just the same, but it wouldn't be exercising the
|
|
# joint quorum path.
|
|
committed cfg=(1,2,3) cfgj=zero idx=(100,101,99)
|
|
----
|
|
idx
|
|
x> 100 (id=1)
|
|
xx> 101 (id=2)
|
|
> 99 (id=3)
|
|
100
|
|
|
|
# Joint nonoverlapping singleton quorums.
|
|
|
|
committed cfg=(1) cfgj=(2) idx=(_,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
? 0 (id=2)
|
|
0
|
|
|
|
# Voter 1 has 100 committed, 2 nothing. This means we definitely won't commit
|
|
# past 100.
|
|
committed cfg=(1) cfgj=(2) idx=(100,_)
|
|
----
|
|
idx
|
|
x> 100 (id=1)
|
|
? 0 (id=2)
|
|
0
|
|
|
|
# Committed index collapses once both majorities do, to the lower index.
|
|
committed cfg=(1) cfgj=(2) idx=(13, 100)
|
|
----
|
|
idx
|
|
> 13 (id=1)
|
|
x> 100 (id=2)
|
|
13
|
|
|
|
# Joint overlapping (i.e. identical) singleton quorum.
|
|
|
|
committed cfg=(1) cfgj=(1) idx=(_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
0
|
|
|
|
committed cfg=(1) cfgj=(1) idx=(100)
|
|
----
|
|
idx
|
|
> 100 (id=1)
|
|
100
|
|
|
|
|
|
|
|
# Two-node config joint with non-overlapping single node config
|
|
committed cfg=(1,3) cfgj=(2) idx=(_,_,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
0
|
|
|
|
committed cfg=(1,3) cfgj=(2) idx=(100,_,_)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
0
|
|
|
|
# 1 has 100 committed, 2 has 50 (collapsing half of the joint quorum to 50).
|
|
committed cfg=(1,3) cfgj=(2) idx=(100,_,50)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
x> 50 (id=2)
|
|
? 0 (id=3)
|
|
0
|
|
|
|
# 2 reports 45, collapsing the other half (to 45).
|
|
committed cfg=(1,3) cfgj=(2) idx=(100,45,50)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
x> 50 (id=2)
|
|
> 45 (id=3)
|
|
45
|
|
|
|
# Two-node config with overlapping single-node config.
|
|
|
|
committed cfg=(1,2) cfgj=(2) idx=(_,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
? 0 (id=2)
|
|
0
|
|
|
|
# 1 reports 100.
|
|
committed cfg=(1,2) cfgj=(2) idx=(100,_)
|
|
----
|
|
idx
|
|
x> 100 (id=1)
|
|
? 0 (id=2)
|
|
0
|
|
|
|
# 2 reports 100.
|
|
committed cfg=(1,2) cfgj=(2) idx=(_,100)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
x> 100 (id=2)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(2) idx=(50,100)
|
|
----
|
|
idx
|
|
> 50 (id=1)
|
|
x> 100 (id=2)
|
|
50
|
|
|
|
committed cfg=(1,2) cfgj=(2) idx=(100,50)
|
|
----
|
|
idx
|
|
x> 100 (id=1)
|
|
> 50 (id=2)
|
|
50
|
|
|
|
|
|
|
|
# Joint non-overlapping two-node configs.
|
|
|
|
committed cfg=(1,2) cfgj=(3,4) idx=(50,_,_,_)
|
|
----
|
|
idx
|
|
xxx> 50 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
? 0 (id=4)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(3,4) idx=(50,_,49,_)
|
|
----
|
|
idx
|
|
xxx> 50 (id=1)
|
|
? 0 (id=2)
|
|
xx> 49 (id=3)
|
|
? 0 (id=4)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(3,4) idx=(50,48,49,_)
|
|
----
|
|
idx
|
|
xxx> 50 (id=1)
|
|
x> 48 (id=2)
|
|
xx> 49 (id=3)
|
|
? 0 (id=4)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(3,4) idx=(50,48,49,47)
|
|
----
|
|
idx
|
|
xxx> 50 (id=1)
|
|
x> 48 (id=2)
|
|
xx> 49 (id=3)
|
|
> 47 (id=4)
|
|
47
|
|
|
|
# Joint overlapping two-node configs.
|
|
committed cfg=(1,2) cfgj=(2,3) idx=(_,_,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(2,3) idx=(100,_,_)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(2,3) idx=(_,100,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
xx> 100 (id=2)
|
|
? 0 (id=3)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(2,3) idx=(_,100,99)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
xx> 100 (id=2)
|
|
x> 99 (id=3)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(2,3) idx=(101,100,99)
|
|
----
|
|
idx
|
|
xx> 101 (id=1)
|
|
x> 100 (id=2)
|
|
> 99 (id=3)
|
|
99
|
|
|
|
# Joint identical two-node configs.
|
|
committed cfg=(1,2) cfgj=(1,2) idx=(_,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
? 0 (id=2)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(1,2) idx=(_,40)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
x> 40 (id=2)
|
|
0
|
|
|
|
committed cfg=(1,2) cfgj=(1,2) idx=(41,40)
|
|
----
|
|
idx
|
|
x> 41 (id=1)
|
|
> 40 (id=2)
|
|
40
|
|
|
|
|
|
|
|
# Joint disjoint three-node configs.
|
|
|
|
committed cfg=(1,2,3) cfgj=(4,5,6) idx=(_,_,_,_,_,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
? 0 (id=4)
|
|
? 0 (id=5)
|
|
? 0 (id=6)
|
|
0
|
|
|
|
committed cfg=(1,2,3) cfgj=(4,5,6) idx=(100,_,_,_,_,_)
|
|
----
|
|
idx
|
|
xxxxx> 100 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
? 0 (id=4)
|
|
? 0 (id=5)
|
|
? 0 (id=6)
|
|
0
|
|
|
|
committed cfg=(1,2,3) cfgj=(4,5,6) idx=(100,_,_,90,_,_)
|
|
----
|
|
idx
|
|
xxxxx> 100 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
xxxx> 90 (id=4)
|
|
? 0 (id=5)
|
|
? 0 (id=6)
|
|
0
|
|
|
|
committed cfg=(1,2,3) cfgj=(4,5,6) idx=(100,99,_,_,_,_)
|
|
----
|
|
idx
|
|
xxxxx> 100 (id=1)
|
|
xxxx> 99 (id=2)
|
|
? 0 (id=3)
|
|
? 0 (id=4)
|
|
? 0 (id=5)
|
|
? 0 (id=6)
|
|
0
|
|
|
|
# First quorum <= 99, second one <= 97. Both quorums guarantee that 90 is
|
|
# committed.
|
|
committed cfg=(1,2,3) cfgj=(4,5,6) idx=(_,99,90,97,95,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
xxxxx> 99 (id=2)
|
|
xx> 90 (id=3)
|
|
xxxx> 97 (id=4)
|
|
xxx> 95 (id=5)
|
|
? 0 (id=6)
|
|
90
|
|
|
|
# First quorum collapsed to 92. Second one already had at least 95 committed,
|
|
# so the result also collapses.
|
|
committed cfg=(1,2,3) cfgj=(4,5,6) idx=(92,99,90,97,95,_)
|
|
----
|
|
idx
|
|
xx> 92 (id=1)
|
|
xxxxx> 99 (id=2)
|
|
x> 90 (id=3)
|
|
xxxx> 97 (id=4)
|
|
xxx> 95 (id=5)
|
|
? 0 (id=6)
|
|
92
|
|
|
|
# Second quorum collapses, but nothing changes in the output.
|
|
committed cfg=(1,2,3) cfgj=(4,5,6) idx=(92,99,90,97,95,77)
|
|
----
|
|
idx
|
|
xx> 92 (id=1)
|
|
xxxxx> 99 (id=2)
|
|
x> 90 (id=3)
|
|
xxxx> 97 (id=4)
|
|
xxx> 95 (id=5)
|
|
> 77 (id=6)
|
|
92
|
|
|
|
|
|
# Joint overlapping three-node configs.
|
|
|
|
committed cfg=(1,2,3) cfgj=(1,4,5) idx=(_,_,_,_,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
? 0 (id=4)
|
|
? 0 (id=5)
|
|
0
|
|
|
|
committed cfg=(1,2,3) cfgj=(1,4,5) idx=(100,_,_,_,_)
|
|
----
|
|
idx
|
|
xxxx> 100 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
? 0 (id=4)
|
|
? 0 (id=5)
|
|
0
|
|
|
|
committed cfg=(1,2,3) cfgj=(1,4,5) idx=(100,101,_,_,_)
|
|
----
|
|
idx
|
|
xxx> 100 (id=1)
|
|
xxxx> 101 (id=2)
|
|
? 0 (id=3)
|
|
? 0 (id=4)
|
|
? 0 (id=5)
|
|
0
|
|
|
|
committed cfg=(1,2,3) cfgj=(1,4,5) idx=(100,101,100,_,_)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
xxxx> 101 (id=2)
|
|
> 100 (id=3)
|
|
? 0 (id=4)
|
|
? 0 (id=5)
|
|
0
|
|
|
|
# Second quorum could commit either 98 or 99, but first quorum is open.
|
|
committed cfg=(1,2,3) cfgj=(1,4,5) idx=(_,100,_,99,98)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
xxxx> 100 (id=2)
|
|
? 0 (id=3)
|
|
xxx> 99 (id=4)
|
|
xx> 98 (id=5)
|
|
0
|
|
|
|
# Additionally, first quorum can commit either 100 or 99
|
|
committed cfg=(1,2,3) cfgj=(1,4,5) idx=(_,100,99,99,98)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
xxxx> 100 (id=2)
|
|
xx> 99 (id=3)
|
|
> 99 (id=4)
|
|
x> 98 (id=5)
|
|
98
|
|
|
|
committed cfg=(1,2,3) cfgj=(1,4,5) idx=(1,100,99,99,98)
|
|
----
|
|
idx
|
|
> 1 (id=1)
|
|
xxxx> 100 (id=2)
|
|
xx> 99 (id=3)
|
|
> 99 (id=4)
|
|
x> 98 (id=5)
|
|
98
|
|
|
|
committed cfg=(1,2,3) cfgj=(1,4,5) idx=(100,100,99,99,98)
|
|
----
|
|
idx
|
|
xxx> 100 (id=1)
|
|
> 100 (id=2)
|
|
x> 99 (id=3)
|
|
> 99 (id=4)
|
|
> 98 (id=5)
|
|
99
|
|
|
|
|
|
# More overlap.
|
|
|
|
committed cfg=(1,2,3) cfgj=(2,3,4) idx=(_,_,_,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
? 0 (id=4)
|
|
0
|
|
|
|
committed cfg=(1,2,3) cfgj=(2,3,4) idx=(_,100,99,_)
|
|
----
|
|
idx
|
|
? 0 (id=1)
|
|
xxx> 100 (id=2)
|
|
xx> 99 (id=3)
|
|
? 0 (id=4)
|
|
99
|
|
|
|
committed cfg=(1,2,3) cfgj=(2,3,4) idx=(98,100,99,_)
|
|
----
|
|
idx
|
|
x> 98 (id=1)
|
|
xxx> 100 (id=2)
|
|
xx> 99 (id=3)
|
|
? 0 (id=4)
|
|
99
|
|
|
|
committed cfg=(1,2,3) cfgj=(2,3,4) idx=(100,100,99,_)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
> 100 (id=2)
|
|
x> 99 (id=3)
|
|
? 0 (id=4)
|
|
99
|
|
|
|
committed cfg=(1,2,3) cfgj=(2,3,4) idx=(100,100,99,98)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
> 100 (id=2)
|
|
x> 99 (id=3)
|
|
> 98 (id=4)
|
|
99
|
|
|
|
committed cfg=(1,2,3) cfgj=(2,3,4) idx=(100,_,_,101)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
? 0 (id=2)
|
|
? 0 (id=3)
|
|
xxx> 101 (id=4)
|
|
0
|
|
|
|
committed cfg=(1,2,3) cfgj=(2,3,4) idx=(100,99,_,101)
|
|
----
|
|
idx
|
|
xx> 100 (id=1)
|
|
x> 99 (id=2)
|
|
? 0 (id=3)
|
|
xxx> 101 (id=4)
|
|
99
|
|
|
|
# Identical. This is also exercised in the test harness, so it's listed here
|
|
# only briefly.
|
|
committed cfg=(1,2,3) cfgj=(1,2,3) idx=(50,45,_)
|
|
----
|
|
idx
|
|
xx> 50 (id=1)
|
|
x> 45 (id=2)
|
|
? 0 (id=3)
|
|
45
|