109 lines
2.8 KiB
Go
109 lines
2.8 KiB
Go
package fasthttputil_test
|
|
|
|
import (
|
|
"net"
|
|
"testing"
|
|
|
|
"github.com/valyala/fasthttp"
|
|
"github.com/valyala/fasthttp/fasthttputil"
|
|
)
|
|
|
|
// BenchmarkPlainStreaming measures end-to-end plaintext streaming performance
|
|
// for fasthttp client and server.
|
|
//
|
|
// It issues http requests over a small number of keep-alive connections.
|
|
func BenchmarkPlainStreaming(b *testing.B) {
|
|
benchmark(b, streamingHandler, false)
|
|
}
|
|
|
|
// BenchmarkPlainHandshake measures end-to-end plaintext handshake performance
|
|
// for fasthttp client and server.
|
|
//
|
|
// It re-establishes new connection per each http request.
|
|
func BenchmarkPlainHandshake(b *testing.B) {
|
|
benchmark(b, handshakeHandler, false)
|
|
}
|
|
|
|
// BenchmarkTLSStreaming measures end-to-end TLS streaming performance
|
|
// for fasthttp client and server.
|
|
//
|
|
// It issues http requests over a small number of TLS keep-alive connections.
|
|
func BenchmarkTLSStreaming(b *testing.B) {
|
|
benchmark(b, streamingHandler, true)
|
|
}
|
|
|
|
// BenchmarkTLSHandshake measures end-to-end TLS handshake performance
|
|
// for fasthttp client and server.
|
|
//
|
|
// It re-establishes new TLS connection per each http request.
|
|
func BenchmarkTLSHandshake(b *testing.B) {
|
|
benchmark(b, handshakeHandler, true)
|
|
}
|
|
|
|
func benchmark(b *testing.B, h fasthttp.RequestHandler, isTLS bool) {
|
|
ln := fasthttputil.NewInmemoryListener()
|
|
serverStopCh := startServer(b, ln, h, isTLS)
|
|
c := newClient(ln, isTLS)
|
|
b.RunParallel(func(pb *testing.PB) {
|
|
runRequests(b, pb, c)
|
|
})
|
|
ln.Close()
|
|
<-serverStopCh
|
|
}
|
|
|
|
func streamingHandler(ctx *fasthttp.RequestCtx) {
|
|
ctx.WriteString("foobar")
|
|
}
|
|
|
|
func handshakeHandler(ctx *fasthttp.RequestCtx) {
|
|
streamingHandler(ctx)
|
|
|
|
// Explicitly close connection after each response.
|
|
ctx.SetConnectionClose()
|
|
}
|
|
|
|
func startServer(b *testing.B, ln *fasthttputil.InmemoryListener, h fasthttp.RequestHandler, isTLS bool) <-chan struct{} {
|
|
ch := make(chan struct{})
|
|
go func() {
|
|
var err error
|
|
if isTLS {
|
|
err = fasthttp.ServeTLS(ln, certFile, keyFile, h)
|
|
} else {
|
|
err = fasthttp.Serve(ln, h)
|
|
}
|
|
if err != nil {
|
|
b.Fatalf("unexpected error in server: %s", err)
|
|
}
|
|
close(ch)
|
|
}()
|
|
return ch
|
|
}
|
|
|
|
const (
|
|
certFile = "./ssl-cert-snakeoil.pem"
|
|
keyFile = "./ssl-cert-snakeoil.key"
|
|
)
|
|
|
|
func newClient(ln *fasthttputil.InmemoryListener, isTLS bool) *fasthttp.HostClient {
|
|
return &fasthttp.HostClient{
|
|
Dial: func(addr string) (net.Conn, error) {
|
|
return ln.Dial()
|
|
},
|
|
IsTLS: isTLS,
|
|
}
|
|
}
|
|
|
|
func runRequests(b *testing.B, pb *testing.PB, c *fasthttp.HostClient) {
|
|
var req fasthttp.Request
|
|
req.SetRequestURI("http://foo.bar/baz")
|
|
var resp fasthttp.Response
|
|
for pb.Next() {
|
|
if err := c.Do(&req, &resp); err != nil {
|
|
b.Fatalf("unexpected error: %s", err)
|
|
}
|
|
if resp.StatusCode() != fasthttp.StatusOK {
|
|
b.Fatalf("unexpected status code: %d. Expecting %d", resp.StatusCode(), fasthttp.StatusOK)
|
|
}
|
|
}
|
|
}
|