Skip to content

Commit 9545aea

Browse files
committed
http2: clearer distinction between test server types
newServerTester is used to create an HTTP/2 server for testing. It returns a *serverTester, which includes a number of methods for sending frames to and reading frames from a server connection under test. Many tests also use newServerTester to simply start an *httptest.Server. These tests pass an "optOnlyServer" to indicate that they don't need a client connection to interact with. They interact with the *httptest.Server, and use no methods or fields of *serverTester. Make a clearer distinction between test types. Add a newTestServer function which starts and returns an *httptest.Server. This function replaces use of newServerTester with optOnlyServer. Change-Id: Ia590c9b4dcc23c17e530b0cc273b9120965da11a Reviewed-on: https://go-review.googlesource.com/c/net/+/586155 Reviewed-by: Jonathan Amsterdam <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]>
1 parent b1ec120 commit 9545aea

File tree

2 files changed

+249
-273
lines changed

2 files changed

+249
-273
lines changed

http2/server_test.go

+89-67
Original file line numberDiff line numberDiff line change
@@ -101,12 +101,50 @@ func resetHooks() {
101101
testHookOnPanicMu.Unlock()
102102
}
103103

104+
func newTestServer(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *httptest.Server {
105+
ts := httptest.NewUnstartedServer(handler)
106+
ts.EnableHTTP2 = true
107+
ts.Config.ErrorLog = log.New(twriter{t: t}, "", log.LstdFlags)
108+
h2server := new(Server)
109+
for _, opt := range opts {
110+
switch v := opt.(type) {
111+
case func(*httptest.Server):
112+
v(ts)
113+
case func(*Server):
114+
v(h2server)
115+
default:
116+
t.Fatalf("unknown newTestServer option type %T", v)
117+
}
118+
}
119+
ConfigureServer(ts.Config, h2server)
120+
121+
// ConfigureServer populates ts.Config.TLSConfig.
122+
// Copy it to ts.TLS as well.
123+
ts.TLS = ts.Config.TLSConfig
124+
125+
// Go 1.22 changes the default minimum TLS version to TLS 1.2,
126+
// in order to properly test cases where we want to reject low
127+
// TLS versions, we need to explicitly configure the minimum
128+
// version here.
129+
ts.Config.TLSConfig.MinVersion = tls.VersionTLS10
130+
131+
ts.StartTLS()
132+
t.Cleanup(func() {
133+
ts.CloseClientConnections()
134+
ts.Close()
135+
})
136+
137+
return ts
138+
}
139+
104140
type serverTesterOpt string
105141

106-
var optOnlyServer = serverTesterOpt("only_server")
107-
var optQuiet = serverTesterOpt("quiet_logging")
108142
var optFramerReuseFrames = serverTesterOpt("frame_reuse_frames")
109143

144+
var optQuiet = func(ts *httptest.Server) {
145+
ts.Config.ErrorLog = log.New(io.Discard, "", 0)
146+
}
147+
110148
func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester {
111149
resetHooks()
112150

@@ -117,7 +155,7 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
117155
NextProtos: []string{NextProtoTLS},
118156
}
119157

120-
var onlyServer, quiet, framerReuseFrames bool
158+
var framerReuseFrames bool
121159
h2server := new(Server)
122160
for _, opt := range opts {
123161
switch v := opt.(type) {
@@ -129,10 +167,6 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
129167
v(h2server)
130168
case serverTesterOpt:
131169
switch v {
132-
case optOnlyServer:
133-
onlyServer = true
134-
case optQuiet:
135-
quiet = true
136170
case optFramerReuseFrames:
137171
framerReuseFrames = true
138172
}
@@ -159,9 +193,7 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
159193
st.hpackDec = hpack.NewDecoder(initialHeaderTableSize, st.onHeaderField)
160194

161195
ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config
162-
if quiet {
163-
ts.Config.ErrorLog = log.New(ioutil.Discard, "", 0)
164-
} else {
196+
if ts.Config.ErrorLog == nil {
165197
ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, &st.serverLogBuf), "", log.LstdFlags)
166198
}
167199
ts.StartTLS()
@@ -175,32 +207,30 @@ func newServerTester(t testing.TB, handler http.HandlerFunc, opts ...interface{}
175207
st.sc = v
176208
}
177209
log.SetOutput(io.MultiWriter(stderrv(), twriter{t: t, st: st}))
178-
if !onlyServer {
179-
cc, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig)
180-
if err != nil {
181-
t.Fatal(err)
210+
cc, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig)
211+
if err != nil {
212+
t.Fatal(err)
213+
}
214+
st.cc = cc
215+
st.fr = NewFramer(cc, cc)
216+
if framerReuseFrames {
217+
st.fr.SetReuseFrames()
218+
}
219+
if !logFrameReads && !logFrameWrites {
220+
st.fr.debugReadLoggerf = func(m string, v ...interface{}) {
221+
m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
222+
st.frameReadLogMu.Lock()
223+
fmt.Fprintf(&st.frameReadLogBuf, m, v...)
224+
st.frameReadLogMu.Unlock()
182225
}
183-
st.cc = cc
184-
st.fr = NewFramer(cc, cc)
185-
if framerReuseFrames {
186-
st.fr.SetReuseFrames()
187-
}
188-
if !logFrameReads && !logFrameWrites {
189-
st.fr.debugReadLoggerf = func(m string, v ...interface{}) {
190-
m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
191-
st.frameReadLogMu.Lock()
192-
fmt.Fprintf(&st.frameReadLogBuf, m, v...)
193-
st.frameReadLogMu.Unlock()
194-
}
195-
st.fr.debugWriteLoggerf = func(m string, v ...interface{}) {
196-
m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
197-
st.frameWriteLogMu.Lock()
198-
fmt.Fprintf(&st.frameWriteLogBuf, m, v...)
199-
st.frameWriteLogMu.Unlock()
200-
}
201-
st.fr.logReads = true
202-
st.fr.logWrites = true
226+
st.fr.debugWriteLoggerf = func(m string, v ...interface{}) {
227+
m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
228+
st.frameWriteLogMu.Lock()
229+
fmt.Fprintf(&st.frameWriteLogBuf, m, v...)
230+
st.frameWriteLogMu.Unlock()
203231
}
232+
st.fr.logReads = true
233+
st.fr.logWrites = true
204234
}
205235
return st
206236
}
@@ -3067,16 +3097,15 @@ func testServerWritesTrailers(t *testing.T, withFlush bool) {
30673097
func TestServerWritesUndeclaredTrailers(t *testing.T) {
30683098
const trailer = "Trailer-Header"
30693099
const value = "hi1"
3070-
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3100+
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
30713101
w.Header().Set(http.TrailerPrefix+trailer, value)
3072-
}, optOnlyServer)
3073-
defer st.Close()
3102+
})
30743103

30753104
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
30763105
defer tr.CloseIdleConnections()
30773106

30783107
cl := &http.Client{Transport: tr}
3079-
resp, err := cl.Get(st.ts.URL)
3108+
resp, err := cl.Get(ts.URL)
30803109
if err != nil {
30813110
t.Fatal(err)
30823111
}
@@ -3731,7 +3760,7 @@ func TestExpect100ContinueAfterHandlerWrites(t *testing.T) {
37313760
doRead := make(chan bool, 1)
37323761
defer close(doRead) // fallback cleanup
37333762

3734-
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3763+
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
37353764
io.WriteString(w, msg)
37363765
w.(http.Flusher).Flush()
37373766

@@ -3740,14 +3769,12 @@ func TestExpect100ContinueAfterHandlerWrites(t *testing.T) {
37403769
r.Body.Read(make([]byte, 10))
37413770

37423771
io.WriteString(w, msg2)
3743-
3744-
}, optOnlyServer)
3745-
defer st.Close()
3772+
})
37463773

37473774
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
37483775
defer tr.CloseIdleConnections()
37493776

3750-
req, _ := http.NewRequest("POST", st.ts.URL, io.LimitReader(neverEnding('A'), 2<<20))
3777+
req, _ := http.NewRequest("POST", ts.URL, io.LimitReader(neverEnding('A'), 2<<20))
37513778
req.Header.Set("Expect", "100-continue")
37523779

37533780
res, err := tr.RoundTrip(req)
@@ -3808,14 +3835,13 @@ func TestUnreadFlowControlReturned_Server(t *testing.T) {
38083835
unblock := make(chan bool, 1)
38093836
defer close(unblock)
38103837

3811-
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3838+
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
38123839
// Don't read the 16KB request body. Wait until the client's
38133840
// done sending it and then return. This should cause the Server
38143841
// to then return those 16KB of flow control to the client.
38153842
tt.reqFn(r)
38163843
<-unblock
3817-
}, optOnlyServer)
3818-
defer st.Close()
3844+
})
38193845

38203846
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
38213847
defer tr.CloseIdleConnections()
@@ -3833,7 +3859,7 @@ func TestUnreadFlowControlReturned_Server(t *testing.T) {
38333859
return 0, io.EOF
38343860
}),
38353861
)
3836-
req, _ := http.NewRequest("POST", st.ts.URL, body)
3862+
req, _ := http.NewRequest("POST", ts.URL, body)
38373863
res, err := tr.RoundTrip(req)
38383864
if err != nil {
38393865
t.Fatal(tt.name, err)
@@ -3949,22 +3975,21 @@ func TestIssue20704Race(t *testing.T) {
39493975
itemCount = 100
39503976
)
39513977

3952-
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
3978+
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
39533979
for i := 0; i < itemCount; i++ {
39543980
_, err := w.Write(make([]byte, itemSize))
39553981
if err != nil {
39563982
return
39573983
}
39583984
}
3959-
}, optOnlyServer)
3960-
defer st.Close()
3985+
})
39613986

39623987
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
39633988
defer tr.CloseIdleConnections()
39643989
cl := &http.Client{Transport: tr}
39653990

39663991
for i := 0; i < 1000; i++ {
3967-
resp, err := cl.Get(st.ts.URL)
3992+
resp, err := cl.Get(ts.URL)
39683993
if err != nil {
39693994
t.Fatal(err)
39703995
}
@@ -4241,26 +4266,25 @@ func TestContentEncodingNoSniffing(t *testing.T) {
42414266

42424267
for _, tt := range resps {
42434268
t.Run(tt.name, func(t *testing.T) {
4244-
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4269+
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
42454270
if tt.contentEncoding != nil {
42464271
w.Header().Set("Content-Encoding", tt.contentEncoding.(string))
42474272
}
42484273
w.Write(tt.body)
4249-
}, optOnlyServer)
4250-
defer st.Close()
4274+
})
42514275

42524276
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
42534277
defer tr.CloseIdleConnections()
42544278

4255-
req, _ := http.NewRequest("GET", st.ts.URL, nil)
4279+
req, _ := http.NewRequest("GET", ts.URL, nil)
42564280
res, err := tr.RoundTrip(req)
42574281
if err != nil {
4258-
t.Fatalf("GET %s: %v", st.ts.URL, err)
4282+
t.Fatalf("GET %s: %v", ts.URL, err)
42594283
}
42604284
defer res.Body.Close()
42614285

42624286
g := res.Header.Get("Content-Encoding")
4263-
t.Logf("%s: Content-Encoding: %s", st.ts.URL, g)
4287+
t.Logf("%s: Content-Encoding: %s", ts.URL, g)
42644288

42654289
if w := tt.contentEncoding; g != w {
42664290
if w != nil { // The case where contentEncoding was set explicitly.
@@ -4274,7 +4298,7 @@ func TestContentEncodingNoSniffing(t *testing.T) {
42744298
if w := tt.wantContentType; g != w {
42754299
t.Errorf("Content-Type mismatch\n\tgot: %q\n\twant: %q", g, w)
42764300
}
4277-
t.Logf("%s: Content-Type: %s", st.ts.URL, g)
4301+
t.Logf("%s: Content-Type: %s", ts.URL, g)
42784302
})
42794303
}
42804304
}
@@ -4606,7 +4630,7 @@ func TestCanonicalHeaderCacheGrowth(t *testing.T) {
46064630
// We should not access the slice after this point.
46074631
func TestServerWriteDoesNotRetainBufferAfterReturn(t *testing.T) {
46084632
donec := make(chan struct{})
4609-
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4633+
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
46104634
defer close(donec)
46114635
buf := make([]byte, 1<<20)
46124636
var i byte
@@ -4620,13 +4644,12 @@ func TestServerWriteDoesNotRetainBufferAfterReturn(t *testing.T) {
46204644
return
46214645
}
46224646
}
4623-
}, optOnlyServer)
4624-
defer st.Close()
4647+
})
46254648

46264649
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
46274650
defer tr.CloseIdleConnections()
46284651

4629-
req, _ := http.NewRequest("GET", st.ts.URL, nil)
4652+
req, _ := http.NewRequest("GET", ts.URL, nil)
46304653
res, err := tr.RoundTrip(req)
46314654
if err != nil {
46324655
t.Fatal(err)
@@ -4642,7 +4665,7 @@ func TestServerWriteDoesNotRetainBufferAfterReturn(t *testing.T) {
46424665
// We should not access the slice after this point.
46434666
func TestServerWriteDoesNotRetainBufferAfterServerClose(t *testing.T) {
46444667
donec := make(chan struct{}, 1)
4645-
st := newServerTester(t, func(w http.ResponseWriter, r *http.Request) {
4668+
ts := newTestServer(t, func(w http.ResponseWriter, r *http.Request) {
46464669
donec <- struct{}{}
46474670
defer close(donec)
46484671
buf := make([]byte, 1<<20)
@@ -4657,20 +4680,19 @@ func TestServerWriteDoesNotRetainBufferAfterServerClose(t *testing.T) {
46574680
return
46584681
}
46594682
}
4660-
}, optOnlyServer)
4661-
defer st.Close()
4683+
})
46624684

46634685
tr := &Transport{TLSClientConfig: tlsConfigInsecure}
46644686
defer tr.CloseIdleConnections()
46654687

4666-
req, _ := http.NewRequest("GET", st.ts.URL, nil)
4688+
req, _ := http.NewRequest("GET", ts.URL, nil)
46674689
res, err := tr.RoundTrip(req)
46684690
if err != nil {
46694691
t.Fatal(err)
46704692
}
46714693
defer res.Body.Close()
46724694
<-donec
4673-
st.ts.Config.Close()
4695+
ts.Config.Close()
46744696
<-donec
46754697
}
46764698

0 commit comments

Comments
 (0)