Files
mesh-controller/internal/inventory/mirrored_test.go
T
mesh-tools af267cb557 Take the catalogue from mesh-sdk in internal/inventory and internal/link, and keep the tests that read this repository's own manifest, Dockerfile and Makefile in internal/ownmanifest (issue 1381, 5 of 6 import swaps)
The three tests of the controller's own module.json (process, claimed seat, addresses), the Dockerfile and Makefile pin test, the build-agent registry test and the manifest-in-use seat test move with their old package, as tests of mesh-sdk's exported API; a moved test is exempt from failing first.
2026-10-20 08:27:10 +00:00

179 lines
6.3 KiB
Go

//go:build integration
package inventory
import (
"context"
"fmt"
"slices"
"strings"
"testing"
"git.novox.be/novox/mesh-sdk/go/catalogue"
)
// A base a build copies into the store is recorded where it is copied, and kept while a kept build stood
// on it (novox/hq ADR 0257).
func mirrorRef(repository string, n int) string {
return fmt.Sprintf("%s%s@sha256:%064x", catalogue.ArtifactStoreScheme, repository, n)
}
// builtOn records a successful build of a module that made one image and stood on these bases.
func builtOn(t *testing.T, inv *Inventory, id, module string, n int, mirrored []string, against ...string) {
t.Helper()
b := aBuild(id, module, "")
b.Made = []Artifact{{Name: "app", Kind: "image", Reference: ref(module, "app", n)}}
b.Against = against
b.Mirrored = mirrored
if err := inv.RecordBuild(context.Background(), b); err != nil {
t.Fatal(err)
}
}
func stateOf(t *testing.T, inv *Inventory, reference string) ArtifactState {
t.Helper()
states, err := inv.Artifacts(context.Background())
if err != nil {
t.Fatal(err)
}
for _, s := range states {
if s.Reference == reference {
return s
}
}
return ArtifactState{Reference: reference, State: "unrecorded"}
}
func TestACopyAFailedBuildMadeIsRecordedAndNothingKeepsIt(t *testing.T) {
inv := fresh(t)
golang := mirrorRef("upstream/docker.io/library/golang", 1)
failed := aBuild("f1", "", "the recipe fetched an undeclared image")
failed.Mirrored = []string{golang}
if err := inv.RecordBuild(context.Background(), failed); err != nil {
t.Fatal(err)
}
if s := stateOf(t, inv, golang); s.State != ArtifactEligible {
t.Fatalf("a copy only a failed build made reads %+v; want eligible", s)
}
}
func TestACopyIsKeptByTheKeptBuildsThatStoodOnItAndByNothingElse(t *testing.T) {
inv := fresh(t)
ctx := context.Background()
holding(t, inv, "proxy")
old := mirrorRef("upstream/docker.io/library/golang", 1)
current := mirrorRef("upstream/docker.io/library/golang", 2)
// The first build stood on the old copy; six more on the current one. The old copy falls out of
// the five kept builds; the current one is stood on by all five.
builtOn(t, inv, "b01", "proxy", 1, []string{old}, old)
for i := 2; i <= 7; i++ {
builtOn(t, inv, fmt.Sprintf("b%02d", i), "proxy", i, []string{current}, current)
}
if s := stateOf(t, inv, old); s.State != ArtifactEligible {
t.Fatalf("a copy no kept build stood on reads %+v", s)
}
if s := stateOf(t, inv, current); s.State != ArtifactKept || !slices.Equal(s.Why, []string{KeptStoodOn}) {
t.Fatalf("a copy the kept builds stood on reads %+v", s)
}
// A definition naming the image upstream, by the digest every copy shares, keeps no copy.
m := catalogue.Manifest{Module: "proxy", Version: "2",
Build: &catalogue.Build{On: []catalogue.BuildsOn{{Arg: "GO_BASE", Image: "golang@" + strings.SplitN(old, "@", 2)[1]}}}}
if err := inv.RegisterModule(ctx, m, Source{Repository: "https://forge.invalid/proxy.git"}); err != nil {
t.Fatal(err)
}
if s := stateOf(t, inv, old); s.State != ArtifactEligible {
t.Fatalf("a definition naming the upstream image kept the old copy: %+v", s)
}
go_, err := inv.ToCollect(ctx)
if err != nil {
t.Fatal(err)
}
if !slices.Contains(go_, old) || slices.Contains(go_, current) {
t.Fatalf("offered %v to collect", go_)
}
// Once let go of, a copy stays let go of, even should a kept build still name it.
if err := inv.MarkCollected(ctx, []string{current}); err != nil {
t.Fatal(err)
}
if s := stateOf(t, inv, current); s.State != ArtifactCollected {
t.Fatalf("a collected copy reads %+v", s)
}
}
func TestAModulesBaseIsNotKeptAsACopy(t *testing.T) {
// A base that is another module's artifact is kept by that module's own builds, as before: the
// stood-on reason is a copy's alone.
inv := fresh(t)
holding(t, inv, "app")
base := ref("go-base", "build", 1)
b := aBuild("g1", "go-base", "")
b.Made = []Artifact{{Name: "build", Kind: "image", Reference: base}}
if err := inv.RecordBuild(context.Background(), b); err != nil {
t.Fatal(err)
}
builtOn(t, inv, "a1", "app", 1, nil, base)
if s := stateOf(t, inv, base); s.State != ArtifactEligible {
t.Fatalf("a forgotten module's artifact read %+v because a build stood on it", s)
}
}
func TestAPersonRecordsACopyAndTheFirstRecordStands(t *testing.T) {
inv := fresh(t)
ctx := context.Background()
copyRef := mirrorRef("route-proxy/on-go_base", 3)
if err := inv.RecordMirrored(ctx, "", "copied before copies were recorded", []string{copyRef}); err != nil {
t.Fatal(err)
}
if err := inv.RecordMirrored(ctx, "b9", "", []string{copyRef}); err != nil {
t.Fatal(err)
}
known, err := inv.Mirrored(ctx)
if err != nil || !known[copyRef] {
t.Fatalf("recorded copies %v %v", known, err)
}
var why string
if err := inv.store.Pool().QueryRow(ctx, `select why from artifact_mirrored where reference = $1`, copyRef).Scan(&why); err != nil {
t.Fatal(err)
}
if why != "copied before copies were recorded" {
t.Fatalf("the first record did not stand: %q", why)
}
if s := stateOf(t, inv, copyRef); s.State != ArtifactEligible {
t.Fatalf("a copy a person recorded reads %+v", s)
}
}
// A copy let go of and copied again by a later build is held again: its record is back, and the sweep
// decides about it as before.
func TestACopyLetGoOfAndCopiedAgainIsHeldAgain(t *testing.T) {
inv := fresh(t)
ctx := context.Background()
holding(t, inv, "proxy")
golang := mirrorRef("upstream/docker.io/library/golang", 1)
builtOn(t, inv, "b01", "proxy", 1, []string{golang}, golang)
if err := inv.MarkCollected(ctx, []string{golang}); err != nil {
t.Fatal(err)
}
if s := stateOf(t, inv, golang); s.State != ArtifactCollected {
t.Fatalf("a let-go copy reads %+v", s)
}
builtOn(t, inv, "b02", "proxy", 2, []string{golang}, golang)
if s := stateOf(t, inv, golang); s.State != ArtifactKept || !slices.Equal(s.Why, []string{KeptStoodOn}) {
t.Fatalf("a copy copied again reads %+v; want kept again", s)
}
// A person's record never undoes a collection: only a build that copied it says it is there.
if err := inv.MarkCollected(ctx, []string{golang}); err != nil {
t.Fatal(err)
}
if err := inv.RecordMirrored(ctx, "", "again", []string{golang}); err != nil {
t.Fatal(err)
}
if s := stateOf(t, inv, golang); s.State != ArtifactCollected {
t.Fatalf("a person's record brought a collected copy back: %+v", s)
}
}