diff options
| author | Paul Buetow <paul@buetow.org> | 2026-02-21 20:53:07 +0200 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-02-21 20:53:07 +0200 |
| commit | cd516e1577ad97d5c8b1603657b13d110557e1b2 (patch) | |
| tree | af13921fff67f173d4e9ff97e48c54812dc1ca81 /integrationtests/expectations_test.go | |
| parent | 4e287fd01d5057d0345183b6845dcc58683a46e4 (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/expectations_test.go')
| -rw-r--r-- | integrationtests/expectations_test.go | 111 |
1 files changed, 111 insertions, 0 deletions
diff --git a/integrationtests/expectations_test.go b/integrationtests/expectations_test.go new file mode 100644 index 0000000..fd06e31 --- /dev/null +++ b/integrationtests/expectations_test.go @@ -0,0 +1,111 @@ +package integrationtests + +import ( + "ior/internal/flamegraph" + "ior/internal/types" + "testing" +) + +func TestAssertEventsAbsentNoMatch(t *testing.T) { + result := TestResult{ + Records: []flamegraph.IterRecord{ + {Path: "/tmp/testfile.txt", TraceID: types.SYS_ENTER_OPENAT, Comm: "ioworkload"}, + }, + } + + mt := &testing.T{} + AssertEventsAbsent(mt, result, []ExpectedEvent{ + {PathContains: "missing.txt"}, + }) + if mt.Failed() { + t.Error("AssertEventsAbsent should not fail when event is absent") + } +} + +func TestAssertEventsAbsentWithMatch(t *testing.T) { + result := TestResult{ + Records: []flamegraph.IterRecord{ + {Path: "/tmp/testfile.txt", TraceID: types.SYS_ENTER_OPENAT, Comm: "ioworkload"}, + }, + } + + mt := &testing.T{} + AssertEventsAbsent(mt, result, []ExpectedEvent{ + {PathContains: "testfile.txt"}, + }) + if !mt.Failed() { + t.Error("AssertEventsAbsent should fail when event is present") + } +} + +func TestAssertEventsAbsentEmptyResult(t *testing.T) { + result := TestResult{} + + mt := &testing.T{} + AssertEventsAbsent(mt, result, []ExpectedEvent{ + {PathContains: "anything.txt"}, + }) + if mt.Failed() { + t.Error("AssertEventsAbsent should not fail on empty result") + } +} + +func TestAssertEventsAbsentMultiField(t *testing.T) { + result := TestResult{ + Records: []flamegraph.IterRecord{ + {Path: "/tmp/testfile.txt", TraceID: types.SYS_ENTER_OPENAT, Comm: "ioworkload"}, + {Path: "/tmp/testfile.txt", TraceID: types.SYS_ENTER_WRITE, Comm: "ioworkload"}, + }, + } + + // Multi-field match: path + tracepoint + comm — all match first record. + mt := &testing.T{} + AssertEventsAbsent(mt, result, []ExpectedEvent{ + {PathContains: "testfile.txt", Tracepoint: "enter_openat", Comm: "ioworkload"}, + }) + if !mt.Failed() { + t.Error("AssertEventsAbsent should fail when multi-field event matches") + } + + // Multi-field partial mismatch: path matches but tracepoint doesn't. + mt2 := &testing.T{} + AssertEventsAbsent(mt2, result, []ExpectedEvent{ + {PathContains: "testfile.txt", Tracepoint: "enter_read"}, + }) + if mt2.Failed() { + t.Error("AssertEventsAbsent should pass when multi-field expectation partially mismatches") + } +} + +func TestAssertEventsAbsentMultipleExpectations(t *testing.T) { + result := TestResult{ + Records: []flamegraph.IterRecord{ + {Path: "/tmp/found.txt", TraceID: types.SYS_ENTER_OPENAT, Comm: "ioworkload"}, + }, + } + + // First expectation absent, second present — should fail. + mt := &testing.T{} + AssertEventsAbsent(mt, result, []ExpectedEvent{ + {PathContains: "missing.txt"}, + {PathContains: "found.txt"}, + }) + if !mt.Failed() { + t.Error("AssertEventsAbsent should fail when any expectation matches") + } +} + +func TestAssertEventsAbsentRejectsZeroValue(t *testing.T) { + result := TestResult{ + Records: []flamegraph.IterRecord{ + {Path: "/tmp/testfile.txt", TraceID: types.SYS_ENTER_OPENAT, Comm: "ioworkload"}, + }, + } + + // Zero-value ExpectedEvent should be rejected with an error. + mt := &testing.T{} + AssertEventsAbsent(mt, result, []ExpectedEvent{{}}) + if !mt.Failed() { + t.Error("AssertEventsAbsent should reject zero-value ExpectedEvent") + } +} |
