Deprecate the ARM simulator
[official-gcc.git] / libgo / go / net / http / export_test.go
bloba849327f4528b430cac53046168f4a4a9440aaf2
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
36 Export_is408Message = is408Message
39 const MaxWriteWaitBeforeConnReuse = maxWriteWaitBeforeConnReuse
41 func init() {
42 // We only want to pay for this cost during testing.
43 // When not under test, these values are always nil
44 // and never assigned to.
45 testHookMu = new(sync.Mutex)
47 testHookClientDoResult = func(res *Response, err error) {
48 if err != nil {
49 if _, ok := err.(*url.Error); !ok {
50 panic(fmt.Sprintf("unexpected Client.Do error of type %T; want *url.Error", err))
52 } else {
53 if res == nil {
54 panic("Client.Do returned nil, nil")
56 if res.Body == nil {
57 panic("Client.Do returned nil res.Body and no error")
63 func CondSkipHTTP2(t *testing.T) {
64 if omitBundledHTTP2 {
65 t.Skip("skipping HTTP/2 test when nethttpomithttp2 build tag in use")
69 var (
70 SetEnterRoundTripHook = hookSetter(&testHookEnterRoundTrip)
71 SetRoundTripRetried = hookSetter(&testHookRoundTripRetried)
74 func SetReadLoopBeforeNextReadHook(f func()) {
75 testHookMu.Lock()
76 defer testHookMu.Unlock()
77 unnilTestHook(&f)
78 testHookReadLoopBeforeNextRead = f
81 // SetPendingDialHooks sets the hooks that run before and after handling
82 // pending dials.
83 func SetPendingDialHooks(before, after func()) {
84 unnilTestHook(&before)
85 unnilTestHook(&after)
86 testHookPrePendingDial, testHookPostPendingDial = before, after
89 func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn }
91 func NewTestTimeoutHandler(handler Handler, ctx context.Context) Handler {
92 return &timeoutHandler{
93 handler: handler,
94 testContext: ctx,
95 // (no body)
99 func ResetCachedEnvironment() {
100 resetProxyConfig()
103 func (t *Transport) NumPendingRequestsForTesting() int {
104 t.reqMu.Lock()
105 defer t.reqMu.Unlock()
106 return len(t.reqCanceler)
109 func (t *Transport) IdleConnKeysForTesting() (keys []string) {
110 keys = make([]string, 0)
111 t.idleMu.Lock()
112 defer t.idleMu.Unlock()
113 for key := range t.idleConn {
114 keys = append(keys, key.String())
116 sort.Strings(keys)
117 return
120 func (t *Transport) IdleConnKeyCountForTesting() int {
121 t.idleMu.Lock()
122 defer t.idleMu.Unlock()
123 return len(t.idleConn)
126 func (t *Transport) IdleConnStrsForTesting() []string {
127 var ret []string
128 t.idleMu.Lock()
129 defer t.idleMu.Unlock()
130 for _, conns := range t.idleConn {
131 for _, pc := range conns {
132 ret = append(ret, pc.conn.LocalAddr().String()+"/"+pc.conn.RemoteAddr().String())
135 sort.Strings(ret)
136 return ret
139 func (t *Transport) IdleConnStrsForTesting_h2() []string {
140 var ret []string
141 noDialPool := t.h2transport.(*http2Transport).ConnPool.(http2noDialClientConnPool)
142 pool := noDialPool.http2clientConnPool
144 pool.mu.Lock()
145 defer pool.mu.Unlock()
147 for k, cc := range pool.conns {
148 for range cc {
149 ret = append(ret, k)
153 sort.Strings(ret)
154 return ret
157 func (t *Transport) IdleConnCountForTesting(scheme, addr string) int {
158 t.idleMu.Lock()
159 defer t.idleMu.Unlock()
160 key := connectMethodKey{"", scheme, addr, false}
161 cacheKey := key.String()
162 for k, conns := range t.idleConn {
163 if k.String() == cacheKey {
164 return len(conns)
167 return 0
170 func (t *Transport) IdleConnWaitMapSizeForTesting() int {
171 t.idleMu.Lock()
172 defer t.idleMu.Unlock()
173 return len(t.idleConnWait)
176 func (t *Transport) IsIdleForTesting() bool {
177 t.idleMu.Lock()
178 defer t.idleMu.Unlock()
179 return t.closeIdle
182 func (t *Transport) QueueForIdleConnForTesting() {
183 t.queueForIdleConn(nil)
186 // PutIdleTestConn reports whether it was able to insert a fresh
187 // persistConn for scheme, addr into the idle connection pool.
188 func (t *Transport) PutIdleTestConn(scheme, addr string) bool {
189 c, _ := net.Pipe()
190 key := connectMethodKey{"", scheme, addr, false}
192 if t.MaxConnsPerHost > 0 {
193 // Transport is tracking conns-per-host.
194 // Increment connection count to account
195 // for new persistConn created below.
196 t.connsPerHostMu.Lock()
197 if t.connsPerHost == nil {
198 t.connsPerHost = make(map[connectMethodKey]int)
200 t.connsPerHost[key]++
201 t.connsPerHostMu.Unlock()
204 return t.tryPutIdleConn(&persistConn{
205 t: t,
206 conn: c, // dummy
207 closech: make(chan struct{}), // so it can be closed
208 cacheKey: key,
209 }) == nil
212 // PutIdleTestConnH2 reports whether it was able to insert a fresh
213 // HTTP/2 persistConn for scheme, addr into the idle connection pool.
214 func (t *Transport) PutIdleTestConnH2(scheme, addr string, alt RoundTripper) bool {
215 key := connectMethodKey{"", scheme, addr, false}
217 if t.MaxConnsPerHost > 0 {
218 // Transport is tracking conns-per-host.
219 // Increment connection count to account
220 // for new persistConn created below.
221 t.connsPerHostMu.Lock()
222 if t.connsPerHost == nil {
223 t.connsPerHost = make(map[connectMethodKey]int)
225 t.connsPerHost[key]++
226 t.connsPerHostMu.Unlock()
229 return t.tryPutIdleConn(&persistConn{
230 t: t,
231 alt: alt,
232 cacheKey: key,
233 }) == nil
236 // All test hooks must be non-nil so they can be called directly,
237 // but the tests use nil to mean hook disabled.
238 func unnilTestHook(f *func()) {
239 if *f == nil {
240 *f = nop
244 func hookSetter(dst *func()) func(func()) {
245 return func(fn func()) {
246 unnilTestHook(&fn)
247 *dst = fn
251 func ExportHttp2ConfigureTransport(t *Transport) error {
252 t2, err := http2configureTransports(t)
253 if err != nil {
254 return err
256 t.h2transport = t2
257 return nil
260 func (s *Server) ExportAllConnsIdle() bool {
261 s.mu.Lock()
262 defer s.mu.Unlock()
263 for c := range s.activeConn {
264 st, unixSec := c.getState()
265 if unixSec == 0 || st != StateIdle {
266 return false
269 return true
272 func (s *Server) ExportAllConnsByState() map[ConnState]int {
273 states := map[ConnState]int{}
274 s.mu.Lock()
275 defer s.mu.Unlock()
276 for c := range s.activeConn {
277 st, _ := c.getState()
278 states[st] += 1
280 return states
283 func (r *Request) WithT(t *testing.T) *Request {
284 return r.WithContext(context.WithValue(r.Context(), tLogKey{}, t.Logf))
287 func ExportSetH2GoawayTimeout(d time.Duration) (restore func()) {
288 old := http2goAwayTimeout
289 http2goAwayTimeout = d
290 return func() { http2goAwayTimeout = old }
293 func (r *Request) ExportIsReplayable() bool { return r.isReplayable() }
295 // ExportCloseTransportConnsAbruptly closes all idle connections from
296 // tr in an abrupt way, just reaching into the underlying Conns and
297 // closing them, without telling the Transport or its persistConns
298 // that it's doing so. This is to simulate the server closing connections
299 // on the Transport.
300 func ExportCloseTransportConnsAbruptly(tr *Transport) {
301 tr.idleMu.Lock()
302 for _, pcs := range tr.idleConn {
303 for _, pc := range pcs {
304 pc.conn.Close()
307 tr.idleMu.Unlock()