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:
@@ -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)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user