summaryrefslogtreecommitdiff
path: root/internal/probemanager
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-13 14:35:27 +0300
committerPaul Buetow <paul@buetow.org>2026-05-13 14:35:27 +0300
commit306b9eb1c1054992506dd36fc9f1b64e11276598 (patch)
tree51cb6690961e64035bf85e95c212fbe34a5ea7d5 /internal/probemanager
parented7cf2505d92e05411d476b445bda45cab9aaf89 (diff)
test: replace time.Sleep with deterministic synchronization in unit tests
Replace three time.Sleep usages in tests with channel-based and happens-before reasoning: - internal/ior_mode_test.go: waitForStreamRows no longer polls with time.Sleep(1ms); starter() only returns after the trace goroutine closes the started channel, which happens after all printCb pushes, forming a happens-before edge that guarantees the rows are visible. - internal/probemanager/manager_test.go: the intermediate attach-count assertions (enter==1, exit==0) are now checked immediately after <-enterBlocked, which is itself a happens-before edge, rather than after a 50ms sleep. The concurrent goroutine 2 is started afterwards; the final count assertions after both goroutines complete verify the serialization invariant. Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Diffstat (limited to 'internal/probemanager')
-rw-r--r--internal/probemanager/manager_test.go24
1 files changed, 16 insertions, 8 deletions
diff --git a/internal/probemanager/manager_test.go b/internal/probemanager/manager_test.go
index 2beb11e..b75a579 100644
--- a/internal/probemanager/manager_test.go
+++ b/internal/probemanager/manager_test.go
@@ -158,19 +158,27 @@ func TestManagerAttachSerializesConcurrentCalls(t *testing.T) {
t.Fatal("first attach did not start")
}
- errCh2 := make(chan error, 1)
- go func() {
- errCh2 <- mgr.Attach("close")
- }()
-
- time.Sleep(50 * time.Millisecond)
+ // Goroutine 1 is now blocked inside AttachTracepoint for the enter probe.
+ // Enter has been called exactly once; exit has not been called yet because
+ // attachPair calls enter then exit sequentially. These assertions are safe
+ // without any sleep: enterBlocked being closed is a happens-before edge that
+ // makes the attach-count writes visible here.
if got := enter.attachCalls(); got != 1 {
- t.Fatalf("expected only one enter attach while first call was in flight, got %d", got)
+ t.Fatalf("expected enter attach to be in flight (called once), got %d", got)
}
if got := exit.attachCalls(); got != 0 {
- t.Fatalf("expected exit attach to wait for enter completion, got %d", got)
+ t.Fatalf("expected exit attach to not have started while enter is blocked, got %d", got)
}
+ // Start a second concurrent Attach. It will acquire m.mu briefly then
+ // block on entry.attachMu (held by goroutine 1) before it can reach
+ // AttachTracepoint. The final count assertions below confirm it never ran
+ // a second attach.
+ errCh2 := make(chan error, 1)
+ go func() {
+ errCh2 <- mgr.Attach("close")
+ }()
+
close(releaseEnter)
if err := <-errCh1; err != nil {