With no plan left to take a done key in, a write of the builder's keys registers the new fingerprint, composes the module's nodes and the bus's user list, and writes its grant, so the assigner's rules can name it (ADR 0539 clauses 5 and 7). The new controller composes every node at its start, and the controller it replaced at its own fingerprint, the operator's way back (clause 10); the merge window's, silent sends' and building plans' buckets are no longer asserted and are deleted once, each said as the event bucket-deleted (clause 13). The assigner may read the compositions' digests, and a node-engine hears its backup holder's backed-up.
93 lines
3.7 KiB
Go
93 lines
3.7 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"} {
|
|
if !s.Keeps(name) || s.Readable(name) {
|
|
t.Errorf("%s: kept %v, readable %v", name, s.Keeps(name), s.Readable(name))
|
|
}
|
|
}
|
|
// The buckets of plan state release 6 deleted are no longer kept (ADR 0539 clause 13).
|
|
for _, name := range []string{"merge-window", "rollout-silent", "plans-building"} {
|
|
if s.Keeps(name) {
|
|
t.Errorf("%s is still kept", 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")
|
|
}
|
|
}
|