controllerdeps refuses any manifest naming the controller's seat, states or buckets, the lease and the entries once kept to its write among them, and any module file naming one of its buckets (ADR 0590 §5). The words check refuses a controller address in any text a module shows. The handacts check and noplacement's list of assignments readers are folded into it (issue 1126 B10). Claude-Session: https://claude.ai/code/session_01NcbgfJ9Gum47zkFKWRaovL
62 lines
3.1 KiB
Go
62 lines
3.1 KiB
Go
package controllerdeps
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// ADR 0590 §5 (issue 1126 B10): no manifest of the catalogue at this head reads, invokes, consumes, waits on, uses or
|
|
// otherwise names the controller's seat, states or buckets, and no module's code names a bucket of the controller's.
|
|
func TestNothingInTheCatalogueNamesTheController(t *testing.T) {
|
|
got, err := Refusals("../..")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
for _, r := range got {
|
|
t.Error(r)
|
|
}
|
|
}
|
|
|
|
// The check refuses every name of the controller, the lease and the entries once kept to its write among them, on a
|
|
// tree of its own; a repository named mesh-controller (an issue's owner) and a word in prose are no dependency.
|
|
func TestRefusalsJudgeATree(t *testing.T) {
|
|
for _, row := range []struct {
|
|
name string
|
|
files map[string]string
|
|
want string // empty: passes
|
|
}{
|
|
{"the lease is refused like any read", map[string]string{"modules/a/module.json": `{"module":"a","reads":["mesh-controller.lease"]}`}, `a: names "mesh-controller.lease"`},
|
|
{"a verb once kept to the write", map[string]string{"modules/b/module.json": `{"module":"b","invokes":["seat:mesh-controller.collect"]}`}, `b: names "seat:mesh-controller.collect"`},
|
|
{"an event consumed", map[string]string{"modules/c/module.json": `{"module":"c","consumes":[{"event":"mesh-controller.artifacts-gone"}]}`}, "mesh-controller.artifacts-gone"},
|
|
{"a requirement", map[string]string{"modules/d/module.json": `{"module":"d","requires":[{"name":"x","from":"mesh-controller"}]}`}, `d: names "mesh-controller"`},
|
|
{"the controller's own module", map[string]string{"modules/mesh-controller/module.json": `{"module":"mesh-controller"}`}, "mesh-controller: the controller is no module of the catalogue"},
|
|
{"a bucket in code", map[string]string{"modules/e/cmd/e/main.go": "package main\nconst b = \"mesh-controller_assignments\"\n"}, "modules/e/cmd/e/main.go:2: names the controller's bucket"},
|
|
{"a bucket in a test is its data", map[string]string{"modules/e/cmd/e/main_test.go": "package main\n// mesh-controller_lease\n"}, ""},
|
|
{"a fixture copied from elsewhere", map[string]string{"modules/e/cmd/e/testdata/x.md": "mesh-controller_rollouts\n"}, ""},
|
|
{"an owner and prose pass", map[string]string{"modules/f/module.json": `{"module":"f","config":{"owners":{"default":["mesh-controller","mesh-controller modules/route-proxy"]}},"why":"the mesh-controller module is gone"}`}, ""},
|
|
{"the seat's successors pass", map[string]string{"modules/g/module.json": `{"module":"g","reads":["mesh-placement.placement"],"invokes":["seat:mesh-hand-acts.hand-act"]}`}, ""},
|
|
} {
|
|
t.Run(row.name, func(t *testing.T) {
|
|
root := t.TempDir()
|
|
for path, text := range row.files {
|
|
p := filepath.Join(root, path)
|
|
if err := os.MkdirAll(filepath.Dir(p), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(p, []byte(text), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
got, err := Refusals(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if joined := strings.Join(got, "\n"); (row.want == "") != (joined == "") || !strings.Contains(joined, row.want) {
|
|
t.Errorf("refusals %q, want %q", joined, row.want)
|
|
}
|
|
})
|
|
}
|
|
}
|