From b3526c0fbad4af15a6b9a7eee854cfcb55227895 Mon Sep 17 00:00:00 2001 From: Deluan Date: Wed, 22 Jul 2026 13:15:47 -0400 Subject: [PATCH] test(artwork): make leak and permission tests pass on linux goleak now ignores notify's nonrecursive-tree goroutines (linux uses inotify, which spawns dispatch+internal instead of darwin's recursive dispatch), and the read-only-dir prune spec skips under root, where permission bits cannot make Remove fail. --- core/artwork/artwork_suite_test.go | 6 ++++-- core/artwork/prune_test.go | 3 +++ 2 files changed, 7 insertions(+), 2 deletions(-) diff --git a/core/artwork/artwork_suite_test.go b/core/artwork/artwork_suite_test.go index b721200e1..e2a1a591c 100644 --- a/core/artwork/artwork_suite_test.go +++ b/core/artwork/artwork_suite_test.go @@ -23,9 +23,11 @@ func TestArtwork(t *testing.T) { // package's control, so they're ignored by exact top-function instead. defer goleak.VerifyNone(t, goleak.IgnoreTopFunction("github.com/onsi/ginkgo/v2/internal/interrupt_handler.(*InterruptHandler).registerForInterrupts.func2"), - // notify's own init() starts this dispatcher the moment it's imported - // (via core/storage/local or plugins); it never exits. + // notify's own init() starts a singleton tree the moment it's imported (via + // core/storage/local or plugins); recursive on darwin, nonrecursive on linux. goleak.IgnoreTopFunction("github.com/rjeczalik/notify.(*recursiveTree).dispatch"), + goleak.IgnoreTopFunction("github.com/rjeczalik/notify.(*nonrecursiveTree).dispatch"), + goleak.IgnoreTopFunction("github.com/rjeczalik/notify.(*nonrecursiveTree).internal"), // The old cache_warmer.go starts a goroutine per NewCacheWarmer call with // no shutdown path (dark-launch target for Phase 2, not touched here). goleak.IgnoreTopFunction("github.com/navidrome/navidrome/core/artwork.(*cacheWarmer).waitSignal"), diff --git a/core/artwork/prune_test.go b/core/artwork/prune_test.go index 5511b2305..646ad7440 100644 --- a/core/artwork/prune_test.go +++ b/core/artwork/prune_test.go @@ -189,6 +189,9 @@ var _ = Describe("Prune", func() { It("warns and continues past a store.Remove failure instead of aborting the loop", func() { tests.SkipOnWindows("uses Unix file permission bits") + if os.Geteuid() == 0 { + Skip("read-only dir cannot block root (e.g. tests in a container)") + } old := time.Now().Add(-2 * time.Hour) blocked := []byte("blocked-bytes")