From ad4d7fca20d80f71ccabef3281e3f80081f4db62 Mon Sep 17 00:00:00 2001 From: Paul Buetow Date: Thu, 26 Feb 2026 08:50:12 +0200 Subject: Add byte assertions for read/write integration scenarios --- integrationtests/helpers_test.go | 6 ++ integrationtests/readwrite_test.go | 120 ++++++++++++++++++++++++++++++++++--- 2 files changed, 117 insertions(+), 9 deletions(-) (limited to 'integrationtests') diff --git a/integrationtests/helpers_test.go b/integrationtests/helpers_test.go index 5f60f0f..feb7a55 100644 --- a/integrationtests/helpers_test.go +++ b/integrationtests/helpers_test.go @@ -48,6 +48,11 @@ func writeScript(t *testing.T, dir, name, content string) string { } func runScenario(t *testing.T, scenario string, expected []ExpectedEvent) { + t.Helper() + runScenarioResult(t, scenario, expected) +} + +func runScenarioResult(t *testing.T, scenario string, expected []ExpectedEvent) (TestResult, int) { t.Helper() enableParallelIfRequested(t) h := newTestHarness(t) @@ -59,6 +64,7 @@ func runScenario(t *testing.T, scenario string, expected []ExpectedEvent) { AssertNoUnexpectedPID(t, result, pid) AssertNoUnexpectedComm(t, result, "ioworkload") AssertEventsPresent(t, result, expected) + return result, pid } func enableParallelIfRequested(t *testing.T) { diff --git a/integrationtests/readwrite_test.go b/integrationtests/readwrite_test.go index 7251d51..a55bf78 100644 --- a/integrationtests/readwrite_test.go +++ b/integrationtests/readwrite_test.go @@ -2,9 +2,9 @@ package integrationtests import "testing" -// TODO: Also test how much bytes were read and writen func TestReadwriteBasic(t *testing.T) { - runScenario(t, "readwrite-basic", []ExpectedEvent{ + const payloadLen = uint64(len("hello from ioworkload")) + result, _ := runScenarioResult(t, "readwrite-basic", []ExpectedEvent{ { PathContains: "rwfile.txt", Tracepoint: "enter_write", @@ -18,6 +18,16 @@ func TestReadwriteBasic(t *testing.T) { MinCount: 1, }, }) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "rwfile.txt", + Tracepoint: "enter_write", + Comm: "ioworkload", + }, payloadLen) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "rwfile.txt", + Tracepoint: "enter_read", + Comm: "ioworkload", + }, payloadLen) } func TestReadwritePread(t *testing.T) { @@ -32,7 +42,7 @@ func TestReadwritePread(t *testing.T) { } func TestReadwritePwrite(t *testing.T) { - runScenario(t, "readwrite-pwrite", []ExpectedEvent{ + result, _ := runScenarioResult(t, "readwrite-pwrite", []ExpectedEvent{ { PathContains: "pwritefile.txt", Tracepoint: "enter_pwrite64", @@ -40,10 +50,15 @@ func TestReadwritePwrite(t *testing.T) { MinCount: 1, }, }) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "pwritefile.txt", + Tracepoint: "enter_pwrite64", + Comm: "ioworkload", + }, 1) } func TestReadwriteReadv(t *testing.T) { - runScenario(t, "readwrite-readv", []ExpectedEvent{ + result, _ := runScenarioResult(t, "readwrite-readv", []ExpectedEvent{ { PathContains: "readvfile.txt", Tracepoint: "enter_readv", @@ -51,10 +66,15 @@ func TestReadwriteReadv(t *testing.T) { MinCount: 1, }, }) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "readvfile.txt", + Tracepoint: "enter_readv", + Comm: "ioworkload", + }, 1) } func TestReadwriteWritev(t *testing.T) { - runScenario(t, "readwrite-writev", []ExpectedEvent{ + result, _ := runScenarioResult(t, "readwrite-writev", []ExpectedEvent{ { PathContains: "writevfile.txt", Tracepoint: "enter_writev", @@ -62,10 +82,15 @@ func TestReadwriteWritev(t *testing.T) { MinCount: 1, }, }) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "writevfile.txt", + Tracepoint: "enter_writev", + Comm: "ioworkload", + }, 1) } func TestReadwriteWronlyRead(t *testing.T) { - runScenario(t, "readwrite-wronly-read", []ExpectedEvent{ + result, _ := runScenarioResult(t, "readwrite-wronly-read", []ExpectedEvent{ { PathContains: "wronlyfile.txt", Tracepoint: "enter_read", @@ -73,10 +98,20 @@ func TestReadwriteWronlyRead(t *testing.T) { MinCount: 1, }, }) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "wronlyfile.txt", + Tracepoint: "enter_read", + Comm: "ioworkload", + }, 1) + assertEventBytesReasonable(t, result, ExpectedEvent{ + PathContains: "wronlyfile.txt", + Tracepoint: "enter_read", + Comm: "ioworkload", + }) } func TestReadwriteRdonlyWrite(t *testing.T) { - runScenario(t, "readwrite-rdonly-write", []ExpectedEvent{ + result, _ := runScenarioResult(t, "readwrite-rdonly-write", []ExpectedEvent{ { PathContains: "rdonlywritefile.txt", Tracepoint: "enter_write", @@ -84,10 +119,20 @@ func TestReadwriteRdonlyWrite(t *testing.T) { MinCount: 1, }, }) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "rdonlywritefile.txt", + Tracepoint: "enter_write", + Comm: "ioworkload", + }, 1) + assertEventBytesReasonable(t, result, ExpectedEvent{ + PathContains: "rdonlywritefile.txt", + Tracepoint: "enter_write", + Comm: "ioworkload", + }) } func TestReadwritePreadInvalid(t *testing.T) { - runScenario(t, "readwrite-pread-invalid", []ExpectedEvent{ + result, _ := runScenarioResult(t, "readwrite-pread-invalid", []ExpectedEvent{ { PathContains: "preadinvalid.txt", Tracepoint: "enter_pread64", @@ -95,10 +140,20 @@ func TestReadwritePreadInvalid(t *testing.T) { MinCount: 1, }, }) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "preadinvalid.txt", + Tracepoint: "enter_pread64", + Comm: "ioworkload", + }, 1) + assertEventBytesReasonable(t, result, ExpectedEvent{ + PathContains: "preadinvalid.txt", + Tracepoint: "enter_pread64", + Comm: "ioworkload", + }) } func TestReadwritePwriteInvalid(t *testing.T) { - runScenario(t, "readwrite-pwrite-invalid", []ExpectedEvent{ + result, _ := runScenarioResult(t, "readwrite-pwrite-invalid", []ExpectedEvent{ { PathContains: "pwriteinvalid.txt", Tracepoint: "enter_pwrite64", @@ -106,4 +161,51 @@ func TestReadwritePwriteInvalid(t *testing.T) { MinCount: 1, }, }) + assertEventBytesAtLeast(t, result, ExpectedEvent{ + PathContains: "pwriteinvalid.txt", + Tracepoint: "enter_pwrite64", + Comm: "ioworkload", + }, 1) + assertEventBytesReasonable(t, result, ExpectedEvent{ + PathContains: "pwriteinvalid.txt", + Tracepoint: "enter_pwrite64", + Comm: "ioworkload", + }) +} + +func assertEventBytesAtLeast(t *testing.T, result TestResult, exp ExpectedEvent, minBytes uint64) { + t.Helper() + var matched bool + var totalBytes uint64 + for _, rec := range result.Records { + if !matchesExpectation(rec, exp) { + continue + } + matched = true + totalBytes += rec.Cnt.Bytes + } + if !matched { + t.Fatalf("expected event not found while asserting bytes: %+v", exp) + } + if totalBytes < minBytes { + t.Fatalf("bytes for %+v too small: got=%d want>=%d", exp, totalBytes, minBytes) + } +} + +func assertEventBytesReasonable(t *testing.T, result TestResult, exp ExpectedEvent) { + t.Helper() + const maxReasonableBytes = 1 << 20 // 1MiB is far above any bytes used in these scenarios. + var matched bool + for _, rec := range result.Records { + if !matchesExpectation(rec, exp) { + continue + } + matched = true + if rec.Cnt.Bytes > maxReasonableBytes { + t.Fatalf("unreasonable bytes for %+v: got=%d (possible underflow/sign issue)", exp, rec.Cnt.Bytes) + } + } + if !matched { + t.Fatalf("expected event not found while asserting byte range: %+v", exp) + } } -- cgit v1.2.3