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).
87 lines
3.4 KiB
Go
87 lines
3.4 KiB
Go
package broker
|
|
|
|
import (
|
|
"slices"
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/announce"
|
|
)
|
|
|
|
// D3 (ADR 0495 clause 3, ADR 0513 §3; issue 1790): a reader's `reads` is granted where the owner announced the state
|
|
// readable, refused where it announced and did not, and granted as before where the owner announced nothing yet.
|
|
func TestAReadIsGrantedFromItsOwnersAnnouncement(t *testing.T) {
|
|
announced := map[string]announce.States{
|
|
"owner": {Module: "owner", States: []announce.State{{Name: "open", Readable: true}, {Name: "closed"}}},
|
|
}
|
|
granted, refused := ReadsAnnounced([]string{"owner.open", "owner.closed", "owner.unsaid", "quiet.any"}, announced)
|
|
if !slices.Equal(granted, []string{"owner.open", "quiet.any"}) || !slices.Equal(refused, []string{"owner.closed", "owner.unsaid"}) {
|
|
t.Fatalf("granted %v, refused %v", granted, refused)
|
|
}
|
|
r := Records{Announced: announced, Assigned: map[string][]Declared{"one": {{Module: "reader", Reads: granted,
|
|
ReadsRefused: refused}}}}
|
|
if got := NotAnnounced(r); !slices.Equal(got, []string{"quiet"}) {
|
|
t.Fatalf("not yet announced: %v", got)
|
|
}
|
|
}
|
|
|
|
// D1 (ADR 0495 clause 2): the controller announces every bucket of its own, and readable exactly the record mirrors (the
|
|
// declared packages the pacman module reads among them, ADR 0507 §5), the chain's buckets, the checks running and the
|
|
// plans building.
|
|
func TestTheControllerAnnouncesWhatItKeeps(t *testing.T) {
|
|
s := ControllerAnnouncement("novox")
|
|
if _, err := announce.Encode(s); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var readable []string
|
|
for _, k := range s.States {
|
|
if k.Readable {
|
|
readable = append(readable, k.Name)
|
|
}
|
|
}
|
|
want := []string{ChainBuilds, MirrorDeclaredConfig, MirrorPredefined, ChainRollouts,
|
|
MirrorAssignments, MirrorDeclaredPackages, ControllerGrants, ControllerComposed}
|
|
slices.Sort(want)
|
|
if !slices.Equal(readable, want) {
|
|
t.Fatalf("readable %v, want %v", readable, want)
|
|
}
|
|
for _, name := range []string{"lease", "calls", "states-announced", "merge-window"} {
|
|
if !s.Keeps(name) || s.Readable(name) {
|
|
t.Errorf("%s: kept %v, readable %v", name, s.Keeps(name), s.Readable(name))
|
|
}
|
|
}
|
|
perms, err := PermissionsFor(Principal{Kind: KindController})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !slices.Contains(perms.Publish, announce.Subject(ControllerSeat)) {
|
|
t.Fatal("the controller may not say what it keeps")
|
|
}
|
|
}
|
|
|
|
// D2: every account that keeps state may say so on its own subject, a process account included, and no other's.
|
|
func TestAnAccountKeepingStateMaySayWhatItKeeps(t *testing.T) {
|
|
keeper, err := PermissionsFor(Principal{Kind: KindModule, Node: "one", Module: "keeper", PasswordHash: "x",
|
|
State: []string{"things"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !slices.Contains(keeper.Publish, announce.Subject("keeper")) || slices.Contains(keeper.Publish, announce.Subject("other")) {
|
|
t.Fatalf("the keeper's announcement grants: %v", keeper.Publish)
|
|
}
|
|
process, err := PermissionsFor(Principal{Kind: KindProcess, Node: "one", Module: "keeper", Process: "send",
|
|
PasswordHash: "x", State: []string{"sends"}})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if !slices.Contains(process.Publish, announce.Subject("keeper")) {
|
|
t.Fatal("a process keeping state may not say what it keeps")
|
|
}
|
|
none, err := PermissionsFor(Principal{Kind: KindModule, Node: "one", Module: "stateless", PasswordHash: "x"})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if slices.Contains(none.Publish, announce.Subject("stateless")) {
|
|
t.Fatal("a module keeping nothing may say it keeps something")
|
|
}
|
|
}
|