//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. 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") { 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) } }