aboutsummaryrefslogtreecommitdiff
path: root/src/net/http/transport_test.go
diff options
context:
space:
mode:
authorZiheng Liu <lzhfromustc@gmail.com>2020-02-13 16:20:30 -0500
committerIan Lance Taylor <iant@golang.org>2020-02-27 19:04:17 +0000
commit42f8199290f27a65f2aba9f1f6b9bdfd2406612e (patch)
tree572e42c6d0be4d1a9daf2987f1704d43a05093cf /src/net/http/transport_test.go
parentea3bfba87cfd7141870f975102029e2e341b4af3 (diff)
downloadgo-42f8199290f27a65f2aba9f1f6b9bdfd2406612e.tar.gz
go-42f8199290f27a65f2aba9f1f6b9bdfd2406612e.zip
all: fix incorrect channel and API usage in some unit tests
This CL changes some unit test functions, making sure that these tests (and goroutines spawned during test) won't block. Since they are just test functions, I use one CL to fix them all. I hope this won't cause trouble to reviewers and can save time for us. There are three main categories of incorrect logic fixed by this CL: 1. Use testing.Fatal()/Fatalf() in spawned goroutines, which is forbidden by Go's document. 2. Channels are used in such a way that, when errors or timeout happen, the test will be blocked and never return. 3. Channels are used in such a way that, when errors or timeout happen, the test can return but some spawned goroutines will be leaked, occupying resource until all other tests return and the process is killed. Change-Id: I3df931ec380794a0cf1404e632c1dd57c65d63e8 Reviewed-on: https://go-review.googlesource.com/c/go/+/219380 Run-TryBot: Ian Lance Taylor <iant@golang.org> TryBot-Result: Gobot Gobot <gobot@golang.org> Reviewed-by: Ian Lance Taylor <iant@golang.org>
Diffstat (limited to 'src/net/http/transport_test.go')
-rw-r--r--src/net/http/transport_test.go35
1 files changed, 28 insertions, 7 deletions
diff --git a/src/net/http/transport_test.go b/src/net/http/transport_test.go
index 3ca7ce93b2..f4014d95bb 100644
--- a/src/net/http/transport_test.go
+++ b/src/net/http/transport_test.go
@@ -451,14 +451,23 @@ func TestTransportReadToEndReusesConn(t *testing.T) {
func TestTransportMaxPerHostIdleConns(t *testing.T) {
defer afterTest(t)
+ stop := make(chan struct{}) // stop marks the exit of main Test goroutine
+ defer close(stop)
+
resch := make(chan string)
gotReq := make(chan bool)
ts := httptest.NewServer(HandlerFunc(func(w ResponseWriter, r *Request) {
gotReq <- true
- msg := <-resch
+ var msg string
+ select {
+ case <-stop:
+ return
+ case msg = <-resch:
+ }
_, err := w.Write([]byte(msg))
if err != nil {
- t.Fatalf("Write: %v", err)
+ t.Errorf("Write: %v", err)
+ return
}
}))
defer ts.Close()
@@ -472,6 +481,13 @@ func TestTransportMaxPerHostIdleConns(t *testing.T) {
// Their responses will hang until we write to resch, though.
donech := make(chan bool)
doReq := func() {
+ defer func() {
+ select {
+ case <-stop:
+ return
+ case donech <- t.Failed():
+ }
+ }()
resp, err := c.Get(ts.URL)
if err != nil {
t.Error(err)
@@ -481,7 +497,6 @@ func TestTransportMaxPerHostIdleConns(t *testing.T) {
t.Errorf("ReadAll: %v", err)
return
}
- donech <- true
}
go doReq()
<-gotReq
@@ -842,7 +857,9 @@ func TestStressSurpriseServerCloses(t *testing.T) {
// where we won the race.
res.Body.Close()
}
- activityc <- true
+ if !<-activityc { // Receives false when close(activityc) is executed
+ return
+ }
}
}()
}
@@ -850,8 +867,9 @@ func TestStressSurpriseServerCloses(t *testing.T) {
// Make sure all the request come back, one way or another.
for i := 0; i < numClients*reqsPerClient; i++ {
select {
- case <-activityc:
+ case activityc <- true:
case <-time.After(5 * time.Second):
+ close(activityc)
t.Fatalf("presumed deadlock; no HTTP client activity seen in awhile")
}
}
@@ -2361,7 +2379,9 @@ func TestTransportCancelRequestInDial(t *testing.T) {
tr := &Transport{
Dial: func(network, addr string) (net.Conn, error) {
eventLog.Println("dial: blocking")
- inDial <- true
+ if !<-inDial {
+ return nil, errors.New("main Test goroutine exited")
+ }
<-unblockDial
return nil, errors.New("nope")
},
@@ -2376,8 +2396,9 @@ func TestTransportCancelRequestInDial(t *testing.T) {
}()
select {
- case <-inDial:
+ case inDial <- true:
case <-time.After(5 * time.Second):
+ close(inDial)
t.Fatal("timeout; never saw blocking dial")
}