The new controller says its first start's deletions as an event, a node-engine hears only its backup holder, and the way back right after the switch, a want and a composition written at the terminal, runs on the user list today's controller composes (ADR 0539 clauses 2, 10 and 13). The operator is the administrator person, the one second writer ADR 0539 names.
87 lines
3.9 KiB
Go
87 lines
3.9 KiB
Go
package broker
|
|
|
|
import (
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/nats-io/nats.go/jetstream"
|
|
)
|
|
|
|
// 1945 (the review's A1): the bus's user list today's controller composes, which is the one the bus runs after release
|
|
// 6's switch, already grants every subject the new controller, every new node-engine and the assigner use: the
|
|
// controller writes each node's compositions and the digests; a node-engine reads its own compositions and wants, asks
|
|
// its own backup holder and hears its word, and nothing of another node's; the assigner reads the digests, announced
|
|
// readable.
|
|
func TestTheUserListBeforeTheSwitchGrantsWhatReleaseSixUses(t *testing.T) {
|
|
controller, err := PermissionsFor(Principal{Kind: KindController, PasswordHash: "x", FilesFor: []string{"ace", "g14"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, s := range []string{"$KV.composed-ace.>", "$KV.composed-g14.>", "$KV.mesh-controller_composed.>",
|
|
"mesh.seat.mesh-controller.event.bucket-deleted"} {
|
|
has(t, controller.Publish, s)
|
|
}
|
|
node, err := PermissionsFor(Principal{Kind: KindNode, Node: "ace", PasswordHash: "x"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, s := range []string{
|
|
"$JS.API.STREAM.INFO.KV_composed-ace", "$JS.API.DIRECT.GET.KV_composed-ace.>", "$JS.API.CONSUMER.CREATE.KV_composed-ace.>",
|
|
"$JS.API.DIRECT.GET.KV_mesh-delivery-assigner_wants.$KV.mesh-delivery-assigner_wants.want.ace.>",
|
|
"$JS.API.CONSUMER.CREATE.KV_mesh-delivery-assigner_wants.*.$KV.mesh-delivery-assigner_wants.want.ace.>",
|
|
"mesh.seat.node-backup.tool.now.ace", "mesh.seat.node-backup.tool.backed-up.ace",
|
|
} {
|
|
has(t, node.Publish, s)
|
|
}
|
|
has(t, node.Subscribe, "mesh.mod.restic.event.backed-up")
|
|
for _, p := range node.Publish {
|
|
if strings.Contains(p, "composed-g14") || strings.Contains(p, "mesh-controller_composed") || strings.Contains(p, "want.g14") ||
|
|
strings.HasPrefix(p, "$KV.composed-") || strings.HasSuffix(p, "node-backup.tool.now.*") {
|
|
t.Errorf("a node-engine of ace may publish %s", p)
|
|
}
|
|
}
|
|
if !slices.Contains(controllerReadableStates(), ControllerComposed) ||
|
|
!slices.Contains(ControllerBuckets(), ControllerComposedBucket) || !IsControllerBucket(ControllerComposedBucket) {
|
|
t.Fatalf("the digests are not announced readable among the controller's buckets")
|
|
}
|
|
if !ControllerAnnouncement("novox").Readable(ControllerComposed) {
|
|
t.Fatalf("the controller does not announce %s readable", ControllerComposed)
|
|
}
|
|
assigner, err := PermissionsFor(Principal{Kind: KindModule, Node: "novox", Module: "mesh-delivery-assigner", PasswordHash: "x",
|
|
Reads: []string{"mesh-controller.composed"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
has(t, assigner.Publish, "$JS.API.STREAM.INFO.KV_mesh-controller_composed")
|
|
has(t, assigner.Publish, "$JS.API.CONSUMER.CREATE.KV_mesh-controller_composed.>")
|
|
if c := ComposedDigestsConfig(); c.Bucket != "mesh-controller_composed" || c.History != 5 || c.Storage != jetstream.FileStorage {
|
|
t.Errorf("the digests' bucket is %+v", c)
|
|
}
|
|
}
|
|
|
|
// 1945 (the review of A1, (b)): the operator's account, a person who may invoke every tool, writes release 6's hand
|
|
// path: a want of any node, each node's compositions and the digests; a person with fewer tools writes none of it.
|
|
func TestTheOperatorWritesTheHandPathAheadOfTheSwitch(t *testing.T) {
|
|
users, err := Users(Records{Nodes: []string{"ace", "novox"}, People: map[string][]string{"jochen": {"*"}, "guest": {"mesh-controller.status"}}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, u := range users {
|
|
if u.Kind != KindPerson {
|
|
continue
|
|
}
|
|
perms, err := PermissionsFor(u)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
hand := []string{"$KV.mesh-delivery-assigner_wants.want.>", "$KV.composed-ace.>", "$KV.composed-novox.>",
|
|
"$KV.mesh-controller_composed.>", "$O.declaration-files-ace.>"}
|
|
for _, s := range hand {
|
|
if got := slices.Contains(perms.Publish, s); got != (u.Module == "jochen") {
|
|
t.Errorf("%s may publish %s: %v", u.Module, s, got)
|
|
}
|
|
}
|
|
}
|
|
}
|