mirror of
https://github.com/golang/go
synced 2024-11-23 20:30:04 -07:00
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 <emm.odeke@gmail.com>
This commit is contained in:
parent
01f34cbf52
commit
242622b4fc
@ -8,12 +8,14 @@ import (
|
||||
"bufio"
|
||||
"bytes"
|
||||
"context"
|
||||
"crypto/rand"
|
||||
"encoding/base64"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"mime/multipart"
|
||||
. "net/http"
|
||||
"net/http/httptest"
|
||||
"net/url"
|
||||
"os"
|
||||
"reflect"
|
||||
@ -1046,3 +1048,92 @@ func BenchmarkReadRequestWrk(b *testing.B) {
|
||||
Host: localhost:8080
|
||||
`)
|
||||
}
|
||||
|
||||
const (
|
||||
withTLS = true
|
||||
noTLS = false
|
||||
)
|
||||
|
||||
func BenchmarkFileAndServer_1KB(b *testing.B) {
|
||||
benchmarkFileAndServer(b, 1<<10)
|
||||
}
|
||||
|
||||
func BenchmarkFileAndServer_16MB(b *testing.B) {
|
||||
benchmarkFileAndServer(b, 1<<24)
|
||||
}
|
||||
|
||||
func BenchmarkFileAndServer_64MB(b *testing.B) {
|
||||
benchmarkFileAndServer(b, 1<<26)
|
||||
}
|
||||
|
||||
func benchmarkFileAndServer(b *testing.B, n int64) {
|
||||
f, err := ioutil.TempFile(os.TempDir(), "go-bench-http-file-and-server")
|
||||
if err != nil {
|
||||
b.Fatalf("Failed to create temp file: %v", err)
|
||||
}
|
||||
|
||||
defer func() {
|
||||
f.Close()
|
||||
os.RemoveAll(f.Name())
|
||||
}()
|
||||
|
||||
if _, err := io.CopyN(f, rand.Reader, n); err != nil {
|
||||
b.Fatalf("Failed to copy %d bytes: %v", n, err)
|
||||
}
|
||||
|
||||
b.Run("NoTLS", func(b *testing.B) {
|
||||
runFileAndServerBenchmarks(b, noTLS, f, n)
|
||||
})
|
||||
|
||||
b.Run("TLS", func(b *testing.B) {
|
||||
runFileAndServerBenchmarks(b, withTLS, f, n)
|
||||
})
|
||||
}
|
||||
|
||||
func runFileAndServerBenchmarks(b *testing.B, tlsOption bool, f *os.File, n int64) {
|
||||
handler := HandlerFunc(func(rw ResponseWriter, req *Request) {
|
||||
defer req.Body.Close()
|
||||
nc, err := io.Copy(ioutil.Discard, req.Body)
|
||||
if err != nil {
|
||||
panic(err)
|
||||
}
|
||||
|
||||
if nc != n {
|
||||
panic(fmt.Errorf("Copied %d Wanted %d bytes", nc, n))
|
||||
}
|
||||
})
|
||||
|
||||
var cst *httptest.Server
|
||||
if tlsOption == withTLS {
|
||||
cst = httptest.NewTLSServer(handler)
|
||||
} else {
|
||||
cst = httptest.NewServer(handler)
|
||||
}
|
||||
|
||||
defer cst.Close()
|
||||
b.ResetTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
// Perform some setup.
|
||||
b.StopTimer()
|
||||
if _, err := f.Seek(0, 0); err != nil {
|
||||
b.Fatalf("Failed to seek back to file: %v", err)
|
||||
}
|
||||
|
||||
b.StartTimer()
|
||||
req, err := NewRequest("PUT", cst.URL, ioutil.NopCloser(f))
|
||||
if err != nil {
|
||||
b.Fatal(err)
|
||||
}
|
||||
|
||||
req.ContentLength = n
|
||||
// Prevent mime sniffing by setting the Content-Type.
|
||||
req.Header.Set("Content-Type", "application/octet-stream")
|
||||
res, err := cst.Client().Do(req)
|
||||
if err != nil {
|
||||
b.Fatalf("Failed to make request to backend: %v", err)
|
||||
}
|
||||
|
||||
res.Body.Close()
|
||||
b.SetBytes(n)
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user