Files
mesh-delivery/modules/mesh-delivery-indexer/internal/index/candidate_manifests_test.go
T

107 lines
4.5 KiB
Go

package index
import (
"context"
"errors"
"reflect"
"strings"
"testing"
"git.novox.be/novox/mesh-sdk/go/delivery"
)
func manifestPull(t *testing.T, number int, head, manifest string) delivery.Forge {
f := delivery.Forge{V: delivery.Version, Kind: delivery.ForgePull, Repository: catalogueRepo, Branch: "feat/x", Number: number, Head: head,
Action: delivery.PullUpdated, Dirs: []string{"modules/avahi"}, DirsKnown: true}
if manifest != "" {
f.Manifests = map[string]string{"modules/avahi": manifest}
}
return f
}
func candidateOf(t *testing.T, st *memStore) delivery.Candidate {
t.Helper()
key, err := delivery.CandidatesKey("feat/x")
if err != nil {
t.Fatal(err)
}
raw, ok := st.vals[key]
if !ok {
t.Fatalf("candidates holds %d keys, none %s", len(st.vals), key)
}
c, err := delivery.DecodeCandidate(raw)
if err != nil {
t.Fatal(err)
}
return c
}
func TestACandidateGivesEachTouchedModuleItsManifestAndTheReasonItHasNoPreview(t *testing.T) { // 1451/AC1
avahi := catalogueManifest(t, "avahi")
ix, _, _ := manifestsIndexer(t, rec(t, "build-1", "avahi", catalogueRepo, "modules/avahi", "main", "", "2026-10-19T09:00:00Z", aInputs))
if err := ix.Apply(context.Background(), manifestPull(t, 301, h1, avahi)); err != nil {
t.Fatal(err)
}
c := candidateOf(t, ix.Store.(*memStore)) // DecodeCandidate has run Candidate.check
want := delivery.CandidateModule{Manifest: delivery.ManifestDigest([]byte(avahi)), None2: "no merge preview is computed"}
if len(c.Pulls) != 1 || len(c.Pulls[0].Fps) != 1 || !reflect.DeepEqual(c.Pulls[0].Fps["avahi"], want) {
t.Fatalf("pulls = %+v, want Fps[avahi] = %+v", c.Pulls, want)
}
if c.FPSet == "" || c.FPSet != delivery.FingerprintSet(c.Pulls) {
t.Errorf("fpset = %q, want %q", c.FPSet, delivery.FingerprintSet(c.Pulls))
}
// The same pull request heard again without its directories (the head unchanged) keeps what it had.
again := manifestPull(t, 301, h1, "")
again.Dirs, again.DirsKnown = nil, false
if err := ix.Apply(context.Background(), again); err != nil {
t.Fatal(err)
}
if c2 := candidateOf(t, ix.Store.(*memStore)); !reflect.DeepEqual(c2.Pulls[0].Fps["avahi"], want) || c2.FPSet != c.FPSet {
t.Errorf("after a message without directories: %+v fpset %q", c2.Pulls[0].Fps, c2.FPSet)
}
}
func TestAPullWithoutManifestsWritesTheCandidateAsToday(t *testing.T) { // 1451/AC2
ix, _, _ := manifestsIndexer(t, rec(t, "build-1", "avahi", catalogueRepo, "modules/avahi", "main", "", "2026-10-19T09:00:00Z", aInputs))
if err := ix.Apply(context.Background(), manifestPull(t, 301, h1, "")); err != nil {
t.Fatal(err)
}
c := candidateOf(t, ix.Store.(*memStore))
if len(c.Pulls) != 1 || c.Pulls[0].Fps != nil || c.FPSet != "" || len(c.Pulls[0].Modules) != 1 || c.Pulls[0].Modules[0] != "avahi" {
t.Errorf("candidate = %+v, want the module avahi and no Fps and no fpset", c)
}
}
func TestTwoPullsGivingOneModuleDifferentManifestsAreRefusedNamingBoth(t *testing.T) { // 1451/AC3
avahi := catalogueManifest(t, "avahi")
// The second pull request carries avahi's manifest changed (a line added at its end) for the same directory.
other := avahi + "\n"
ix, _, _ := manifestsIndexer(t, rec(t, "build-1", "avahi", catalogueRepo, "modules/avahi", "main", "", "2026-10-19T09:00:00Z", aInputs))
if err := ix.Apply(context.Background(), manifestPull(t, 301, h1, avahi)); err != nil {
t.Fatal(err)
}
before := candidateOf(t, ix.Store.(*memStore))
writes := ix.Store.(*memStore).writes
err := ix.Apply(context.Background(), manifestPull(t, 302, h2, other))
if !errors.Is(err, ErrUnreadable) {
t.Fatalf("err = %v, want a refusal", err)
}
for _, w := range []string{catalogueRepo + "#301", catalogueRepo + "#302", `"avahi"`} {
if !strings.Contains(err.Error(), w) {
t.Errorf("the refusal %q does not name %s", err, w)
}
}
// Candidate.check refuses the group too, which is what the refusal stands for.
if _, encErr := delivery.EncodeCandidate(delivery.Candidate{V: delivery.Version, Group: "feat.x", HeadsHash: before.HeadsHash, Pulls: []delivery.CandidatePull{before.Pulls[0], {
Head: delivery.Head{Repository: catalogueRepo, Number: 302, Head: h2}, Modules: []string{"avahi"},
Fps: map[string]delivery.CandidateModule{"avahi": {Manifest: delivery.ManifestDigest([]byte(other)), None2: NoneNoPreview}}}}}); encErr == nil {
t.Error("the candidate check accepts two manifests for one module")
}
if ix.Store.(*memStore).writes != writes {
t.Error("a partial write was made")
}
if after := candidateOf(t, ix.Store.(*memStore)); len(after.Pulls) != 1 || after.FPSet != before.FPSet {
t.Errorf("the candidate changed: %+v", after)
}
}