Merge pull request 'Phase 5 (4/4): replay issues 263 and 273 (hq ADR 0237)' (#98) from feat/replays into main
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
mesh/delivery held for a person: merged without a passing check: only a person decides that it goes on
This commit was merged in pull request #98.
This commit is contained in:
@@ -0,0 +1,113 @@
|
||||
package main
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/novox/mesh-controller/internal/catalogue"
|
||||
)
|
||||
|
||||
// The replays of the controller's incidents (novox/hq to-be 45 §9, M9): each a scripted replay of what
|
||||
// happened, asserting the rule's outcome rather than the fix's mechanism, so it can be run against the
|
||||
// commit before the fix and fail there, and against the fix and pass. **Written only with what the
|
||||
// controller had before each fix** — the stores, register, assign, planFor, declarationFor — so the
|
||||
// prover (mesh-lab replays/cmd/prove) can lay this file over the older commit and run it there.
|
||||
//
|
||||
// Registered in mesh-lab's replays/register.go with the fix each one proves; run by this repository's
|
||||
// merge check on every pull request with the rest of the suite.
|
||||
|
||||
// **R263 — a consumer's identity never refuses its provider's machine.** On 2026-10-06 the network
|
||||
// manager came to require the mesh's resolver; on a machine whose name made its identity 23 to 26
|
||||
// characters against the one global bound of 20, the anchor — the resolver's holder, carrying every
|
||||
// consumer's grant — could not compose, and no push to it could go through. The outcome asserted: the
|
||||
// provider's machine composes whatever its consumers are called, and a provision that mints no
|
||||
// credential holds no consumer to a key's length.
|
||||
func TestReplay263AnIdentityTooLongNeverRefusesItsProvidersMachine(t *testing.T) {
|
||||
open := aMesh(t)
|
||||
ctx := t.Context()
|
||||
register(t, open, catalogue.Manifest{Module: "resolver", Version: "1",
|
||||
Provides: []catalogue.Offer{{Name: "wildcard-resolution", Scope: catalogue.ScopeMesh}}})
|
||||
register(t, open, catalogue.Manifest{Module: "networkmanager", Version: "1",
|
||||
Requires: []string{"wildcard-resolution"}})
|
||||
for _, a := range [][2]string{{"anchor", "resolver"}, {"laptop", "networkmanager"}} {
|
||||
if _, err := assign(ctx, open, a[0], a[1]); err != nil {
|
||||
t.Fatalf("assign %s %s: %v", a[0], a[1], err)
|
||||
}
|
||||
}
|
||||
// The consumer's machine composes first, as a push does: what it is sent is what its provider grants.
|
||||
for _, node := range []string{"laptop", "anchor"} {
|
||||
plan, settings, err := planFor(ctx, open, node)
|
||||
if err != nil {
|
||||
t.Fatalf("%s does not resolve: %v", node, err)
|
||||
}
|
||||
if _, err := declarationFor(ctx, open, node, plan, settings); err != nil {
|
||||
t.Fatalf("%s cannot be sent anything — the consumer networkmanager on laptop, identified "+
|
||||
"mesh_laptop_networkmanager (26 characters), refused it: %v", node, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// **R273 — a binding to a consumer's data does not move by itself.** On 2026-10-05 a rule written for
|
||||
// the resolver re-bound every database consumer on the home server — which runs its own store, beside
|
||||
// its applications' data — to the store seat's holder on the control node, which made each a new empty
|
||||
// database; five applications ran on empty data for twenty hours. The outcome asserted: a consumer on a
|
||||
// machine running its own store stays bound to it while another machine holds the store's seat; the
|
||||
// resolver, which every holder answers alike, follows its seat.
|
||||
func TestReplay273AConsumerBesideItsStoreStaysBoundToIt(t *testing.T) {
|
||||
open := aMesh(t)
|
||||
ctx := t.Context()
|
||||
inv := open.inventory
|
||||
if _, err := inv.SeedSeats(ctx, catalogue.DefaultSeats()); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
for _, m := range []catalogue.Manifest{
|
||||
{Module: "store", Version: "1",
|
||||
Provides: []catalogue.Offer{{Name: "postgres-database", Scope: catalogue.ScopeMesh}},
|
||||
Claims: []catalogue.Claim{{Name: "mesh-store", Scope: catalogue.ScopeMesh}},
|
||||
Serves: map[string]map[string]any{"postgres-database": {"port": 5432}},
|
||||
Grants: map[string]string{"postgres-database": "/var/lib/mesh/store/grants"}},
|
||||
{Module: "resolver", Version: "1",
|
||||
Provides: []catalogue.Offer{{Name: "wildcard-resolution", Scope: catalogue.ScopeMesh}},
|
||||
Claims: []catalogue.Claim{{Name: "mesh-dns-resolver", Scope: catalogue.ScopeMesh}}},
|
||||
{Module: "network", Version: "1", Requires: []string{"wildcard-resolution"}},
|
||||
{Module: "board", Version: "1", Requires: []string{"postgres-database"}},
|
||||
} {
|
||||
register(t, open, m)
|
||||
}
|
||||
assignAll := func(pairs ...[2]string) {
|
||||
for _, a := range pairs {
|
||||
if _, err := assign(ctx, open, a[0], a[1]); err != nil {
|
||||
t.Fatalf("assign %s %s: %v", a[0], a[1], err)
|
||||
}
|
||||
}
|
||||
}
|
||||
// The control node holds the mesh's store and resolver seats; the home server runs its own of each.
|
||||
assignAll([2]string{"anchor", "store"}, [2]string{"anchor", "resolver"})
|
||||
for _, seat := range [][2]string{{"mesh-store", "store"}, {"mesh-dns-resolver", "resolver"}} {
|
||||
if err := inv.HoldSeat(ctx, seat[0], catalogue.ScopeMesh, "anchor", seat[1]); err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
}
|
||||
assignAll([2]string{"laptop", "store"}, [2]string{"laptop", "resolver"}, [2]string{"laptop", "network"},
|
||||
[2]string{"laptop", "board"})
|
||||
|
||||
plan, _, err := planFor(ctx, open, "laptop")
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var board, network string
|
||||
for _, n := range plan.Needs {
|
||||
switch {
|
||||
case n.For == "board" && n.Name == "postgres-database":
|
||||
board = n.From
|
||||
case n.For == "network" && n.Name == "wildcard-resolution":
|
||||
network = n.From
|
||||
}
|
||||
}
|
||||
if board != "laptop" {
|
||||
t.Fatalf("the consumer beside its store was bound to the store on %q, which would make it a new, empty "+
|
||||
"database there (issue 273)", board)
|
||||
}
|
||||
if network != "anchor" {
|
||||
t.Fatalf("the resolver was bound to %q; its seat is held on anchor (issue 258)", network)
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user