mesh/merge-gate pass: builds asus-zephyrus-g14, i3status-rust, power → ace, g14, novox, shanks; no bus step; every machine composes with the change as it d…
mesh/repo-check fail: THE CHANGE ALTERS ITS OWN CHECK (merge-check.sh): main's version judged it; the change's judges the pull requests after it merges; it…
mesh/delivery superseded: a newer head of the same pull request
The SDK hands the current value over before Watch returns, and the follower had no entry for it yet, so the first value was dropped. A silent watch is now told from an expired key and watched again rather than polled, each write takes its own temporary file, drop-in directories are no module's, and an entry added to the path check's lists is refused unless its line says why.
136 lines
5.1 KiB
Go
136 lines
5.1 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func catalogue(t *testing.T, files map[string]string) string {
|
|
t.Helper()
|
|
root := t.TempDir()
|
|
for p, c := range files {
|
|
full := filepath.Join(root, p)
|
|
if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.WriteFile(full, []byte(c), 0o644); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
return root
|
|
}
|
|
|
|
const owner = `{"module":"power","resources":[{"id":"d","type":"directory","path":"/run/mesh-power"}]}`
|
|
|
|
func TestAModuleReadingAnothersStateIsFound(t *testing.T) {
|
|
root := catalogue(t, map[string]string{
|
|
"modules/power/module.json": owner,
|
|
"modules/power/cmd/power/draw.go": `const f = "/run/mesh-power/draw"`,
|
|
"modules/bar/module.json": `{"module":"bar","resources":[{"id":"x","type":"file","path":"/etc/x","content":"cat /run/mesh-power/draw"}]}`,
|
|
"modules/other/module.json": `{"module":"other"}`,
|
|
"modules/other/files/bin/read": "#!/bin/sh\ncat /run/mesh-power\n",
|
|
"modules/other/README.md": "it once read /run/mesh-power/draw",
|
|
"modules/other/cmd/x/x_test.go": `"/run/mesh-power"`,
|
|
"modules/near/module.json": `{"module":"near","resources":[{"id":"y","type":"file","path":"/etc/y","content":"/run/mesh-power-other/x"}]}`,
|
|
})
|
|
found, err := Check(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var got []string
|
|
for _, f := range found {
|
|
got = append(got, f.Module+" "+f.File)
|
|
}
|
|
want := []string{"bar modules/bar/module.json", "other modules/other/files/bin/read"}
|
|
if strings.Join(got, "|") != strings.Join(want, "|") {
|
|
t.Fatalf("found %v, want %v", got, want)
|
|
}
|
|
if !strings.Contains(found[0].String(), "power's") {
|
|
t.Fatalf("%s", found[0])
|
|
}
|
|
}
|
|
|
|
func TestACatalogueWhereEachKeepsToItsOwnIsClean(t *testing.T) {
|
|
root := catalogue(t, map[string]string{
|
|
"modules/power/module.json": owner,
|
|
"modules/power/cmd/power/draw.go": `const f = "/run/mesh-power/draw"`,
|
|
})
|
|
if found, err := Check(root); err != nil || len(found) != 0 {
|
|
t.Fatalf("%v %v", found, err)
|
|
}
|
|
}
|
|
|
|
func TestEtcAndUsrLocalLibAreAModulesTooButNotInsideAContainer(t *testing.T) {
|
|
root := catalogue(t, map[string]string{
|
|
"modules/power/module.json": `{"module":"power","resources":[{"id":"m","type":"directory","path":"/etc/mesh-power/moments"},` +
|
|
`{"id":"s","type":"archive","path":"/usr/local/lib/mesh-power"}]}`,
|
|
"modules/reader/module.json": `{"module":"reader"}`,
|
|
"modules/reader/cmd/r/r.go": `const a, b = "/etc/mesh-power/moments/after-wake", "/usr/local/lib/mesh-power/bin/x"`,
|
|
// A container that mounts something at that path inside itself names its own world.
|
|
"modules/boxed/module.json": `{"module":"boxed","resources":[{"id":"c","type":"container",` +
|
|
`"volumes":["/srv/boxed:/etc/mesh-power/moments",{"source":"/srv/b","target":"/usr/local/lib/mesh-power"}]}]}`,
|
|
// A binary says what its source says.
|
|
"modules/boxed/bin/tool": "\x00\x01/etc/mesh-power/moments\x00",
|
|
})
|
|
found, err := Check(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var got []string
|
|
for _, f := range found {
|
|
got = append(got, f.Module+" "+f.Path)
|
|
}
|
|
want := []string{"reader /etc/mesh-power/moments", "reader /usr/local/lib/mesh-power"}
|
|
if strings.Join(got, "|") != strings.Join(want, "|") {
|
|
t.Fatalf("found %v, want %v", got, want)
|
|
}
|
|
}
|
|
|
|
func TestSharedPathsPassAndKnownFindingsOnlyShrink(t *testing.T) {
|
|
found := []Finding{
|
|
{Module: "dns", File: "modules/dns/module.json", Path: "/etc/hosts", Owner: "hostname"},
|
|
{Module: "laptop", File: "modules/laptop/k.go", Path: "/etc/triggers", Owner: "keys"},
|
|
{Module: "new", File: "modules/new/n.go", Path: "/run/mesh-power", Owner: "power"},
|
|
}
|
|
shared := map[string]bool{"/etc/hosts": true}
|
|
known := map[string]bool{
|
|
"laptop /etc/triggers modules/laptop/k.go": true,
|
|
"old /run/x modules/old/o.go": true,
|
|
}
|
|
refused, gone := Judge(found, shared, known)
|
|
if len(refused) != 1 || refused[0].Module != "new" {
|
|
t.Fatalf("refused %v", refused)
|
|
}
|
|
if len(gone) != 1 || gone[0] != "old /run/x modules/old/o.go" {
|
|
t.Fatalf("gone %v", gone)
|
|
}
|
|
}
|
|
|
|
func TestADropInDirectoryIsNoModulesButItsFilesAre(t *testing.T) {
|
|
root := catalogue(t, map[string]string{
|
|
"modules/memory/module.json": `{"module":"memory","resources":[{"id":"d","type":"directory","path":"/etc/sysctl.d"},` +
|
|
`{"id":"f","type":"file","path":"/etc/sysctl.d/90-memory.conf"}]}`,
|
|
"modules/other/module.json": `{"module":"other","resources":[{"id":"f","type":"file","path":"/etc/sysctl.d/80-other.conf"}]}`,
|
|
"modules/other/cmd/o/o.go": `const a, b = "/etc/sysctl.d", "/etc/sysctl.d/90-memory.conf"`,
|
|
})
|
|
found, err := Check(root)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if len(found) != 1 || found[0].Path != "/etc/sysctl.d/90-memory.conf" || found[0].Module != "other" {
|
|
t.Fatalf("%v", found)
|
|
}
|
|
}
|
|
|
|
func TestAListGrowsOnlyWithAReasonTheDiffShows(t *testing.T) {
|
|
base := map[string]bool{"/etc/hosts": true}
|
|
now := map[string]bool{"/etc/hosts": true, "/etc/a": true, "/etc/b": true}
|
|
why := map[string]string{"/etc/a": "because", "/etc/b": "allow: every program reads it"}
|
|
got := Grown("shared", now, why, base)
|
|
if len(got) != 1 || !strings.Contains(got[0], `"/etc/a"`) {
|
|
t.Fatalf("%v", got)
|
|
}
|
|
}
|