http2: speed up TestTransportRetryHasLimit This test takes ~30s to execute with real timers, making it almost 50% of the total execution time of the http2 tests. Use a fake timer in tests. Change-Id: I750237c7d3b8f7b87881b8a0a8aff2bf4a3cdd9f Reviewed-on: https://go-review.googlesource.com/c/net/+/446375 Reviewed-by: Bryan Mills <bcmills@google.com> Reviewed-by: Brad Fitzpatrick <bradfitz@golang.org> Run-TryBot: Damien Neil <dneil@google.com> TryBot-Result: Gopher Robot <gobot@golang.org>
diff --git a/http2/transport.go b/http2/transport.go index 5a179b6..46dda4d 100644 --- a/http2/transport.go +++ b/http2/transport.go
@@ -502,6 +502,15 @@ return net.JoinHostPort(host, port) } +var retryBackoffHook func(time.Duration) *time.Timer + +func backoffNewTimer(d time.Duration) *time.Timer { + if retryBackoffHook != nil { + return retryBackoffHook(d) + } + return time.NewTimer(d) +} + // RoundTripOpt is like RoundTrip, but takes options. func (t *Transport) RoundTripOpt(req *http.Request, opt RoundTripOpt) (*http.Response, error) { if !(req.URL.Scheme == "https" || (req.URL.Scheme == "http" && t.AllowHTTP)) { @@ -527,11 +536,14 @@ } backoff := float64(uint(1) << (uint(retry) - 1)) backoff += backoff * (0.1 * mathrand.Float64()) + d := time.Second * time.Duration(backoff) + timer := backoffNewTimer(d) select { - case <-time.After(time.Second * time.Duration(backoff)): + case <-timer.C: t.vlogf("RoundTrip retrying after failure: %v", err) continue case <-req.Context().Done(): + timer.Stop() err = req.Context().Err() } }
diff --git a/http2/transport_test.go b/http2/transport_test.go index c738911..9eaf7bf 100644 --- a/http2/transport_test.go +++ b/http2/transport_test.go
@@ -3881,6 +3881,12 @@ if testing.Short() { t.Skip("skipping long test in short mode") } + retryBackoffHook = func(d time.Duration) *time.Timer { + return time.NewTimer(0) // fires immediately + } + defer func() { + retryBackoffHook = nil + }() clientDone := make(chan struct{}) ct := newClientTester(t) ct.client = func() error {