libgo: update to go1.9
[official-gcc.git] / libgo / go / net / http / transport_internal_test.go
blob594bf6e2c8374a9b261e2b55ebb3f46204fd8bd2
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 func TestTransportShouldRetryRequest(t *testing.T) {
100 tests := []struct {
101 pc *persistConn
102 req *Request
104 err error
105 want bool
107 0: {
108 pc: &persistConn{reused: false},
109 req: dummyRequest("POST"),
110 err: nothingWrittenError{},
111 want: false,
113 1: {
114 pc: &persistConn{reused: true},
115 req: dummyRequest("POST"),
116 err: nothingWrittenError{},
117 want: true,
119 2: {
120 pc: &persistConn{reused: true},
121 req: dummyRequest("POST"),
122 err: http2ErrNoCachedConn,
123 want: true,
125 3: {
126 pc: &persistConn{reused: true},
127 req: dummyRequest("POST"),
128 err: errMissingHost,
129 want: false,
131 4: {
132 pc: &persistConn{reused: true},
133 req: dummyRequest("POST"),
134 err: transportReadFromServerError{},
135 want: false,
137 5: {
138 pc: &persistConn{reused: true},
139 req: dummyRequest("GET"),
140 err: transportReadFromServerError{},
141 want: true,
143 6: {
144 pc: &persistConn{reused: true},
145 req: dummyRequest("GET"),
146 err: errServerClosedIdle,
147 want: true,
149 7: {
150 pc: &persistConn{reused: true},
151 req: dummyRequestWithBody("POST"),
152 err: nothingWrittenError{},
153 want: true,
155 8: {
156 pc: &persistConn{reused: true},
157 req: dummyRequestWithBodyNoGetBody("POST"),
158 err: nothingWrittenError{},
159 want: false,
162 for i, tt := range tests {
163 got := tt.pc.shouldRetryRequest(tt.req, tt.err)
164 if got != tt.want {
165 t.Errorf("%d. shouldRetryRequest = %v; want %v", i, got, tt.want)