Under a module's own record (its manifest's, or its irreplaceable data's), every move waited for a person's push, even one that only changed a tools bundle: the database server stayed behind on ace on 2026-10-15 although its walk said it recreated none of its containers. ADR 0377 lets such a move roll out. A move is judged per machine against the build that machine was last sent: it goes when no container, mounted file, data path, data declaration, provider or (for a module with data) long-running process changes. A person's record, the bus and any move that cannot be judged still wait. The walk keeps per machine which way each recorded module went and why, says it in its note and log, and status names a machine behind with `push <node>` only for a move that waits.
83 lines
3.0 KiB
Go
83 lines
3.0 KiB
Go
package inventory
|
|
|
|
import (
|
|
"reflect"
|
|
"testing"
|
|
|
|
"github.com/novox/mesh-controller/internal/catalogue"
|
|
)
|
|
|
|
// novox/hq issue 259: a send keeps which build of each module it carried. A machine never sent
|
|
// anything, or sent with nothing recorded — before this was kept, or by hand — is not known, which
|
|
// is not the same as having been sent nothing.
|
|
func TestASendKeepsTheBuildsItCarried(t *testing.T) {
|
|
inv := ForTest(t)
|
|
ctx := t.Context()
|
|
node, err := inv.AddNode(ctx, "anchor")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if builds, known, err := inv.SentBuilds(ctx, "anchor"); err != nil || known || builds != nil {
|
|
t.Fatalf("a machine never sent anything has known builds %v (%v): %v", builds, known, err)
|
|
}
|
|
|
|
carried := map[string]string{"resolver": "abc123", "network": ""}
|
|
if err := inv.RecordSent(ctx, node.ID, "d1", carried); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
builds, known, err := inv.SentBuilds(ctx, "anchor")
|
|
if err != nil || !known || !reflect.DeepEqual(builds, carried) {
|
|
t.Fatalf("the builds sent were not kept: %v %v %v", builds, known, err)
|
|
}
|
|
|
|
// Sent with nothing carried: known, and empty.
|
|
if err := inv.RecordSent(ctx, node.ID, "d2", map[string]string{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if builds, known, err := inv.SentBuilds(ctx, "anchor"); err != nil || !known || len(builds) != 0 {
|
|
t.Fatalf("an empty send: %v %v %v", builds, known, err)
|
|
}
|
|
|
|
// Sent by hand: not known, and the digest still recorded.
|
|
if err := inv.RecordSent(ctx, node.ID, "d3", nil); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if builds, known, err := inv.SentBuilds(ctx, "anchor"); err != nil || known || builds != nil {
|
|
t.Fatalf("a send whose builds are not known read as %v %v: %v", builds, known, err)
|
|
}
|
|
if sent, err := inv.Outstanding(ctx, "anchor"); err != nil || sent != "d3" {
|
|
t.Fatalf("the digest was not recorded with it: %q %v", sent, err)
|
|
}
|
|
|
|
if _, known, err := inv.SentBuilds(ctx, "nobody"); err != nil || known {
|
|
t.Fatalf("a machine the mesh does not know: %v %v", known, err)
|
|
}
|
|
}
|
|
|
|
// A module's current build is the commit its manifest was read at, with its upgrade policy.
|
|
func TestTheCurrentBuildsAreTheCatalogues(t *testing.T) {
|
|
inv := ForTest(t)
|
|
ctx := t.Context()
|
|
if err := inv.RegisterModule(ctx, catalogue.Manifest{Module: "resolver", Version: "1"},
|
|
Source{Repository: "novox/mesh-catalog", BuiltFrom: "c1"}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := inv.RegisterModule(ctx, catalogue.Manifest{Module: "by-hand", Version: "1"}, Source{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := inv.SetUpgradeOf(ctx, "by-hand", Upgrade{RollOut: true}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
current, err := inv.CurrentBuilds(ctx)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
// Rolled out by default, one machine first and gated (novox/hq ADR 0236).
|
|
if got := current["resolver"]; got != (CurrentBuild{Commit: "c1", RollOut: true, From: catalogue.FromDefault}) {
|
|
t.Errorf("resolver is at %+v", got)
|
|
}
|
|
if got := current["by-hand"]; got != (CurrentBuild{RollOut: true, From: catalogue.FromPerson}) {
|
|
t.Errorf("a module with no source is at %+v", got)
|
|
}
|
|
}
|