summaryrefslogtreecommitdiff
path: root/integrationtests/cmd
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-02-21 20:53:07 +0200
committerPaul Buetow <paul@buetow.org>2026-02-21 20:53:07 +0200
commitcd516e1577ad97d5c8b1603657b13d110557e1b2 (patch)
treeaf13921fff67f173d4e9ff97e48c54812dc1ca81 /integrationtests/cmd
parent4e287fd01d5057d0345183b6845dcc58683a46e4 (diff)
Add negative integration tests for open syscalls
- openEnoent: verifies ior captures enter_openat even when syscall fails (ENOENT) - openRdonlyWrite: verifies tracing of open + failed write to read-only fd - openPidFilter: verifies child process I/O is excluded by PID filtering - AssertEventsAbsent helper with zero-value guard and 6 unit tests Task: 348 Amp-Thread-ID: https://ampcode.com/threads/T-019c8185-55f4-72f0-8ddb-3be5e4002c0d Co-authored-by: Amp <amp@ampcode.com>
Diffstat (limited to 'integrationtests/cmd')
-rw-r--r--integrationtests/cmd/ioworkload/scenarios.go80
1 files changed, 80 insertions, 0 deletions
diff --git a/integrationtests/cmd/ioworkload/scenarios.go b/integrationtests/cmd/ioworkload/scenarios.go
index cb9f455..4ced6d5 100644
--- a/integrationtests/cmd/ioworkload/scenarios.go
+++ b/integrationtests/cmd/ioworkload/scenarios.go
@@ -3,6 +3,7 @@ package main
import (
"fmt"
"os"
+ "os/exec"
"path/filepath"
"runtime"
"syscall"
@@ -15,6 +16,9 @@ var scenarios = map[string]func() error{
"open-basic": openBasic,
"open-creat": openCreat,
"open-by-handle-at": openByHandleAt,
+ "open-enoent": openEnoent,
+ "open-rdonly-write": openRdonlyWrite,
+ "open-pid-filter": openPidFilter,
"readwrite-basic": readwriteBasic,
"readwrite-pread": readwritePread,
"readwrite-pwrite": readwritePwrite,
@@ -108,6 +112,82 @@ func openCreat() error {
return syscall.Close(int(fd))
}
+// openEnoent attempts to open a nonexistent file path. The openat syscall
+// returns ENOENT, but ior should still capture the enter_openat tracepoint
+// because the filename is read on entry before the syscall executes.
+func openEnoent() error {
+ dir, cleanup, err := makeTempDir("open-enoent")
+ if err != nil {
+ return err
+ }
+ defer cleanup()
+
+ path := filepath.Join(dir, "nonexistent", "enoentfile.txt")
+ _, err = syscall.Open(path, syscall.O_RDONLY, 0)
+ if err == nil {
+ return fmt.Errorf("expected ENOENT, but open succeeded")
+ }
+ return nil
+}
+
+// openRdonlyWrite opens a file O_RDONLY, then attempts to write to it.
+// The write fails with EBADF, but ior should capture both the openat
+// tracepoint and the write tracepoint.
+func openRdonlyWrite() error {
+ dir, cleanup, err := makeTempDir("open-rdonly-write")
+ if err != nil {
+ return err
+ }
+ defer cleanup()
+
+ path := filepath.Join(dir, "rdonlyfile.txt")
+ fd, err := syscall.Open(path, syscall.O_RDWR|syscall.O_CREAT, 0o644)
+ if err != nil {
+ return fmt.Errorf("create file: %w", err)
+ }
+ syscall.Close(fd)
+
+ fd, err = syscall.Open(path, syscall.O_RDONLY, 0)
+ if err != nil {
+ return fmt.Errorf("open rdonly: %w", err)
+ }
+ defer syscall.Close(fd)
+
+ _, err = syscall.Write(fd, []byte("should fail"))
+ if err == nil {
+ return fmt.Errorf("expected write to rdonly fd to fail")
+ }
+ return nil
+}
+
+// openPidFilter spawns a child process that performs file I/O. Since ior
+// filters by the workload PID, the child's I/O should NOT appear in results.
+// The parent also performs its own open so the test can verify positive and
+// negative expectations simultaneously.
+func openPidFilter() error {
+ dir, cleanup, err := makeTempDir("open-pid-filter")
+ if err != nil {
+ return err
+ }
+ defer cleanup()
+
+ // Parent opens a file (should be captured by ior).
+ parentPath := filepath.Join(dir, "parentfile.txt")
+ fd, err := syscall.Open(parentPath, syscall.O_RDWR|syscall.O_CREAT, 0o644)
+ if err != nil {
+ return fmt.Errorf("parent open: %w", err)
+ }
+ syscall.Close(fd)
+
+ // Spawn a child process that creates a file with a distinctive name.
+ childPath := filepath.Join(dir, "childfile.txt")
+ cmd := exec.Command("touch", childPath)
+ if err := cmd.Run(); err != nil {
+ return fmt.Errorf("child touch: %w", err)
+ }
+ return nil
+}
+
// readwriteBasic opens a file, writes data, seeks to start, reads it back.
func readwriteBasic() error {
dir, cleanup, err := makeTempDir("readwrite-basic")