Files
mesh-delivery/contracts/go/clients/meshdeliverycheckerclient/client_test.go
T

224 lines
10 KiB
Go

package meshdeliverycheckerclient
import (
"strings"
"testing"
checker "git.novox.be/novox/mesh-delivery/contracts/go/seats/meshdeliverychecker"
)
type verdict = checker.VerdictsByGroupHeadsValue
func passing() verdict {
return verdict{Group: "g", Heads: "0123456789ab", State: VerdictPass, Trunk: map[string]string{"novox/a": "c1"},
Levels: map[string]checker.VerdictsByGroupHeadsValueLevelsValue{LevelUnit: {Run: 3}, LevelIntegration: {Run: 1}}}
}
// The rules a verdict keeps to be written or read: each case edits a passing verdict and names what the refusal says.
func TestAVerdictIsRefusedForWhatAReaderCouldNotPlace(t *testing.T) {
if err := CheckVerdict(passing()); err != nil {
t.Fatalf("a passing verdict is refused: %v", err)
}
for name, c := range map[string]struct {
edit func(*verdict)
says string
}{
"no group": {func(v *verdict) { v.Group = "" }, "no group"},
"heads of 11 digits": {func(v *verdict) { v.Heads = "0123456789a" }, "12 lowercase hex"},
"an empty trunk head": {func(v *verdict) { v.Trunk["novox/a"] = "" }, "trunk head"},
"merged and read": {func(v *verdict) { v.Beside = map[string]string{"novox/a": "c2"} }, "trunk it merged and as a sibling"},
"nothing carried": {func(v *verdict) { v.CarriedFrom = map[string]string{"novox/a": "c1"} }, "nothing moved"},
"a running carry": {func(v *verdict) { v.State, v.CarriedFrom = VerdictRunning, map[string]string{"novox/a": "c0"} }, "carried from nothing"},
"a series to itself": {func(v *verdict) {
v.Series = []checker.VerdictsByGroupHeadsValueSeriesItem{{Module: "m", Artifact: "a", From: "0.1", To: "0.1"}}
}, "same series"},
"an unknown level": {func(v *verdict) { v.Levels["smoke"] = checker.VerdictsByGroupHeadsValueLevelsValue{} }, "smoke"},
"a negative count": {func(v *verdict) { v.Levels[LevelUnit] = checker.VerdictsByGroupHeadsValueLevelsValue{Run: -1} }, "negative"},
"a negative time": {func(v *verdict) { v.Took = &checker.VerdictsByGroupHeadsValueTook{Unit: -1} }, "negative"},
"a pass without a level": {func(v *verdict) { delete(v.Levels, LevelIntegration) }, "integration level"},
"a pass that failed": {func(v *verdict) { v.Failed = &checker.VerdictsByGroupHeadsValueFailed{Test: "T"} }, "names no failure"},
"failures of a pass": {func(v *verdict) { v.Failures = []checker.VerdictsByGroupHeadsValueFailuresItem{{Test: "T"}} }, "names no failures"},
"a fail naming nothing": {func(v *verdict) { v.State = VerdictFail }, "neither a test nor a machine"},
"an unknown state": {func(v *verdict) { v.State = "maybe" }, "maybe"},
"a composition passed without a commit": {func(v *verdict) {
v.Composition = &checker.VerdictsByGroupHeadsValueComposition{State: CompositionPass}
}, "mesh-sdk commit"},
"the same level over bound twice": {func(v *verdict) { v.OverBound = []string{LevelUnit, LevelUnit} }, "twice"},
} {
v := passing()
c.edit(&v)
if err := CheckVerdict(v); err == nil || !strings.Contains(err.Error(), c.says) {
t.Errorf("%s: %v, want a refusal saying %q", name, err, c.says)
}
}
failed := passing()
failed.State, failed.Failed = VerdictFail, &checker.VerdictsByGroupHeadsValueFailed{Machine: "ace"}
if err := CheckVerdict(failed); err != nil {
t.Errorf("a fail naming a machine is refused: %v", err)
}
}
func TestAKeptVerdictIsAPassOfAPackageAtALevel(t *testing.T) {
t.Run("a preview is refused for what a reader of candidates could not place", previewIsRefused)
ok := checker.KeptByLevelDigestValue{State: VerdictPass, Repository: "novox/mesh-sdk", Package: "./go/keys", Level: LevelUnit, Toolchain: "1.26.0", At: "2026-11-05T10:00:00Z"}
if err := CheckKept(ok); err != nil {
t.Fatalf("a kept pass is refused: %v", err)
}
for name, edit := range map[string]func(*checker.KeptByLevelDigestValue){
"a fail": func(k *checker.KeptByLevelDigestValue) { k.State = VerdictFail },
"no owner": func(k *checker.KeptByLevelDigestValue) { k.Repository = "mesh-sdk" },
"no package": func(k *checker.KeptByLevelDigestValue) { k.Package = "" },
"an unknown level": func(k *checker.KeptByLevelDigestValue) { k.Level = "smoke" },
"negative tests": func(k *checker.KeptByLevelDigestValue) { k.Tests = -1 },
"no toolchain": func(k *checker.KeptByLevelDigestValue) { k.Toolchain = "" },
"no time": func(k *checker.KeptByLevelDigestValue) { k.At = "" },
} {
k := ok
edit(&k)
if CheckKept(k) == nil {
t.Errorf("%s was taken", name)
}
}
}
// A preview is refused for what a reader of candidates could not place.
func previewIsRefused(t *testing.T) {
good := func() checker.PreviewsByRepositoryHeadTrunkValue {
return checker.PreviewsByRepositoryHeadTrunkValue{Repository: "novox/a", Head: "h1", Trunk: "t1", Merge: "m1",
Modules: map[string]checker.PreviewsByRepositoryHeadTrunkValueModulesValue{"mod": {Tree: "tr", Manifest: strings.Repeat("a", 64),
Locks: map[string]string{"go.sum": "x"}, Paths: map[string]string{"src": "o1"}}}}
}
if err := CheckPreview(good()); err != nil {
t.Fatalf("a good preview is refused: %v", err)
}
for name, c := range map[string]struct {
edit func(*checker.PreviewsByRepositoryHeadTrunkValue)
says string
}{
"a repository with no owner": {func(p *checker.PreviewsByRepositoryHeadTrunkValue) { p.Repository = "a" }, "<owner>/<name>"},
"a head with a dot": {func(p *checker.PreviewsByRepositoryHeadTrunkValue) { p.Head = "h.1" }, "head"},
"a conflict with a merge": {func(p *checker.PreviewsByRepositoryHeadTrunkValue) { p.Conflicts = []string{"f"} }, "in conflict"},
"no merge commit": {func(p *checker.PreviewsByRepositoryHeadTrunkValue) { p.Merge = "" }, "no merge commit"},
"a module with no tree": {func(p *checker.PreviewsByRepositoryHeadTrunkValue) {
m := p.Modules["mod"]
m.Tree = ""
p.Modules["mod"] = m
}, "no tree"},
"a short manifest digest": {func(p *checker.PreviewsByRepositoryHeadTrunkValue) {
m := p.Modules["mod"]
m.Manifest = "abc"
p.Modules["mod"] = m
}, "manifest digest"},
"a path outside the module": {func(p *checker.PreviewsByRepositoryHeadTrunkValue) {
m := p.Modules["mod"]
m.Paths = map[string]string{"../x": "o"}
p.Modules["mod"] = m
}, "clean path"},
} {
p := good()
c.edit(&p)
if err := CheckPreview(p); err == nil || !strings.Contains(err.Error(), c.says) {
t.Errorf("%s: CheckPreview = %v, want it to say %q", name, err, c.says)
}
}
if err := CheckPreview(checker.PreviewsByRepositoryHeadTrunkValue{Repository: "novox/a", Head: "h", Trunk: "t", Conflicts: []string{"f"}}); err != nil {
t.Errorf("a head in conflict is refused: %v", err)
}
}
// A verdict's key as go/delivery's CheckerVerdictKey wrote it (golden): the group escaped, the heads hash after the
// last dot.
func TestVerdictKeyAsGoDeliveryWroteIt(t *testing.T) {
key, err := VerdictKey("fix/1.2", "0123456789ab")
if err != nil || key != "fix/1=2e2.0123456789ab" {
t.Fatalf("%q %v", key, err)
}
group, heads, err := ParseVerdictKey(key)
if err != nil || group != "fix/1.2" || heads != "0123456789ab" {
t.Fatalf("%q %q %v", group, heads, err)
}
for _, bad := range []string{"nodot", "g.XYZ", ".0123456789ab", "a.b.0123456789ab", "g=zz.0123456789ab"} {
if _, _, err := ParseVerdictKey(bad); err == nil {
t.Errorf("%q parses", bad)
}
}
if _, err := VerdictKey("", "0123456789ab"); err == nil {
t.Error("an empty group keys")
}
if _, err := VerdictKey("g", "0123"); err == nil {
t.Error("a short hash keys")
}
}
// The codecs write a value at the kept values' version after its rules and read it back through them.
func TestTheCodecsWriteAtTheVersionAndReadBackThroughTheRules(t *testing.T) {
raw, err := EncodeVerdict(passing())
if err != nil {
t.Fatal(err)
}
if got, err := DecodeVerdict(raw); err != nil || got.V == 0 || got.Group != "g" {
t.Errorf("verdict read back = %+v, %v", got, err)
}
bad := passing()
bad.Heads = "x"
if _, err := EncodeVerdict(bad); err == nil {
t.Error("a verdict whose heads are no hash is written")
}
if _, err := DecodeVerdict([]byte(`{"v":99,"group":"g","heads":"0123456789ab","state":"running"}`)); err == nil {
t.Error("a verdict of an unknown version is read")
}
k := checker.KeptByLevelDigestValue{State: VerdictPass, Repository: "novox/mesh-sdk", Package: "./go/keys", Level: LevelUnit, Toolchain: "1.26.0", At: "2026-11-05T10:00:00Z"}
raw, err = EncodeKept(k)
if err != nil {
t.Fatal(err)
}
if got, err := DecodeKept(raw); err != nil || got.Package != k.Package {
t.Errorf("kept read back = %+v, %v", got, err)
}
k.State = VerdictFail
if _, err := EncodeKept(k); err == nil {
t.Error("a failure is kept")
}
p := checker.PreviewsByRepositoryHeadTrunkValue{Repository: "novox/a", Head: "h1", Trunk: "t1", Conflicts: []string{"f.go"}}
raw, err = EncodePreview(p)
if err != nil {
t.Fatal(err)
}
if got, err := DecodePreview(raw); err != nil || got.Head != "h1" {
t.Errorf("preview read back = %+v, %v", got, err)
}
p.Conflicts = nil
if _, err := EncodePreview(p); err == nil {
t.Error("a preview with no merge commit and no conflict is written")
}
}
// The kept and preview keys: a key reads back to its parts, and a part that does not key is refused.
func TestKeptAndPreviewKeysReadBack(t *testing.T) {
digest := strings.Repeat("ab", 32)
key, err := KeptKey(LevelUnit, digest)
if err != nil || key != "unit."+digest {
t.Fatalf("kept key = %q, %v", key, err)
}
if level, d, err := ParseKeptKey(key); err != nil || level != LevelUnit || d != digest {
t.Errorf("kept key read back = %q %q, %v", level, d, err)
}
for _, bad := range []string{"fast." + digest, "unit.XY", "unit"} {
if _, _, err := ParseKeptKey(bad); err == nil {
t.Errorf("kept key %q is read", bad)
}
}
key, err = PreviewKey("novox/mesh-sdk", "h1", "t1")
if err != nil {
t.Fatal(err)
}
if repo, h, tr, err := ParsePreviewKey(key); err != nil || repo != "novox/mesh-sdk" || h != "h1" || tr != "t1" {
t.Errorf("preview key %q read back = %q %q %q, %v", key, repo, h, tr, err)
}
for _, bad := range []string{"novox.h1.t1", "a/b.h1", "a/b.h1.t1.x"} {
if _, _, _, err := ParsePreviewKey(bad); err == nil {
t.Errorf("preview key %q is read", bad)
}
}
}