Bases reach a recipe as build arguments, so the digest was never in the file the builder read edges from: no build on the mesh recorded what it stood on, and 'build --on', the bases-first order and the merge follow-up all walked a graph with no edges (novox/hq 04-ISSUES/131). The builder now reports every base it resolved; the controller records them by artifact path and reads the newest build's edges from the store, since a recorded manifest carries no build.on.
93 lines
3.6 KiB
Go
93 lines
3.6 KiB
Go
package main
|
|
|
|
import (
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/novox/mesh-controller/internal/catalogue"
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
"github.com/novox/mesh-controller/internal/link"
|
|
)
|
|
|
|
// entry is a module as the catalogue holds it: built, so its manifest carries no `build` any more.
|
|
func entry(module string, _ ...string) inventory.Entry {
|
|
return inventory.Entry{Manifest: catalogue.Manifest{Module: module}}
|
|
}
|
|
|
|
// stoodOn is what each module's newest build recorded it was handed.
|
|
func stoodOn(edges map[string][]string) map[string][]string {
|
|
out := map[string][]string{}
|
|
for module, bases := range edges {
|
|
for _, b := range bases {
|
|
out[module] = append(out[module], catalogue.ArtifactStoreScheme+b+"/runtime@sha256:"+strings.Repeat("0", 64))
|
|
}
|
|
}
|
|
return out
|
|
}
|
|
|
|
// A module built before the module it stands on is built against the old one and reports success
|
|
// (novox/hq 04-ISSUES/131). So bases come first, however the set arrived.
|
|
func TestBasesAreBuiltBeforeWhatStandsOnThem(t *testing.T) {
|
|
in := []inventory.Entry{entry("app"), entry("runtime"), entry("other"), entry("base")}
|
|
edges := stoodOn(map[string][]string{"app": {"runtime"}, "runtime": {"base"}})
|
|
got := orderByBases(in, edges)
|
|
pos := map[string]int{}
|
|
for i, e := range got {
|
|
pos[e.Manifest.Module] = i
|
|
}
|
|
if !(pos["base"] < pos["runtime"] && pos["runtime"] < pos["app"]) {
|
|
t.Fatalf("bases not first: %v", pos)
|
|
}
|
|
if len(got) != 4 {
|
|
t.Fatalf("an entry was lost or doubled: %d", len(got))
|
|
}
|
|
// A base outside the set is not waited for: it is not being rebuilt.
|
|
got = orderByBases([]inventory.Entry{entry("app")}, stoodOn(map[string][]string{"app": {"elsewhere"}}))
|
|
if len(got) != 1 {
|
|
t.Fatalf("a dependency outside the set changed the set: %v", got)
|
|
}
|
|
}
|
|
|
|
// A module registered from its manifest and never built still names its bases there; once built,
|
|
// the recorded edge is what says so. Both are read, and a module never stands on itself.
|
|
func TestWhatStandsOnAModuleIsReadFromItsBuildOrItsManifest(t *testing.T) {
|
|
built := entry("gitea")
|
|
edges := stoodOn(map[string][]string{"gitea": {"mesh-tools"}})
|
|
if !standsOnModule(built, "mesh-tools", edges) {
|
|
t.Fatal("a recorded edge was not read")
|
|
}
|
|
if standsOnModule(built, "gitea", edges) || standsOnModule(built, "postgres", edges) {
|
|
t.Fatal("an edge was invented")
|
|
}
|
|
fresh := inventory.Entry{Manifest: catalogue.Manifest{Module: "plex", Build: &catalogue.Build{
|
|
On: []catalogue.BuildsOn{{Arg: "RUNTIME_BASE", Module: "mesh-tools", Artifact: "runtime"}},
|
|
}}}
|
|
if !standsOnModule(fresh, "mesh-tools", nil) {
|
|
t.Fatal("a manifest's own base was not read")
|
|
}
|
|
}
|
|
|
|
// A merge names a repository the way the forge does; a source is recorded the way a build was
|
|
// asked for. The two meet on owner/repo and branch, whichever form the record took.
|
|
func TestAMergeMatchesTheSourcesBuiltFromIt(t *testing.T) {
|
|
m := link.SourceMoved{Owner: "novox", Repo: "mesh-controller", Base: "main",
|
|
CloneURL: "http://forge.internal:20000/novox/mesh-controller.git"}
|
|
for _, s := range []inventory.Source{
|
|
{Repository: "http://forge.internal:20000/novox/mesh-controller.git", Ref: "main"},
|
|
{Repository: "novox/mesh-controller", Seat: "git", Ref: ""},
|
|
{Repository: "https://elsewhere.example/novox/mesh-controller", Ref: "main"},
|
|
} {
|
|
if !sourceIs(s, m) {
|
|
t.Errorf("%+v was not matched by the merge", s)
|
|
}
|
|
}
|
|
for _, s := range []inventory.Source{
|
|
{Repository: "novox/mesh-host", Seat: "git"},
|
|
{Repository: "http://forge.internal:20000/novox/mesh-controller.git", Ref: "release"},
|
|
} {
|
|
if sourceIs(s, m) {
|
|
t.Errorf("%+v was matched by a merge that is not its", s)
|
|
}
|
|
}
|
|
}
|