watch: add tests for ignores and number of watches (#1838)

This commit is contained in:
Nick Santos 2019-07-11 17:54:50 -04:00 committed by Nicolas De loof
parent 7f6e189dbc
commit 390d5cf165
4 changed files with 113 additions and 28 deletions

View File

@ -1,6 +1,14 @@
package watch package watch
import "github.com/windmilleng/tilt/internal/logger" import (
"expvar"
"github.com/windmilleng/tilt/internal/logger"
)
var (
numberOfWatches = expvar.NewInt("watch.naive.numberOfWatches")
)
type FileEvent struct { type FileEvent struct {
Path string Path string

View File

@ -14,6 +14,7 @@ import (
"github.com/stretchr/testify/assert" "github.com/stretchr/testify/assert"
"github.com/windmilleng/tilt/internal/dockerignore"
"github.com/windmilleng/tilt/internal/logger" "github.com/windmilleng/tilt/internal/logger"
"github.com/windmilleng/tilt/internal/testutils/tempdir" "github.com/windmilleng/tilt/internal/testutils/tempdir"
) )
@ -412,36 +413,99 @@ func TestWatchNonexistentDirectory(t *testing.T) {
} }
} }
// doesn't work on linux func TestWatchNonexistentFileInNonexistentDirectory(t *testing.T) {
// func TestWatchNonexistentFileInNonexistentDirectory(t *testing.T) { f := newNotifyFixture(t)
// f := newNotifyFixture(t) defer f.tearDown()
// defer f.tearDown()
// root := f.JoinPath("root") root := f.JoinPath("root")
// err := os.Mkdir(root, 0777) err := os.Mkdir(root, 0777)
// if err != nil { if err != nil {
// t.Fatal(err) t.Fatal(err)
// } }
// parent := f.JoinPath("parent") parent := f.JoinPath("parent")
// file := f.JoinPath("parent", "a") file := f.JoinPath("parent", "a")
// f.watch(file) f.watch(file)
// f.assertEvents() f.assertEvents()
// err = os.Mkdir(parent, 0777) err = os.Mkdir(parent, 0777)
// if err != nil { if err != nil {
// t.Fatal(err) t.Fatal(err)
// } }
// f.assertEvents() f.assertEvents()
// f.WriteFile(file, "hello") f.WriteFile(file, "hello")
// f.assertEvents(file) f.assertEvents(file)
// } }
func TestWatchCountInnerFile(t *testing.T) {
f := newNotifyFixture(t)
defer f.tearDown()
root := f.paths[0]
a := f.JoinPath(root, "a")
b := f.JoinPath(a, "b")
file := f.JoinPath(b, "bigFile")
f.WriteFile(file, "hello")
f.assertEvents(a, b, file)
expectedWatches := 3
if runtime.GOOS == "darwin" {
expectedWatches = 1
}
assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
}
func TestWatchCountInnerFileWithIgnore(t *testing.T) {
f := newNotifyFixture(t)
defer f.tearDown()
root := f.paths[0]
ignore, _ := dockerignore.NewDockerPatternMatcher(root, []string{
"a",
"!a/b",
})
f.setIgnore(ignore)
a := f.JoinPath(root, "a")
b := f.JoinPath(a, "b")
file := f.JoinPath(b, "bigFile")
f.WriteFile(file, "hello")
f.assertEvents(b, file)
expectedWatches := 3
if runtime.GOOS == "darwin" {
expectedWatches = 1
}
assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
}
func TestIgnore(t *testing.T) {
f := newNotifyFixture(t)
defer f.tearDown()
root := f.paths[0]
ignore, _ := dockerignore.NewDockerPatternMatcher(root, []string{"a/b"})
f.setIgnore(ignore)
a := f.JoinPath(root, "a")
b := f.JoinPath(a, "b")
file := f.JoinPath(b, "bigFile")
f.WriteFile(file, "hello")
f.assertEvents(a)
expectedWatches := 3
if runtime.GOOS == "darwin" {
expectedWatches = 1
}
assert.Equal(t, expectedWatches, int(numberOfWatches.Value()))
}
type notifyFixture struct { type notifyFixture struct {
out *bytes.Buffer out *bytes.Buffer
*tempdir.TempDirFixture *tempdir.TempDirFixture
notify Notify notify Notify
ignore PathMatcher
paths []string paths []string
events []FileEvent events []FileEvent
} }
@ -451,15 +515,24 @@ func newNotifyFixture(t *testing.T) *notifyFixture {
nf := &notifyFixture{ nf := &notifyFixture{
TempDirFixture: tempdir.NewTempDirFixture(t), TempDirFixture: tempdir.NewTempDirFixture(t),
paths: []string{}, paths: []string{},
ignore: EmptyMatcher{},
out: out, out: out,
} }
nf.watch(nf.TempDir("watched")) nf.watch(nf.TempDir("watched"))
return nf return nf
} }
func (f *notifyFixture) setIgnore(ignore PathMatcher) {
f.ignore = ignore
f.rebuildWatcher()
}
func (f *notifyFixture) watch(path string) { func (f *notifyFixture) watch(path string) {
f.paths = append(f.paths, path) f.paths = append(f.paths, path)
f.rebuildWatcher()
}
func (f *notifyFixture) rebuildWatcher() {
// sync any outstanding events and close the old watcher // sync any outstanding events and close the old watcher
if f.notify != nil { if f.notify != nil {
f.fsync() f.fsync()
@ -467,7 +540,7 @@ func (f *notifyFixture) watch(path string) {
} }
// create a new watcher // create a new watcher
notify, err := NewWatcher(f.paths, EmptyMatcher{}, logger.NewLogger(logger.DebugLvl, f.out)) notify, err := NewWatcher(f.paths, f.ignore, logger.NewLogger(logger.DebugLvl, f.out))
if err != nil { if err != nil {
f.T().Fatal(err) f.T().Fatal(err)
} }
@ -569,4 +642,5 @@ func (f *notifyFixture) closeWatcher() {
func (f *notifyFixture) tearDown() { func (f *notifyFixture) tearDown() {
f.closeWatcher() f.closeWatcher()
f.TempDirFixture.TearDown() f.TempDirFixture.TearDown()
numberOfWatches.Set(0)
} }

View File

@ -89,6 +89,8 @@ func (d *darwinNotify) initAdd(name string) {
} }
func (d *darwinNotify) Start() error { func (d *darwinNotify) Start() error {
numberOfWatches.Add(int64(len(d.stream.Paths)))
d.stream.Start() d.stream.Start()
go d.loop() go d.loop()
@ -97,6 +99,8 @@ func (d *darwinNotify) Start() error {
} }
func (d *darwinNotify) Close() error { func (d *darwinNotify) Close() error {
numberOfWatches.Add(int64(-len(d.stream.Paths)))
d.stream.Stop() d.stream.Stop()
close(d.errors) close(d.errors)
close(d.stop) close(d.stop)

View File

@ -3,7 +3,6 @@
package watch package watch
import ( import (
"expvar"
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
@ -32,12 +31,9 @@ type naiveNotify struct {
events chan fsnotify.Event events chan fsnotify.Event
wrappedEvents chan FileEvent wrappedEvents chan FileEvent
errors chan error errors chan error
numWatches int64
} }
var (
numberOfWatches = expvar.NewInt("watch.naive.numberOfWatches")
)
func (d *naiveNotify) Start() error { func (d *naiveNotify) Start() error {
for name := range d.notifyList { for name := range d.notifyList {
fi, err := os.Stat(name) fi, err := os.Stat(name)
@ -108,6 +104,8 @@ func (d *naiveNotify) watchAncestorOfMissingPath(path string) error {
} }
func (d *naiveNotify) Close() error { func (d *naiveNotify) Close() error {
numberOfWatches.Add(-d.numWatches)
d.numWatches = 0
return d.watcher.Close() return d.watcher.Close()
} }
@ -191,6 +189,7 @@ func (d *naiveNotify) add(path string) error {
if err != nil { if err != nil {
return err return err
} }
d.numWatches++
numberOfWatches.Add(1) numberOfWatches.Add(1)
return nil return nil
} }