netramesh

Форк
0
/
export_test.go 
244 строки · 5.7 Кб
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
	"context"
12
	"fmt"
13
	"net"
14
	"net/url"
15
	"sort"
16
	"sync"
17
	"testing"
18
	"time"
19
)
20

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
)
37

38
const MaxWriteWaitBeforeConnReuse = maxWriteWaitBeforeConnReuse
39

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)
45

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))
50
			}
51
		} else {
52
			if res == nil {
53
				panic("Client.Do returned nil, nil")
54
			}
55
			if res.Body == nil {
56
				panic("Client.Do returned nil res.Body and no error")
57
			}
58
		}
59
	}
60
}
61

62
var (
63
	SetEnterRoundTripHook = hookSetter(&testHookEnterRoundTrip)
64
	SetRoundTripRetried   = hookSetter(&testHookRoundTripRetried)
65
)
66

67
func SetReadLoopBeforeNextReadHook(f func()) {
68
	testHookMu.Lock()
69
	defer testHookMu.Unlock()
70
	unnilTestHook(&f)
71
	testHookReadLoopBeforeNextRead = f
72
}
73

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
80
}
81

82
func SetTestHookServerServe(fn func(*Server, net.Listener)) { testHookServerServe = fn }
83

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)
94
	}
95
}
96

97
func ResetCachedEnvironment() {
98
	resetProxyConfig()
99
}
100

101
func (t *Transport) NumPendingRequestsForTesting() int {
102
	t.reqMu.Lock()
103
	defer t.reqMu.Unlock()
104
	return len(t.reqCanceler)
105
}
106

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())
113
	}
114
	sort.Strings(keys)
115
	return
116
}
117

118
func (t *Transport) IdleConnKeyCountForTesting() int {
119
	t.idleMu.Lock()
120
	defer t.idleMu.Unlock()
121
	return len(t.idleConn)
122
}
123

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())
131
		}
132
	}
133
	sort.Strings(ret)
134
	return ret
135
}
136

137
func (t *Transport) IdleConnStrsForTesting_h2() []string {
138
	var ret []string
139
	noDialPool := t.h2transport.(*http2Transport).ConnPool.(http2noDialClientConnPool)
140
	pool := noDialPool.http2clientConnPool
141

142
	pool.mu.Lock()
143
	defer pool.mu.Unlock()
144

145
	for k, cc := range pool.conns {
146
		for range cc {
147
			ret = append(ret, k)
148
		}
149
	}
150

151
	sort.Strings(ret)
152
	return ret
153
}
154

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)
163
		}
164
	}
165
	return 0
166
}
167

168
func (t *Transport) IdleConnChMapSizeForTesting() int {
169
	t.idleMu.Lock()
170
	defer t.idleMu.Unlock()
171
	return len(t.idleConnCh)
172
}
173

174
func (t *Transport) IsIdleForTesting() bool {
175
	t.idleMu.Lock()
176
	defer t.idleMu.Unlock()
177
	return t.wantIdle
178
}
179

180
func (t *Transport) RequestIdleConnChForTesting() {
181
	t.getIdleConnCh(connectMethod{nil, "http", "example.com"})
182
}
183

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
191
	}
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
198
}
199

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
205
	}
206
}
207

208
func hookSetter(dst *func()) func(func()) {
209
	return func(fn func()) {
210
		unnilTestHook(&fn)
211
		*dst = fn
212
	}
213
}
214

215
func ExportHttp2ConfigureTransport(t *Transport) error {
216
	t2, err := http2configureTransport(t)
217
	if err != nil {
218
		return err
219
	}
220
	t.h2transport = t2
221
	return nil
222
}
223

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
231
		}
232
	}
233
	return true
234
}
235

236
func (r *Request) WithT(t *testing.T) *Request {
237
	return r.WithContext(context.WithValue(r.Context(), tLogKey{}, t.Logf))
238
}
239

240
func ExportSetH2GoawayTimeout(d time.Duration) (restore func()) {
241
	old := http2goAwayTimeout
242
	http2goAwayTimeout = d
243
	return func() { http2goAwayTimeout = old }
244
}
245

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.