github.com/sean-/go@v0.0.0-20151219100004-97f854cd7bb6/src/net/http/export_test.go (about) 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. 4 5 // Bridge package to expose http internals to tests in the http_test 6 // package. 7 8 package http 9 10 import ( 11 "net" 12 "sync" 13 "time" 14 ) 15 16 var ( 17 DefaultUserAgent = defaultUserAgent 18 NewLoggingConn = newLoggingConn 19 ExportAppendTime = appendTime 20 ExportRefererForURL = refererForURL 21 ExportServerNewConn = (*Server).newConn 22 ExportCloseWriteAndWait = (*conn).closeWriteAndWait 23 ExportErrRequestCanceled = errRequestCanceled 24 ExportServeFile = serveFile 25 ExportHttp2ConfigureTransport = http2ConfigureTransport 26 ExportHttp2ConfigureServer = http2ConfigureServer 27 ) 28 29 func init() { 30 // We only want to pay for this cost during testing. 31 // When not under test, these values are always nil 32 // and never assigned to. 33 testHookMu = new(sync.Mutex) 34 } 35 36 var ( 37 SetEnterRoundTripHook = hookSetter(&testHookEnterRoundTrip) 38 SetTestHookWaitResLoop = hookSetter(&testHookWaitResLoop) 39 SetRoundTripRetried = hookSetter(&testHookRoundTripRetried) 40 ) 41 42 func SetReadLoopBeforeNextReadHook(f func()) { 43 testHookMu.Lock() 44 defer testHookMu.Unlock() 45 unnilTestHook(&f) 46 testHookReadLoopBeforeNextRead = f 47 } 48 49 // SetPendingDialHooks sets the hooks that run before and after handling 50 // pending dials. 51 func SetPendingDialHooks(before, after func()) { 52 unnilTestHook(&before) 53 unnilTestHook(&after) 54 testHookPrePendingDial, testHookPostPendingDial = before, after 55 } 56 57 func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn } 58 59 func NewTestTimeoutHandler(handler Handler, ch <-chan time.Time) Handler { 60 return &timeoutHandler{ 61 handler: handler, 62 timeout: func() <-chan time.Time { return ch }, 63 // (no body and nil cancelTimer) 64 } 65 } 66 67 func ResetCachedEnvironment() { 68 httpProxyEnv.reset() 69 httpsProxyEnv.reset() 70 noProxyEnv.reset() 71 } 72 73 func (t *Transport) NumPendingRequestsForTesting() int { 74 t.reqMu.Lock() 75 defer t.reqMu.Unlock() 76 return len(t.reqCanceler) 77 } 78 79 func (t *Transport) IdleConnKeysForTesting() (keys []string) { 80 keys = make([]string, 0) 81 t.idleMu.Lock() 82 defer t.idleMu.Unlock() 83 if t.idleConn == nil { 84 return 85 } 86 for key := range t.idleConn { 87 keys = append(keys, key.String()) 88 } 89 return 90 } 91 92 func (t *Transport) IdleConnCountForTesting(cacheKey string) int { 93 t.idleMu.Lock() 94 defer t.idleMu.Unlock() 95 if t.idleConn == nil { 96 return 0 97 } 98 for k, conns := range t.idleConn { 99 if k.String() == cacheKey { 100 return len(conns) 101 } 102 } 103 return 0 104 } 105 106 func (t *Transport) IdleConnChMapSizeForTesting() int { 107 t.idleMu.Lock() 108 defer t.idleMu.Unlock() 109 return len(t.idleConnCh) 110 } 111 112 func (t *Transport) IsIdleForTesting() bool { 113 t.idleMu.Lock() 114 defer t.idleMu.Unlock() 115 return t.wantIdle 116 } 117 118 func (t *Transport) RequestIdleConnChForTesting() { 119 t.getIdleConnCh(connectMethod{nil, "http", "example.com"}) 120 } 121 122 func (t *Transport) PutIdleTestConn() bool { 123 c, _ := net.Pipe() 124 return t.putIdleConn(&persistConn{ 125 t: t, 126 conn: c, // dummy 127 closech: make(chan struct{}), // so it can be closed 128 cacheKey: connectMethodKey{"", "http", "example.com"}, 129 }) 130 } 131 132 // All test hooks must be non-nil so they can be called directly, 133 // but the tests use nil to mean hook disabled. 134 func unnilTestHook(f *func()) { 135 if *f == nil { 136 *f = nop 137 } 138 } 139 140 func hookSetter(dst *func()) func(func()) { 141 return func(fn func()) { 142 unnilTestHook(&fn) 143 *dst = fn 144 } 145 }