Skip to content

Commit 95fab85

Browse files
committed
net/http: deflake TestServerCancelsReadTimeoutWhenIdle
I can reproduce with a very short timeout (fractions of a millisecond) combined with -race. But given that this is inherently sensitive to actual time, add a testing mechanism to retry with increasingly large times to compensate for busy buidlers. This also means the test is usually faster now, too, since we can start with smaller durations. Fixes #19608 Change-Id: I3a222464720195849da768e9801eb7b43baa4aeb Reviewed-on: https://go-review.googlesource.com/82595 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent 613f8ca commit 95fab85

File tree

1 file changed

+46
-24
lines changed

1 file changed

+46
-24
lines changed

src/net/http/serve_test.go

Lines changed: 46 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -5478,32 +5478,54 @@ func testServerKeepAlivesEnabled(t *testing.T, h2 bool) {
54785478
func TestServerCancelsReadTimeoutWhenIdle(t *testing.T) {
54795479
setParallel(t)
54805480
defer afterTest(t)
5481-
const timeout = 250 * time.Millisecond
5482-
ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
5483-
select {
5484-
case <-time.After(2 * timeout):
5485-
fmt.Fprint(w, "ok")
5486-
case <-r.Context().Done():
5487-
fmt.Fprint(w, r.Context().Err())
5488-
}
5489-
}))
5490-
ts.Config.ReadTimeout = timeout
5491-
ts.Start()
5492-
defer ts.Close()
5481+
runTimeSensitiveTest(t, []time.Duration{
5482+
10 * time.Millisecond,
5483+
50 * time.Millisecond,
5484+
250 * time.Millisecond,
5485+
time.Second,
5486+
2 * time.Second,
5487+
}, func(t *testing.T, timeout time.Duration) error {
5488+
ts := httptest.NewUnstartedServer(HandlerFunc(func(w ResponseWriter, r *Request) {
5489+
select {
5490+
case <-time.After(2 * timeout):
5491+
fmt.Fprint(w, "ok")
5492+
case <-r.Context().Done():
5493+
fmt.Fprint(w, r.Context().Err())
5494+
}
5495+
}))
5496+
ts.Config.ReadTimeout = timeout
5497+
ts.Start()
5498+
defer ts.Close()
54935499

5494-
c := ts.Client()
5500+
c := ts.Client()
54955501

5496-
res, err := c.Get(ts.URL)
5497-
if err != nil {
5498-
t.Fatal(err)
5499-
}
5500-
slurp, err := ioutil.ReadAll(res.Body)
5501-
res.Body.Close()
5502-
if err != nil {
5503-
t.Fatal(err)
5504-
}
5505-
if string(slurp) != "ok" {
5506-
t.Fatalf("Got: %q, want ok", slurp)
5502+
res, err := c.Get(ts.URL)
5503+
if err != nil {
5504+
return fmt.Errorf("Get: %v", err)
5505+
}
5506+
slurp, err := ioutil.ReadAll(res.Body)
5507+
res.Body.Close()
5508+
if err != nil {
5509+
return fmt.Errorf("Body ReadAll: %v", err)
5510+
}
5511+
if string(slurp) != "ok" {
5512+
return fmt.Errorf("got: %q, want ok", slurp)
5513+
}
5514+
return nil
5515+
})
5516+
}
5517+
5518+
// runTimeSensitiveTest runs test with the provided durations until one passes.
5519+
// If they all fail, t.Fatal is called with the last one's duration and error value.
5520+
func runTimeSensitiveTest(t *testing.T, durations []time.Duration, test func(t *testing.T, d time.Duration) error) {
5521+
for i, d := range durations {
5522+
err := test(t, d)
5523+
if err == nil {
5524+
return
5525+
}
5526+
if i == len(durations)-1 {
5527+
t.Fatalf("failed with duration %v: %v", d, err)
5528+
}
55075529
}
55085530
}
55095531

0 commit comments

Comments
 (0)