Skip to content

Commit

Permalink
Add "test scripts" in testdata/ (#623)
Browse files Browse the repository at this point in the history
This is the same as the existing tests, except more readable and
maintainable.
  • Loading branch information
arp242 committed Apr 27, 2024
1 parent eec439f commit 5fba421
Show file tree
Hide file tree
Showing 57 changed files with 1,152 additions and 1,181 deletions.
97 changes: 97 additions & 0 deletions CONTRIBUTING.md
Expand Up @@ -20,6 +20,103 @@ platforms. Testing different platforms locally can be done with something like

Use the `-short` flag to make the "stress test" run faster.

Writing new tests
-----------------
Scripts in the testdata directory allow creating test cases in a "shell-like"
syntax. The basic format is:

script

Output:
desired output

For example:

# Create a new empty file with some data.
watch /
echo data /file

Output:
create /file
write /file

Just create a new file to add a new test; select which tests to run with
`-run TestScript/[path]`.

script
------
The script is a "shell-like" script:

cmd arg arg

Comments are supported with `#`:

# Comment
cmd arg arg # Comment

All operations are done in a temp directory; a path like "/foo" is rewritten to
"/tmp/TestFoo/foo".

Arguments can be quoted with `"` or `'`; there are no escapes and they're
functionally identical right now, but this may change in the future, so best to
assume shell-like rules.

touch "$tmp/file with spaces"

End-of-line escapes with `\` are not supported.

A command will sleep for 50ms after the desired operation; prefix the command
with `nowait` to skip this:

nowait touch $tmp/file

### Supported commands

watch path # Watch the path, reporting events for it.

touch path
mkdir [-p] dir
ln -s target link # Only ln -s supported.
mkfifo path
mknod dev path
mv src dst
rm [-r] path
chmod mode path # Octal only
sleep time-in-ms

echo str >>path # Append "str" to "path".
echo str >path # Truncate "path" and write "str".


require reason # Skip the test if "reason" is true; both "skip" and
skip reason # "require" behave identical; it supports both for
# readability. Possible reasons are:
#
# symlink Symlinks are supported (requires admin
# permissions on Windows).
# mkfifo Platform doesn't support FIFO named sockets.
# mknod Platform doesn't support device nodes.


output
------
After `Output:` the desired output is given; this is indented by convention, but
that's not required.

The format of that is:

# Comment
event path # Comment

system:
event path
system2:
event path

It's a list of events relative to $tmp. After a `system:` line exceptions can be
added for a specific system.



[goon]: https://github.com/arp242/goon
[Vagrant]: https://www.vagrantup.com/
Expand Down
1 change: 0 additions & 1 deletion backend_fen.go
@@ -1,5 +1,4 @@
//go:build solaris
// +build solaris

// FEN backend for illumos (supported) and Solaris (untested, but should work).
//
Expand Down
1 change: 0 additions & 1 deletion backend_fen_test.go
@@ -1,5 +1,4 @@
//go:build solaris
// +build solaris

package fsnotify

Expand Down
1 change: 0 additions & 1 deletion backend_inotify.go
@@ -1,5 +1,4 @@
//go:build linux && !appengine
// +build linux,!appengine

// Note: the documentation on the Watcher type and methods is generated from
// mkdoc.zsh
Expand Down
67 changes: 33 additions & 34 deletions backend_inotify_test.go
@@ -1,5 +1,4 @@
//go:build linux
// +build linux

package fsnotify

Expand All @@ -13,6 +12,39 @@ import (
"time"
)

func TestRemoveState(t *testing.T) {
var (
tmp = t.TempDir()
dir = join(tmp, "dir")
file = join(dir, "file")
)
mkdir(t, dir)
touch(t, file)

w := newWatcher(t, tmp)
addWatch(t, w, tmp)
addWatch(t, w, file)

check := func(want int) {
t.Helper()
if w.watches.len() != want {
t.Error(w.watches)
}
}

check(2)

if err := w.Remove(file); err != nil {
t.Fatal(err)
}
check(1)

if err := w.Remove(tmp); err != nil {
t.Fatal(err)
}
check(0)
}

// Ensure that the correct error is returned on overflows.
func TestInotifyOverflow(t *testing.T) {
t.Parallel()
Expand Down Expand Up @@ -101,36 +133,3 @@ func TestInotifyDeleteOpenFile(t *testing.T) {
e = w.stop(t)
cmpEvents(t, tmp, e, newEvents(t, `remove /file`))
}

func TestRemoveState(t *testing.T) {
var (
tmp = t.TempDir()
dir = join(tmp, "dir")
file = join(dir, "file")
)
mkdir(t, dir)
touch(t, file)

w := newWatcher(t, tmp)
addWatch(t, w, tmp)
addWatch(t, w, file)

check := func(want int) {
t.Helper()
if w.watches.len() != want {
t.Error(w.watches)
}
}

check(2)

if err := w.Remove(file); err != nil {
t.Fatal(err)
}
check(1)

if err := w.Remove(tmp); err != nil {
t.Fatal(err)
}
check(0)
}
1 change: 0 additions & 1 deletion backend_kqueue.go
@@ -1,5 +1,4 @@
//go:build freebsd || openbsd || netbsd || dragonfly || darwin
// +build freebsd openbsd netbsd dragonfly darwin

// Note: the documentation on the Watcher type and methods is generated from
// mkdoc.zsh
Expand Down
1 change: 0 additions & 1 deletion backend_kqueue_test.go
@@ -1,5 +1,4 @@
//go:build freebsd || openbsd || netbsd || dragonfly || darwin
// +build freebsd openbsd netbsd dragonfly darwin

package fsnotify

Expand Down
1 change: 0 additions & 1 deletion backend_other.go
@@ -1,5 +1,4 @@
//go:build appengine || (!darwin && !dragonfly && !freebsd && !openbsd && !linux && !netbsd && !solaris && !windows)
// +build appengine !darwin,!dragonfly,!freebsd,!openbsd,!linux,!netbsd,!solaris,!windows

// Note: the documentation on the Watcher type and methods is generated from
// mkdoc.zsh
Expand Down
1 change: 0 additions & 1 deletion backend_windows.go
@@ -1,5 +1,4 @@
//go:build windows
// +build windows

// Windows backend based on ReadDirectoryChangesW()
//
Expand Down
1 change: 0 additions & 1 deletion backend_windows_test.go
@@ -1,5 +1,4 @@
//go:build windows
// +build windows

package fsnotify

Expand Down

0 comments on commit 5fba421

Please sign in to comment.