Added benchmark for net/http client with fake fast server

This commit is contained in:
Aliaksandr Valialkin
2015-11-13 19:50:31 +02:00
parent 69f3c67fce
commit bbcdceaa76
+52 -7
View File
@@ -8,22 +8,29 @@ import (
"net/http"
"strings"
"sync"
"sync/atomic"
"testing"
"time"
)
type fakeClientConn struct {
net.Conn
s []byte
n int
v interface{}
s []byte
n int
ch chan struct{}
v interface{}
}
func (c *fakeClientConn) Write(b []byte) (int, error) {
c.ch <- struct{}{}
return len(b), nil
}
func (c *fakeClientConn) Read(b []byte) (int, error) {
if c.n == 0 {
// wait for request :)
<-c.ch
}
n := 0
for len(b) > 0 {
if c.n == len(c.s) {
@@ -51,7 +58,8 @@ func acquireFakeServerConn(s []byte) *fakeClientConn {
v := fakeClientConnPool.Get()
if v == nil {
c := &fakeClientConn{
s: s,
s: s,
ch: make(chan struct{}, 1),
}
c.v = c
return c
@@ -64,17 +72,17 @@ var fakeClientConnPool sync.Pool
func BenchmarkClientGetFastServer(b *testing.B) {
body := []byte("012345678912")
s := []byte(fmt.Sprintf("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %d\r\n\r\n%s", len(body), body))
requestURI := []byte("http://foobar.com/aaa/bbb")
c := &Client{
Dial: func(addr string) (net.Conn, error) {
return acquireFakeServerConn(s), nil
},
}
nn := uint32(0)
b.RunParallel(func(pb *testing.PB) {
var req Request
var resp Response
req.Header.RequestURI = requestURI
req.Header.RequestURI = []byte(fmt.Sprintf("http://foobar%d.com/aaa/bbb", atomic.AddUint32(&nn, 1)))
for pb.Next() {
if err := c.Do(&req, &resp); err != nil {
b.Fatalf("unexpected error: %s", err)
@@ -89,6 +97,43 @@ func BenchmarkClientGetFastServer(b *testing.B) {
})
}
func BenchmarkNetHTTPClientGetFastServer(b *testing.B) {
body := []byte("012345678912")
s := []byte(fmt.Sprintf("HTTP/1.1 200 OK\r\nContent-Type: text/plain\r\nContent-Length: %d\r\n\r\n%s", len(body), body))
c := &http.Client{
Transport: &http.Transport{
Dial: func(network, addr string) (net.Conn, error) {
return acquireFakeServerConn(s), nil
},
},
}
nn := uint32(0)
b.RunParallel(func(pb *testing.PB) {
req, err := http.NewRequest("GET", fmt.Sprintf("http://foobar%d.com/aaa/bbb", atomic.AddUint32(&nn, 1)), nil)
if err != nil {
b.Fatalf("unexpected error: %s", err)
}
for pb.Next() {
resp, err := c.Do(req)
if err != nil {
b.Fatalf("unexpected error: %s", err)
}
if resp.StatusCode != http.StatusOK {
b.Fatalf("unexpected status code: %d", resp.StatusCode)
}
respBody, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
b.Fatalf("unexpected error when reading response body: %s", err)
}
if !bytes.Equal(respBody, body) {
b.Fatalf("unexpected response body: %q. Expected %q", respBody, body)
}
}
})
}
func fasthttpEchoHandler(ctx *RequestCtx) {
ctx.Success("text/plain", ctx.Request.Header.RequestURI)
}
@@ -170,10 +215,10 @@ func BenchmarkNetHTTPClientGetEndToEnd(b *testing.B) {
b.Fatalf("unexpected status code: %d. Expecting %d", resp.StatusCode, http.StatusOK)
}
body, err := ioutil.ReadAll(resp.Body)
resp.Body.Close()
if err != nil {
b.Fatalf("unexpected error when reading response body: %s", err)
}
resp.Body.Close()
if !EqualBytesStr(body, requestURI) {
b.Fatalf("unexpected response %q. Expecting %q", body, requestURI)
}