summaryrefslogtreecommitdiff
path: root/internal/ior_mode_test.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-12 22:12:32 +0300
committerPaul Buetow <paul@buetow.org>2026-05-12 22:12:32 +0300
commit8a4cb57703845c1d8ffbc9318a4125818a72a545 (patch)
tree5bd9dbc8f77b99de7dced2e867c36ccbf653e533 /internal/ior_mode_test.go
parenta256cbf9f54ab89aeae0aa9408c1c2b25622fa9d (diff)
invert dependency: internal no longer imports internal/tui
Introduce internal/runtime as a neutral contract package that both the core engine (internal) and the TUI layer (internal/tui) depend on. - internal/runtime: defines TraceStarter, StreamSource, EventSink, LiveTrieSource, SnapshotSource, ProbeManager, RuntimePublisher, RuntimeState, TraceRuntimeBindings, and all context key/helper functions (RuntimeBindingsFromContext, RuntimePublisherFromContext, ContextWithRuntimeBindings, ContextWithTraceFilters, TraceFiltersFromContext). These were previously defined in internal/tui, forcing the core package to import the TUI layer. - internal/streamrow: add RingBuffer (moved from internal/tui/eventstream) so the core tracing engine can use the ring buffer without importing the TUI layer. - internal/tui/eventstream/ringbuffer.go: change to a thin re-export of streamrow.RingBuffer via a type alias, preserving the existing API for all callers within the TUI layer. - internal/tui/tui.go: replace locally-defined interface declarations (TraceStarter, SnapshotSource, ProbeManager, RuntimePublisher, RuntimeState, TraceRuntimeBindings) with type aliases from internal/runtime. Delegate all context helper functions to runtime. - internal/ior.go, internal/ior_bpfsetup.go: remove imports of internal/tui and internal/tui/eventstream; use internal/runtime and internal/streamrow instead. Add SetTUIRunners injection point so the concrete TUI runner functions are wired in by cmd/ior/main.go. - cmd/ior/main.go: call internal.SetTUIRunners with the concrete TUI runner functions before internal.Run, completing the wiring without creating a cycle. - Test files (internal/ior_mode_test.go, internal/bench_pipeline_test.go): updated to use runtime.* and streamrow.* types in place of tui.* and eventstream.* types. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/ior_mode_test.go')
-rw-r--r--internal/ior_mode_test.go82
1 files changed, 42 insertions, 40 deletions
diff --git a/internal/ior_mode_test.go b/internal/ior_mode_test.go
index 876b374..0697ada 100644
--- a/internal/ior_mode_test.go
+++ b/internal/ior_mode_test.go
@@ -18,9 +18,8 @@ import (
"ior/internal/flags"
"ior/internal/globalfilter"
"ior/internal/parquet"
- "ior/internal/tui"
- "ior/internal/tui/eventstream"
- flamegraphtui "ior/internal/tui/flamegraph"
+ "ior/internal/runtime"
+ "ior/internal/streamrow"
"ior/internal/types"
parquetgo "github.com/parquet-go/parquet-go"
@@ -117,15 +116,15 @@ func TestDispatchRunUsesTraceModeWhenRequested(t *testing.T) {
t.Fatalf("runParquetFn should not be called in plain trace mode")
return nil
}
- runTUIFn = func(flags.Config, tui.TraceStarter) error {
+ runTUIFn = func(flags.Config, runtime.TraceStarter) error {
tuiCalled = true
return nil
}
- runTUITestFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestFlamesFn should not be called in trace mode")
return nil
}
- runTUITestLiveFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestLiveFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestLiveFlamesFn should not be called in trace mode")
return nil
}
@@ -170,15 +169,15 @@ func TestDispatchRunUsesHeadlessParquetModeWhenRequested(t *testing.T) {
parquetCalled = true
return nil
}
- runTUIFn = func(flags.Config, tui.TraceStarter) error {
+ runTUIFn = func(flags.Config, runtime.TraceStarter) error {
tuiCalled = true
return nil
}
- runTUITestFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestFlamesFn should not be called in parquet mode")
return nil
}
- runTUITestLiveFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestLiveFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestLiveFlamesFn should not be called in parquet mode")
return nil
}
@@ -219,15 +218,15 @@ func TestDispatchRunUsesTUIWhenOnlyPprofEnabled(t *testing.T) {
traceCalled = true
return nil
}
- runTUIFn = func(flags.Config, tui.TraceStarter) error {
+ runTUIFn = func(flags.Config, runtime.TraceStarter) error {
tuiCalled = true
return nil
}
- runTUITestFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestFlamesFn should not be called for regular TUI mode")
return nil
}
- runTUITestLiveFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestLiveFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestLiveFlamesFn should not be called for regular TUI mode")
return nil
}
@@ -270,7 +269,7 @@ func TestDispatchRunUsesTUIStarterWhenNotPlain(t *testing.T) {
}
tuiCalled := false
- runTUIFn = func(_ flags.Config, starter tui.TraceStarter) error {
+ runTUIFn = func(_ flags.Config, starter runtime.TraceStarter) error {
tuiCalled = true
if starter == nil {
t.Fatalf("expected non-nil starter")
@@ -280,11 +279,11 @@ func TestDispatchRunUsesTUIStarterWhenNotPlain(t *testing.T) {
}
return nil
}
- runTUITestFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestFlamesFn should not be called for normal starter path")
return nil
}
- runTUITestLiveFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestLiveFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestLiveFlamesFn should not be called for normal starter path")
return nil
}
@@ -323,18 +322,18 @@ func TestDispatchRunUsesTestFlamesModeWhenRequested(t *testing.T) {
traceCalled = true
return nil
}
- runTUIFn = func(flags.Config, tui.TraceStarter) error {
+ runTUIFn = func(flags.Config, runtime.TraceStarter) error {
regularTUICalled = true
return nil
}
- runTUITestFlamesFn = func(_ flags.Config, starter tui.TraceStarter) error {
+ runTUITestFlamesFn = func(_ flags.Config, starter runtime.TraceStarter) error {
testFlamesCalled = true
if starter == nil {
t.Fatalf("expected non-nil starter for test flames mode")
}
return starter(context.Background())
}
- runTUITestLiveFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestLiveFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestLiveFlamesFn should not be called for --testflames")
return nil
}
@@ -373,15 +372,15 @@ func TestDispatchRunUsesTestLiveFlamesModeWhenRequested(t *testing.T) {
traceCalled = true
return nil
}
- runTUIFn = func(flags.Config, tui.TraceStarter) error {
+ runTUIFn = func(flags.Config, runtime.TraceStarter) error {
regularTUICalled = true
return nil
}
- runTUITestFlamesFn = func(flags.Config, tui.TraceStarter) error {
+ runTUITestFlamesFn = func(flags.Config, runtime.TraceStarter) error {
t.Fatalf("runTUITestFlamesFn should not be called for --testliveflames")
return nil
}
- runTUITestLiveFlamesFn = func(_ flags.Config, starter tui.TraceStarter) error {
+ runTUITestLiveFlamesFn = func(_ flags.Config, starter runtime.TraceStarter) error {
testLiveFlamesCalled = true
if starter == nil {
t.Fatalf("expected non-nil starter for test live flames mode")
@@ -577,7 +576,7 @@ func TestTuiTraceStarterFromRunTraceUsesContextFilters(t *testing.T) {
},
)
- ctx := tui.ContextWithTraceFilters(context.Background(), globalfilter.Filter{
+ ctx := runtime.ContextWithTraceFilters(context.Background(), globalfilter.Filter{
PID: &globalfilter.NumericFilter{Op: globalfilter.OpEq, Value: 2222},
TID: &globalfilter.NumericFilter{Op: globalfilter.OpEq, Value: 3333},
Comm: &globalfilter.StringFilter{Pattern: "nginx"},
@@ -766,8 +765,8 @@ func TestTuiTraceStarterFromRunTracePersistsRecorderAcrossRestarts(t *testing.T)
}
bindings := &traceRuntimeBindingsStub{
- streamBuffer: eventstream.NewRingBuffer(),
- streamSeq: eventstream.NewSequencer(0),
+ streamBuffer: streamrow.NewRingBuffer(),
+ streamSeq: streamrow.NewSequencer(0),
recorder: recorder,
}
base := flags.NewFlags()
@@ -797,7 +796,7 @@ func TestTuiTraceStarterFromRunTracePersistsRecorderAcrossRestarts(t *testing.T)
},
)
- ctx := tui.ContextWithRuntimeBindings(context.Background(), bindings)
+ ctx := runtime.ContextWithRuntimeBindings(context.Background(), bindings)
if err := starter(ctx); err != nil {
t.Fatalf("first starter() error = %v", err)
}
@@ -839,8 +838,8 @@ func TestTuiTraceStarterFromRunTracePersistsRecorderAcrossRestarts(t *testing.T)
// printCb admits, without any restart of the trace pipeline.
func TestTuiTraceStarterAppliesLiveFilterSwapInPlace(t *testing.T) {
bindings := &traceRuntimeBindingsStub{
- streamBuffer: eventstream.NewRingBuffer(),
- streamSeq: eventstream.NewSequencer(0),
+ streamBuffer: streamrow.NewRingBuffer(),
+ streamSeq: streamrow.NewSequencer(0),
}
base := flags.NewFlags()
base.GlobalFilter = globalfilter.Filter{Comm: &globalfilter.StringFilter{Pattern: "keep"}}
@@ -864,7 +863,7 @@ func TestTuiTraceStarterAppliesLiveFilterSwapInPlace(t *testing.T) {
},
)
- ctx := tui.ContextWithRuntimeBindings(context.Background(), bindings)
+ ctx := runtime.ContextWithRuntimeBindings(context.Background(), bindings)
starterErr := make(chan error, 1)
go func() { starterErr <- starter(ctx) }()
@@ -898,28 +897,31 @@ func TestTuiTraceStarterAppliesLiveFilterSwapInPlace(t *testing.T) {
}
}
+// traceRuntimeBindingsStub is a test double for runtime.TraceRuntimeBindings
+// that records injected stream sources and exposes the live-filter setter for
+// assertions.
type traceRuntimeBindingsStub struct {
- streamBuffer *eventstream.RingBuffer
- streamSource eventstream.Source
- streamSeq *eventstream.Sequencer
+ streamBuffer *streamrow.RingBuffer
+ streamSource runtime.StreamSource
+ streamSeq *streamrow.Sequencer
recorder *parquet.Recorder
filterEpoch uint64
// mu guards liveFilterSetter, which is mutated from the trace-starter
- // goroutine (via SetLiveFilterSetter) and read from the test
- // goroutine when invoking the in-place swap.
+ // goroutine (via SetLiveFilterSetter) and read from the test goroutine
+ // when invoking the in-place swap.
mu sync.Mutex
liveFilterSetter func(globalfilter.Filter)
}
-func (b *traceRuntimeBindingsStub) SetDashboardSnapshotSource(tui.SnapshotSource) {}
+func (b *traceRuntimeBindingsStub) SetDashboardSnapshotSource(runtime.SnapshotSource) {}
-func (b *traceRuntimeBindingsStub) SetEventStreamSource(source eventstream.Source) {
+func (b *traceRuntimeBindingsStub) SetEventStreamSource(source runtime.StreamSource) {
b.streamSource = source
}
-func (b *traceRuntimeBindingsStub) SetLiveTrie(flamegraphtui.LiveTrieSource) {}
+func (b *traceRuntimeBindingsStub) SetLiveTrie(runtime.LiveTrieSource) {}
-func (b *traceRuntimeBindingsStub) SetProbeManager(tui.ProbeManager) {}
+func (b *traceRuntimeBindingsStub) SetProbeManager(runtime.ProbeManager) {}
func (b *traceRuntimeBindingsStub) SetLiveFilterSetter(setter func(globalfilter.Filter)) {
b.mu.Lock()
@@ -933,7 +935,7 @@ func (b *traceRuntimeBindingsStub) currentLiveFilterSetter() func(globalfilter.F
return b.liveFilterSetter
}
-func (b *traceRuntimeBindingsStub) StreamBuffer() eventstream.Source {
+func (b *traceRuntimeBindingsStub) StreamBuffer() runtime.StreamSource {
return b.streamBuffer
}
@@ -941,7 +943,7 @@ func (b *traceRuntimeBindingsStub) Recorder() *parquet.Recorder {
return b.recorder
}
-func (b *traceRuntimeBindingsStub) StreamSequencer() *eventstream.Sequencer {
+func (b *traceRuntimeBindingsStub) StreamSequencer() *streamrow.Sequencer {
return b.streamSeq
}
@@ -962,7 +964,7 @@ func testTracePair(seq uint64, comm string) *event.Pair {
return pair
}
-func waitForStreamRows(t *testing.T, buffer *eventstream.RingBuffer, want int) {
+func waitForStreamRows(t *testing.T, buffer *streamrow.RingBuffer, want int) {
t.Helper()
deadline := time.Now().Add(2 * time.Second)
for time.Now().Before(deadline) {