The controller follows the forge's merges (novox/hq 04-ISSUES/131). For each module recorded as built from that repository and branch it records the move to the merge commit and builds it — bases first, because a module built before the module it stands on is built against the old one and reports success, and a base that fails stops what stands on it. Nothing is pushed here: what a finished build does to the machines running the module stays the upgrade's decision. Two more things the same ordering gives: `build --behind` builds bases first, and `build --on <module>` rebuilds everything that stands on a module — the rebuild a changed base needs, which "behind" does not see because their sources did not move.
64 lines
2.3 KiB
Go
64 lines
2.3 KiB
Go
package main
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"github.com/novox/mesh-controller/internal/catalogue"
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
"github.com/novox/mesh-controller/internal/link"
|
|
)
|
|
|
|
func entry(module string, on ...string) inventory.Entry {
|
|
b := &catalogue.Build{}
|
|
for _, o := range on {
|
|
b.On = append(b.On, catalogue.BuildsOn{Arg: "X", Module: o, Artifact: "runtime"})
|
|
}
|
|
return inventory.Entry{Manifest: catalogue.Manifest{Module: module, Build: b}}
|
|
}
|
|
|
|
// 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", "runtime"), entry("runtime", "base"), entry("other"), entry("base")}
|
|
got := orderByBases(in)
|
|
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", "elsewhere")})
|
|
if len(got) != 1 {
|
|
t.Fatalf("a dependency outside the set changed the set: %v", got)
|
|
}
|
|
}
|
|
|
|
// 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)
|
|
}
|
|
}
|
|
}
|