navidrome/plugins/watcher_integration_test.go
Deluan 6ac3ce3511 test(plugins): ignore goroutine leaks from notify library in tests
Signed-off-by: Deluan <deluan@navidrome.org>
2025-12-31 17:06:28 -05:00

103 lines
3.1 KiB
Go

package plugins
import (
"context"
"os"
"path/filepath"
"testing"
"github.com/navidrome/navidrome/conf"
. "github.com/onsi/ginkgo/v2"
. "github.com/onsi/gomega"
"github.com/rjeczalik/notify"
)
var _ = Describe("Watcher Integration", Ordered, func() {
// Uses testdataDir and createTestManager from BeforeSuite
var (
manager *Manager
tmpDir string
ctx context.Context
)
BeforeAll(func() {
if testing.Short() {
Skip("Skipping integration test in short mode")
}
ctx = GinkgoT().Context()
// Create manager for watcher lifecycle tests (no plugin preloaded - tests copy plugin as needed)
manager, tmpDir = createTestManager(nil)
// Remove the auto-loaded plugin so tests can control loading
_ = manager.UnloadPlugin("fake-metadata-agent")
_ = os.Remove(filepath.Join(tmpDir, "fake-metadata-agent.wasm"))
})
// Helper to copy test plugin into the temp folder
copyTestPlugin := func() {
srcPath := filepath.Join(testdataDir, "fake-metadata-agent.wasm")
destPath := filepath.Join(tmpDir, "fake-metadata-agent.wasm")
data, err := os.ReadFile(srcPath)
Expect(err).ToNot(HaveOccurred())
err = os.WriteFile(destPath, data, 0600)
Expect(err).ToNot(HaveOccurred())
}
Describe("Plugin event processing (integration)", func() {
// These tests verify the full flow with actual WASM plugin loading.
AfterEach(func() {
// Clean up: unload plugin if loaded, remove copied file
_ = manager.UnloadPlugin("fake-metadata-agent")
_ = os.Remove(filepath.Join(tmpDir, "fake-metadata-agent.wasm"))
})
It("loads a plugin on CREATE event", func() {
copyTestPlugin()
manager.processPluginEvent("fake-metadata-agent", notify.Create)
Expect(manager.PluginNames(string(CapabilityMetadataAgent))).To(ContainElement("fake-metadata-agent"))
})
It("reloads a plugin on WRITE event", func() {
copyTestPlugin()
err := manager.LoadPlugin("fake-metadata-agent")
Expect(err).ToNot(HaveOccurred())
manager.processPluginEvent("fake-metadata-agent", notify.Write)
Expect(manager.PluginNames(string(CapabilityMetadataAgent))).To(ContainElement("fake-metadata-agent"))
})
It("unloads a plugin on REMOVE event", func() {
copyTestPlugin()
err := manager.LoadPlugin("fake-metadata-agent")
Expect(err).ToNot(HaveOccurred())
manager.processPluginEvent("fake-metadata-agent", notify.Remove)
Expect(manager.PluginNames(string(CapabilityMetadataAgent))).ToNot(ContainElement("fake-metadata-agent"))
})
})
Describe("Watcher lifecycle", func() {
It("does not start file watcher when AutoReload is disabled", func() {
Expect(manager.watcherEvents).To(BeNil())
Expect(manager.watcherDone).To(BeNil())
})
It("starts file watcher when AutoReload is enabled", func() {
_ = manager.Stop()
conf.Server.Plugins.AutoReload = true
autoReloadManager := &Manager{
plugins: make(map[string]*pluginInstance),
}
err := autoReloadManager.Start(ctx)
Expect(err).ToNot(HaveOccurred())
DeferCleanup(autoReloadManager.Stop)
Expect(autoReloadManager.watcherEvents).ToNot(BeNil())
Expect(autoReloadManager.watcherDone).ToNot(BeNil())
})
})
})