Files
mesh-host/internal/apply/oldshape_test.go
T
jschoubben d12bba0109
mesh/merge-gate head d12bba01090d merged into trunk dd9ab7927d96 — pass: builds mesh-host → ace, g14, novox, shanks; no bus step; every machine composes wi…
mesh/repo-check head d12bba01090d merged into trunk dd9ab7927d96 — pass: its merge-check.sh passed
mesh/delivery delivered
Give the kept-folder tests' folders an unprivileged owner when they run as root (hq ADR 0325)
The build seat runs merge-check as root, so every folder a test made was root's
data, which is never kept (§12), and 28 tests failed for that alone. A test's
folders now stand for an operator's: run as root, they are given to nobody before
they are judged. The root rule is unchanged.
2026-10-12 19:34:59 +02:00

137 lines
5.0 KiB
Go

//go:build linux
package apply
import (
"context"
"errors"
"os"
"path/filepath"
"strings"
"testing"
"golang.org/x/sys/unix"
"github.com/novox/mesh-host/internal/declaration"
"github.com/novox/mesh-host/internal/store"
)
// The engine delivers before the controller half (novox/hq ADR 0325): a controller that does not speak
// link.IdentityContract sends no identities, no users and no taken, and every access of its declarations is applied
// exactly as before this engine — mounted when present, refused when absent (ADR 0051 §7), nothing kept, nothing
// made, no container held, nothing judged. These are origin/main's outcomes, word for word.
func TestAnOlderControllersAccessesAreAppliedExactlyAsBefore(t *testing.T) {
keeping(t, nil, nil)
dir := userDir(t)
unwritable := filepath.Join(dir, "library") // its group may not write it
empty := filepath.Join(dir, "spool")
absent := filepath.Join(dir, "media", "movies")
for _, d := range []string{unwritable, empty} {
if err := os.Mkdir(d, 0o755); err != nil {
t.Fatal(err)
}
if err := os.Chmod(d, 0o755); err != nil {
t.Fatal(err)
}
}
// A root-owned empty folder, read only.
rootEmpty := ""
for _, c := range []string{"/var/empty", "/srv/http", "/srv/ftp"} {
if entries, err := os.ReadDir(c); err == nil && len(entries) == 0 {
if uid, _, _ := statOwner(mustLstat(t, c)); uid == 0 {
rootEmpty = c
break
}
}
}
resources := []string{
`{"id":"radarr.library","type":"access","path":"` + unwritable + `","mode":"read-write"}`,
`{"id":"sab.spool","type":"access","path":"` + empty + `","mode":"read-write"}`,
`{"id":"plex.movies","type":"access","path":"` + absent + `"}`,
`{"id":"plex.app","type":"container","name":"plex","image":"` + pinned + `","volumes":["` + absent + `:/movies"]}`,
}
if rootEmpty != "" {
resources = append(resources, `{"id":"web.root","type":"access","path":"`+rootEmpty+`","mode":"read-write"}`)
}
var started bool
run := func(_ context.Context, name string, args ...string) (string, error) {
if len(args) > 0 && args[0] == "run" {
started = true
}
if len(args) > 0 && args[0] == "container" {
if started {
return "true\t" + containerSpec(declare(t, resources[3]).Resources[0].(*declaration.Container), inputs{}), nil
}
return "", errors.New("no such container")
}
return "", nil
}
toUser(t)
report, _, err := Apply(context.Background(), archHost(t), declare(t, strings.Join(resources, ",")), store.State{},
store.OriginDeclared, run, nil, nil)
if err == nil || !strings.Contains(err.Error(), absent+" is not there, and the mesh does not own it — the operator "+
"must provide it") {
t.Fatalf("an absent access is not refused as before: %v", err)
}
for id, mode := range map[string]string{"radarr.library": "read-write", "sab.spool": "read-write"} {
o := outcomeOf(report, id)
if o.Action != "unchanged" || o.Detail != "operator-owned; present, "+mode+", nothing managed" {
t.Errorf("%s: %+v, and before it was unchanged, %q", id, o, "operator-owned; present, "+mode+", nothing managed")
}
}
if rootEmpty != "" {
if o := outcomeOf(report, "web.root"); o.Action != "unchanged" {
t.Errorf("a root-owned folder was judged: %+v", o)
}
}
if !started {
t.Error("a container mounting an absent access was held, and before it was created")
}
if _, err := os.Stat(absent); !errors.Is(err, os.ErrNotExist) {
t.Error("an absent access was made")
}
for _, d := range []string{unwritable, empty} {
if n, _ := unix.Getxattr(d, aclAccessXattr, nil); n > 0 {
t.Errorf("an ACL was set on %s", d)
}
if info := mustLstat(t, d); info.Mode().Perm() != 0o755 {
t.Errorf("%s changed mode: %o", d, info.Mode().Perm())
}
}
if all, _ := KeptFolders.All(); len(all) != 0 {
t.Errorf("folders were recorded as kept: %v", all)
}
if len(Leftovers()) != 0 || len(WaitingOnAccess(declare(t, strings.Join(resources, ",")))) != 0 {
t.Error("something was said or held for an older controller's access")
}
}
func mustLstat(t *testing.T, path string) os.FileInfo {
t.Helper()
info, err := os.Lstat(path)
if err != nil {
t.Fatal(err)
}
return info
}
// Review (low): a folder no access names, whose filesystem could not be named this look, is not said as its disk
// being away.
func TestALeftoverSaysWhyItsWalkCouldNotRun(t *testing.T) {
uuid, fsid, source := "6f1c0a4e-1b2d-4c3e-8f00-aa11bb22cc33", "0000080100000000", "/dev/sdb1"
_, lib, access := poolNamed(t, &uuid, &fsid, &source)
takeIt(t, lib, access)
other := `{"id":"x.dir","type":"directory","path":"` + filepath.Join(filepath.Dir(filepath.Dir(lib)), "x") + `"}`
if _, _, err := applyAccesses(t, store.State{}, other); err != nil {
t.Fatal(err)
}
uuid, fsid, source = "", "0000000000000000", "" // nothing names it now
toUser(t)
ReconcileKept(context.Background())
left := Leftovers()
if len(left) != 1 || strings.Contains(left[0].Why, "disk") || !strings.Contains(left[0].Why, "could not be named") {
t.Fatalf("the leftover does not say why its walk could not run: %+v", left)
}
}