Commit 409a667f authored by Brad Fitzpatrick's avatar Brad Fitzpatrick

net/http: fix parallel tests using global DefaultTransport

When I added t.Parallel to some tests earlier, I overlooked some using
the global "Get" func, which uses DefaultTransport.

The DefaultTransport can have its CloseIdleConnections called by other
parallel tests. Use a private Transport instead.

Fixes #18006

Change-Id: Ia4faca5bac235cfa95dcf2703c25f3627112a5e9
Reviewed-on: https://go-review.googlesource.com/33432
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
Reviewed-by: 's avatarIan Lance Taylor <iant@golang.org>
parent 75055de8
...@@ -151,3 +151,7 @@ func waitErrCondition(waitFor, checkEvery time.Duration, fn func() error) error ...@@ -151,3 +151,7 @@ func waitErrCondition(waitFor, checkEvery time.Duration, fn func() error) error
} }
return err return err
} }
func closeClient(c *http.Client) {
c.Transport.(*http.Transport).CloseIdleConnections()
}
...@@ -620,13 +620,16 @@ func TestIdentityResponse(t *testing.T) { ...@@ -620,13 +620,16 @@ func TestIdentityResponse(t *testing.T) {
ts := httptest.NewServer(handler) ts := httptest.NewServer(handler)
defer ts.Close() defer ts.Close()
c := &Client{Transport: new(Transport)}
defer closeClient(c)
// Note: this relies on the assumption (which is true) that // Note: this relies on the assumption (which is true) that
// Get sends HTTP/1.1 or greater requests. Otherwise the // Get sends HTTP/1.1 or greater requests. Otherwise the
// server wouldn't have the choice to send back chunked // server wouldn't have the choice to send back chunked
// responses. // responses.
for _, te := range []string{"", "identity"} { for _, te := range []string{"", "identity"} {
url := ts.URL + "/?te=" + te url := ts.URL + "/?te=" + te
res, err := Get(url) res, err := c.Get(url)
if err != nil { if err != nil {
t.Fatalf("error with Get of %s: %v", url, err) t.Fatalf("error with Get of %s: %v", url, err)
} }
...@@ -645,7 +648,7 @@ func TestIdentityResponse(t *testing.T) { ...@@ -645,7 +648,7 @@ func TestIdentityResponse(t *testing.T) {
// Verify that ErrContentLength is returned // Verify that ErrContentLength is returned
url := ts.URL + "/?overwrite=1" url := ts.URL + "/?overwrite=1"
res, err := Get(url) res, err := c.Get(url)
if err != nil { if err != nil {
t.Fatalf("error with Get of %s: %v", url, err) t.Fatalf("error with Get of %s: %v", url, err)
} }
...@@ -968,7 +971,10 @@ func TestIdentityResponseHeaders(t *testing.T) { ...@@ -968,7 +971,10 @@ func TestIdentityResponseHeaders(t *testing.T) {
})) }))
defer ts.Close() defer ts.Close()
res, err := Get(ts.URL) c := &Client{Transport: new(Transport)}
defer closeClient(c)
res, err := c.Get(ts.URL)
if err != nil { if err != nil {
t.Fatalf("Get error: %v", err) t.Fatalf("Get error: %v", err)
} }
...@@ -1910,6 +1916,9 @@ func TestTimeoutHandlerRace(t *testing.T) { ...@@ -1910,6 +1916,9 @@ func TestTimeoutHandlerRace(t *testing.T) {
ts := httptest.NewServer(TimeoutHandler(delayHi, 20*time.Millisecond, "")) ts := httptest.NewServer(TimeoutHandler(delayHi, 20*time.Millisecond, ""))
defer ts.Close() defer ts.Close()
c := &Client{Transport: new(Transport)}
defer closeClient(c)
var wg sync.WaitGroup var wg sync.WaitGroup
gate := make(chan bool, 10) gate := make(chan bool, 10)
n := 50 n := 50
...@@ -1923,7 +1932,7 @@ func TestTimeoutHandlerRace(t *testing.T) { ...@@ -1923,7 +1932,7 @@ func TestTimeoutHandlerRace(t *testing.T) {
go func() { go func() {
defer wg.Done() defer wg.Done()
defer func() { <-gate }() defer func() { <-gate }()
res, err := Get(fmt.Sprintf("%s/%d", ts.URL, rand.Intn(50))) res, err := c.Get(fmt.Sprintf("%s/%d", ts.URL, rand.Intn(50)))
if err == nil { if err == nil {
io.Copy(ioutil.Discard, res.Body) io.Copy(ioutil.Discard, res.Body)
res.Body.Close() res.Body.Close()
...@@ -1951,13 +1960,15 @@ func TestTimeoutHandlerRaceHeader(t *testing.T) { ...@@ -1951,13 +1960,15 @@ func TestTimeoutHandlerRaceHeader(t *testing.T) {
if testing.Short() { if testing.Short() {
n = 10 n = 10
} }
c := &Client{Transport: new(Transport)}
defer closeClient(c)
for i := 0; i < n; i++ { for i := 0; i < n; i++ {
gate <- true gate <- true
wg.Add(1) wg.Add(1)
go func() { go func() {
defer wg.Done() defer wg.Done()
defer func() { <-gate }() defer func() { <-gate }()
res, err := Get(ts.URL) res, err := c.Get(ts.URL)
if err != nil { if err != nil {
t.Error(err) t.Error(err)
return return
...@@ -2036,11 +2047,15 @@ func TestTimeoutHandlerStartTimerWhenServing(t *testing.T) { ...@@ -2036,11 +2047,15 @@ func TestTimeoutHandlerStartTimerWhenServing(t *testing.T) {
timeout := 300 * time.Millisecond timeout := 300 * time.Millisecond
ts := httptest.NewServer(TimeoutHandler(handler, timeout, "")) ts := httptest.NewServer(TimeoutHandler(handler, timeout, ""))
defer ts.Close() defer ts.Close()
c := &Client{Transport: new(Transport)}
defer closeClient(c)
// Issue was caused by the timeout handler starting the timer when // Issue was caused by the timeout handler starting the timer when
// was created, not when the request. So wait for more than the timeout // was created, not when the request. So wait for more than the timeout
// to ensure that's not the case. // to ensure that's not the case.
time.Sleep(2 * timeout) time.Sleep(2 * timeout)
res, err := Get(ts.URL) res, err := c.Get(ts.URL)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -2061,7 +2076,10 @@ func TestTimeoutHandlerEmptyResponse(t *testing.T) { ...@@ -2061,7 +2076,10 @@ func TestTimeoutHandlerEmptyResponse(t *testing.T) {
ts := httptest.NewServer(TimeoutHandler(handler, timeout, "")) ts := httptest.NewServer(TimeoutHandler(handler, timeout, ""))
defer ts.Close() defer ts.Close()
res, err := Get(ts.URL) c := &Client{Transport: new(Transport)}
defer closeClient(c)
res, err := c.Get(ts.URL)
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
...@@ -2342,7 +2360,10 @@ func TestStripPrefix(t *testing.T) { ...@@ -2342,7 +2360,10 @@ func TestStripPrefix(t *testing.T) {
ts := httptest.NewServer(StripPrefix("/foo", h)) ts := httptest.NewServer(StripPrefix("/foo", h))
defer ts.Close() defer ts.Close()
res, err := Get(ts.URL + "/foo/bar") c := &Client{Transport: new(Transport)}
defer closeClient(c)
res, err := c.Get(ts.URL + "/foo/bar")
if err != nil { if err != nil {
t.Fatal(err) t.Fatal(err)
} }
......
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