libgo: update to Go 1.11
[official-gcc.git] / libgo / go / net / http / export_test.go
blobbc0db53a2c600549bdb884899a4626b144f352f6
1 // Copyright 2011 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 // Bridge package to expose http internals to tests in the http_test
6 // package.
8 package http
10 import (
11 "context"
12 "fmt"
13 "net"
14 "net/url"
15 "sort"
16 "sync"
17 "testing"
18 "time"
21 var (
22 DefaultUserAgent = defaultUserAgent
23 NewLoggingConn = newLoggingConn
24 ExportAppendTime = appendTime
25 ExportRefererForURL = refererForURL
26 ExportServerNewConn = (*Server).newConn
27 ExportCloseWriteAndWait = (*conn).closeWriteAndWait
28 ExportErrRequestCanceled = errRequestCanceled
29 ExportErrRequestCanceledConn = errRequestCanceledConn
30 ExportErrServerClosedIdle = errServerClosedIdle
31 ExportServeFile = serveFile
32 ExportScanETag = scanETag
33 ExportHttp2ConfigureServer = http2ConfigureServer
34 Export_shouldCopyHeaderOnRedirect = shouldCopyHeaderOnRedirect
35 Export_writeStatusLine = writeStatusLine
38 const MaxWriteWaitBeforeConnReuse = maxWriteWaitBeforeConnReuse
40 func init() {
41 // We only want to pay for this cost during testing.
42 // When not under test, these values are always nil
43 // and never assigned to.
44 testHookMu = new(sync.Mutex)
46 testHookClientDoResult = func(res *Response, err error) {
47 if err != nil {
48 if _, ok := err.(*url.Error); !ok {
49 panic(fmt.Sprintf("unexpected Client.Do error of type %T; want *url.Error", err))
51 } else {
52 if res == nil {
53 panic("Client.Do returned nil, nil")
55 if res.Body == nil {
56 panic("Client.Do returned nil res.Body and no error")
62 var (
63 SetEnterRoundTripHook = hookSetter(&testHookEnterRoundTrip)
64 SetRoundTripRetried = hookSetter(&testHookRoundTripRetried)
67 func SetReadLoopBeforeNextReadHook(f func()) {
68 testHookMu.Lock()
69 defer testHookMu.Unlock()
70 unnilTestHook(&f)
71 testHookReadLoopBeforeNextRead = f
74 // SetPendingDialHooks sets the hooks that run before and after handling
75 // pending dials.
76 func SetPendingDialHooks(before, after func()) {
77 unnilTestHook(&before)
78 unnilTestHook(&after)
79 testHookPrePendingDial, testHookPostPendingDial = before, after
82 func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn }
84 func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler {
85 ctx, cancel := context.WithCancel(context.Background())
86 go func() {
87 <-ch
88 cancel()
89 }()
90 return &timeoutHandler{
91 handler: handler,
92 testContext: ctx,
93 // (no body)
97 func ResetCachedEnvironment() {
98 resetProxyConfig()
101 func (t *Transport) NumPendingRequestsForTesting() int {
102 t.reqMu.Lock()
103 defer t.reqMu.Unlock()
104 return len(t.reqCanceler)
107 func (t *Transport) IdleConnKeysForTesting() (keys []string) {
108 keys = make([]string, 0)
109 t.idleMu.Lock()
110 defer t.idleMu.Unlock()
111 for key := range t.idleConn {
112 keys = append(keys, key.String())
114 sort.Strings(keys)
115 return
118 func (t *Transport) IdleConnKeyCountForTesting() int {
119 t.idleMu.Lock()
120 defer t.idleMu.Unlock()
121 return len(t.idleConn)
124 func (t *Transport) IdleConnStrsForTesting() []string {
125 var ret []string
126 t.idleMu.Lock()
127 defer t.idleMu.Unlock()
128 for _, conns := range t.idleConn {
129 for _, pc := range conns {
130 ret = append(ret, pc.conn.LocalAddr().String()+"/"+pc.conn.RemoteAddr().String())
133 sort.Strings(ret)
134 return ret
137 func (t *Transport) IdleConnStrsForTesting_h2() []string {
138 var ret []string
139 noDialPool := t.h2transport.(*http2Transport).ConnPool.(http2noDialClientConnPool)
140 pool := noDialPool.http2clientConnPool
142 pool.mu.Lock()
143 defer pool.mu.Unlock()
145 for k, cc := range pool.conns {
146 for range cc {
147 ret = append(ret, k)
151 sort.Strings(ret)
152 return ret
155 func (t *Transport) IdleConnCountForTesting(scheme, addr string) int {
156 t.idleMu.Lock()
157 defer t.idleMu.Unlock()
158 key := connectMethodKey{"", scheme, addr}
159 cacheKey := key.String()
160 for k, conns := range t.idleConn {
161 if k.String() == cacheKey {
162 return len(conns)
165 return 0
168 func (t *Transport) IdleConnChMapSizeForTesting() int {
169 t.idleMu.Lock()
170 defer t.idleMu.Unlock()
171 return len(t.idleConnCh)
174 func (t *Transport) IsIdleForTesting() bool {
175 t.idleMu.Lock()
176 defer t.idleMu.Unlock()
177 return t.wantIdle
180 func (t *Transport) RequestIdleConnChForTesting() {
181 t.getIdleConnCh(connectMethod{nil, "http", "example.com"})
184 func (t *Transport) PutIdleTestConn(scheme, addr string) bool {
185 c, _ := net.Pipe()
186 key := connectMethodKey{"", scheme, addr}
187 select {
188 case <-t.incHostConnCount(key):
189 default:
190 return false
192 return t.tryPutIdleConn(&persistConn{
193 t: t,
194 conn: c, // dummy
195 closech: make(chan struct{}), // so it can be closed
196 cacheKey: key,
197 }) == nil
200 // All test hooks must be non-nil so they can be called directly,
201 // but the tests use nil to mean hook disabled.
202 func unnilTestHook(f *func()) {
203 if *f == nil {
204 *f = nop
208 func hookSetter(dst *func()) func(func()) {
209 return func(fn func()) {
210 unnilTestHook(&fn)
211 *dst = fn
215 func ExportHttp2ConfigureTransport(t *Transport) error {
216 t2, err := http2configureTransport(t)
217 if err != nil {
218 return err
220 t.h2transport = t2
221 return nil
224 func (s *Server) ExportAllConnsIdle() bool {
225 s.mu.Lock()
226 defer s.mu.Unlock()
227 for c := range s.activeConn {
228 st, unixSec := c.getState()
229 if unixSec == 0 || st != StateIdle {
230 return false
233 return true
236 func (r *Request) WithT(t *testing.T) *Request {
237 return r.WithContext(context.WithValue(r.Context(), tLogKey{}, t.Logf))
240 func ExportSetH2GoawayTimeout(d time.Duration) (restore func()) {
241 old := http2goAwayTimeout
242 http2goAwayTimeout = d
243 return func() { http2goAwayTimeout = old }