aboutsummaryrefslogtreecommitdiff
path: root/client_timing_test.go
diff options
context:
space:
mode:
authorGravatar Aliaksandr Valialkin <valyala@gmail.com> 2015-11-13 19:50:31 +0200
committerGravatar Aliaksandr Valialkin <valyala@gmail.com> 2015-11-13 19:50:31 +0200
commitbbcdceaa764529f7e47a83aa09fc7f0b1d1dbe6f (patch)
tree9e40cdeb829c31865899d8e0c40feb74ba8ed42a /client_timing_test.go
parentAdded benchmark for measuring the maximum client throughput (diff)
downloadfasthttp-bbcdceaa764529f7e47a83aa09fc7f0b1d1dbe6f.tar.gz
fasthttp-bbcdceaa764529f7e47a83aa09fc7f0b1d1dbe6f.tar.bz2
fasthttp-bbcdceaa764529f7e47a83aa09fc7f0b1d1dbe6f.zip
Added benchmark for net/http client with fake fast server
Diffstat (limited to 'client_timing_test.go')
-rw-r--r--client_timing_test.go59
1 files changed, 52 insertions, 7 deletions
diff --git a/client_timing_test.go b/client_timing_test.go
index 7cacb45..654c3a0 100644
--- a/client_timing_test.go
+++ b/client_timing_test.go
@@ -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)
}