From d455543bf0838c7fe2250081c5ea8ed3e275d236 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Sat, 21 Feb 2026 21:39:18 +0200 Subject: Add negative integration tests for sync syscalls (task 348) Add three EBADF scenarios testing ior's ability to capture sync-related tracepoints even when the underlying syscall fails: - sync-fsync-ebadf: fsync on invalid fd, expects enter_fsync - sync-fdatasync-ebadf: fdatasync on invalid fd, expects enter_fdatasync - sync-file-range-ebadf: sync_file_range on invalid fd, expects enter_sync_file_range Amp-Thread-ID: https://ampcode.com/threads/T-019c81b4-216a-732c-90b1-e6771e27ed75 Co-authored-by: Amp --- integrationtests/cmd/ioworkload/scenarios.go | 41 +++++++++++++++++++++++++--- 1 file changed, 37 insertions(+), 4 deletions(-) (limited to 'integrationtests/cmd') diff --git a/integrationtests/cmd/ioworkload/scenarios.go b/integrationtests/cmd/ioworkload/scenarios.go index 3f5ee4c..58c78e1 100644 --- a/integrationtests/cmd/ioworkload/scenarios.go +++ b/integrationtests/cmd/ioworkload/scenarios.go @@ -79,10 +79,13 @@ var scenarios = map[string]func() error{ "stat-enoent": statEnoent, "stat-access-enoent": statAccessEnoent, "stat-fstat-ebadf": statFstatEbadf, - "sync-basic": syncBasic, - "sync-fdatasync": syncFdatasync, - "sync-sync": syncSync, - "sync-sync-file-range": syncSyncFileRange, + "sync-basic": syncBasic, + "sync-fdatasync": syncFdatasync, + "sync-sync": syncSync, + "sync-sync-file-range": syncSyncFileRange, + "sync-fsync-ebadf": syncFsyncEbadf, + "sync-fdatasync-ebadf": syncFdatasyncEbadf, + "sync-file-range-ebadf": syncFileRangeEbadf, "truncate-basic": truncateBasic, "truncate-ftruncate": truncateFtruncate, "iouring-setup": iouringSetup, @@ -2146,6 +2149,36 @@ func syncSyncFileRange() error { return syscall.SyncFileRange(fd, 0, int64(len(data)), 0) } +// syncFsyncEbadf calls fsync on an invalid fd. +// The syscall fails with EBADF, but ior captures the enter_fsync tracepoint. +func syncFsyncEbadf() error { + _, _, errno := syscall.Syscall(syscall.SYS_FSYNC, 99999, 0, 0) + if errno == 0 { + return fmt.Errorf("expected EBADF, but fsync succeeded") + } + return nil +} + +// syncFdatasyncEbadf calls fdatasync on an invalid fd. +// The syscall fails with EBADF, but ior captures the enter_fdatasync tracepoint. +func syncFdatasyncEbadf() error { + _, _, errno := syscall.Syscall(syscall.SYS_FDATASYNC, 99999, 0, 0) + if errno == 0 { + return fmt.Errorf("expected EBADF, but fdatasync succeeded") + } + return nil +} + +// syncFileRangeEbadf calls sync_file_range on an invalid fd. +// The syscall fails with EBADF, but ior captures the enter_sync_file_range tracepoint. +func syncFileRangeEbadf() error { + _, _, errno := syscall.Syscall6(syscall.SYS_SYNC_FILE_RANGE, 99999, 0, 0, 0, 0, 0) + if errno == 0 { + return fmt.Errorf("expected EBADF, but sync_file_range succeeded") + } + return nil +} + // truncateBasic opens a file, writes data, then truncates it via // syscall.Truncate which uses SYS_TRUNCATE directly on amd64 (path-based). func truncateBasic() error { -- cgit v1.2.3