net/http: add new Server benchmark

The new BenchmarkServer avoids profiling the client code
by running it in a child process.

R=rsc
CC=golang-dev
https://golang.org/cl/6260053
This commit is contained in:
Brad Fitzpatrick 2012-06-04 08:04:40 -07:00
parent 3238705f0c
commit afeaf554aa

View file

@ -20,7 +20,9 @@ import (
"net/http/httputil"
"net/url"
"os"
"os/exec"
"reflect"
"strconv"
"strings"
"syscall"
"testing"
@ -1262,3 +1264,56 @@ func BenchmarkClientServer(b *testing.B) {
b.StopTimer()
}
// A benchmark for profiling the server without the HTTP client code.
// The client code runs in a subprocess.
//
// For use like:
// $ go test -c
// $ ./http.test -test.run=XX -test.bench=Benchmarktime=15 -test.cpuprofile=http.prof
// $ go tool pprof http.test http.prof
// (pprof) web
func BenchmarkServer(b *testing.B) {
// Child process mode;
if url := os.Getenv("TEST_BENCH_SERVER_URL"); url != "" {
n, err := strconv.Atoi(os.Getenv("TEST_BENCH_CLIENT_N"))
if err != nil {
panic(err)
}
for i := 0; i < n; i++ {
res, err := Get(url)
if err != nil {
log.Panicf("Get:", err)
}
all, err := ioutil.ReadAll(res.Body)
if err != nil {
log.Panicf("ReadAll:", err)
}
body := string(all)
if body != "Hello world.\n" {
log.Panicf("Got body:", body)
}
}
os.Exit(0)
return
}
var res = []byte("Hello world.\n")
b.StopTimer()
ts := httptest.NewServer(HandlerFunc(func(rw ResponseWriter, r *Request) {
rw.Header().Set("Content-Type", "text/html; charset=utf-8")
rw.Write(res)
}))
defer ts.Close()
b.StartTimer()
cmd := exec.Command(os.Args[0], "-test.run=XXXX", "-test.bench=BenchmarkServer")
cmd.Env = append([]string{
fmt.Sprintf("TEST_BENCH_CLIENT_N=%d", b.N),
fmt.Sprintf("TEST_BENCH_SERVER_URL=%s", ts.URL),
}, os.Environ()...)
out, err := cmd.CombinedOutput()
if err != nil {
b.Errorf("Test failure: %v, with output: %s", err, out)
}
}