The switch to release 6 is today's controller's last plan, and the bus runs the user list it composes until the new controller writes one: so the new controller's writes of each node's compositions and their digests, each new node-engine's reads of its own compositions and wants and its backup holder's verbs and word, and the assigner's read of the digests must be granted by this controller already (ADR 0539 clauses 2, 6, 9 and 16; the review's A1).
61 lines
2.8 KiB
Go
61 lines
2.8 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.>"} {
|
|
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.*.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)
|
|
}
|
|
}
|