internal/library/watch_test.go

59 lines · 1653 bytes

 1package library
 2
 3import (
 4	"context"
 5	"os"
 6	"path/filepath"
 7	"testing"
 8	"time"
 9
10	"github.com/fsnotify/fsnotify"
11)
12
13func expectCall(t *testing.T, ch <-chan struct{}, what string) {
14	t.Helper()
15	select {
16	case <-ch:
17	case <-time.After(3 * time.Second):
18		t.Fatalf("no onChange after %s", what)
19	}
20}
21
22func TestWatchDebouncesAndFollowsNewDirs(t *testing.T) {
23	root := writeTree(t, map[string]string{"tokyo/a.jpg": "x"})
24	ctx, cancel := context.WithCancel(context.Background())
25	defer cancel()
26
27	calls := make(chan struct{}, 10)
28	if err := Watch(ctx, root, 100*time.Millisecond, func() { calls <- struct{}{} }); err != nil {
29		t.Fatal(err)
30	}
31
32	for _, n := range []string{"b.jpg", "c.jpg", "d.jpg"} {
33		os.WriteFile(filepath.Join(root, "tokyo", n), []byte("x"), 0o644)
34	}
35	expectCall(t, calls, "writes in existing album")
36	select {
37	case <-calls:
38		t.Fatal("burst of writes produced more than one call")
39	case <-time.After(300 * time.Millisecond):
40	}
41
42	os.Mkdir(filepath.Join(root, "iceland"), 0o755)
43	expectCall(t, calls, "new album dir")
44	time.Sleep(150 * time.Millisecond) // let the watcher add the new dir
45	os.WriteFile(filepath.Join(root, "iceland", "a.jpg"), []byte("x"), 0o644)
46	expectCall(t, calls, "write in new album")
47}
48
49func TestWatchLoopOverflowTriggersRescan(t *testing.T) {
50	ctx, cancel := context.WithCancel(context.Background())
51	defer cancel()
52	events := make(chan fsnotify.Event)
53	errs := make(chan error)
54	calls := make(chan struct{}, 1)
55	go watchLoop(ctx, events, errs, func(string) error { return nil }, 50*time.Millisecond, func() { calls <- struct{}{} })
56
57	errs <- fsnotify.ErrEventOverflow
58	expectCall(t, calls, "event overflow")
59}