78 lines
2.5 KiB
Go
78 lines
2.5 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)
|
|
}
|
|
}
|