86 lines
3.1 KiB
Go
86 lines
3.1 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"testing"
|
|
"time"
|
|
|
|
"github.com/novox/mesh-controller/internal/catalogue"
|
|
snapshot "github.com/novox/mesh-controller/internal/facts"
|
|
"github.com/novox/mesh-controller/internal/inventory"
|
|
"github.com/novox/mesh-controller/internal/link"
|
|
)
|
|
|
|
// Issue 969: the gate composes a machine as the mesh does, so a moved module is handed where the machine takes
|
|
// handed files and composed the old way where it does not.
|
|
func TestIssue969TheGateGivesAMachineItsContractSoItTakesHandedFiles(t *testing.T) {
|
|
taken := time.Date(2026, 10, 16, 12, 0, 0, 0, time.UTC)
|
|
|
|
stated, ok := standInHealth(snapshot.Machine{Name: "f35", Contract: link.HandedContract}, taken)
|
|
if !ok || !takesHanded(stated, ok) {
|
|
t.Fatalf("a machine whose engine takes handed files must be given that in the gate: %+v, %v", stated, ok)
|
|
}
|
|
old, ok := standInHealth(snapshot.Machine{Name: "e12", Contract: link.HandedContract - 1}, taken)
|
|
if !ok || takesHanded(old, ok) {
|
|
t.Fatalf("a machine whose engine is older must not take handed files: %+v, %v", old, ok)
|
|
}
|
|
none, ok := standInHealth(snapshot.Machine{Name: "d01"}, taken)
|
|
if ok || takesHanded(none, ok) {
|
|
t.Fatalf("a snapshot that carries no contract states nothing: %+v, %v", none, ok)
|
|
}
|
|
}
|
|
|
|
// Issue 969, through the store: a machine whose engine stated the handed contract is in the snapshot with it, the
|
|
// gate raises it as taking handed files, and one whose statement is below it is raised as not taking them. Run in
|
|
// the merge check with the other tests that need a store; the composition itself, handed here and refused there, is
|
|
// the catalogue's TestAHandedModuleNamingARunTimeBoundKeyComposesOnlyWhereItIsHanded.
|
|
func TestIssue969TheGateRaisesEachMachineAsItsEngineStatedItself(t *testing.T) {
|
|
open := aMesh(t)
|
|
ctx := t.Context()
|
|
said := time.Date(2026, 10, 16, 12, 0, 0, 0, time.UTC)
|
|
for node, contract := range map[string]int{"anchor": link.HandedContract, "laptop": link.HandedContract - 1} {
|
|
if _, err := open.inventory.RecordHealth(ctx, inventory.NodeHealth{Node: node, Contract: contract,
|
|
SaidAt: said, HeardAt: said}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
f, err := gatherFacts(ctx, open, "2.11.17")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(f.Machines) != 2 {
|
|
t.Fatalf("the snapshot holds %d machines", len(f.Machines))
|
|
}
|
|
want := map[string]bool{}
|
|
for _, m := range f.Machines {
|
|
if m.Contract == 0 {
|
|
t.Fatalf("%s: the snapshot carries no contract", m.Name)
|
|
}
|
|
want[m.Name] = m.Contract >= link.HandedContract
|
|
}
|
|
handing := 0
|
|
for _, hands := range want {
|
|
if hands {
|
|
handing++
|
|
}
|
|
}
|
|
if handing != 1 {
|
|
t.Fatalf("one machine takes handed files in the snapshot, got %v", want)
|
|
}
|
|
|
|
raised, drop, err := throwawayStores(ctx, os.Getenv("MESH_TEST_POSTGRES"))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
defer drop()
|
|
if _, err := raiseFromFacts(ctx, raised, f, map[string]catalogue.Manifest{}, map[string]inventory.Source{}); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for name, hands := range want {
|
|
got, err := engineTakesHanded(ctx, raised.inventory, name)
|
|
if err != nil || got != hands {
|
|
t.Errorf("%s: the gate raises it as taking handed files = %v (%v), the mesh says %v", name, got, err, hands)
|
|
}
|
|
}
|
|
}
|