Skip to content

Commit 10976fb

Browse files
committed
Add Stringer and test multiple events
- Add String() implementation to Event and Action types - Add test to check multiple events
1 parent ee4bfd4 commit 10976fb

File tree

2 files changed

+91
-3
lines changed

2 files changed

+91
-3
lines changed

fanotify_api.go

Lines changed: 35 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@ package fanotify
55

66
import (
77
"errors"
8+
"fmt"
89
"os"
10+
"strings"
911

1012
"golang.org/x/sys/unix"
1113
)
@@ -99,9 +101,9 @@ func NewListener(mountpointPath string, maxEvents uint, withName bool) (*Listene
99101
// The events are pushed into the Listener's `Events` buffered channel.
100102
// The function panics if there nothing to watch.
101103
func (l *Listener) Start() {
102-
if len(l.watches) == 0 {
103-
panic("Nothing to watch. Add Directory/File to the listener to watch")
104-
}
104+
//if len(l.watches) == 0 {
105+
// panic("Nothing to watch. Add Directory/File to the listener to watch")
106+
//}
105107
var fds [2]unix.PollFd
106108
// Fanotify Fd
107109
fds[0].Fd = int32(l.fd)
@@ -185,3 +187,33 @@ func (actions Action) Has(a Action) bool {
185187
func (actions Action) Or(a Action) Action {
186188
return actions | a
187189
}
190+
191+
// String prints action
192+
func (a Action) String() string {
193+
var actions = map[Action]string{
194+
unix.FAN_ACCESS: "Access",
195+
unix.FAN_MODIFY: "Modify",
196+
unix.FAN_CLOSE_WRITE: "CloseWrite",
197+
unix.FAN_CLOSE_NOWRITE: "CloseNoWrite",
198+
unix.FAN_OPEN: "Open",
199+
unix.FAN_OPEN_EXEC: "OpenExec",
200+
unix.FAN_ATTRIB: "AttribChange",
201+
unix.FAN_CREATE: "Create",
202+
unix.FAN_DELETE: "Delete",
203+
unix.FAN_DELETE_SELF: "SelfDelete",
204+
unix.FAN_MOVED_FROM: "MovedFrom",
205+
unix.FAN_MOVED_TO: "MovedTo",
206+
unix.FAN_MOVE_SELF: "SelfMove",
207+
}
208+
var actionList []string
209+
for k, v := range actions {
210+
if a.Has(k) {
211+
actionList = append(actionList, v)
212+
}
213+
}
214+
return strings.Join(actionList, ",")
215+
}
216+
217+
func (e Event) String() string {
218+
return fmt.Sprintf("Fd:(%d), Pid:(%d), Action:(%s), Path:(%s), Filename:(%s)", e.Fd, e.Pid, e.Actions, e.Path, e.FileName)
219+
}

fanotify_test.go

Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -381,3 +381,59 @@ func TestActions(t *testing.T) {
381381
assert.True(t, actions.Has(FileModified))
382382
assert.True(t, actions.Has(FileDeleted))
383383
}
384+
385+
func TestMultipleEvents(t *testing.T) {
386+
l, err := NewListener("/", 4096, true)
387+
assert.Nil(t, err)
388+
assert.NotNil(t, l)
389+
go l.Start()
390+
defer l.Stop()
391+
392+
watchDir := t.TempDir()
393+
actions := FileOrDirCreated.Or(FileModified.Or(FileDeleted))
394+
l.AddWatch(watchDir, actions)
395+
testFile := fmt.Sprintf("%s/test.txt", watchDir)
396+
pid, err := runAsCmd("touch", testFile) // create file
397+
assert.Nil(t, err)
398+
select {
399+
case <-time.After(100 * time.Millisecond):
400+
t.Error("Timeout Error: FileCreated event not received")
401+
case event := <-l.Events:
402+
assert.Equal(t, fmt.Sprintf("%s/%s", event.Path, event.FileName), testFile)
403+
assert.Equal(t, event.Pid, pid)
404+
assert.True(t, event.Actions.Has(FileCreated))
405+
t.Logf("Received: (%s)", event)
406+
}
407+
touchPid := pid
408+
409+
// modify file
410+
os.WriteFile(testFile, []byte("test string"), 0666)
411+
pid = os.Getpid()
412+
select {
413+
case <-time.After(100 * time.Millisecond):
414+
t.Error("Timeout Error: FileModified event not received")
415+
case event := <-l.Events:
416+
assert.Equal(t, fmt.Sprintf("%s/%s", event.Path, event.FileName), testFile)
417+
assert.Equal(t, event.Pid, pid)
418+
assert.True(t, event.Actions.Has(FileModified))
419+
t.Logf("Received: (%s)", event)
420+
}
421+
422+
t.Logf("Pids: Self(%d), Touch(%d)", pid, touchPid)
423+
// NOTE: os.WriteFile sends two modify events; so draining them
424+
for len(l.Events) > 0 {
425+
e := <-l.Events
426+
t.Logf("Drain-Event: (%s)", e)
427+
}
428+
pid, err = runAsCmd("rm", "-f", testFile)
429+
assert.Nil(t, err)
430+
select {
431+
case <-time.After(100 * time.Millisecond):
432+
t.Error("Timeout Error: FileDeleted event not received")
433+
case event := <-l.Events:
434+
assert.Equal(t, fmt.Sprintf("%s/%s", event.Path, event.FileName), testFile)
435+
assert.Equal(t, event.Pid, pid)
436+
assert.True(t, event.Actions.Has(FileDeleted))
437+
t.Logf("Received: (%s)", event)
438+
}
439+
}

0 commit comments

Comments
 (0)