Commit dfa909b9 authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

http2: fix flaky TestTransportHandlerBodyClose

Don't assume goroutines are gone immediately.

Copy the waitCondition & waitErrCondition helpers from net/http's
tests, so we can assume both exist in both repos, even though we only
use one of them as of this CL.

Fixes golang/go#22889

Change-Id: Ife251c9552bc68646e174a7ac082b363e32132a1
Reviewed-on: https://go-review.googlesource.com/114012
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarAndrew Bonventre <andybons@golang.org>
parent 9ef9f5bb
...@@ -14,6 +14,7 @@ import ( ...@@ -14,6 +14,7 @@ import (
"strconv" "strconv"
"strings" "strings"
"testing" "testing"
"time"
"golang.org/x/net/http2/hpack" "golang.org/x/net/http2/hpack"
) )
...@@ -197,3 +198,30 @@ func TestSorterPoolAllocs(t *testing.T) { ...@@ -197,3 +198,30 @@ func TestSorterPoolAllocs(t *testing.T) {
t.Logf("Keys allocs = %v; want <1", allocs) t.Logf("Keys allocs = %v; want <1", allocs)
} }
} }
// waitCondition reports whether fn eventually returned true,
// checking immediately and then every checkEvery amount,
// until waitFor has elapsed, at which point it returns false.
func waitCondition(waitFor, checkEvery time.Duration, fn func() bool) bool {
deadline := time.Now().Add(waitFor)
for time.Now().Before(deadline) {
if fn() {
return true
}
time.Sleep(checkEvery)
}
return false
}
// waitErrCondition is like waitCondition but with errors instead of bools.
func waitErrCondition(waitFor, checkEvery time.Duration, fn func() error) error {
deadline := time.Now().Add(waitFor)
var err error
for time.Now().Before(deadline) {
if err = fn(); err == nil {
return nil
}
time.Sleep(checkEvery)
}
return err
}
...@@ -2395,11 +2395,12 @@ func TestTransportHandlerBodyClose(t *testing.T) { ...@@ -2395,11 +2395,12 @@ func TestTransportHandlerBodyClose(t *testing.T) {
} }
tr.CloseIdleConnections() tr.CloseIdleConnections()
gd := runtime.NumGoroutine() - g0 if !waitCondition(5*time.Second, 100*time.Millisecond, func() bool {
if gd > numReq/2 { gd := runtime.NumGoroutine() - g0
return gd < numReq/2
}) {
t.Errorf("appeared to leak goroutines") t.Errorf("appeared to leak goroutines")
} }
} }
// https://golang.org/issue/15930 // https://golang.org/issue/15930
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment