60 lines
1.4 KiB
Go
60 lines
1.4 KiB
Go
package data
|
|
|
|
import (
|
|
"os"
|
|
"path/filepath"
|
|
"sync"
|
|
"testing"
|
|
"time"
|
|
|
|
"kra/internal/config"
|
|
)
|
|
|
|
func TestConfigWatcherStopWaitsForDebouncedReload(t *testing.T) {
|
|
root := t.TempDir()
|
|
configPath := filepath.Join(root, "config.yaml")
|
|
config := []byte("data:\n database:\n driver: sqlite\n path: " + filepath.ToSlash(root) + "\nadmin: {}\n")
|
|
if err := os.WriteFile(configPath, config, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
runtime := config.NewStore(&config.Config{Data: &config.Data{}, Admin: &config.Admin{ConfigPath: configPath}})
|
|
started := make(chan struct{})
|
|
release := make(chan struct{})
|
|
var startOnce sync.Once
|
|
stopListener := runtime.Subscribe(func(*config.Data, *config.Admin) {
|
|
startOnce.Do(func() { close(started) })
|
|
<-release
|
|
})
|
|
defer stopListener()
|
|
data := &Data{runtime: runtime}
|
|
stop := data.watchConfig()
|
|
|
|
// A write event schedules the 100ms debounce reload.
|
|
if err := os.WriteFile(configPath, config, 0o600); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
select {
|
|
case <-started:
|
|
case <-time.After(3 * time.Second):
|
|
stop()
|
|
t.Fatal("debounced reload did not start")
|
|
}
|
|
|
|
stopped := make(chan struct{})
|
|
go func() {
|
|
stop()
|
|
close(stopped)
|
|
}()
|
|
select {
|
|
case <-stopped:
|
|
t.Fatal("watcher stop returned before reload callback finished")
|
|
case <-time.After(100 * time.Millisecond):
|
|
}
|
|
close(release)
|
|
select {
|
|
case <-stopped:
|
|
case <-time.After(time.Second):
|
|
t.Fatal("watcher stop did not wait for callback completion")
|
|
}
|
|
}
|