//go:build darwin && !ios && !ios_target
package persistence
import (
"os"
"path/filepath"
"strings"
"testing"
)
func withDarwinTempHome(t *testing.T) string {
t.Helper()
home := t.TempDir()
origHome := currentUserHomeDir
origStartupName := DefaultStartupName
currentUserHomeDir = func() (string, error) { return home, nil }
DefaultStartupName = ""
t.Cleanup(func() {
currentUserHomeDir = origHome
DefaultStartupName = origStartupName
})
return home
}
func writeDarwinSourceExecutable(t *testing.T) string {
t.Helper()
src := filepath.Join(t.TempDir(), "source-agent")
if err := os.WriteFile(src, []byte("agent-bytes"), 0644); err != nil {
t.Fatalf("write source executable: %v", err)
}
return src
}
func TestDarwinInstallCreatesLaunchAgentAndExecutable(t *testing.T) {
home := withDarwinTempHome(t)
src := writeDarwinSourceExecutable(t)
if err := InstallFrom(src); err != nil {
t.Fatalf("InstallFrom() error: %v", err)
}
target := filepath.Join(home, "Library", "Application Support", "Overlord", "agent")
gotBytes, err := os.ReadFile(target)
if err != nil {
t.Fatalf("read installed executable: %v", err)
}
if string(gotBytes) != "agent-bytes" {
t.Fatalf("installed executable content mismatch: %q", string(gotBytes))
}
if info, err := os.Stat(target); err != nil {
t.Fatalf("stat installed executable: %v", err)
} else if info.Mode().Perm() != 0755 {
t.Fatalf("installed executable mode = %o, want 0755", info.Mode().Perm())
}
plistPath := filepath.Join(home, "Library", "LaunchAgents", "com.overlord.agent.plist")
plistBytes, err := os.ReadFile(plistPath)
if err != nil {
t.Fatalf("read launch agent plist: %v", err)
}
plist := string(plistBytes)
for _, want := range []string{
"com.overlord.agent",
"ProgramArguments",
"" + target + "",
"RunAtLoad",
"KeepAlive",
} {
if !strings.Contains(plist, want) {
t.Fatalf("launch agent plist missing %q:\n%s", want, plist)
}
}
}
func TestDarwinConfigureCreatesLaunchAgentForExistingPath(t *testing.T) {
home := withDarwinTempHome(t)
exePath := filepath.Join(home, "bin", "existing-agent")
if err := Configure(exePath); err != nil {
t.Fatalf("Configure() error: %v", err)
}
plistPath := filepath.Join(home, "Library", "LaunchAgents", "com.overlord.agent.plist")
plistBytes, err := os.ReadFile(plistPath)
if err != nil {
t.Fatalf("read launch agent plist: %v", err)
}
if plist := string(plistBytes); !strings.Contains(plist, ""+exePath+"") {
t.Fatalf("launch agent plist missing executable path %q:\n%s", exePath, plist)
}
}
func TestDarwinCustomStartupNameRequiresLaunchAgentLabel(t *testing.T) {
home := withDarwinTempHome(t)
DefaultStartupName = "updater"
if err := InstallFrom(writeDarwinSourceExecutable(t)); err == nil {
t.Fatal("InstallFrom() error = nil, want invalid startup name error")
}
if err := Configure(filepath.Join(home, "bin", "updater")); err == nil {
t.Fatal("Configure() error = nil, want invalid startup name error")
}
if _, err := TargetPath(); err == nil {
t.Fatal("TargetPath() error = nil, want invalid startup name error")
}
}
func TestDarwinCustomStartupNameCreatesCustomLabelAndBinary(t *testing.T) {
home := withDarwinTempHome(t)
DefaultStartupName = "com.example.updater"
if err := InstallFrom(writeDarwinSourceExecutable(t)); err != nil {
t.Fatalf("InstallFrom() error: %v", err)
}
target := filepath.Join(home, "Library", "Application Support", "Overlord", "com.example.updater")
if _, err := os.Stat(target); err != nil {
t.Fatalf("stat custom executable: %v", err)
}
plistPath := filepath.Join(home, "Library", "LaunchAgents", "com.example.updater.plist")
plistBytes, err := os.ReadFile(plistPath)
if err != nil {
t.Fatalf("read custom launch agent plist: %v", err)
}
plist := string(plistBytes)
if !strings.Contains(plist, "com.example.updater") {
t.Fatalf("custom launch agent plist missing label:\n%s", plist)
}
if !strings.Contains(plist, ""+target+"") {
t.Fatalf("custom launch agent plist missing target %q:\n%s", target, plist)
}
}
func TestDarwinReplaceExecutablePreservesExecutableModeWhenTargetExists(t *testing.T) {
_ = withDarwinTempHome(t)
src := writeDarwinSourceExecutable(t)
target := filepath.Join(t.TempDir(), "agent")
if err := os.WriteFile(target, []byte("old"), 0644); err != nil {
t.Fatalf("write existing target: %v", err)
}
if err := replaceExecutable(src, target); err != nil {
t.Fatalf("replaceExecutable() error: %v", err)
}
if info, err := os.Stat(target); err != nil {
t.Fatalf("stat replaced executable: %v", err)
} else if info.Mode().Perm() != 0755 {
t.Fatalf("replaced executable mode = %o, want 0755", info.Mode().Perm())
}
}