Files
wehub-resource-sync a06f331eb8
CI / benchmark (push) Has been skipped
install-script / posix-syntax (push) Successful in 6m1s
CI / build-onnx (push) Failing after 6m43s
init-smoke / dry-run (push) Failing after 15m57s
security / govulncheck (push) Has been cancelled
security / trivy-fs (push) Has been cancelled
CI / test (1.26, ubuntu-latest) (push) Has been cancelled
Scorecard supply-chain security / Scorecard analysis (push) Has been cancelled
CI / test (1.26, macos-latest) (push) Has been cancelled
CI / build-windows (push) Has been cancelled
CI / lint (push) Has been cancelled
install-script / powershell-syntax (push) Has been cancelled
install-script / install (macos-14) (push) Has been cancelled
install-script / install (ubuntu-latest) (push) Has been cancelled
chore: import upstream snapshot with attribution
2026-07-13 12:33:42 +08:00

68 lines
2.0 KiB
Go

package daemon
import (
"os"
"path/filepath"
"strconv"
"testing"
)
// TestRunningPID covers the four states RunningPID must distinguish: no PID
// file, a live owner, a stale owner (process gone), and a corrupt file. The
// stale case is the load-bearing one — misreading a crashed daemon's leftover
// PID file as "running" would block every subsequent start.
func TestRunningPID(t *testing.T) {
pidPath := filepath.Join(t.TempDir(), "daemon.pid")
t.Setenv("GORTEX_DAEMON_PIDFILE", pidPath)
t.Run("no pid file", func(t *testing.T) {
if pid, ok := RunningPID(); ok {
t.Fatalf("want (0,false), got (%d,%v)", pid, ok)
}
})
t.Run("live owner", func(t *testing.T) {
writePID(t, pidPath, os.Getpid())
pid, ok := RunningPID()
if !ok || pid != os.Getpid() {
t.Fatalf("want (%d,true), got (%d,%v)", os.Getpid(), pid, ok)
}
})
t.Run("live owner with trailing newline", func(t *testing.T) {
// A pidfile written by `echo`/a process manager ends in "\n". The
// guard must still detect the live owner — otherwise a restart
// silently races the store lock again.
if err := os.WriteFile(pidPath, []byte(strconv.Itoa(os.Getpid())+"\n"), 0o600); err != nil {
t.Fatal(err)
}
if pid, ok := RunningPID(); !ok || pid != os.Getpid() {
t.Fatalf("want (%d,true), got (%d,%v)", os.Getpid(), pid, ok)
}
})
t.Run("stale owner", func(t *testing.T) {
// A PID well above any platform's pid_max — guaranteed not live.
writePID(t, pidPath, 1<<30)
if pid, ok := RunningPID(); ok {
t.Fatalf("stale pid must read as not running, got (%d,%v)", pid, ok)
}
})
t.Run("corrupt file", func(t *testing.T) {
if err := os.WriteFile(pidPath, []byte("not-a-pid"), 0o600); err != nil {
t.Fatal(err)
}
if pid, ok := RunningPID(); ok {
t.Fatalf("corrupt pid file must read as not running, got (%d,%v)", pid, ok)
}
})
}
func writePID(t *testing.T, path string, pid int) {
t.Helper()
if err := os.WriteFile(path, []byte(strconv.Itoa(pid)), 0o600); err != nil {
t.Fatal(err)
}
}