Skip to content

Commit 3970667

Browse files
committed
net/http: fix TestTransportServerClosingUnexpectedly flake
Fixes #32119 Change-Id: I8cf2e2e69737e2485568af91ab75149f3cf66781 Reviewed-on: https://go-review.googlesource.com/c/go/+/178918 Run-TryBot: Brad Fitzpatrick <[email protected]> TryBot-Result: Gobot Gobot <[email protected]> Reviewed-by: Ian Lance Taylor <[email protected]>
1 parent f736de0 commit 3970667

File tree

2 files changed

+25
-7
lines changed

2 files changed

+25
-7
lines changed

src/net/http/export_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -244,3 +244,18 @@ func ExportSetH2GoawayTimeout(d time.Duration) (restore func()) {
244244
}
245245

246246
func (r *Request) ExportIsReplayable() bool { return r.isReplayable() }
247+
248+
// ExportCloseTransportConnsAbruptly closes all idle connections from
249+
// tr in an abrupt way, just reaching into the underlying Conns and
250+
// closing them, without telling the Transport or its persistConns
251+
// that it's doing so. This is to simulate the server closing connections
252+
// on the Transport.
253+
func ExportCloseTransportConnsAbruptly(tr *Transport) {
254+
tr.idleMu.Lock()
255+
for _, pcs := range tr.idleConn {
256+
for _, pc := range pcs {
257+
pc.conn.Close()
258+
}
259+
}
260+
tr.idleMu.Unlock()
261+
}

src/net/http/transport_test.go

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -737,6 +737,8 @@ func TestTransportRemovesDeadIdleConnections(t *testing.T) {
737737
}
738738
}
739739

740+
// Test that the Transport notices when a server hangs up on its
741+
// unexpectedly (a keep-alive connection is closed).
740742
func TestTransportServerClosingUnexpectedly(t *testing.T) {
741743
setParallel(t)
742744
defer afterTest(t)
@@ -773,13 +775,14 @@ func TestTransportServerClosingUnexpectedly(t *testing.T) {
773775
body1 := fetch(1, 0)
774776
body2 := fetch(2, 0)
775777

776-
ts.CloseClientConnections() // surprise!
777-
778-
// This test has an expected race. Sleeping for 25 ms prevents
779-
// it on most fast machines, causing the next fetch() call to
780-
// succeed quickly. But if we do get errors, fetch() will retry 5
781-
// times with some delays between.
782-
time.Sleep(25 * time.Millisecond)
778+
// Close all the idle connections in a way that's similar to
779+
// the server hanging up on us. We don't use
780+
// httptest.Server.CloseClientConnections because it's
781+
// best-effort and stops blocking after 5 seconds. On a loaded
782+
// machine running many tests concurrently it's possible for
783+
// that method to be async and cause the body3 fetch below to
784+
// run on an old connection. This function is synchronous.
785+
ExportCloseTransportConnsAbruptly(c.Transport.(*Transport))
783786

784787
body3 := fetch(3, 5)
785788

0 commit comments

Comments
 (0)