Skip to content

Commit 312bfc5

Browse files
vanclueverodeke-em
authored andcommitted
net/http: add request file upload benchmarks
This adds benchmarks to test file uploads using PUT requests. It's designed to complement changes https://golang.org/cl/163599 and https://golang.org/cl/163737, allowing an easy comparison of performance before and after these changes are applied. Updates #30377. Co-authored-by: Emmanuel Odeke <[email protected]> Change-Id: Ib8e692c61e1f7957d88c7101669d4f7fb8110c65 GitHub-Last-Rev: 242622b GitHub-Pull-Request: #30424 Reviewed-on: https://go-review.googlesource.com/c/go/+/163862 Run-TryBot: Emmanuel Odeke <[email protected]> Reviewed-by: Emmanuel Odeke <[email protected]>
1 parent c7408a8 commit 312bfc5

File tree

1 file changed

+91
-0
lines changed

1 file changed

+91
-0
lines changed

src/net/http/request_test.go

Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,12 +8,14 @@ import (
88
"bufio"
99
"bytes"
1010
"context"
11+
"crypto/rand"
1112
"encoding/base64"
1213
"fmt"
1314
"io"
1415
"io/ioutil"
1516
"mime/multipart"
1617
. "net/http"
18+
"net/http/httptest"
1719
"net/url"
1820
"os"
1921
"reflect"
@@ -1046,3 +1048,92 @@ func BenchmarkReadRequestWrk(b *testing.B) {
10461048
Host: localhost:8080
10471049
`)
10481050
}
1051+
1052+
const (
1053+
withTLS = true
1054+
noTLS = false
1055+
)
1056+
1057+
func BenchmarkFileAndServer_1KB(b *testing.B) {
1058+
benchmarkFileAndServer(b, 1<<10)
1059+
}
1060+
1061+
func BenchmarkFileAndServer_16MB(b *testing.B) {
1062+
benchmarkFileAndServer(b, 1<<24)
1063+
}
1064+
1065+
func BenchmarkFileAndServer_64MB(b *testing.B) {
1066+
benchmarkFileAndServer(b, 1<<26)
1067+
}
1068+
1069+
func benchmarkFileAndServer(b *testing.B, n int64) {
1070+
f, err := ioutil.TempFile(os.TempDir(), "go-bench-http-file-and-server")
1071+
if err != nil {
1072+
b.Fatalf("Failed to create temp file: %v", err)
1073+
}
1074+
1075+
defer func() {
1076+
f.Close()
1077+
os.RemoveAll(f.Name())
1078+
}()
1079+
1080+
if _, err := io.CopyN(f, rand.Reader, n); err != nil {
1081+
b.Fatalf("Failed to copy %d bytes: %v", n, err)
1082+
}
1083+
1084+
b.Run("NoTLS", func(b *testing.B) {
1085+
runFileAndServerBenchmarks(b, noTLS, f, n)
1086+
})
1087+
1088+
b.Run("TLS", func(b *testing.B) {
1089+
runFileAndServerBenchmarks(b, withTLS, f, n)
1090+
})
1091+
}
1092+
1093+
func runFileAndServerBenchmarks(b *testing.B, tlsOption bool, f *os.File, n int64) {
1094+
handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
1095+
defer req.Body.Close()
1096+
nc, err := io.Copy(ioutil.Discard, req.Body)
1097+
if err != nil {
1098+
panic(err)
1099+
}
1100+
1101+
if nc != n {
1102+
panic(fmt.Errorf("Copied %d Wanted %d bytes", nc, n))
1103+
}
1104+
})
1105+
1106+
var cst *httptest.Server
1107+
if tlsOption == withTLS {
1108+
cst = httptest.NewTLSServer(handler)
1109+
} else {
1110+
cst = httptest.NewServer(handler)
1111+
}
1112+
1113+
defer cst.Close()
1114+
b.ResetTimer()
1115+
for i := 0; i < b.N; i++ {
1116+
// Perform some setup.
1117+
b.StopTimer()
1118+
if _, err := f.Seek(0, 0); err != nil {
1119+
b.Fatalf("Failed to seek back to file: %v", err)
1120+
}
1121+
1122+
b.StartTimer()
1123+
req, err := NewRequest("PUT", cst.URL, ioutil.NopCloser(f))
1124+
if err != nil {
1125+
b.Fatal(err)
1126+
}
1127+
1128+
req.ContentLength = n
1129+
// Prevent mime sniffing by setting the Content-Type.
1130+
req.Header.Set("Content-Type", "application/octet-stream")
1131+
res, err := cst.Client().Do(req)
1132+
if err != nil {
1133+
b.Fatalf("Failed to make request to backend: %v", err)
1134+
}
1135+
1136+
res.Body.Close()
1137+
b.SetBytes(n)
1138+
}
1139+
}

0 commit comments

Comments
 (0)