# 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