package main import ( "os" "path/filepath" "strings" "syscall" "testing" "github.com/stretchr/testify/assert" "github.com/stretchr/testify/require" ) // hyperguild#157: the server refuses to start while a symlink exists in the // brain dir, or while any part of it cannot be scanned (which could hide // one); a missing brain dir is the only thing it lets pass. func TestStartupSymlinkCheckRefusesABrainWithASymlink(t *testing.T) { brain := t.TempDir() require.NoError(t, os.Symlink(t.TempDir(), filepath.Join(brain, "planted"))) err := startupSymlinkCheck(brain) require.Error(t, err) assert.Contains(t, err.Error(), "planted") } func TestStartupSymlinkCheckRefusesABrainWithAnUnreadableDir(t *testing.T) { if os.Geteuid() == 0 { t.Skip("root reads mode-000 directories") } brain := t.TempDir() locked := filepath.Join(brain, "aaa") require.NoError(t, os.MkdirAll(locked, 0o755)) require.NoError(t, os.Chmod(locked, 0o000)) t.Cleanup(func() { _ = os.Chmod(locked, 0o755) }) err := startupSymlinkCheck(brain) require.Error(t, err) assert.Contains(t, err.Error(), "aaa") } func TestStartupSymlinkCheckPassesACleanOrMissingBrain(t *testing.T) { brain := t.TempDir() require.NoError(t, os.WriteFile(filepath.Join(brain, "n.md"), []byte("x"), 0o644)) assert.NoError(t, startupSymlinkCheck(brain)) assert.NoError(t, startupSymlinkCheck(filepath.Join(brain, "missing"))) } func TestSymlinkScanIntervalFallsBackOnNonPositive(t *testing.T) { for _, v := range []string{"0", "-5", "", "junk"} { got := symlinkScanInterval(func(string) string { return v }) assert.Positive(t, got, "env %q", v) } } func TestAlertingWarningsNamesTheSymlinkTripwire(t *testing.T) { w := strings.Join(alertingWarnings(func(string) string { return "" }), " ") assert.Contains(t, w, "symlink tripwire") } func TestStartupSymlinkCheckRefusesAnUnlistableBrainRoot(t *testing.T) { if os.Geteuid() == 0 { t.Skip("root lists mode-0100 directories") } brain := t.TempDir() require.NoError(t, os.Chmod(brain, 0o100)) t.Cleanup(func() { _ = os.Chmod(brain, 0o755) }) assert.Error(t, startupSymlinkCheck(brain)) } // hyperguild#179: a FIFO in the brain is refused at startup with a clear // message, instead of hanging or exiting later in a reader. func TestStartupSymlinkCheckRefusesABrainWithAFIFO(t *testing.T) { brain := t.TempDir() require.NoError(t, syscall.Mkfifo(filepath.Join(brain, "classification.yaml"), 0o644)) err := startupSymlinkCheck(brain) require.Error(t, err) assert.Contains(t, err.Error(), "classification.yaml") }