Commit 312bfc5d authored by Chris Marchesi's avatar Chris Marchesi Committed by Emmanuel Odeke

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: default avatarEmmanuel Odeke <emm.odeke@gmail.com>

Change-Id: Ib8e692c61e1f7957d88c7101669d4f7fb8110c65
GitHub-Last-Rev: 242622b4fca9f289defa2f268efc31208743e5dd
GitHub-Pull-Request: golang/go#30424
Reviewed-on: https://go-review.googlesource.com/c/go/+/163862
Run-TryBot: Emmanuel Odeke <emm.odeke@gmail.com>
Reviewed-by: default avatarEmmanuel Odeke <emm.odeke@gmail.com>
parent c7408a87
...@@ -8,12 +8,14 @@ import ( ...@@ -8,12 +8,14 @@ import (
"bufio" "bufio"
"bytes" "bytes"
"context" "context"
"crypto/rand"
"encoding/base64" "encoding/base64"
"fmt" "fmt"
"io" "io"
"io/ioutil" "io/ioutil"
"mime/multipart" "mime/multipart"
. "net/http" . "net/http"
"net/http/httptest"
"net/url" "net/url"
"os" "os"
"reflect" "reflect"
...@@ -1046,3 +1048,92 @@ func BenchmarkReadRequestWrk(b *testing.B) { ...@@ -1046,3 +1048,92 @@ func BenchmarkReadRequestWrk(b *testing.B) {
Host: localhost:8080 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)
}
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment