The node-engine composes seat passes with the SDK's one rule instead of its own copy (issue 1966, ADR 0660)

Claude-Session: https://claude.ai/code/session_01NcbgfFfQ4Z9UE5jK32PmE5
This commit is contained in:
2026-11-08 15:31:32 +01:00
parent 875b4ee5ce
commit 5108c28e22
4 changed files with 40 additions and 159 deletions
+37 -2
View File
@@ -6,7 +6,6 @@ import (
"git.novox.be/novox/mesh-networking/modules/mesh-wireguard/go/overlay"
"git.novox.be/novox/mesh-sdk/go/catalogue"
"github.com/novox/mesh-host/internal/compose/resolution"
)
// objects and files are the provider and consumer of mesh-controller's facts_test.go aMeshWithSecrets (cmd/mesh-controller at
@@ -186,7 +185,7 @@ func TestAHolderAssignedButNotOnTheShelfIsNotTakenForGone(t *testing.T) {
withSeat(t)
as := assignmentsOf(map[string]catalogue.Manifest{"gate": aBrokerClaiming("gate")},
map[string][]string{"novox": {"gate", "old-broker"}})
passes, _ := resolution.SeatsToPassOn(
passes, _ := catalogue.SeatsToPassOn(
[]catalogue.Held{{Claim: "mesh-broker", Scope: catalogue.ScopeMesh, Node: "novox", Module: "old-broker"}}, as)
if len(passes) != 0 {
t.Fatalf("a holder missing from the shelf lost its seat: %+v", passes)
@@ -230,3 +229,39 @@ func TestEachNodeIsResolvedWithItsOwnPinsInTheRestOfTheMesh(t *testing.T) {
t.Fatalf("a pin to a provider that does not answer did not leave the consumer out: %v %v", left, err)
}
}
// ADR 0660: a holder on record that is still assigned, whose manifest no longer claims the seat, has left it; the seat is
// composed with the one claimant, the pass is returned and said, and Input's holdings (the record) are not written.
func TestAHolderWhoseManifestDroppedTheSeatGoesToItsOnlyClaimant(t *testing.T) {
withSeat(t)
mk := func(claimants ...string) Input {
cat := map[string]catalogue.Manifest{"old-broker": {Module: "old-broker"}}
assigned := []string{"old-broker"}
for _, c := range claimants {
cat[c] = aBrokerClaiming(c)
assigned = append(assigned, c)
}
return Input{Catalogue: cat,
Nodes: []Node{{Name: "novox", Place: Place{Site: "here"}, Assigned: assigned}},
Holdings: []catalogue.Held{{Claim: "mesh-broker", Scope: catalogue.ScopeMesh, Node: "novox", Module: "old-broker", Site: "here"}}}
}
in := mk("gate")
w, passes, _, err := TheRestOfTheMesh(in, "")
if err != nil || len(passes.Passes) != 1 || passes.Passes[0].To.Module != "gate" || passes.Passes[0].From.Module != "old-broker" {
t.Fatalf("%v %+v", err, passes)
}
if len(w.Holdings) != 1 || w.Holdings[0].Module != "gate" {
t.Fatalf("the composition does not hold the pass: %+v", w.Holdings)
}
unchanged(t, func() Input { return mk("gate") }, func(in Input) {
if _, _, _, err := TheRestOfTheMesh(in, ""); err != nil {
t.Fatal(err)
}
})
_, passes, _, err = TheRestOfTheMesh(mk("gate", "other"), "")
said := strings.Join(passes.Said, "\n")
if err != nil || len(passes.Passes) != 0 || !strings.Contains(said, "gate") || !strings.Contains(said, "other") ||
!strings.Contains(said, "seat mesh-broker --to <node>/<module>") {
t.Fatalf("two claimants: %v %+v", err, passes)
}
}