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}