libgo: update to Go 1.11
[official-gcc.git] / libgo / go / net / http / transport_internal_test.go
bloba5f29c97a9087cc2b7716b50ee247e178e5ef666
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).
7 package http
9 import (
10 "errors"
11 "net"
12 "strings"
13 "testing"
16 // Issue 15446: incorrect wrapping of errors when server closes an idle connection.
17 func TestTransportPersistConnReadLoopEOF(t *testing.T) {
18 ln := newLocalListener(t)
19 defer ln.Close()
21 connc := make(chan net.Conn, 1)
22 go func() {
23 defer close(connc)
24 c, err := ln.Accept()
25 if err != nil {
26 t.Error(err)
27 return
29 connc <- c
30 }()
32 tr := new(Transport)
33 req, _ := NewRequest("GET", "http://"+ln.Addr().String(), nil)
34 req = req.WithT(t)
35 treq := &transportRequest{Request: req}
36 cm := connectMethod{targetScheme: "http", targetAddr: ln.Addr().String()}
37 pc, err := tr.getConn(treq, cm)
38 if err != nil {
39 t.Fatal(err)
41 defer pc.close(errors.New("test over"))
43 conn := <-connc
44 if conn == nil {
45 // Already called t.Error in the accept goroutine.
46 return
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)
55 <-pc.closech
56 err = pc.closed
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)
64 return ok
67 func newLocalListener(t *testing.T) net.Listener {
68 ln, err := net.Listen("tcp", "127.0.0.1:0")
69 if err != nil {
70 ln, err = net.Listen("tcp6", "[::1]:0")
72 if err != nil {
73 t.Fatal(err)
75 return ln
78 func dummyRequest(method string) *Request {
79 req, err := NewRequest(method, "http://fake.tld/", nil)
80 if err != nil {
81 panic(err)
83 return req
85 func dummyRequestWithBody(method string) *Request {
86 req, err := NewRequest(method, "http://fake.tld/", strings.NewReader("foo"))
87 if err != nil {
88 panic(err)
90 return req
93 func dummyRequestWithBodyNoGetBody(method string) *Request {
94 req := dummyRequestWithBody(method)
95 req.GetBody = nil
96 return req
99 // issue22091Error acts like a golang.org/x/net/http2.ErrNoCachedConn.
100 type issue22091Error struct{}
102 func (issue22091Error) IsHTTP2NoCachedConnError() {}
103 func (issue22091Error) Error() string { return "issue22091Error" }
105 func TestTransportShouldRetryRequest(t *testing.T) {
106 tests := []struct {
107 pc *persistConn
108 req *Request
110 err error
111 want bool
113 0: {
114 pc: &persistConn{reused: false},
115 req: dummyRequest("POST"),
116 err: nothingWrittenError{},
117 want: false,
119 1: {
120 pc: &persistConn{reused: true},
121 req: dummyRequest("POST"),
122 err: nothingWrittenError{},
123 want: true,
125 2: {
126 pc: &persistConn{reused: true},
127 req: dummyRequest("POST"),
128 err: http2ErrNoCachedConn,
129 want: true,
131 3: {
132 pc: nil,
133 req: nil,
134 err: issue22091Error{}, // like an external http2ErrNoCachedConn
135 want: true,
137 4: {
138 pc: &persistConn{reused: true},
139 req: dummyRequest("POST"),
140 err: errMissingHost,
141 want: false,
143 5: {
144 pc: &persistConn{reused: true},
145 req: dummyRequest("POST"),
146 err: transportReadFromServerError{},
147 want: false,
149 6: {
150 pc: &persistConn{reused: true},
151 req: dummyRequest("GET"),
152 err: transportReadFromServerError{},
153 want: true,
155 7: {
156 pc: &persistConn{reused: true},
157 req: dummyRequest("GET"),
158 err: errServerClosedIdle,
159 want: true,
161 8: {
162 pc: &persistConn{reused: true},
163 req: dummyRequestWithBody("POST"),
164 err: nothingWrittenError{},
165 want: true,
167 9: {
168 pc: &persistConn{reused: true},
169 req: dummyRequestWithBodyNoGetBody("POST"),
170 err: nothingWrittenError{},
171 want: false,
174 for i, tt := range tests {
175 got := tt.pc.shouldRetryRequest(tt.req, tt.err)
176 if got != tt.want {
177 t.Errorf("%d. shouldRetryRequest = %v; want %v", i, got, tt.want)