Skip to content

Commit

Permalink
net/http: update bundled http2; fixes TestTransportAndServerSharedBod…
Browse files Browse the repository at this point in the history
…yRace_h2

Update bundled http2 to git rev d1ba260648 (https://golang.org/cl/18288).

Fixes the flaky TestTransportAndServerSharedBodyRace_h2.

Also adds some debugging to TestTransportAndServerSharedBodyRace_h2
which I hope won't ever be necessary again, but I know will be.

Fixes golang#13556

Change-Id: Ibcf2fc23ec0122dcac8891fdc3bd7f8acddd880e
Reviewed-on: https://go-review.googlesource.com/18289
Reviewed-by: Andrew Gerrand <adg@golang.org>
Run-TryBot: Brad Fitzpatrick <bradfitz@golang.org>
TryBot-Result: Gobot Gobot <gobot@golang.org>
  • Loading branch information
bradfitz committed Jan 7, 2016
1 parent e9fc522 commit 67fa797
Show file tree
Hide file tree
Showing 2 changed files with 95 additions and 11 deletions.
53 changes: 47 additions & 6 deletions src/net/http/h2_bundle.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

53 changes: 48 additions & 5 deletions src/net/http/serve_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ import (
"os/exec"
"reflect"
"runtime"
"runtime/debug"
"sort"
"strconv"
"strings"
Expand Down Expand Up @@ -3038,19 +3039,47 @@ func TestTransportAndServerSharedBodyRace_h1(t *testing.T) {
testTransportAndServerSharedBodyRace(t, h1Mode)
}
func TestTransportAndServerSharedBodyRace_h2(t *testing.T) {
t.Skip("failing in http2 mode; golang.org/issue/13556")
testTransportAndServerSharedBodyRace(t, h2Mode)
}
func testTransportAndServerSharedBodyRace(t *testing.T, h2 bool) {
defer afterTest(t)

const bodySize = 1 << 20

// errorf is like t.Errorf, but also writes to println. When
// this test fails, it hangs. This helps debugging and I've
// added this enough times "temporarily". It now gets added
// full time.
errorf := func(format string, args ...interface{}) {
v := fmt.Sprintf(format, args...)
println(v)
t.Error(v)
}

unblockBackend := make(chan bool)
backend := newClientServerTest(t, h2, HandlerFunc(func(rw ResponseWriter, req *Request) {
io.CopyN(rw, req.Body, bodySize)
gone := rw.(CloseNotifier).CloseNotify()
didCopy := make(chan interface{})
go func() {
n, err := io.CopyN(rw, req.Body, bodySize)
didCopy <- []interface{}{n, err}
}()
isGone := false
Loop:
for {
select {
case <-didCopy:
break Loop
case <-gone:
isGone = true
case <-time.After(time.Second):
println("1 second passes in backend, proxygone=", isGone)
}
}
<-unblockBackend
}))
var quitTimer *time.Timer
defer func() { quitTimer.Stop() }()
defer backend.close()

backendRespc := make(chan *Response, 1)
Expand All @@ -3063,17 +3092,17 @@ func testTransportAndServerSharedBodyRace(t *testing.T, h2 bool) {

bresp, err := proxy.c.Do(req2)
if err != nil {
t.Errorf("Proxy outbound request: %v", err)
errorf("Proxy outbound request: %v", err)
return
}
_, err = io.CopyN(ioutil.Discard, bresp.Body, bodySize/2)
if err != nil {
t.Errorf("Proxy copy error: %v", err)
errorf("Proxy copy error: %v", err)
return
}
backendRespc <- bresp // to close later

// Try to cause a race: Both the DefaultTransport and the proxy handler's Server
// Try to cause a race: Both the Transport and the proxy handler's Server
// will try to read/close req.Body (aka req2.Body)
if h2 {
close(cancel)
Expand All @@ -3083,6 +3112,20 @@ func testTransportAndServerSharedBodyRace(t *testing.T, h2 bool) {
rw.Write([]byte("OK"))
}))
defer proxy.close()
defer func() {
// Before we shut down our two httptest.Servers, start a timer.
// We choose 7 seconds because httptest.Server starts logging
// warnings to stderr at 5 seconds. If we don't disarm this bomb
// in 7 seconds (after the two httptest.Server.Close calls above),
// then we explode with stacks.
quitTimer = time.AfterFunc(7*time.Second, func() {
debug.SetTraceback("ALL")
stacks := make([]byte, 1<<20)
stacks = stacks[:runtime.Stack(stacks, true)]
fmt.Fprintf(os.Stderr, "%s", stacks)
log.Fatalf("Timeout.")
})
}()

defer close(unblockBackend)
req, _ := NewRequest("POST", proxy.ts.URL, io.LimitReader(neverEnding('a'), bodySize))
Expand Down

0 comments on commit 67fa797

Please sign in to comment.