103 lines
3.9 KiB
Go
103 lines
3.9 KiB
Go
package check
|
|
|
|
import (
|
|
"context"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/delivery"
|
|
)
|
|
|
|
const repoC = "novox/mesh-controller"
|
|
|
|
func statusOf(t *testing.T, r *rig, repo string, n int, head string) string {
|
|
t.Helper()
|
|
key, _ := delivery.CheckerOwedKey(repo, n, head)
|
|
raw, _, found, _ := r.owed.Get(context.Background(), key)
|
|
if !found {
|
|
return ""
|
|
}
|
|
o, err := delivery.DecodeCheckerOwed(raw)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
return o.State
|
|
}
|
|
|
|
// 1791 note 9 (issue 1921, try speed S9): two of a group's three members merge. The candidate keeps them, marked merged,
|
|
// with the same heads; their trunks moved by their own merges. No new check is asked, and the member left keeps its
|
|
// passed status, so the merge of the rest is not refused.
|
|
func TestTwoMembersMergingAskNoNewCheckAndTheThirdKeepsItsPass(t *testing.T) {
|
|
ctx, j := context.Background(), passJudge()
|
|
r := newRig(t, j)
|
|
r.setTrunks(t, map[string]string{repoA: trunkA, repoSDK: trunkS, repoC: trunkA})
|
|
a, s, c := pullOf(repoA, 7, head1), pullOf(repoSDK, 12, head2), pullOf(repoC, 3, head1)
|
|
r.ch.Candidate(ctx, "feat%2Fx", candidateOf(t, "feat/x", a, s, c))
|
|
r.ch.Wait()
|
|
if j.count() != 1 || statusOf(t, r, repoC, 3, head1) != "success" {
|
|
t.Fatalf("judged %d times, the third's status %q", j.count(), statusOf(t, r, repoC, 3, head1))
|
|
}
|
|
a.Merged, s.Merged = true, true
|
|
r.ch.Candidate(ctx, "feat%2Fx", candidateOf(t, "feat/x", a, s, c))
|
|
r.setTrunks(t, map[string]string{repoA: trunkA2, repoSDK: trunkS2, repoC: trunkA})
|
|
r.ch.TrunkMoved(ctx)
|
|
r.ch.Wait()
|
|
if j.count() != 1 {
|
|
t.Errorf("a new check was asked after two members merged: judged %d times", j.count())
|
|
}
|
|
if got := statusOf(t, r, repoC, 3, head1); got != "success" {
|
|
t.Errorf("the third member's status is %q, want success", got)
|
|
}
|
|
// The trunk of the member left moves: that is a re-judge as before.
|
|
r.setTrunks(t, map[string]string{repoA: trunkA2, repoSDK: trunkS2, repoC: trunkA2})
|
|
r.ch.TrunkMoved(ctx)
|
|
r.ch.Wait()
|
|
if j.count() != 2 {
|
|
t.Errorf("the member left's trunk moved and it was judged %d times, want again", j.count())
|
|
}
|
|
}
|
|
|
|
// 1791 note 8 (issue 1921, try speed S9): a group opened member by member writes a candidate for each partial set. When
|
|
// the group's candidate moves to new heads, the check of the older heads is stopped and ends failed, superseded, instead
|
|
// of running on or staying running; it puts no status, as the newer check owns the heads they share.
|
|
func TestACheckWhoseHeadsTheGroupNoLongerHoldsIsStoppedAndEndsSuperseded(t *testing.T) {
|
|
ctx := context.Background()
|
|
started := make(chan struct{})
|
|
j := &judgeFunc{f: func(ctx context.Context, c *Case, call int) (Outcome, error) {
|
|
if len(c.Pulls) == 1 {
|
|
close(started)
|
|
select {
|
|
case <-ctx.Done():
|
|
return Outcome{Verdict: failure("checker", ctx.Err().Error())}, nil
|
|
case <-time.After(3 * time.Second):
|
|
return Outcome{Verdict: passing()}, nil // never stopped
|
|
}
|
|
}
|
|
return Outcome{Verdict: passing()}, nil
|
|
}}
|
|
r := newRig(t, j)
|
|
partial := candidateOf(t, "feat/x", pullOf(repoA, 7, head1))
|
|
whole := candidateOf(t, "feat/x", pullOf(repoA, 7, head1), pullOf(repoSDK, 12, head2))
|
|
r.ch.Candidate(ctx, "feat%2Fx", partial)
|
|
<-started
|
|
r.ch.Candidate(ctx, "feat%2Fx", whole)
|
|
done := make(chan struct{})
|
|
go func() { r.ch.Wait(); close(done) }()
|
|
select {
|
|
case <-done:
|
|
case <-time.After(2 * time.Second):
|
|
t.Fatal("the check of the older heads was not stopped")
|
|
}
|
|
old := r.verdict(t, keyOf(t, "feat/x", partial))
|
|
if old.State != delivery.VerdictFail || !strings.Contains(old.Failed.Words, "superseded") {
|
|
t.Errorf("the older heads' verdict = %+v, want failed, superseded", old)
|
|
}
|
|
if v := r.verdict(t, keyOf(t, "feat/x", whole)); v.State != delivery.VerdictPass {
|
|
t.Errorf("the newer heads' verdict = %+v", v)
|
|
}
|
|
if got := statusOf(t, r, repoA, 7, head1); got != "success" {
|
|
t.Errorf("the shared head's status is %q, want the newer check's success", got)
|
|
}
|
|
}
|