From ebc370e517a4221a092c1c2a33cc7b749c651aa0 Mon Sep 17 00:00:00 2001 From: James Sanderson Date: Wed, 1 Oct 2025 14:44:15 +0100 Subject: [PATCH] ipn/ipnlocal: fail test if more notifies are put than expected The `put` callback runs on a different goroutine to the test, so calling t.Fatalf in put had no effect. `drain` is always called when checking what was put and is called from the test goroutine, so that's a good place to fail the test if the channel was too full. Updates #17363 Signed-off-by: James Sanderson --- ipn/ipnlocal/state_test.go | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/ipn/ipnlocal/state_test.go b/ipn/ipnlocal/state_test.go index 9c0aa66a9..347aaf8b8 100644 --- a/ipn/ipnlocal/state_test.go +++ b/ipn/ipnlocal/state_test.go @@ -59,8 +59,9 @@ type notifyThrottler struct { // ch gets replaced frequently. Lock the mutex before getting or // setting it, but not while waiting on it. - mu sync.Mutex - ch chan ipn.Notify + mu sync.Mutex + ch chan ipn.Notify + putErr error // set by put if the channel is full } // expect tells the throttler to expect count upcoming notifications. @@ -81,7 +82,11 @@ func (nt *notifyThrottler) put(n ipn.Notify) { case ch <- n: return default: - nt.t.Fatalf("put: channel full: %v", n) + err := fmt.Errorf("put: channel full: %v", n) + nt.t.Log(err) + nt.mu.Lock() + nt.putErr = err + nt.mu.Unlock() } } @@ -91,8 +96,13 @@ func (nt *notifyThrottler) drain(count int) []ipn.Notify { nt.t.Helper() nt.mu.Lock() ch := nt.ch + putErr := nt.putErr nt.mu.Unlock() + if putErr != nil { + nt.t.Fatalf("drain: previous call to put errored: %s", putErr) + } + nn := []ipn.Notify{} for i := range count { select {