From 4cf07c411cbb0b260f1b106ce618506aaea041f9 Mon Sep 17 00:00:00 2001 From: Deivid Soto Date: Mon, 6 Apr 2026 18:49:44 +0200 Subject: [PATCH] fix(daemon): use correct systemd user target and isolate test cache --- internal/cmd/daemon_install.go | 3 +-- internal/upgrade/cache.go | 14 +++++++++----- internal/upgrade/upgrade_test.go | 14 ++++++++++++++ 3 files changed, 24 insertions(+), 7 deletions(-) diff --git a/internal/cmd/daemon_install.go b/internal/cmd/daemon_install.go index 5087a20..8f1c0b6 100644 --- a/internal/cmd/daemon_install.go +++ b/internal/cmd/daemon_install.go @@ -22,11 +22,10 @@ Type=simple ExecStart={{.BinPath}} start Restart=always RestartSec=10 -User={{.User}} Environment=HOME={{.Home}} [Install] -WantedBy=multi-user.target +WantedBy=default.target ` const launchdTemplate = ` diff --git a/internal/upgrade/cache.go b/internal/upgrade/cache.go index 7bdcfb0..7cf5869 100644 --- a/internal/upgrade/cache.go +++ b/internal/upgrade/cache.go @@ -18,15 +18,17 @@ type versionCache struct { CheckedAt time.Time `json:"checkedAt"` } -// cacheFilePath returns the path to the version cache file. -func cacheFilePath() string { +// cacheFilePathFn returns the path to the version cache file. +// Overridable in tests to avoid polluting the real cache. +// NOTE: not safe for parallel tests — callers must not use t.Parallel(). +var cacheFilePathFn = func() string { return filepath.Join(config.DataDir(), "latest-version.json") } // ReadCachedVersion returns the cached latest version if it's fresh (< cacheTTL). // Returns empty string if cache is missing, stale, or corrupt. func ReadCachedVersion() string { - data, err := os.ReadFile(cacheFilePath()) + data, err := os.ReadFile(cacheFilePathFn()) if err != nil { return "" } @@ -50,14 +52,16 @@ func writeCachedVersion(version string) { if err != nil { return } - path := cacheFilePath() + path := cacheFilePathFn() os.MkdirAll(filepath.Dir(path), 0o755) // Best-effort write — ignore errors tmp := path + ".tmp" if err := os.WriteFile(tmp, data, 0o644); err != nil { return } - os.Rename(tmp, path) + if os.Rename(tmp, path) != nil { + os.Remove(tmp) + } } // CheckLatestCached returns the latest version, using cache when fresh. diff --git a/internal/upgrade/upgrade_test.go b/internal/upgrade/upgrade_test.go index b8805db..18904f0 100644 --- a/internal/upgrade/upgrade_test.go +++ b/internal/upgrade/upgrade_test.go @@ -316,6 +316,16 @@ func swapHTTPClient(c *http.Client) func() { return func() { httpClient = orig } } +// swapCacheDir redirects the version cache to a temp directory to avoid +// polluting the real ~/.local/share/unarr/latest-version.json during tests. +func swapCacheDir(t *testing.T) func() { + t.Helper() + tmpDir := t.TempDir() + orig := cacheFilePathFn + cacheFilePathFn = func() string { return filepath.Join(tmpDir, "latest-version.json") } + return func() { cacheFilePathFn = orig } +} + // rewriteTransport redirects all requests to the given base URL, // preserving path and query. type rewriteTransport struct { @@ -563,6 +573,10 @@ func TestFetchLatestVersionWithHTTPTest(t *testing.T) { }) defer restore() + // Redirect cache to temp dir so tests don't pollute the real cache + restoreCache := swapCacheDir(t) + defer restoreCache() + ver, err := CheckLatest(context.Background()) if tt.wantErr { if err == nil {