A named push flushed every other machine whose declaration differed from what it was last sent (hq ADR 0083). Under an upgrade policy of `record`, or a plan still waiting on its first machine (ADR 0218), every machine running the module differs, so `push <one>` sent the held build to all of them (hq issue 259). Each send now records which build of each module it carried (node.sent_builds, migration 0061). The cascade, and the bus holder added to a named push, skip a machine any of whose modules would move to a build its policy records or an open plan has not sent it, and say which module, which build, why, and that `push <node>` sends it. A machine whose last send was not recorded is held until it is named. The named machine itself, a whole-mesh push and `push --behind` are unchanged.
82 lines
2.9 KiB
Go
82 lines
2.9 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)
|
|
}
|
|
if got := current["resolver"]; got != (CurrentBuild{Commit: "c1"}) {
|
|
t.Errorf("resolver is at %+v", got)
|
|
}
|
|
if got := current["by-hand"]; got != (CurrentBuild{RollOut: true}) {
|
|
t.Errorf("a module with no source is at %+v", got)
|
|
}
|
|
}
|