diff options
| author | Paul Buetow <paul@buetow.org> | 2026-05-13 14:28:37 +0300 |
|---|---|---|
| committer | Paul Buetow <paul@buetow.org> | 2026-05-13 14:28:37 +0300 |
| commit | 27b94f917064948fa33141309a3f08deb40ffde2 (patch) | |
| tree | 0f1c63eba01da1cc89fbbedcfe71cdcb55b06cb0 /internal/streamrow/ringbuffer_test.go | |
| parent | 140d6c0fe472f112170022b9831dfe700698f382 (diff) | |
improve unit test coverage to >=60% in probes, common, export, streamrow, pidpicker, tui/export
Before: probes=30%, tui/common=41%, export=0%, streamrow=25%, pidpicker=59%, tui/export=45%
After: probes=89%, tui/common=97%, export=77%, streamrow=100%, pidpicker=73%, tui/export=99%
New test files cover RingBuffer push/wrap/reset, Row accessor methods, nil
Sequencer safety, SnapshotCSV nil and data paths, helper functions snapValue /
snapValueF / trendSummary, all table navigation keys, VisibleTableWindow/
ClampTableCol edge cases, RenderTableHeader/Row, PickerShortHelp, probe modal
navigation/search/toggle/view/error paths, truncateText/sanitizeOneLine,
export modal View rendering, key navigation, status messages, scanAllThreadsFrom,
readThreadInfo guards, formatProcess variants, and clamp helper.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/streamrow/ringbuffer_test.go')
| -rw-r--r-- | internal/streamrow/ringbuffer_test.go | 104 |
1 files changed, 104 insertions, 0 deletions
diff --git a/internal/streamrow/ringbuffer_test.go b/internal/streamrow/ringbuffer_test.go new file mode 100644 index 0000000..91f3f7d --- /dev/null +++ b/internal/streamrow/ringbuffer_test.go @@ -0,0 +1,104 @@ +package streamrow + +import ( + "testing" +) + +// TestRingBufferPushAndSnapshot verifies that pushed rows are retrievable in +// insertion order. +func TestRingBufferPushAndSnapshot(t *testing.T) { + rb := NewRingBuffer() + + if got := rb.Len(); got != 0 { + t.Fatalf("expected empty buffer, got len=%d", got) + } + + rows := []Row{ + {Seq: 1, Syscall: "read"}, + {Seq: 2, Syscall: "write"}, + {Seq: 3, Syscall: "openat"}, + } + for _, r := range rows { + rb.Push(r) + } + + if got := rb.Len(); got != 3 { + t.Fatalf("expected len=3, got %d", got) + } + if got := rb.TotalPushed(); got != 3 { + t.Fatalf("expected totalPushed=3, got %d", got) + } + + snap := rb.Snapshot() + if len(snap) != 3 { + t.Fatalf("expected snapshot len 3, got %d", len(snap)) + } + for i, want := range rows { + if snap[i].Seq != want.Seq || snap[i].Syscall != want.Syscall { + t.Fatalf("row[%d] = %+v, want %+v", i, snap[i], want) + } + } +} + +// TestRingBufferWrapsAroundCapacity verifies that the ring buffer overwrites the +// oldest entry when full and preserves insertion order in the snapshot. +func TestRingBufferWrapsAroundCapacity(t *testing.T) { + rb := NewRingBuffer() + + // Fill beyond capacity to force wrap-around. + const extra = 5 + for i := range RingBufferCapacity + extra { + rb.Push(Row{Seq: uint64(i + 1)}) + } + + if got := rb.Len(); got != RingBufferCapacity { + t.Fatalf("expected len=%d after overflow, got %d", RingBufferCapacity, got) + } + if got := rb.TotalPushed(); got != uint64(RingBufferCapacity+extra) { + t.Fatalf("expected totalPushed=%d, got %d", RingBufferCapacity+extra, got) + } + + snap := rb.Snapshot() + if len(snap) != RingBufferCapacity { + t.Fatalf("snapshot len = %d, want %d", len(snap), RingBufferCapacity) + } + // After filling cap+extra rows the oldest surviving seq should be extra+1. + wantFirstSeq := uint64(extra + 1) + if snap[0].Seq != wantFirstSeq { + t.Fatalf("oldest surviving seq = %d, want %d", snap[0].Seq, wantFirstSeq) + } +} + +// TestRingBufferSnapshotOnEmpty verifies that Snapshot on an empty buffer +// returns an empty (non-nil) slice. +func TestRingBufferSnapshotOnEmpty(t *testing.T) { + rb := NewRingBuffer() + snap := rb.Snapshot() + if snap == nil { + t.Fatal("expected non-nil snapshot on empty buffer") + } + if len(snap) != 0 { + t.Fatalf("expected empty snapshot, got len=%d", len(snap)) + } +} + +// TestRingBufferReset verifies that Reset clears all rows and counters. +func TestRingBufferReset(t *testing.T) { + rb := NewRingBuffer() + for i := range 10 { + rb.Push(Row{Seq: uint64(i + 1)}) + } + + rb.Reset() + + if got := rb.Len(); got != 0 { + t.Fatalf("expected len=0 after reset, got %d", got) + } + if got := rb.TotalPushed(); got != 0 { + t.Fatalf("expected totalPushed=0 after reset, got %d", got) + } + snap := rb.Snapshot() + if len(snap) != 0 { + t.Fatalf("expected empty snapshot after reset, got len=%d", len(snap)) + } +} |
