Files
mesh-controller/internal/broker/cancelled_test.go
T
jochen 9873b3bf13 Keep a replay from moving the mesh backwards, and tighten the queue's edges (review of hq ADR 0219)
A registered replay asked now outranked newer asks of its module, and a plan
took any later outcome as its answer. A replay is now refused while the module
is asked anywhere, a plan module asked under an id is answered by that id
alone, and a rebuild of a commit asks what the module follows. An ask handed
back after a restart no longer reads as dead; a cancel that meets a start is
withdrawn; pause holds for an ask fetched as it lands; kill removes containers
before and after the build ends and says whether its outcome went out; a
holder may say only its own machine is paused.
2026-10-05 19:45:45 +02:00

74 lines
3.3 KiB
Go

package broker
import "testing"
// A build agent reads its seat's cancelled set by key and nothing more, answers its verbs on its own
// machine's subjects, and says whether it is paused under its own machine's name; the controller may
// ask any machine's holder its verbs (novox/hq ADR 0219).
func TestTheBuildQueueIsControlledWithTheGrantsItNeedsAndNoMore(t *testing.T) {
seat := Seat{Name: "node-build-agent", Scope: "node", Accepts: []string{"build"},
Emits: []string{"started", "built", "log.*", "paused.*"},
Serves: []string{"current", "kill", "pause", "resume"}}
holder, err := PermissionsFor(Principal{Kind: KindModule, Node: "ace", Module: "build-agent",
Holds: []Seat{seat}, PasswordHash: "x"})
if err != nil {
t.Fatal(err)
}
has(t, holder.Publish, "$JS.API.DIRECT.GET.KV_SEAT_NODE_BUILD_AGENT_cancelled.$KV.SEAT_NODE_BUILD_AGENT_cancelled.>")
hasNot(t, holder.Publish, "$KV.SEAT_NODE_BUILD_AGENT_cancelled.>")
has(t, holder.Publish, "mesh.seat.node-build-agent.event.paused.ace")
hasNot(t, holder.Publish, "mesh.seat.node-build-agent.event.paused.*")
has(t, holder.Publish, "mesh.seat.node-build-agent.event.log.*")
has(t, holder.Subscribe, "mesh.seat.node-build-agent.tool.kill.ace")
hasNot(t, holder.Subscribe, "mesh.seat.node-build-agent.tool.kill.g14")
// A module's own seat's queue is its own affair: no cancelled set, no grant for one.
other, _ := PermissionsFor(Principal{Kind: KindModule, Node: "ace", Module: "telegram",
Holds: []Seat{{Name: "telegram-sender", Accepts: []string{"send"}}}, PasswordHash: "x"})
hasNot(t, other.Publish, "$JS.API.DIRECT.GET.KV_SEAT_TELEGRAM_SENDER_cancelled.$KV.SEAT_TELEGRAM_SENDER_cancelled.>")
controller, _ := PermissionsFor(Principal{Kind: KindController, PasswordHash: "x"})
has(t, controller.Publish, "mesh.seat.node-build-agent.tool.>")
if CancelledSetName("node-build-agent") != "SEAT_NODE_BUILD_AGENT_cancelled" ||
!IsCancelledSet("SEAT_NODE_BUILD_AGENT_cancelled") || IsCancelledSet("build-agent_cancelled") {
t.Error("the cancelled set is not named as its seat's family")
}
}
// Only the work queues the controller asks get a cancelled set.
func TestOnlyTheControllersQueuesHaveACancelledSet(t *testing.T) {
var asserted []string
a := asserterFunc(func(seat string) error { asserted = append(asserted, seat); return nil })
if err := RaiseCancelledSets(a, []DeclaredSeat{
{Name: "node-build-agent", Accepts: []string{"build"}},
{Name: "telegram-sender", Accepts: []string{"send"}},
{Name: "mesh-controller"},
}); err != nil {
t.Fatal(err)
}
if len(asserted) != 1 || asserted[0] != "node-build-agent" {
t.Fatalf("asserted %v", asserted)
}
}
type asserterFunc func(string) error
func (f asserterFunc) EnsureCancelledSet(seat string) error { return f(seat) }
// A seat's cancelled set is never reported as state nothing declares.
func TestACancelledSetIsNotUndeclaredState(t *testing.T) {
undeclared, err := RaiseBuckets(fakeBuckets{names: []string{"SEAT_NODE_BUILD_AGENT_cancelled", "gone_state"}}, nil)
if err != nil {
t.Fatal(err)
}
if len(undeclared) != 1 || undeclared[0] != "gone_state" {
t.Fatalf("undeclared %v", undeclared)
}
}
type fakeBuckets struct{ names []string }
func (f fakeBuckets) EnsureBucket(Bucket) error { return nil }
func (f fakeBuckets) BucketNames() ([]string, error) { return f.names, nil }