summaryrefslogtreecommitdiffstats
path: root/vendor/gopkg.in/fsnotify.v1/inotify_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/gopkg.in/fsnotify.v1/inotify_test.go')
-rw-r--r--vendor/gopkg.in/fsnotify.v1/inotify_test.go128
1 files changed, 72 insertions, 56 deletions
diff --git a/vendor/gopkg.in/fsnotify.v1/inotify_test.go b/vendor/gopkg.in/fsnotify.v1/inotify_test.go
index 2527cad1f..a4bb202d1 100644
--- a/vendor/gopkg.in/fsnotify.v1/inotify_test.go
+++ b/vendor/gopkg.in/fsnotify.v1/inotify_test.go
@@ -10,10 +10,9 @@ import (
"fmt"
"os"
"path/filepath"
+ "strings"
"testing"
"time"
-
- "golang.org/x/sys/unix"
)
func TestInotifyCloseRightAway(t *testing.T) {
@@ -154,10 +153,14 @@ func TestInotifyCloseCreate(t *testing.T) {
}
}
+// This test verifies the watcher can keep up with file creations/deletions
+// when under load.
func TestInotifyStress(t *testing.T) {
+ maxNumToCreate := 1000
+
testDir := tempMkdir(t)
defer os.RemoveAll(testDir)
- testFile := filepath.Join(testDir, "testfile")
+ testFilePrefix := filepath.Join(testDir, "testfile")
w, err := NewWatcher()
if err != nil {
@@ -165,84 +168,85 @@ func TestInotifyStress(t *testing.T) {
}
defer w.Close()
- killchan := make(chan struct{})
- defer close(killchan)
-
err = w.Add(testDir)
if err != nil {
t.Fatalf("Failed to add testDir: %v", err)
}
- proc, err := os.FindProcess(os.Getpid())
- if err != nil {
- t.Fatalf("Error finding process: %v", err)
- }
+ doneChan := make(chan struct{})
+ // The buffer ensures that the file generation goroutine is never blocked.
+ errChan := make(chan error, 2*maxNumToCreate)
go func() {
- for {
- select {
- case <-time.After(5 * time.Millisecond):
- err := proc.Signal(unix.SIGUSR1)
- if err != nil {
- t.Fatalf("Signal failed: %v", err)
- }
- case <-killchan:
- return
+ for i := 0; i < maxNumToCreate; i++ {
+ testFile := fmt.Sprintf("%s%d", testFilePrefix, i)
+
+ handle, err := os.Create(testFile)
+ if err != nil {
+ errChan <- fmt.Errorf("Create failed: %v", err)
+ continue
}
- }
- }()
- go func() {
- for {
- select {
- case <-time.After(11 * time.Millisecond):
- err := w.poller.wake()
- if err != nil {
- t.Fatalf("Wake failed: %v", err)
- }
- case <-killchan:
- return
+ err = handle.Close()
+ if err != nil {
+ errChan <- fmt.Errorf("Close failed: %v", err)
+ continue
}
}
- }()
- go func() {
- for {
- select {
- case <-killchan:
- return
- default:
- handle, err := os.Create(testFile)
- if err != nil {
- t.Fatalf("Create failed: %v", err)
- }
- handle.Close()
- time.Sleep(time.Millisecond)
- err = os.Remove(testFile)
- if err != nil {
- t.Fatalf("Remove failed: %v", err)
- }
+ // If we delete a newly created file too quickly, inotify will skip the
+ // create event and only send the delete event.
+ time.Sleep(100 * time.Millisecond)
+
+ for i := 0; i < maxNumToCreate; i++ {
+ testFile := fmt.Sprintf("%s%d", testFilePrefix, i)
+ err = os.Remove(testFile)
+ if err != nil {
+ errChan <- fmt.Errorf("Remove failed: %v", err)
}
}
+
+ close(doneChan)
}()
creates := 0
removes := 0
- after := time.After(5 * time.Second)
- for {
+
+ finished := false
+ after := time.After(10 * time.Second)
+ for !finished {
select {
case <-after:
- if creates-removes > 1 || creates-removes < -1 {
- t.Fatalf("Creates and removes should not be off by more than one: %d creates, %d removes", creates, removes)
+ t.Fatalf("Not done")
+ case <-doneChan:
+ finished = true
+ case err := <-errChan:
+ t.Fatalf("Got an error from file creator goroutine: %v", err)
+ case err := <-w.Errors:
+ t.Fatalf("Got an error from watcher: %v", err)
+ case evt := <-w.Events:
+ if !strings.HasPrefix(evt.Name, testFilePrefix) {
+ t.Fatalf("Got an event for an unknown file: %s", evt.Name)
+ }
+ if evt.Op == Create {
+ creates++
}
- if creates < 50 {
- t.Fatalf("Expected at least 50 creates, got %d", creates)
+ if evt.Op == Remove {
+ removes++
}
- return
+ }
+ }
+
+ // Drain remaining events from channels
+ count := 0
+ for count < 10 {
+ select {
+ case err := <-errChan:
+ t.Fatalf("Got an error from file creator goroutine: %v", err)
case err := <-w.Errors:
t.Fatalf("Got an error from watcher: %v", err)
case evt := <-w.Events:
- if evt.Name != testFile {
+ if !strings.HasPrefix(evt.Name, testFilePrefix) {
t.Fatalf("Got an event for an unknown file: %s", evt.Name)
}
if evt.Op == Create {
@@ -251,8 +255,20 @@ func TestInotifyStress(t *testing.T) {
if evt.Op == Remove {
removes++
}
+ count = 0
+ default:
+ count++
+ // Give the watcher chances to fill the channels.
+ time.Sleep(time.Millisecond)
}
}
+
+ if creates-removes > 1 || creates-removes < -1 {
+ t.Fatalf("Creates and removes should not be off by more than one: %d creates, %d removes", creates, removes)
+ }
+ if creates < 50 {
+ t.Fatalf("Expected at least 50 creates, got %d", creates)
+ }
}
func TestInotifyRemoveTwice(t *testing.T) {