76 lines
3.3 KiB
Go
76 lines
3.3 KiB
Go
//go:build linux
|
|
|
|
package apply
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// The read-only judgement of a node's directories (novox/hq issue 358): one line each — placed, would be refused
|
|
// naming the link and who could replace it, or not there yet (placed: an apply makes it) — and nothing made or
|
|
// changed. Who could replace the link is "every account", "the account X" or "the group X", by the account and the
|
|
// directories the test runs as: the checker's isolated step runs as the account nobody, which owns / there (issue 1919,
|
|
// R4g), so the test demands a who in any of the forms couldReplace and linkReplacer produce, not "every account" alone.
|
|
func TestJudgeDirectoriesSaysWhatTheWalkWouldRefuseAndChangesNothing(t *testing.T) {
|
|
base := t.TempDir()
|
|
plain := filepath.Join(base, "plain")
|
|
if err := os.Mkdir(plain, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
elsewhere := filepath.Join(base, "elsewhere", "state")
|
|
if err := os.MkdirAll(elsewhere, 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Symlink(filepath.Join(base, "elsewhere"), filepath.Join(base, "linked")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
missing := filepath.Join(base, "missing", "deeper")
|
|
d := declare(t, `{"id":"a.plain","type":"directory","path":"`+plain+`","mode":"0700"},`+
|
|
`{"id":"a.linked","type":"directory","path":"`+filepath.Join(base, "linked", "state")+`","mode":"0700"},`+
|
|
`{"id":"a.missing","type":"directory","path":"`+missing+`","mode":"0700"}`)
|
|
|
|
said := JudgeDirectories(d)
|
|
lines := strings.Split(said, "\n")
|
|
if len(lines) != 4 || !strings.HasPrefix(lines[0], "3 directories declared: 2 placed, 1 would be refused") {
|
|
t.Fatalf("the judgement: %q", said)
|
|
}
|
|
if lines[1] != plain+": placed" || lines[3] != missing+": placed" {
|
|
t.Errorf("a directory the walk reaches is not said placed: %q", said)
|
|
}
|
|
if !strings.Contains(lines[2], "would be refused") || !strings.Contains(lines[2], filepath.Join(base, "linked")) ||
|
|
!(strings.Contains(lines[2], "every account (") || strings.Contains(lines[2], "the account ") ||
|
|
strings.Contains(lines[2], "the group ")) {
|
|
t.Errorf("the linked directory is not said refused naming the link and who: %q", lines[2])
|
|
}
|
|
if _, err := os.Stat(filepath.Join(base, "missing")); !os.IsNotExist(err) {
|
|
t.Error("the judgement made a directory")
|
|
}
|
|
for _, p := range []string{plain, elsewhere} {
|
|
if info, _ := os.Stat(p); info.Mode().Perm() != 0o755 {
|
|
t.Errorf("the judgement changed %s to %o", p, info.Mode().Perm())
|
|
}
|
|
}
|
|
}
|
|
|
|
// A link only root could have made is followed by the judgement as by the apply.
|
|
func TestJudgeDirectoriesFollowsARootOnlyLink(t *testing.T) {
|
|
wasDirs, wasLinks := couldReplace, linkReplacer
|
|
couldReplace = func(string, uint32, uint32, uint32) string { return "" }
|
|
linkReplacer = func(string, uint32) string { return "" }
|
|
t.Cleanup(func() { couldReplace, linkReplacer = wasDirs, wasLinks })
|
|
base := t.TempDir()
|
|
if err := os.MkdirAll(filepath.Join(base, "real", "state"), 0o755); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
if err := os.Symlink("real", filepath.Join(base, "run")); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
path := filepath.Join(base, "run", "state")
|
|
if said := JudgeDirectories(declare(t, `{"id":"a.s","type":"directory","path":"`+path+`"}`)); !strings.Contains(said, path+": placed") {
|
|
t.Fatalf("a directory behind a root-only link is not said placed: %q", said)
|
|
}
|
|
}
|