package check import ( "context" "errors" "strings" "testing" "git.novox.be/novox/mesh-sdk/go/delivery" ) // fakeCompositions answers the assigner's composition of a check from memory, recording the keys asked. type fakeCompositions struct { v delivery.CompositionVerdict err error asked []string } func (f *fakeCompositions) Await(_ context.Context, key string) (delivery.CompositionVerdict, error) { f.asked = append(f.asked, key) return f.v, f.err } // 1297/AC3 (its unit half): a check whose tests pass takes the assigner's composition of it, by the check's own key, // into its verdict: a pass says it passed with the mesh-sdk and machines it composed, and is no longer "not run". func TestAPassingCheckTakesTheAssignersComposition(t *testing.T) { b := newBench(t) f := &fakeCompositions{v: delivery.CompositionVerdict{Group: "feat/x", Heads: "0123456789ab", State: delivery.CompositionPass, SDK: "v0.1.14-x", Machines: []string{"g14"}, Took: 40}} b.ex.Compositions = f cs := caseOf(t, pullOf(repoA, 7, head1)) v := b.judge(t, cs).Verdict if v.State != delivery.VerdictPass || v.Composition == nil || v.Composition.State != delivery.CompositionPass || v.Composition.SDK != "v0.1.14-x" || v.Took.Composition != 40 { t.Fatalf("verdict = %+v, composition %+v", v, v.Composition) } if len(f.asked) != 1 || f.asked[0] != cs.Key { t.Errorf("asked %v, want the check's key %s", f.asked, cs.Key) } if !compositionMentions(v, "passed") { t.Errorf("the line says %q", compositionWords(v.Composition, v.Took.Composition)) } } func compositionMentions(v delivery.Verdict, word string) bool { return strings.Contains(compositionWords(v.Composition, v.Took.Composition), word) } // 1297/AC2 at the checker: a failed composition fails the check, naming the machine it failed at and its words. func TestAFailedCompositionFailsTheCheck(t *testing.T) { b := newBench(t) b.ex.Compositions = &fakeCompositions{v: delivery.CompositionVerdict{Group: "feat/x", Heads: "0123456789ab", State: delivery.CompositionFail, SDK: "x", Machine: "g14", Words: "g14 runs web, which the change removes from its source"}} v := b.judge(t, caseOf(t, pullOf(repoA, 7, head1))).Verdict if v.State != delivery.VerdictFail || v.Failed.Machine != "g14" || v.Composition == nil || v.Composition.State != delivery.CompositionFail { t.Fatalf("verdict = %+v", v) } v.Group, v.Heads = "feat/x", "0123456789ab" // the checker names them when it writes the verdict if _, err := delivery.EncodeVerdict(v); err != nil { t.Errorf("the verdict cannot be written: %v", err) } } // 1297/B3d: a composition that cannot be read leaves it not run; a try is not composed. func TestACompositionNotHadIsNotRun(t *testing.T) { b := newBench(t) f := &fakeCompositions{err: errors.New("the check's bound passed")} b.ex.Compositions = f v := b.judge(t, caseOf(t, pullOf(repoA, 7, head1))).Verdict if v.State != delivery.VerdictPass || v.Composition == nil || v.Composition.State != delivery.CompositionNotRun { t.Fatalf("verdict = %+v", v) } b2 := newBench(t) f2 := &fakeCompositions{v: delivery.CompositionVerdict{State: delivery.CompositionFail, Words: "w", SDK: "x"}} b2.ex.Compositions = f2 cs := caseOf(t, pullOf(repoA, 7, head1)) cs.Try = &TryOptions{} b2.judge(t, cs) if len(f2.asked) != 0 { t.Errorf("a try asked for a composition: %v", f2.asked) } }