Main reverted G's half merge (#189, reverted by8afc3ebin #191) and then took the reader release's S1-S5, which copied G's code. G's form holds where they differ (process_bus.go, seats.go, state.go and their tests); the release's kept names stay so main's callers keep building: SeatViewPrefix beside SeatReadPrefix, and QueueInvoke's empty strings on not-ok (with its test TestQueueInvoke). The tree differs from G's headf30dee54only by those and the release's two tests (objects cap option, seat states and stream kinds). Builds: design 47 G (the milestone's sdk part, as atf30dee54) Claude-Session: https://claude.ai/code/session_01NcbgfGKaxw984XyAPfLm4h
53 lines
2.6 KiB
Go
53 lines
2.6 KiB
Go
package buscompose
|
|
|
|
import (
|
|
"testing"
|
|
|
|
"git.novox.be/novox/mesh-sdk/go/membership"
|
|
"git.novox.be/novox/mesh-sdk/go/seatdef"
|
|
)
|
|
|
|
// The names this package keeps for the grants part's composer (mesh-grants internal/buscompose, ADR 0593 §1) agree with
|
|
// what the runtime reads: the memberships bucket, and a log's stream and subject.
|
|
func TestTheBusNamesAgree(t *testing.T) {
|
|
if GrantsMembershipsBucket != membership.GrantsBucket {
|
|
t.Fatalf("the memberships bucket is %q here and %q in membership", GrantsMembershipsBucket, membership.GrantsBucket)
|
|
}
|
|
if MembershipKey("ace", "netcheck") != "ace.netcheck" {
|
|
t.Fatal("a membership's key is not <node>.<module>")
|
|
}
|
|
if LogStreamName("mesh-delivery-builder", "build-log") == "" || LogSubject("mesh-delivery-builder", "build-log") == "" {
|
|
t.Fatal("a log has no stream or subject")
|
|
}
|
|
// 1966/AC20: a ledger's history and snapshot subjects are one contract, which the grants part grants a ledger
|
|
// account its publish on.
|
|
if h, sn := LedgerHistorySubject("m", "records"), LedgerSnapshotSubject("m", "records"); h != "mesh.ledger.m.records.history" ||
|
|
sn != "mesh.ledger.m.records.snapshot" {
|
|
t.Fatalf("a ledger's subjects are %q and %q", h, sn)
|
|
}
|
|
// 1966/AC23: a ledger account for m on a is named ledger.a.m.
|
|
if got := (Principal{Kind: KindLedger, Node: "a", Module: "m"}).Username(); got != "ledger.a.m" {
|
|
t.Fatalf("a ledger account is named %q", got)
|
|
}
|
|
// G §469: a state's bucket is capped at its max-mib; naming none is unbounded.
|
|
if (Bucket{}).MaxBytes() != -1 || (Bucket{MaxMiB: 2}).MaxBytes() != 2<<20 {
|
|
t.Fatal("a bucket's cap is not its max-mib in bytes")
|
|
}
|
|
// Design 46 7-approval-mark §5: a stream's local event pattern as the bus spells it.
|
|
for local, wire := range map[string]string{"mail.**": "mail.>", "mail.*.message": "mail.*.message", "sent": "sent"} {
|
|
if got := WirePattern(local); got != wire {
|
|
t.Errorf("WirePattern(%q) = %q, want %q", local, got, wire)
|
|
}
|
|
}
|
|
// Design 46 7-approval-mark §13: a per-machine state reaches its machine's key and the keys below it, no other machine's.
|
|
if got := PerMachineKeys("ace"); len(got) != 2 || got[0] != "ace" || got[1] != "ace.>" {
|
|
t.Errorf("a per-machine state reaches %v on ace", got)
|
|
}
|
|
// A seat's family is the shared events stream filtered to its subjects: a definition says the stream's age.
|
|
for _, st := range MeshStreams() {
|
|
if st.Name == EventsStream && int64(st.MaxAge) != seatdef.SharedEventsMaxAgeDays*24*60*60 {
|
|
t.Errorf("the shared events stream keeps %d s, a seat's definition says %d days", st.MaxAge, seatdef.SharedEventsMaxAgeDays)
|
|
}
|
|
}
|
|
}
|