summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2025-07-10 08:45:45 +0300
committerPaul Buetow <paul@buetow.org>2025-07-10 08:45:45 +0300
commit8220fcdf59dcadb73ac1715287da8b3602dcdba5 (patch)
treef0d9676a3acd4618dd93ae4cd61e286caddda890
parent519d2370495975bc104e7b94952ee939aec4d8bf (diff)
Add comprehensive test cases for all syscall event types
- Add test cases for FdEvent syscalls: read, write, close, fsync, ftruncate - Add test cases for PathEvent syscalls: mkdir, unlink, creat, stat, access - Add test cases for NameEvent syscalls: rename, link, symlink - Add test cases for NullEvent syscalls: sync - Add test cases for Dup3Event syscalls: dup3 All tests pass successfully, validating proper event pairing and file object creation for each syscall type. This provides comprehensive coverage of the eventloop's ability to handle different event types and syscall patterns. 🤖 Generated with Claude Code Co-Authored-By: Claude <noreply@anthropic.com>
-rw-r--r--TODO.md22
-rw-r--r--internal/eventloop_test.go277
2 files changed, 288 insertions, 11 deletions
diff --git a/TODO.md b/TODO.md
index 58f57f0..9f6c84b 100644
--- a/TODO.md
+++ b/TODO.md
@@ -8,26 +8,26 @@
## Remaining Test Cases
### FdEvent Syscalls
-- [ ] Add test case for fsync syscall
-- [ ] Add test case for ftruncate syscall
+- [x] Add test case for fsync syscall
+- [x] Add test case for ftruncate syscall
### PathEvent Syscalls
-- [ ] Add test case for unlink syscall
-- [ ] Add test case for creat syscall
-- [ ] Add test case for stat syscall
-- [ ] Add test case for access syscall
+- [x] Add test case for unlink syscall
+- [x] Add test case for creat syscall
+- [x] Add test case for stat syscall
+- [x] Add test case for access syscall
### NameEvent Syscalls
-- [ ] Add test case for rename syscall
-- [ ] Add test case for link syscall
-- [ ] Add test case for symlink syscall
+- [x] Add test case for rename syscall
+- [x] Add test case for link syscall
+- [x] Add test case for symlink syscall
### NullEvent Syscalls
-- [ ] Add test case for sync syscall
+- [x] Add test case for sync syscall
- [ ] Add test case for io_uring_setup syscall
### Dup3Event Syscalls
-- [ ] Add test case for dup3 syscall
+- [x] Add test case for dup3 syscall
## Advanced Test Cases
diff --git a/internal/eventloop_test.go b/internal/eventloop_test.go
index 2f5e692..1c3dc2a 100644
--- a/internal/eventloop_test.go
+++ b/internal/eventloop_test.go
@@ -30,8 +30,22 @@ func TestEventloop(t *testing.T) {
"ReadEventTest": makeReadEventTestData(t),
"WriteEventTest": makeWriteEventTestData(t),
"CloseEventTest": makeCloseEventTestData(t),
+ "FsyncEventTest": makeFsyncEventTestData(t),
+ "FtruncateEventTest": makeFtruncateEventTestData(t),
// PathEvent tests
"MkdirEventTest": makeMkdirEventTestData(t),
+ "UnlinkEventTest": makeUnlinkEventTestData(t),
+ "CreatEventTest": makeCreatEventTestData(t),
+ "StatEventTest": makeStatEventTestData(t),
+ "AccessEventTest": makeAccessEventTestData(t),
+ // NameEvent tests
+ "RenameEventTest": makeRenameEventTestData(t),
+ "LinkEventTest": makeLinkEventTestData(t),
+ "SymlinkEventTest": makeSymlinkEventTestData(t),
+ // NullEvent tests
+ "SyncEventTest": makeSyncEventTestData(t),
+ // Dup3Event tests
+ "Dup3EventTest": makeDup3EventTestData(t),
}
ctx, cancel := context.WithCancel(context.Background())
@@ -294,6 +308,46 @@ func makeCloseEventTestData(t *testing.T) (td testData) {
return td
}
+func makeFsyncEventTestData(t *testing.T) (td testData) {
+ fd := int32(45)
+ enterEv, enterEvBytes := makeEnterFdEvent(t, defaulTime, defaultPid, defaultTid, fd, types.SYS_ENTER_FSYNC)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitFdEvent(t, defaulTime+100, defaultPid, defaultTid, fd, types.SYS_EXIT_FSYNC)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ })
+
+ return td
+}
+
+func makeFtruncateEventTestData(t *testing.T) (td testData) {
+ fd := int32(46)
+ enterEv, enterEvBytes := makeEnterFdEvent(t, defaulTime, defaultPid, defaultTid, fd, types.SYS_ENTER_FTRUNCATE)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitFdEvent(t, defaulTime+100, defaultPid, defaultTid, fd, types.SYS_EXIT_FTRUNCATE)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ })
+
+ return td
+}
+
// Helper functions for PathEvent
func makeEnterPathEvent(t *testing.T, time uint64, pid, tid uint32, pathname string, traceId types.TraceId) (types.PathEvent, []byte) {
ev := types.PathEvent{
@@ -412,3 +466,226 @@ func makeMkdirEventTestData(t *testing.T) (td testData) {
return td
}
+
+func makeUnlinkEventTestData(t *testing.T) (td testData) {
+ pathname := "/tmp/testfile.txt"
+ enterEv, enterEvBytes := makeEnterPathEvent(t, defaulTime, defaultPid, defaultTid, pathname, types.SYS_ENTER_UNLINK)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_UNLINK, 0)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ filenameA := types.StringValue(enterEv.Pathname[:])
+ if ep.File == nil {
+ t.Errorf("Expected file to be set")
+ } else if ep.File.Name() != filenameA {
+ t.Errorf("Expected file name '%v' but got '%v'", filenameA, ep.File.Name())
+ }
+ })
+
+ return td
+}
+
+func makeCreatEventTestData(t *testing.T) (td testData) {
+ pathname := "/tmp/newfile.txt"
+ enterEv, enterEvBytes := makeEnterPathEvent(t, defaulTime, defaultPid, defaultTid, pathname, types.SYS_ENTER_CREAT)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_CREAT, 47) // fd = 47
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ // For creat, we expect the file to be tracked with the returned fd
+ if ep.File == nil {
+ t.Errorf("Expected file to be set")
+ }
+ })
+
+ return td
+}
+
+func makeStatEventTestData(t *testing.T) (td testData) {
+ pathname := "/tmp/existingfile.txt"
+ enterEv, enterEvBytes := makeEnterPathEvent(t, defaulTime, defaultPid, defaultTid, pathname, types.SYS_ENTER_NEWSTAT)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_NEWSTAT, 0)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ filenameA := types.StringValue(enterEv.Pathname[:])
+ if ep.File == nil {
+ t.Errorf("Expected file to be set")
+ } else if ep.File.Name() != filenameA {
+ t.Errorf("Expected file name '%v' but got '%v'", filenameA, ep.File.Name())
+ }
+ })
+
+ return td
+}
+
+func makeAccessEventTestData(t *testing.T) (td testData) {
+ pathname := "/tmp/checkfile.txt"
+ enterEv, enterEvBytes := makeEnterPathEvent(t, defaulTime, defaultPid, defaultTid, pathname, types.SYS_ENTER_ACCESS)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_ACCESS, 0)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ filenameA := types.StringValue(enterEv.Pathname[:])
+ if ep.File == nil {
+ t.Errorf("Expected file to be set")
+ } else if ep.File.Name() != filenameA {
+ t.Errorf("Expected file name '%v' but got '%v'", filenameA, ep.File.Name())
+ }
+ })
+
+ return td
+}
+
+// Test data functions for NameEvent syscalls
+func makeRenameEventTestData(t *testing.T) (td testData) {
+ oldname := "/tmp/oldfile.txt"
+ newname := "/tmp/newfile.txt"
+ enterEv, enterEvBytes := makeEnterNameEvent(t, defaulTime, defaultPid, defaultTid, oldname, newname, types.SYS_ENTER_RENAME)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_RENAME, 0)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ if ep.File == nil {
+ t.Errorf("Expected file to be set")
+ } else if ep.File.Name() != newname {
+ t.Errorf("Expected file name '%v' but got '%v'", newname, ep.File.Name())
+ }
+ })
+
+ return td
+}
+
+func makeLinkEventTestData(t *testing.T) (td testData) {
+ oldname := "/tmp/original.txt"
+ newname := "/tmp/hardlink.txt"
+ enterEv, enterEvBytes := makeEnterNameEvent(t, defaulTime, defaultPid, defaultTid, oldname, newname, types.SYS_ENTER_LINK)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_LINK, 0)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ if ep.File == nil {
+ t.Errorf("Expected file to be set")
+ } else if ep.File.Name() != newname {
+ t.Errorf("Expected file name '%v' but got '%v'", newname, ep.File.Name())
+ }
+ })
+
+ return td
+}
+
+func makeSymlinkEventTestData(t *testing.T) (td testData) {
+ oldname := "/tmp/target.txt"
+ newname := "/tmp/symlink.txt"
+ enterEv, enterEvBytes := makeEnterNameEvent(t, defaulTime, defaultPid, defaultTid, oldname, newname, types.SYS_ENTER_SYMLINK)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_SYMLINK, 0)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ if ep.File == nil {
+ t.Errorf("Expected file to be set")
+ } else if ep.File.Name() != newname {
+ t.Errorf("Expected file name '%v' but got '%v'", newname, ep.File.Name())
+ }
+ })
+
+ return td
+}
+
+// Test data functions for NullEvent syscalls
+func makeSyncEventTestData(t *testing.T) (td testData) {
+ enterEv, enterEvBytes := makeEnterNullEvent(t, defaulTime, defaultPid, defaultTid, types.SYS_ENTER_SYNC)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ exitEv, exitEvBytes := makeExitNullEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_SYNC)
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ })
+
+ return td
+}
+
+// Test data functions for Dup3Event syscalls
+func makeDup3EventTestData(t *testing.T) (td testData) {
+ oldFd := int32(49)
+ enterEv, enterEvBytes := makeEnterDup3Event(t, defaulTime, defaultPid, defaultTid, oldFd, syscall.O_CLOEXEC)
+ td.rawTracepoints = append(td.rawTracepoints, enterEvBytes)
+
+ newFd := int32(50)
+ exitEv, exitEvBytes := makeExitRetEvent(t, defaulTime+100, defaultPid, defaultTid, types.SYS_EXIT_DUP3, int64(newFd))
+ td.rawTracepoints = append(td.rawTracepoints, exitEvBytes)
+
+ td.validates = append(td.validates, func(t *testing.T, el *eventLoop, ep *event.Pair) {
+ if !enterEv.Equals(ep.EnterEv) {
+ t.Errorf("Expected '%v' but got '%v'", enterEv, ep.EnterEv)
+ }
+ if !exitEv.Equals(ep.ExitEv) {
+ t.Errorf("Expected '%v' but got '%v'", exitEv, ep.ExitEv)
+ }
+ })
+
+ return td
+} \ No newline at end of file