1 // Copyright 2016 The Go Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style
3 // license that can be found in the LICENSE file.
5 // White-box tests for transport.go (in package http instead of http_test).
16 // Issue 15446: incorrect wrapping of errors when server closes an idle connection.
17 func TestTransportPersistConnReadLoopEOF(t
*testing
.T
) {
18 ln
:= newLocalListener(t
)
21 connc
:= make(chan net
.Conn
, 1)
33 req
, _
:= NewRequest("GET", "http://"+ln
.Addr().String(), nil)
35 treq
:= &transportRequest
{Request
: req
}
36 cm
:= connectMethod
{targetScheme
: "http", targetAddr
: ln
.Addr().String()}
37 pc
, err
:= tr
.getConn(treq
, cm
)
41 defer pc
.close(errors
.New("test over"))
45 // Already called t.Error in the accept goroutine.
48 conn
.Close() // simulate the server hanging up on the client
50 _
, err
= pc
.roundTrip(treq
)
51 if !isTransportReadFromServerError(err
) && err
!= errServerClosedIdle
{
52 t
.Errorf("roundTrip = %#v, %v; want errServerClosedIdle or transportReadFromServerError", err
, err
)
57 if !isTransportReadFromServerError(err
) && err
!= errServerClosedIdle
{
58 t
.Errorf("pc.closed = %#v, %v; want errServerClosedIdle or transportReadFromServerError", err
, err
)
62 func isTransportReadFromServerError(err error
) bool {
63 _
, ok
:= err
.(transportReadFromServerError
)
67 func newLocalListener(t
*testing
.T
) net
.Listener
{
68 ln
, err
:= net
.Listen("tcp", "127.0.0.1:0")
70 ln
, err
= net
.Listen("tcp6", "[::1]:0")
78 func dummyRequest(method
string) *Request
{
79 req
, err
:= NewRequest(method
, "http://fake.tld/", nil)
85 func dummyRequestWithBody(method
string) *Request
{
86 req
, err
:= NewRequest(method
, "http://fake.tld/", strings
.NewReader("foo"))
93 func dummyRequestWithBodyNoGetBody(method
string) *Request
{
94 req
:= dummyRequestWithBody(method
)
99 func TestTransportShouldRetryRequest(t
*testing
.T
) {
108 pc
: &persistConn
{reused
: false},
109 req
: dummyRequest("POST"),
110 err
: nothingWrittenError
{},
114 pc
: &persistConn
{reused
: true},
115 req
: dummyRequest("POST"),
116 err
: nothingWrittenError
{},
120 pc
: &persistConn
{reused
: true},
121 req
: dummyRequest("POST"),
122 err
: http2ErrNoCachedConn
,
126 pc
: &persistConn
{reused
: true},
127 req
: dummyRequest("POST"),
132 pc
: &persistConn
{reused
: true},
133 req
: dummyRequest("POST"),
134 err
: transportReadFromServerError
{},
138 pc
: &persistConn
{reused
: true},
139 req
: dummyRequest("GET"),
140 err
: transportReadFromServerError
{},
144 pc
: &persistConn
{reused
: true},
145 req
: dummyRequest("GET"),
146 err
: errServerClosedIdle
,
150 pc
: &persistConn
{reused
: true},
151 req
: dummyRequestWithBody("POST"),
152 err
: nothingWrittenError
{},
156 pc
: &persistConn
{reused
: true},
157 req
: dummyRequestWithBodyNoGetBody("POST"),
158 err
: nothingWrittenError
{},
162 for i
, tt
:= range tests
{
163 got
:= tt
.pc
.shouldRetryRequest(tt
.req
, tt
.err
)
165 t
.Errorf("%d. shouldRetryRequest = %v; want %v", i
, got
, tt
.want
)