Files
mesh-controller/internal/catalogue/collections_test.go
T
mesh-tools 97a2d841c7 Land feature 57's controller work on its release branch
The controller plans config, templates and moved providers' provisions,
hands bus accounts to the vault and judges the new manifest words, on the
feature's SDK and node-engine validator (feature 57, config and provisioning).
2026-10-15 21:27:33 +00:00

180 lines
9.9 KiB
Go

package catalogue
import (
"reflect"
"strings"
"testing"
)
// A collection is declared and filled by the client (novox/hq ADR 0349 §13, design 57 L1, issue 684): a collector
// names a collection it collects, a contributor an item from a template of its own, and a handed composition plans
// both for the node's provisioner client and renders neither. The three old namespaces read as collections of their
// own name. Each file is filled one way: a piece of the other form on the machine is said as not placed.
const (
collectorZsh = `{"module":"zsh","version":"1","moved":true,
"claims":[{"name":"node-login-shell","scope":"node"}],
"collections":[{"name":"widgets","comment":"#"}],
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]},
"resources":[{"id":"rc","type":"file","path":"${machine:account-home}/.zshrc","owner":"${machine:account}",
"mode":"0644","template":"files/zshrc"}]}`
zshrcText = "# zsh\n${shell:zsh:normal}${collected:widgets}"
contributorText = "source ${machine:account-home}/.p10k.zsh\n"
contributorP10k = `{"module":"prompt","version":"1","moved":true,
"items":[{"collection":"shell:zsh:normal","template":"files/zsh"}],
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`
oldFormAliases = `{"module":"aliases","version":"1",
"shell":[{"for":"zsh","slot":"normal","code":"alias ll='ls -l'\n"}]}`
)
func builtWith(module string, texts map[string]string) []Built {
return []Built{{Name: "files", Kind: ArtifactArchive,
Reference: ArtifactStoreScheme + module + "/files/blobs/sha256:" + strings.Repeat("e", 64),
Digest: "sha256:" + strings.Repeat("e", 64), Texts: texts}}
}
func collectionsOn(t *testing.T) Resolution {
t.Helper()
zsh := held(t, collectorZsh, builtWith("zsh", map[string]string{"zshrc": zshrcText}))
prompt := held(t, contributorP10k, builtWith("prompt", map[string]string{"zsh": contributorText}))
aliases, err := ParseManifest([]byte(oldFormAliases))
if err != nil {
t.Fatal(err)
}
r, err := Resolve(shelf(zsh, prompt, aliases), []string{"zsh", "prompt", "aliases"}, workstation(), World{})
if err != nil {
t.Fatal(err)
}
r.Account = "op"
return r
}
func TestAContributorsBuildKeepsItsItemsTemplateAndText(t *testing.T) {
m := held(t, contributorP10k, builtWith("prompt", map[string]string{"zsh": contributorText}))
if m.Handed == nil || !reflect.DeepEqual(m.Handed.Items, map[string]string{"shell:zsh:normal": "zsh"}) {
t.Fatalf("the build kept %+v", m.Handed)
}
if !reflect.DeepEqual(m.Items, []Item{{Collection: "shell:zsh:normal", Content: contributorText}}) {
t.Fatalf("the held items are %+v: the template's text, read back", m.Items)
}
}
func TestAHandedCollectorAndContributorArePlannedAndNeitherIsRendered(t *testing.T) {
c, got := composeWith(t, collectionsOn(t), handingTo("store:5000"))
if strings.Contains(got, ".p10k.zsh") || strings.Contains(got, "alias ll") {
t.Fatalf("the controller rendered a contribution into a handed collector: %s", got)
}
zsh, prompt := c.Plans["zsh"], c.Plans["prompt"]
wantCollections := []PlanCollection{{Name: "shell:zsh:normal", Comment: "#"}, {Name: "widgets", Comment: "#"}}
if !reflect.DeepEqual(zsh.Collections, wantCollections) || len(zsh.Items) != 0 {
t.Fatalf("zsh's plan collects %+v and contributes %+v", zsh.Collections, zsh.Items)
}
if !reflect.DeepEqual(prompt.Items, []PlanItem{{Collection: "shell:zsh:normal", Template: "zsh"}}) ||
len(prompt.Files) != 0 || prompt.Placement["machine:account-home"] != "/home/op" {
t.Fatalf("prompt's plan is %+v: its item, by template, and the placement its template names", prompt)
}
// The old form on the same machine is not placed, and said so.
if len(c.Unplaced) != 1 || !strings.Contains(c.Unplaced[0], "aliases's shell:zsh:normal is not placed") {
t.Fatalf("unplaced: %v", c.Unplaced)
}
}
// A collector filled the old way holds the old forms and each moved contributor's item, rendered from the text the
// mesh holds as its old form was (design 57 L2, issue 681), so the file loses no line where nothing is handed; a
// collection of the new form stays empty.
func TestACollectorFilledTheOldWayHoldsTheOldFormsAndEachHeldItem(t *testing.T) {
c, got := composeWith(t, collectionsOn(t), Rendering{ArtifactStore: "store:5000"})
if c.Plans != nil {
t.Fatalf("handed on a machine that cannot take it: %v", c.Plans)
}
if !strings.Contains(got, `"content":"# zsh\n# aliases\nalias ll='ls -l'\n# prompt\nsource /home/op/.p10k.zsh\n"`) {
t.Fatalf("the old way does not hold the old forms and the held item in module order: %s", got)
}
if len(c.Unplaced) != 0 {
t.Fatalf("unplaced: %v", c.Unplaced)
}
}
// An item the controller cannot render the old way (it names a value but a machine fact) is said as not placed.
func TestAHeldItemNamingMoreThanAFactIsSaidNotPlacedTheOldWay(t *testing.T) {
zsh := held(t, collectorZsh, builtWith("zsh", map[string]string{"zshrc": zshrcText}))
if _, ok := heldItemText(Manifest{Module: "p", Items: []Item{{Collection: "shell:zsh:normal",
Content: "export THEME=${config:theme}\n"}}}, "shell:zsh:normal", map[string]string{}); ok {
t.Fatal("an item naming a config value was rendered by the controller")
}
if _, ok := heldItemText(Manifest{Module: "p", Items: []Item{{Collection: "shell:zsh:normal",
Content: "cd ${machine:account-home}\n"}}}, "shell:zsh:normal", map[string]string{}); ok {
t.Fatal("an item naming a fact this machine lacks was rendered")
}
if _, ok := heldItemText(Manifest{Module: "p", Items: []Item{{Collection: "widgets", Content: "x\n"}}},
"widgets", nil); ok {
t.Fatal("an item of a collection of the new form was rendered the old way")
}
left := itemsLeftOut([]Manifest{zsh, {Module: "p", Items: []Item{{Collection: "shell:zsh:normal",
Content: "export THEME=${config:theme}\n"}}}}, zsh, "shell:zsh:normal", map[string]string{})
if len(left) != 1 || !strings.Contains(left[0], "p's item of shell:zsh:normal is not placed") {
t.Fatalf("left out: %v", left)
}
}
// Each old namespace L2 moves renders a moved contributor's item exactly as its old form did, where the collector is
// not handed: the same contributor written both ways composes the same bytes (design 57 L2, issue 681).
func TestAMovedContributorsItemRendersAsItsOldFormDid(t *testing.T) {
code := "# two lines\nalias a=b"
asOld := Manifest{Module: "laptop", Shell: []ShellCode{{For: "zsh", Slot: "normal", Code: code}},
Contributions: []SeatContribution{{Seat: HotkeysSeat, Kind: "trigger", Content: "KEY_F21 1 touchpad\n"}}}
asItem := Manifest{Module: "laptop", Moved: true, Items: []Item{{Collection: "shell:zsh:normal", Content: code},
{Collection: "contribution:node-hotkeys:trigger", Content: "KEY_F21 1 touchpad\n"}}}
other := Manifest{Module: "zz-other", Shell: []ShellCode{{For: "zsh", Slot: "normal", Code: "x=1\n"}},
Contributions: []SeatContribution{{Seat: HotkeysSeat, Kind: "trigger", Content: "KEY_MUTE 1 mute\n"}}}
first := Manifest{Module: "aa-first", Shell: []ShellCode{{For: "zsh", Slot: "normal", Code: "y=2\n"}}}
for _, mods := range [][]Manifest{{other, first}, {}} {
was := append(append([]Manifest(nil), mods...), asOld)
is := append(append([]Manifest(nil), mods...), asItem)
if a, b := shellCodeOn(was, "zsh", "normal", nil), shellCodeOn(is, "zsh", "normal", nil); a != b || a == "" {
t.Errorf("shell: the old form made %q, the item %q", a, b)
}
a, _, errA := seatContributions(was, hotkeysHolder(), "node-hotkeys:trigger", Rendering{}, nil, nil)
b, left, errB := seatContributions(is, hotkeysHolder(), "node-hotkeys:trigger", Rendering{}, nil, nil)
if errA != nil || errB != nil || a != b || a == "" || len(left) != 0 {
t.Errorf("hotkeys: the old form made %q, the item %q (%v %v %v)", a, b, errA, errB, left)
}
}
}
func TestCollectionsAndItemsAreJudged(t *testing.T) {
for name, c := range map[string]struct{ raw, says string }{
"an item of a module not moved": {`{"module":"m","version":"1",
"items":[{"collection":"shell:zsh:normal","template":"files/x"}],
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`, "is marked moved"},
"two items to one collection": {`{"module":"m","version":"1","moved":true,
"items":[{"collection":"a","template":"files/x"},{"collection":"a","template":"files/y"}],
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`, "contributes to a twice"},
"an item to no slot": {`{"module":"m","version":"1","moved":true,
"items":[{"collection":"shell:zsh:middle","template":"files/x"}],
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`, "is no slot"},
"an item outside the templates": {`{"module":"m","version":"1","moved":true,
"items":[{"collection":"a","template":"x"}],
"build":{"artifacts":[{"name":"files","kind":"archive","from":"files"}]}}`, "is not a file under files/"},
"an item naming a secret": {`{"module":"m","version":"1",
"items":[{"collection":"a","content":"t=${secret:token}"}]}`, "where no secret is"},
"a collection not declared": {`{"module":"m","version":"1",
"resources":[{"id":"f","type":"file","path":"/f","content":"${collected:a}"}]}`, "does not collect"},
"an old namespace declared": {`{"module":"m","version":"1","collections":[{"name":"shell:zsh:normal"}],
"resources":[{"id":"f","type":"file","path":"/f","content":"x"}]}`, "read from its placeholder"},
"a collection placed nowhere": {`{"module":"m","version":"1","collections":[{"name":"a"}],
"resources":[{"id":"f","type":"file","path":"/f","content":"x"}]}`, "no file of its places it"},
"a collection in a path": {`{"module":"m","version":"1","collections":[{"name":"a"}],
"resources":[{"id":"f","type":"file","path":"/${collected:a}","content":"${collected:a}"}]}`,
"only in a file's content"},
} {
_, err := ParseManifest([]byte(c.raw))
if err == nil || !strings.Contains(err.Error(), c.says) {
t.Errorf("%s: %v, want it to say %q", name, err, c.says)
}
}
if _, err := ParseManifest([]byte(collectorZsh)); err != nil {
t.Errorf("a collector: %v", err)
}
}