Files
mesh-delivery/modules/mesh-delivery-indexer/judge/objects_test.go
T
jschoubben 2e91f0b061 Fold the release's new tests into existing ones to stay within the test budget
mesh-delivery is over its budget (810 unit, 73 integration on main), so this
branch adds none net: its new cases are subtests, the three work-queue process
tests and the consumes test become one, the history stream bounds join the
stream values table, and the go/-only mesh-sdk merge check joins the one new
integration test. buildrun's 20 unit and 1 integration tests moved in from
mesh-sdk with it.

Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
2026-11-02 18:40:57 +01:00

79 lines
3.5 KiB
Go

package judge
import (
"strings"
"testing"
"git.novox.be/novox/mesh-sdk/go/catalogue"
)
// knowledge is mesh-knowledge's manifest as ADR 0592 has it: an object bucket granted by its trusted value readers (a
// trusted file takes it), and
// two streams that keep their history.
const knowledge = `{"module":"mesh-knowledge","version":"1",
"resources":[{"id":"state","type":"directory","mode":"0700","place":"."},
{"id":"readers","trusted":true,"type":"file","path":"${dir:state}/readers.json","mode":"0600",
"merge":"json","takes-settings":["readers"],"content":"{\"readers\": {}}"}],
"objects":[{"name":"sections","max-mib":2048,"grant":{"config":"readers"}}],
"streams":[{"name":"versions","retention":"history","max-mib":4096,"events":["version.stored"]},
{"name":"reviews","retention":"history","events":["review.stored"]}]}`
// ADR 0592 §5, §6, §9, §25: a module's own object bucket and a stream that keeps its history are taken as declared (the
// history stream's bounds are in TestAWorkQueueStreamsValuesAreBounded); each bound and form of a bucket is refused, a
// bucket's name has one owner on the bus, and a module reads another's bucket only where the owner grants it.
func TestObjectBucketsAreJudgedAsADR0592Says(t *testing.T) {
if _, err := ParseManifest([]byte(knowledge)); err != nil {
t.Fatalf("mesh-knowledge's manifest was refused: %v", err)
}
for _, c := range []struct{ change, want string }{
{`"max-mib":2048,"grant"`, `"max-mib":0,"grant"`}, // no size: there is no default
{`"max-mib":2048,"grant"`, `"max-mib":8193,"grant"`}, // over the bound
{`"name":"sections"`, `"name":"Sections"`}, // not a plain local name
{`"name":"sections"`, `"name":"sections"},{"name":"sections","max-mib":1`}, // one bucket per name
{`"grant":{"config":"readers"}`, `"grant":{"config":"nobody"}`}, // a grant not by a trusted value
} {
raw := strings.Replace(knowledge, c.change, c.want, 1)
if raw == knowledge {
t.Fatalf("the change %q found nothing to change", c.change)
}
if _, err := ParseManifest([]byte(raw)); err == nil {
t.Errorf("%s was taken", c.want)
}
}
// A bucket whose name on the bus starts with what the mesh derives names with is refused.
if _, err := ParseManifest([]byte(`{"module":"kv","version":"1","objects":[{"name":"x","max-mib":1}]}`)); err == nil ||
!strings.Contains(err.Error(), "KV_") {
t.Errorf("a bucket kv_x was taken: %v", err)
}
parse := func(raw string) catalogue.Manifest {
t.Helper()
m, err := ParseManifest([]byte(raw))
if err != nil {
t.Fatal(err)
}
return m
}
owner := parse(knowledge)
reader := parse(`{"module":"records-page","version":"1","reads":["mesh-knowledge.sections"]}`)
shelf := catalogue.Shelf{"mesh-knowledge": owner, "records-page": reader}
if p := objectProblemsOf(CatalogueProblems(shelf)); len(p) > 0 {
t.Fatalf("a granted read was refused: %v", p)
}
ungranted := parse(strings.Replace(knowledge, `,"grant":{"config":"readers"}`, "", 1))
shelf["mesh-knowledge"] = ungranted
if p := objectProblemsOf(CatalogueProblems(shelf)); len(p) != 1 || !strings.Contains(p[0], "records-page") {
t.Errorf("a read of a bucket its owner grants nobody: %v", p)
}
}
// objectProblemsOf are the problems that name an object bucket or a history stream.
func objectProblemsOf(all []string) []string {
var out []string
for _, p := range all {
if strings.Contains(p, "object bucket") || strings.Contains(p, "history") {
out = append(out, p)
}
}
return out
}