aboutsummaryrefslogtreecommitdiff
path: root/src/net/http
diff options
context:
space:
mode:
authorDamien Neil <dneil@google.com>2026-03-12 14:44:28 -0700
committerGopher Robot <gobot@golang.org>2026-03-12 15:28:22 -0700
commitb3ee07636a1fe4ba5129705fd4692b442cf6b6f0 (patch)
treee3c19c06293417689f3561b6275b79cbf72e3f36 /src/net/http
parent0dc89195f9aece70476320be3fc9d6d657904056 (diff)
downloadgo-b3ee07636a1fe4ba5129705fd4692b442cf6b6f0.tar.xz
net/http/internal/http2: drop benchmarks which use synctest
Drop a number of low-level benchmarks which use internal test APIs that now use synctest. Synctest and benchmarks don't really mix; we don't necessarily expect bubbled code to perform in the same fashion as unbubbled code. Fixes #78114 Change-Id: I23f0a5d296ffeabc836f3865e08778eb6a6a6964 Reviewed-on: https://go-review.googlesource.com/c/go/+/754940 Reviewed-by: Nicholas Husin <nsh@golang.org> Reviewed-by: Nicholas Husin <husin@google.com> Auto-Submit: Damien Neil <dneil@google.com> LUCI-TryBot-Result: Go LUCI <golang-scoped@luci-project-accounts.iam.gserviceaccount.com>
Diffstat (limited to 'src/net/http')
-rw-r--r--src/net/http/internal/http2/export_test.go4
-rw-r--r--src/net/http/internal/http2/server.go12
-rw-r--r--src/net/http/internal/http2/server_test.go313
3 files changed, 3 insertions, 326 deletions
diff --git a/src/net/http/internal/http2/export_test.go b/src/net/http/internal/http2/export_test.go
index a9e230f5d0..8593ea3628 100644
--- a/src/net/http/internal/http2/export_test.go
+++ b/src/net/http/internal/http2/export_test.go
@@ -166,10 +166,6 @@ func SummarizeFrame(f Frame) string {
return summarizeFrame(f)
}
-func SetTestHookGetServerConn(t testing.TB, f func(*serverConn)) {
- SetForTest(t, &testHookGetServerConn, f)
-}
-
func init() {
testHookOnPanicMu = new(sync.Mutex)
}
diff --git a/src/net/http/internal/http2/server.go b/src/net/http/internal/http2/server.go
index a37a7280dd..ebfe16f59a 100644
--- a/src/net/http/internal/http2/server.go
+++ b/src/net/http/internal/http2/server.go
@@ -82,10 +82,9 @@ var responseWriterStatePool = sync.Pool{
// Test hooks.
var (
- testHookOnConn func()
- testHookGetServerConn func(*serverConn)
- testHookOnPanicMu *sync.Mutex // nil except in tests
- testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
+ testHookOnConn func()
+ testHookOnPanicMu *sync.Mutex // nil except in tests
+ testHookOnPanic func(sc *serverConn, panicVal interface{}) (rePanic bool)
)
// Server is an HTTP/2 server.
@@ -269,7 +268,6 @@ func (s *Server) Configure(conf ServerConfig, tcfg *tls.Config) error {
// during next-proto selection, but using TLS <1.2 with
// HTTP/2 is still the client's bug.
- tcfg.PreferServerCipherSuites = true
return nil
}
@@ -483,10 +481,6 @@ func (s *Server) serveConn(c net.Conn, opts *ServeConnOpts, newf func(*serverCon
opts.Settings = nil
}
- if hook := testHookGetServerConn; hook != nil {
- hook(sc)
- }
-
sc.serve(conf)
}
diff --git a/src/net/http/internal/http2/server_test.go b/src/net/http/internal/http2/server_test.go
index 11edfcb3be..d25650e936 100644
--- a/src/net/http/internal/http2/server_test.go
+++ b/src/net/http/internal/http2/server_test.go
@@ -349,99 +349,6 @@ func (call *serverHandlerCall) exit() {
})
}
-// newServerTesterWithRealConn creates a test server listening on a localhost port.
-// Mostly superseded by newServerTester, which creates a test server using a fake
-// net.Conn and synthetic time. This function is still around because some benchmarks
-// rely on it; new tests should use newServerTester.
-func newServerTesterWithRealConn(t testing.TB, handler http.HandlerFunc, opts ...interface{}) *serverTester {
- ts := httptest.NewUnstartedServer(handler)
- t.Cleanup(ts.Close)
-
- tlsConfig := &tls.Config{
- InsecureSkipVerify: true,
- NextProtos: []string{NextProtoTLS},
- }
-
- var framerReuseFrames bool
- h2server := new(Server)
- for _, opt := range opts {
- switch v := opt.(type) {
- case func(*tls.Config):
- v(tlsConfig)
- case func(*httptest.Server):
- v(ts)
- case func(*http.Server):
- v(ts.Config)
- case func(*Server):
- v(h2server)
- case serverTesterOpt:
- switch v {
- case optFramerReuseFrames:
- framerReuseFrames = true
- }
- case func(net.Conn, http.ConnState):
- ts.Config.ConnState = v
- default:
- t.Fatalf("unknown newServerTester option type %T", v)
- }
- }
-
- // Go 1.22 changes the default minimum TLS version to TLS 1.2,
- // in order to properly test cases where we want to reject low
- // TLS versions, we need to explicitly configure the minimum
- // version here.
- ts.Config.TLSConfig.MinVersion = tls.VersionTLS10
-
- st := &serverTester{
- t: t,
- }
- st.hpackEnc = hpack.NewEncoder(&st.headerBuf)
-
- ts.TLS = ts.Config.TLSConfig // the httptest.Server has its own copy of this TLS config
- if ts.Config.ErrorLog == nil {
- ts.Config.ErrorLog = log.New(io.MultiWriter(stderrv(), twriter{t: t, st: st}, &st.serverLogBuf), "", log.LstdFlags)
- }
- ts.StartTLS()
-
- if VerboseLogs {
- t.Logf("Running test server at: %s", ts.URL)
- }
- SetTestHookGetServerConn(t, func(v *ServerConn) {
- st.scMu.Lock()
- defer st.scMu.Unlock()
- st.sc = v
- })
- log.SetOutput(io.MultiWriter(stderrv(), twriter{t: t, st: st}))
- cc, err := tls.Dial("tcp", ts.Listener.Addr().String(), tlsConfig)
- if err != nil {
- t.Fatal(err)
- }
- st.cc = cc
- st.testConnFramer = testConnFramer{
- t: t,
- fr: NewFramer(st.cc, st.cc),
- dec: hpack.NewDecoder(InitialHeaderTableSize, nil),
- }
- if framerReuseFrames {
- st.fr.SetReuseFrames()
- }
- if !LogFrameReads() && !LogFrameWrites() {
- st.fr.TestSetDebugReadLoggerf(func(m string, v ...interface{}) {
- m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
- st.frameReadLogMu.Lock()
- fmt.Fprintf(&st.frameReadLogBuf, m, v...)
- st.frameReadLogMu.Unlock()
- })
- st.fr.TestSetDebugWriteLoggerf(func(m string, v ...interface{}) {
- m = time.Now().Format("2006-01-02 15:04:05.999999999 ") + strings.TrimPrefix(m, "http2: ") + "\n"
- st.frameWriteLogMu.Lock()
- fmt.Fprintf(&st.frameWriteLogBuf, m, v...)
- st.frameWriteLogMu.Unlock()
- })
- }
- return st
-}
-
// sync waits for all goroutines to idle.
func (st *serverTester) sync() {
synctest.Wait()
@@ -3164,162 +3071,6 @@ func testServerDoesntWriteInvalidHeaders(t testing.TB) {
})
}
-func BenchmarkServerGets(b *testing.B) {
- DisableGoroutineTracking(b)
- b.ReportAllocs()
-
- const msg = "Hello, world"
- st := newServerTesterWithRealConn(b, func(w http.ResponseWriter, r *http.Request) {
- io.WriteString(w, msg)
- })
- defer st.Close()
- st.greet()
-
- // Give the server quota to reply. (plus it has the 64KB)
- if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
- b.Fatal(err)
- }
-
- for i := 0; i < b.N; i++ {
- id := 1 + uint32(i)*2
- st.writeHeaders(HeadersFrameParam{
- StreamID: id,
- BlockFragment: st.encodeHeader(),
- EndStream: true,
- EndHeaders: true,
- })
- st.wantFrameType(FrameHeaders)
- if df := readFrame[*DataFrame](b, st); !df.StreamEnded() {
- b.Fatalf("DATA didn't have END_STREAM; got %v", df)
- }
- }
-}
-
-func BenchmarkServerPosts(b *testing.B) {
- DisableGoroutineTracking(b)
- b.ReportAllocs()
-
- const msg = "Hello, world"
- st := newServerTesterWithRealConn(b, func(w http.ResponseWriter, r *http.Request) {
- // Consume the (empty) body from th peer before replying, otherwise
- // the server will sometimes (depending on scheduling) send the peer a
- // a RST_STREAM with the CANCEL error code.
- if n, err := io.Copy(io.Discard, r.Body); n != 0 || err != nil {
- b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
- }
- io.WriteString(w, msg)
- })
- defer st.Close()
- st.greet()
-
- // Give the server quota to reply. (plus it has the 64KB)
- if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
- b.Fatal(err)
- }
-
- for i := 0; i < b.N; i++ {
- id := 1 + uint32(i)*2
- st.writeHeaders(HeadersFrameParam{
- StreamID: id,
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false,
- EndHeaders: true,
- })
- st.writeData(id, true, nil)
- st.wantFrameType(FrameHeaders)
- if df := readFrame[*DataFrame](b, st); !df.StreamEnded() {
- b.Fatalf("DATA didn't have END_STREAM; got %v", df)
- }
- }
-}
-
-// Send a stream of messages from server to client in separate data frames.
-// Brings up performance issues seen in long streams.
-// Created to show problem in go issue #18502
-func BenchmarkServerToClientStreamDefaultOptions(b *testing.B) {
- benchmarkServerToClientStream(b)
-}
-
-// Justification for Change-Id: Iad93420ef6c3918f54249d867098f1dadfa324d8
-// Expect to see memory/alloc reduction by opting in to Frame reuse with the Framer.
-func BenchmarkServerToClientStreamReuseFrames(b *testing.B) {
- benchmarkServerToClientStream(b, optFramerReuseFrames)
-}
-
-func benchmarkServerToClientStream(b *testing.B, newServerOpts ...interface{}) {
- DisableGoroutineTracking(b)
- b.ReportAllocs()
- const msgLen = 1
- // default window size
- const windowSize = 1<<16 - 1
-
- // next message to send from the server and for the client to expect
- nextMsg := func(i int) []byte {
- msg := make([]byte, msgLen)
- msg[0] = byte(i)
- if len(msg) != msgLen {
- panic("invalid test setup msg length")
- }
- return msg
- }
-
- st := newServerTesterWithRealConn(b, func(w http.ResponseWriter, r *http.Request) {
- // Consume the (empty) body from th peer before replying, otherwise
- // the server will sometimes (depending on scheduling) send the peer a
- // a RST_STREAM with the CANCEL error code.
- if n, err := io.Copy(io.Discard, r.Body); n != 0 || err != nil {
- b.Errorf("Copy error; got %v, %v; want 0, nil", n, err)
- }
- for i := 0; i < b.N; i += 1 {
- w.Write(nextMsg(i))
- w.(http.Flusher).Flush()
- }
- }, newServerOpts...)
- defer st.Close()
- st.greet()
-
- const id = uint32(1)
-
- st.writeHeaders(HeadersFrameParam{
- StreamID: id,
- BlockFragment: st.encodeHeader(":method", "POST"),
- EndStream: false,
- EndHeaders: true,
- })
-
- st.writeData(id, true, nil)
- st.wantHeaders(wantHeader{
- streamID: 1,
- endStream: false,
- })
-
- var pendingWindowUpdate = uint32(0)
-
- for i := 0; i < b.N; i += 1 {
- expected := nextMsg(i)
- st.wantData(wantData{
- streamID: 1,
- endStream: false,
- data: expected,
- })
- // try to send infrequent but large window updates so they don't overwhelm the test
- pendingWindowUpdate += uint32(len(expected))
- if pendingWindowUpdate >= windowSize/2 {
- if err := st.fr.WriteWindowUpdate(0, pendingWindowUpdate); err != nil {
- b.Fatal(err)
- }
- if err := st.fr.WriteWindowUpdate(id, pendingWindowUpdate); err != nil {
- b.Fatal(err)
- }
- pendingWindowUpdate = 0
- }
- }
- st.wantData(wantData{
- streamID: 1,
- endStream: true,
- })
-}
-
func TestIssue53(t *testing.T) { synctestTest(t, testIssue53) }
func testIssue53(t testing.TB) {
const data = "PRI * HTTP/2.0\r\n\r\nSM" +
@@ -3494,70 +3245,6 @@ func testServerContentLengthCanBeDisabled(t testing.TB) {
})
}
-func BenchmarkServer_GetRequest(b *testing.B) {
- DisableGoroutineTracking(b)
- b.ReportAllocs()
- const msg = "Hello, world."
- st := newServerTesterWithRealConn(b, func(w http.ResponseWriter, r *http.Request) {
- n, err := io.Copy(io.Discard, r.Body)
- if err != nil || n > 0 {
- b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err)
- }
- io.WriteString(w, msg)
- })
- defer st.Close()
-
- st.greet()
- // Give the server quota to reply. (plus it has the 64KB)
- if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
- b.Fatal(err)
- }
- hbf := st.encodeHeader(":method", "GET")
- for i := 0; i < b.N; i++ {
- streamID := uint32(1 + 2*i)
- st.writeHeaders(HeadersFrameParam{
- StreamID: streamID,
- BlockFragment: hbf,
- EndStream: true,
- EndHeaders: true,
- })
- st.wantFrameType(FrameHeaders)
- st.wantFrameType(FrameData)
- }
-}
-
-func BenchmarkServer_PostRequest(b *testing.B) {
- DisableGoroutineTracking(b)
- b.ReportAllocs()
- const msg = "Hello, world."
- st := newServerTesterWithRealConn(b, func(w http.ResponseWriter, r *http.Request) {
- n, err := io.Copy(io.Discard, r.Body)
- if err != nil || n > 0 {
- b.Errorf("Read %d bytes, error %v; want 0 bytes.", n, err)
- }
- io.WriteString(w, msg)
- })
- defer st.Close()
- st.greet()
- // Give the server quota to reply. (plus it has the 64KB)
- if err := st.fr.WriteWindowUpdate(0, uint32(b.N*len(msg))); err != nil {
- b.Fatal(err)
- }
- hbf := st.encodeHeader(":method", "POST")
- for i := 0; i < b.N; i++ {
- streamID := uint32(1 + 2*i)
- st.writeHeaders(HeadersFrameParam{
- StreamID: streamID,
- BlockFragment: hbf,
- EndStream: false,
- EndHeaders: true,
- })
- st.writeData(streamID, true, nil)
- st.wantFrameType(FrameHeaders)
- st.wantFrameType(FrameData)
- }
-}
-
// golang.org/issue/14214
func TestServer_Rejects_ConnHeaders(t *testing.T) { synctestTest(t, testServer_Rejects_ConnHeaders) }
func testServer_Rejects_ConnHeaders(t testing.TB) {