watch: fix inotify tests on windows (#3140)

This commit is contained in:
Nick Santos 2020-03-30 12:25:09 -04:00 committed by Nicolas De loof
parent ddc88ec41b
commit dda0362b6e
3 changed files with 47 additions and 6 deletions

View File

@ -1,5 +1,3 @@
// +build !windows
package watch package watch
import ( import (
@ -41,6 +39,9 @@ func TestNoWatches(t *testing.T) {
} }
func TestEventOrdering(t *testing.T) { func TestEventOrdering(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping on windows for now")
}
f := newNotifyFixture(t) f := newNotifyFixture(t)
defer f.tearDown() defer f.tearDown()
@ -73,6 +74,9 @@ func TestEventOrdering(t *testing.T) {
// of directories, creates files in them, then deletes // of directories, creates files in them, then deletes
// them all quickly. Make sure there are no errors. // them all quickly. Make sure there are no errors.
func TestGitBranchSwitch(t *testing.T) { func TestGitBranchSwitch(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping on windows for now")
}
f := newNotifyFixture(t) f := newNotifyFixture(t)
defer f.tearDown() defer f.tearDown()
@ -143,10 +147,11 @@ func TestWatchesAreRecursive(t *testing.T) {
f.events = nil f.events = nil
// change sub directory // change sub directory
changeFilePath := filepath.Join(subPath, "change") changeFilePath := filepath.Join(subPath, "change")
_, err := os.OpenFile(changeFilePath, os.O_RDONLY|os.O_CREATE, 0666) h, err := os.OpenFile(changeFilePath, os.O_RDONLY|os.O_CREATE, 0666)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer h.Close()
f.assertEvents(changeFilePath) f.assertEvents(changeFilePath)
} }
@ -168,10 +173,12 @@ func TestNewDirectoriesAreRecursivelyWatched(t *testing.T) {
// change something inside sub directory // change something inside sub directory
changeFilePath := filepath.Join(subPath, "change") changeFilePath := filepath.Join(subPath, "change")
_, err := os.OpenFile(changeFilePath, os.O_RDONLY|os.O_CREATE, 0666) h, err := os.OpenFile(changeFilePath, os.O_RDONLY|os.O_CREATE, 0666)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
defer h.Close()
f.assertEvents(subPath, changeFilePath) f.assertEvents(subPath, changeFilePath)
} }
@ -278,6 +285,9 @@ func TestSingleFile(t *testing.T) {
} }
func TestWriteBrokenLink(t *testing.T) { func TestWriteBrokenLink(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Symlink creation requires admin privileges on Windows")
}
f := newNotifyFixture(t) f := newNotifyFixture(t)
defer f.tearDown() defer f.tearDown()
@ -292,6 +302,9 @@ func TestWriteBrokenLink(t *testing.T) {
} }
func TestWriteGoodLink(t *testing.T) { func TestWriteGoodLink(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Symlink creation requires admin privileges on Windows")
}
f := newNotifyFixture(t) f := newNotifyFixture(t)
defer f.tearDown() defer f.tearDown()
@ -311,6 +324,9 @@ func TestWriteGoodLink(t *testing.T) {
} }
func TestWatchBrokenLink(t *testing.T) { func TestWatchBrokenLink(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Symlink creation requires admin privileges on Windows")
}
f := newNotifyFixture(t) f := newNotifyFixture(t)
defer f.tearDown() defer f.tearDown()
@ -339,6 +355,10 @@ func TestWatchBrokenLink(t *testing.T) {
} }
func TestMoveAndReplace(t *testing.T) { func TestMoveAndReplace(t *testing.T) {
if runtime.GOOS == "windows" {
t.Skip("Skipping on windows for now")
}
f := newNotifyFixture(t) f := newNotifyFixture(t)
defer f.tearDown() defer f.tearDown()

View File

@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"path/filepath" "path/filepath"
"runtime"
"github.com/pkg/errors" "github.com/pkg/errors"
"github.com/windmilleng/fsnotify" "github.com/windmilleng/fsnotify"
@ -135,7 +136,7 @@ func (d *naiveNotify) loop() {
defer close(d.wrappedEvents) defer close(d.wrappedEvents)
for e := range d.events { for e := range d.events {
if e.Op&fsnotify.Create != fsnotify.Create { if e.Op&fsnotify.Create != fsnotify.Create {
if d.shouldNotify(e.Name) { if d.shouldNotify(e.Name) && !isSpuriousWindowsDirChange(e) {
d.wrappedEvents <- FileEvent{e.Name} d.wrappedEvents <- FileEvent{e.Name}
} }
continue continue
@ -262,6 +263,22 @@ func newWatcher(paths []string, ignore PathMatcher, l logger.Logger) (*naiveNoti
return wmw, nil return wmw, nil
} }
// Windows' inotify implementation sometimes fires
// of spurious WRITE events on directories when the
// files inside change.
func isSpuriousWindowsDirChange(e fsnotify.Event) bool {
if runtime.GOOS != "windows" {
return false
}
if e.Op != fsnotify.Write {
return false
}
eIsDir, _ := isDir(e.Name)
return eIsDir
}
func isDir(pth string) (bool, error) { func isDir(pth string) (bool, error) {
fi, err := os.Lstat(pth) fi, err := os.Lstat(pth)
if os.IsNotExist(err) { if os.IsNotExist(err) {

View File

@ -1,4 +1,4 @@
// +build !darwin,!windows // +build !darwin
package watch package watch
@ -6,6 +6,7 @@ import (
"fmt" "fmt"
"os" "os"
"os/exec" "os/exec"
"runtime"
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
@ -92,6 +93,9 @@ func TestDontWatchEachFile(t *testing.T) {
f.events = nil f.events = nil
pid := os.Getpid() pid := os.Getpid()
if runtime.GOOS == "windows" {
return // skip the inotify count
}
output, err := exec.Command("bash", "-c", fmt.Sprintf( output, err := exec.Command("bash", "-c", fmt.Sprintf(
"find /proc/%d/fd -lname anon_inode:inotify -printf '%%hinfo/%%f\n' | xargs cat | grep -c '^inotify'", pid)).Output() "find /proc/%d/fd -lname anon_inode:inotify -printf '%%hinfo/%%f\n' | xargs cat | grep -c '^inotify'", pid)).Output()