Skip to content

Commit 3f96630

Browse files
committed
Make CheckRoutinesStrict a tiny bit more tolerant
1 parent f608b92 commit 3f96630

1 file changed

Lines changed: 24 additions & 1 deletion

File tree

test/util.go

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -54,16 +54,39 @@ func CheckRoutines(t *testing.T) func() {
5454
}
5555

5656
// CheckRoutinesStrict is used to check for leaked go-routines.
57-
// It differs from CheckRoutines in that it won't wait at all
57+
// It differs from CheckRoutines in that it has very little tolerance
5858
// for lingering goroutines. This is helpful for tests that need
5959
// to ensure clean closure of resources.
60+
// Checking the state of goroutines exactly is tricky. As users writing
61+
// goroutines, we tend to clean up gracefully using some synchronization
62+
// pattern. When used correctly, we won't leak goroutines, but we cannot
63+
// gurantee *when* the goroutines will end. This is the nature of waiting
64+
// on the runtime's goexit1 being called which is the final subroutine
65+
// called, which is after any user written code. This small, but possible
66+
// chance to have a thread (not goroutine) be preempted before this is
67+
// called, can have our goroutine stack be not quite correct yet. The
68+
// best we can do is sleep a little bit and try to encourage the runtime
69+
// to run that goroutine (G) on the machine (M) it belongs to.
6070
func CheckRoutinesStrict(tb testing.TB) func() {
6171
tryCheckRoutinesLoop(tb, "Unexpected routines on test startup")
6272
return func() {
73+
runtime.Gosched()
74+
runtime.GC()
6375
routines := getRoutines()
6476
if len(routines) == 0 {
6577
return
6678
}
79+
// arbitrarily short choice to allow the runtime to cleanup any
80+
// goroutines that really aren't doing anything but haven't yet
81+
// completed.
82+
time.Sleep(time.Millisecond)
83+
runtime.Gosched()
84+
runtime.GC()
85+
routines = getRoutines()
86+
if len(routines) == 0 {
87+
return
88+
}
89+
6790
tb.Fatalf("%s: \n%s", "Unexpected routines on test end", strings.Join(routines, "\n\n")) // nolint
6891
}
6992
}

0 commit comments

Comments
 (0)