mesh/delivery merged: source.main moved to novox/mesh-delivery@ecf532af0e85
mesh/check being carried to a7e51b416bc1 on ecf532af0e85 | from 71f786f14662
115 lines
4.0 KiB
Go
115 lines
4.0 KiB
Go
package check
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"sync"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
// The checker's ranked start of checks (ADR 0536 §4, issue 1897): a freed place goes to a head never judged (or asked again
|
|
// after a failure of the nodes) before a head asked again only because its trunk moved; among equals the oldest asked first.
|
|
// A running check is never stopped.
|
|
|
|
// rankRig is a checker of one check at a time whose judge records the order checks start in and holds the first check
|
|
// after hold is set until release is closed.
|
|
type rankRig struct {
|
|
*rig
|
|
mu sync.Mutex
|
|
started []*Case
|
|
hold bool
|
|
held chan struct{} // closed when the held check started
|
|
release chan struct{}
|
|
errs []error // ctx errors the held check saw when released
|
|
}
|
|
|
|
func group(n int) string { return fmt.Sprintf("feat/g%d", n) }
|
|
|
|
func groups(cs []*Case) []string {
|
|
out := make([]string, len(cs))
|
|
for i, c := range cs {
|
|
out[i] = c.Group
|
|
}
|
|
return out
|
|
}
|
|
|
|
func TestCheckerStatusNamesTheWaitingChecksByKind(t *testing.T) { // 1897/AC4
|
|
ctx := context.Background()
|
|
j := &judgeFunc{f: func(_ context.Context, c *Case, _ int) (Outcome, error) {
|
|
if c.Group == group(2) {
|
|
return Outcome{Verdict: failure("the forge", "go.mod cannot be read: no responders (the forge was "+UnheardWords+")")}, nil
|
|
}
|
|
return Outcome{Verdict: passing()}, nil
|
|
}}
|
|
r := newRig(t, j)
|
|
cands := fakeState{}
|
|
put := func(n int, head string) {
|
|
cand := candidateOf(t, group(n), pullOf(repoA, n, head))
|
|
ckey, _ := delivery.CandidatesKey(group(n))
|
|
cands[ckey] = cand
|
|
r.ch.Candidate(ctx, group(n), cand)
|
|
}
|
|
put(1, head1) // judged on the old trunk: a re-judge waits
|
|
put(2, head1) // failed for the nodes: waits for them
|
|
r.ch.Wait()
|
|
r.setTrunks(t, map[string]string{repoA: trunkA2, repoSDK: trunkS})
|
|
put(4, head1) // judged on the new trunk: stands
|
|
r.ch.Wait()
|
|
cand3 := candidateOf(t, group(3), pullOf(repoA, 3, head1)) // never judged
|
|
ckey3, _ := delivery.CandidatesKey(group(3))
|
|
cands[ckey3] = cand3
|
|
verdicts := fakeState{}
|
|
for k, v := range r.verdicts.vals {
|
|
verdicts[k] = v
|
|
}
|
|
rd := Reader{CandidateState: cands.read(), VerdictState: verdicts.read(),
|
|
Trunks: func() (map[string]string, error) { return map[string]string{repoA: trunkA2, repoSDK: trunkS}, nil }}
|
|
st, err := rd.Status()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
want := map[string][]string{KindNew: {group(3)}, KindNodes: {group(2)}, KindTrunk: {group(1)}}
|
|
if fmt.Sprint(st.Waiting) != fmt.Sprint(want) {
|
|
t.Errorf("waiting = %v, want %v", st.Waiting, want)
|
|
}
|
|
}
|
|
|
|
// 568 note 21: a verdict that read the node-engine at its running commit is not waiting for a trunk move while that commit
|
|
// is still the one the mesh runs, though the node-engine's trunk has moved on (ADR 0548 §6).
|
|
func TestCheckerStatusReadsTheNodeEngineAtItsRunningCommit(t *testing.T) { // 568/21
|
|
cand := candidateOf(t, group(1), pullOf(repoA, 1, head1))
|
|
ckey, _ := delivery.CandidatesKey(group(1))
|
|
vkey := keyOf(t, group(1), cand)
|
|
dc, _ := delivery.DecodeCandidate(cand)
|
|
judged, err := delivery.EncodeVerdict(delivery.Verdict{Group: group(1), Heads: dc.HeadsHash, Trunk: map[string]string{repoA: trunkA}, Beside: map[string]string{nodeEngineRepo: "run111"}, State: delivery.VerdictPass, Levels: passing().Levels})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
heads := func() (map[string]string, error) {
|
|
return map[string]string{repoA: trunkA, nodeEngineRepo: "trunk222"}, nil
|
|
}
|
|
for _, row := range []struct {
|
|
name string
|
|
runs runsAt
|
|
want int
|
|
}{
|
|
{"the running commit the verdict read", runsAt{nodeEngineModule: "run111"}, 0},
|
|
{"the running commit moved", runsAt{nodeEngineModule: "run999"}, 1},
|
|
{"no running commit known: the trunk's", nil, 1},
|
|
} {
|
|
rd := Reader{CandidateState: fakeState{ckey: cand}.read(), VerdictState: fakeState{vkey: judged}.read(), Trunks: heads}
|
|
if row.runs != nil {
|
|
rd.Runs = row.runs
|
|
}
|
|
st, err := rd.Status()
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if got := len(st.Waiting[KindTrunk]); got != row.want {
|
|
t.Errorf("%s: waiting for a trunk move = %v, want %d", row.name, st.Waiting[KindTrunk], row.want)
|
|
}
|
|
}
|
|
}
|