Give a channel's verified sender back when the root-free judgement passes again, and say when it is dropped (issue 930)

A push composed during a failed judgement issued the router a membership without the verified sender and nothing composed it again, so every approval was refused. The self-check now issues it again within one run; a composition says which kind lost it and why.
This commit is contained in:
2026-10-16 17:42:23 +02:00
parent e231185572
commit b2e2bf0638
4 changed files with 330 additions and 13 deletions
@@ -0,0 +1,108 @@
package main
import (
"encoding/json"
"strings"
"testing"
"github.com/nats-io/nats.go"
"github.com/novox/mesh-controller/internal/broker"
)
func verifiedSenderRecords(free map[string]bool) (broker.Records, broker.Declared) {
tg := broker.Seat{Name: "channel", Scope: "mesh", Accepts: []string{"show"}, Kinded: true, Kind: "telegram",
DeclaredBy: "messenger", Capabilities: []string{"choice", "verified-sender"}}
router := broker.Declared{Module: "messenger", RunsAs: "messenger", Holds: []broker.Seat{{Name: "operator-channel",
Scope: "mesh", Accepts: []string{"ask"}}}, Uses: []broker.Seat{{Name: "channel", Scope: "mesh", Kinded: true,
DeclaredBy: "messenger"}}}
return broker.Records{Nodes: []string{"novox"}, RootFree: free, Assigned: map[string][]broker.Declared{
"novox": {router, {Module: "telegram", RunsAs: "telegram", Holds: []broker.Seat{tg}}}}}, router
}
type fakeBus struct {
last map[string][]byte
published map[string][]byte
}
func (f *fakeBus) get(node, module string) ([]byte, error) {
if b, ok := f.last[node+"/"+module]; ok {
return b, nil
}
return nil, nats.ErrMsgNotFound
}
func (f *fakeBus) put(node, module string, body []byte) error {
f.published[node+"/"+module] = body
f.last[node+"/"+module] = body
return nil
}
func hasVerified(t *testing.T, membership []byte) bool {
t.Helper()
var m broker.Membership
if err := json.Unmarshal(membership, &m); err != nil {
t.Fatal(err)
}
for _, k := range m.SeatTraffic.Kinds {
if k.Kind == "telegram" {
return strings.Contains(strings.Join(k.Capabilities, ","), "verified-sender")
}
}
t.Fatal("telegram not in the router's membership")
return false
}
// A membership composed while the judgement failed is issued again once it passes, with the verified sender
// (novox/hq issue 930); while it fails, nothing is given back (ADR 0259 §8).
func TestAMembershipThatLostItsVerifiedSenderGetsItBackWhenTheJudgementPasses(t *testing.T) {
failed, router := verifiedSenderRecords(nil)
whereFailed := broker.PlacementsOf(failed, nil)
bus := &fakeBus{last: map[string][]byte{}, published: map[string][]byte{}}
body, _ := json.Marshal(broker.MembershipFor("novox", router, whereFailed))
bus.last["novox/messenger"] = body
if hasVerified(t, body) {
t.Fatal("composed with a failed judgement, and the verified sender is kept")
}
say := func(string, ...any) {}
if n := reissueVerifiedSenders(failed, whereFailed, bus.get, bus.put, say); n != 0 || len(bus.published) != 0 {
t.Fatalf("issued %d while the judgement still fails", n)
}
passing, _ := verifiedSenderRecords(map[string]bool{"novox": true})
wherePassing := broker.PlacementsOf(passing, nil)
if n := reissueVerifiedSenders(passing, wherePassing, bus.get, bus.put, say); n != 1 {
t.Fatalf("issued %d memberships after the judgement passed, want 1", n)
}
if !hasVerified(t, bus.published["novox/messenger"]) {
t.Fatal("the membership issued again lacks the verified sender")
}
if n := reissueVerifiedSenders(passing, wherePassing, bus.get, bus.put, say); n != 0 {
t.Fatalf("issued %d again with nothing changed", n)
}
}
// What a composition drops it says, naming the kind, the machine and the judgement's reason.
func TestADroppedVerifiedSenderIsSaidWithItsReason(t *testing.T) {
records, _ := verifiedSenderRecords(nil)
where := broker.PlacementsOf(records, nil)
lines := droppedVerifiedSenders(records, where, map[string]string{"novox": "not measured: no verb heard"})
if len(lines) != 1 || !strings.Contains(lines[0], "telegram") || !strings.Contains(lines[0], "novox") ||
!strings.Contains(lines[0], "not measured: no verb heard") {
t.Fatalf("said %q", lines)
}
records, _ = verifiedSenderRecords(map[string]bool{"novox": true})
if lines := droppedVerifiedSenders(records, broker.PlacementsOf(records, nil), nil); len(lines) != 0 {
t.Fatalf("said %q of a kind that kept its verified sender", lines)
}
}
func TestAMembershipNeverIssuedIsLeftToItsOwnSend(t *testing.T) {
records, _ := verifiedSenderRecords(map[string]bool{"novox": true})
bus := &fakeBus{last: map[string][]byte{}, published: map[string][]byte{}}
var said []string
n := reissueVerifiedSenders(records, broker.PlacementsOf(records, nil), bus.get, bus.put,
func(f string, a ...any) { said = append(said, f) })
if n != 0 || len(said) != 0 {
t.Fatalf("issued %d, said %v", n, said)
}
}