catalogue: a module's own object bucket, its reader grant and a stream that keeps its history, so the knowledge base can keep its records on the bus (ADR 0592 §5, §6, §9)
Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
This commit is contained in:
@@ -0,0 +1,55 @@
|
||||
package catalogue
|
||||
|
||||
import (
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// A module declares its own object bucket and a stream that keeps its history (ADR 0592 §5, §6, §9): both are read with
|
||||
// their bounds, the bucket's grant names its readers through a trusted config value as a restricted stream's does, and
|
||||
// an unknown key in either is refused, not passed over.
|
||||
func TestAModuleDeclaresAnObjectBucketAndAHistoryStream(t *testing.T) {
|
||||
m, err := decodeForTest([]byte(`{"module":"mesh-knowledge","version":"1",` +
|
||||
`"streams":[{"name":"versions","events":["version.**"],"max-mib":2048,"retention":"history","grant":{"config":"readers","events":"{key}.**"}}],` +
|
||||
`"objects":[{"name":"sections","max-mib":4096,"grant":{"config":"readers"}},{"name":"own","max-mib":1}]}`))
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
s := m.Streams[0]
|
||||
if !s.KeepsHistory() || s.Days() != 0 || s.Cap() != 2048 {
|
||||
t.Fatalf("history stream read as %+v (days %d)", s, s.Days())
|
||||
}
|
||||
o, ok := m.ObjectsNamed("sections")
|
||||
if !ok || o.MaxMiB != 4096 || o.Grant == nil || o.Grant.Config != "readers" || o.Bucket(m.Module) != "mesh-knowledge_sections" {
|
||||
t.Fatalf("object bucket read as %+v", o)
|
||||
}
|
||||
readers := []any{map[string]any{"records": []any{"knowledge-web", "ace.mesh-view"}}}
|
||||
if !o.ObjectsReader(readers, "knowledge-web", "g14") || !o.ObjectsReader(readers, "mesh-view", "ace") ||
|
||||
o.ObjectsReader(readers, "mesh-view", "g14") || o.ObjectsReader(readers, "other", "ace") {
|
||||
t.Fatal("the bucket's grant does not name its readers as a restricted stream's does")
|
||||
}
|
||||
own, _ := m.ObjectsNamed("own")
|
||||
if own.ObjectsReader(readers, "knowledge-web", "g14") {
|
||||
t.Fatal("a bucket with no grant is read by another module")
|
||||
}
|
||||
for name, raw := range map[string]string{
|
||||
"bucket": `{"module":"x","version":"1","objects":[{"name":"a","max-mib":1,"max-age-days":3}]}`,
|
||||
"bucket grant": `{"module":"x","version":"1","objects":[{"name":"a","max-mib":1,"grant":{"config":"r","events":"{key}"}}]}`,
|
||||
} {
|
||||
if _, err := decodeStrictObjects(raw); err == nil || !strings.Contains(err.Error(), "object bucket") {
|
||||
t.Errorf("%s: an unknown key was not refused in the object bucket's words: %v", name, err)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func decodeStrictObjects(raw string) (Manifest, error) {
|
||||
m, err := decodeForTest([]byte(raw))
|
||||
if err == nil && m.SetAside() != "" {
|
||||
return m, errString(m.SetAside())
|
||||
}
|
||||
return m, err
|
||||
}
|
||||
|
||||
type errString string
|
||||
|
||||
func (e errString) Error() string { return string(e) }
|
||||
Reference in New Issue
Block a user