]> Cypherpunks repositories - gostls13.git/commitdiff
net/http: deflake TestServerTimeouts
authorBrad Fitzpatrick <bradfitz@golang.org>
Tue, 14 Mar 2017 17:43:50 +0000 (17:43 +0000)
committerBrad Fitzpatrick <bradfitz@golang.org>
Tue, 14 Mar 2017 18:03:38 +0000 (18:03 +0000)
Retry the test several times with increasingly long timeouts.

Fixes #19538 (hopefully)

Change-Id: Ia3bf2b63b4298a6ee1e4082e14d9bfd5922c293a
Reviewed-on: https://go-review.googlesource.com/38154
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: Josh Bleecher Snyder <josharian@gmail.com>
src/net/http/serve_test.go

index 7d964b309eac4040a6e1e0c2ac6d6915017243ea..795bc207c648ab5d3ae0e225e13e13feb2003c97 100644 (file)
@@ -463,13 +463,29 @@ func TestMuxRedirectLeadingSlashes(t *testing.T) {
 func TestServerTimeouts(t *testing.T) {
        setParallel(t)
        defer afterTest(t)
+       // Try three times, with increasing timeouts.
+       tries := []time.Duration{250 * time.Millisecond, 500 * time.Millisecond, 1 * time.Second}
+       for i, timeout := range tries {
+               err := testServerTimeouts(timeout)
+               if err == nil {
+                       return
+               }
+               t.Logf("failed at %v: %v", timeout, err)
+               if i != len(tries)-1 {
+                       t.Logf("retrying at %v ...", tries[i+1])
+               }
+       }
+       t.Fatal("all attempts failed")
+}
+
+func testServerTimeouts(timeout time.Duration) error {
        reqNum := 0
        ts := httptest.NewUnstartedServer(HandlerFunc(func(res ResponseWriter, req *Request) {
                reqNum++
                fmt.Fprintf(res, "req=%d", reqNum)
        }))
-       ts.Config.ReadTimeout = 250 * time.Millisecond
-       ts.Config.WriteTimeout = 250 * time.Millisecond
+       ts.Config.ReadTimeout = timeout
+       ts.Config.WriteTimeout = timeout
        ts.Start()
        defer ts.Close()
 
@@ -477,12 +493,12 @@ func TestServerTimeouts(t *testing.T) {
        c := ts.Client()
        r, err := c.Get(ts.URL)
        if err != nil {
-               t.Fatalf("http Get #1: %v", err)
+               return fmt.Errorf("http Get #1: %v", err)
        }
        got, err := ioutil.ReadAll(r.Body)
        expected := "req=1"
        if string(got) != expected || err != nil {
-               t.Errorf("Unexpected response for request #1; got %q ,%v; expected %q, nil",
+               return fmt.Errorf("Unexpected response for request #1; got %q ,%v; expected %q, nil",
                        string(got), err, expected)
        }
 
@@ -490,17 +506,18 @@ func TestServerTimeouts(t *testing.T) {
        t1 := time.Now()
        conn, err := net.Dial("tcp", ts.Listener.Addr().String())
        if err != nil {
-               t.Fatalf("Dial: %v", err)
+               return fmt.Errorf("Dial: %v", err)
        }
        buf := make([]byte, 1)
        n, err := conn.Read(buf)
        conn.Close()
        latency := time.Since(t1)
        if n != 0 || err != io.EOF {
-               t.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF)
+               return fmt.Errorf("Read = %v, %v, wanted %v, %v", n, err, 0, io.EOF)
        }
-       if latency < 200*time.Millisecond /* fudge from 250 ms above */ {
-               t.Errorf("got EOF after %s, want >= %s", latency, 200*time.Millisecond)
+       minLatency := timeout / 5 * 4
+       if latency < minLatency {
+               return fmt.Errorf("got EOF after %s, want >= %s", latency, minLatency)
        }
 
        // Hit the HTTP server successfully again, verifying that the
@@ -508,29 +525,31 @@ func TestServerTimeouts(t *testing.T) {
        // get "req=2", not "req=3")
        r, err = c.Get(ts.URL)
        if err != nil {
-               t.Fatalf("http Get #2: %v", err)
+               return fmt.Errorf("http Get #2: %v", err)
        }
        got, err = ioutil.ReadAll(r.Body)
+       r.Body.Close()
        expected = "req=2"
        if string(got) != expected || err != nil {
-               t.Errorf("Get #2 got %q, %v, want %q, nil", string(got), err, expected)
+               return fmt.Errorf("Get #2 got %q, %v, want %q, nil", string(got), err, expected)
        }
 
        if !testing.Short() {
                conn, err := net.Dial("tcp", ts.Listener.Addr().String())
                if err != nil {
-                       t.Fatalf("Dial: %v", err)
+                       return fmt.Errorf("long Dial: %v", err)
                }
                defer conn.Close()
                go io.Copy(ioutil.Discard, conn)
                for i := 0; i < 5; i++ {
                        _, err := conn.Write([]byte("GET / HTTP/1.1\r\nHost: foo\r\n\r\n"))
                        if err != nil {
-                               t.Fatalf("on write %d: %v", i, err)
+                               return fmt.Errorf("on write %d: %v", i, err)
                        }
-                       time.Sleep(ts.Config.ReadTimeout / 2)
+                       time.Sleep(timeout / 2)
                }
        }
+       return nil
 }
 
 // Test that the HTTP/2 server handles Server.WriteTimeout (Issue 18437)