TUN-3208: Add benchmark for large response write
This commit is contained in:
parent
44e3be2c88
commit
42fe2e7266
|
@ -15,10 +15,11 @@ import (
|
||||||
"testing"
|
"testing"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/cloudflare/cloudflared/logger"
|
|
||||||
"github.com/pkg/errors"
|
"github.com/pkg/errors"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
"golang.org/x/sync/errgroup"
|
"golang.org/x/sync/errgroup"
|
||||||
|
|
||||||
|
"github.com/cloudflare/cloudflared/logger"
|
||||||
)
|
)
|
||||||
|
|
||||||
const (
|
const (
|
||||||
|
@ -1032,3 +1033,108 @@ func openStreams(b *testing.B, muxPair *DefaultMuxerPair, n int) {
|
||||||
}
|
}
|
||||||
assert.NoError(b, errGroup.Wait())
|
assert.NoError(b, errGroup.Wait())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func BenchmarkSingleStreamLargeResponseBody(b *testing.B) {
|
||||||
|
const bodySize = 1 << 24
|
||||||
|
|
||||||
|
const writeBufferSize = 16 << 10
|
||||||
|
const writeN = bodySize / writeBufferSize
|
||||||
|
payload := make([]byte, writeBufferSize)
|
||||||
|
for i := range payload {
|
||||||
|
payload[i] = byte(i % 256)
|
||||||
|
}
|
||||||
|
|
||||||
|
const readBufferSize = 16 << 10
|
||||||
|
const readN = bodySize / readBufferSize
|
||||||
|
responseBody := make([]byte, readBufferSize)
|
||||||
|
|
||||||
|
f := MuxedStreamFunc(func(stream *MuxedStream) error {
|
||||||
|
if len(stream.Headers) != 1 {
|
||||||
|
b.Fatalf("expected %d headers, got %d", 1, len(stream.Headers))
|
||||||
|
}
|
||||||
|
if stream.Headers[0].Name != "test-header" {
|
||||||
|
b.Fatalf("expected header name %s, got %s", "test-header", stream.Headers[0].Name)
|
||||||
|
}
|
||||||
|
if stream.Headers[0].Value != "headerValue" {
|
||||||
|
b.Fatalf("expected header value %s, got %s", "headerValue", stream.Headers[0].Value)
|
||||||
|
}
|
||||||
|
stream.WriteHeaders([]Header{
|
||||||
|
{Name: "response-header", Value: "responseValue"},
|
||||||
|
})
|
||||||
|
for i := 0; i < writeN; i++ {
|
||||||
|
n, err := stream.Write(payload)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("origin write error: %s", err)
|
||||||
|
}
|
||||||
|
if n != len(payload) {
|
||||||
|
b.Fatalf("origin short write: %d/%d bytes", n, len(payload))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return nil
|
||||||
|
})
|
||||||
|
|
||||||
|
name := fmt.Sprintf("%s_%d", b.Name(), rand.Int())
|
||||||
|
origin, edge := net.Pipe()
|
||||||
|
|
||||||
|
muxPair := &DefaultMuxerPair{
|
||||||
|
OriginMuxConfig: MuxerConfig{
|
||||||
|
Timeout: testHandshakeTimeout,
|
||||||
|
Handler: f,
|
||||||
|
IsClient: true,
|
||||||
|
Name: "origin",
|
||||||
|
Logger: logger.NewOutputWriter(logger.NewMockWriteManager()),
|
||||||
|
DefaultWindowSize: defaultWindowSize,
|
||||||
|
MaxWindowSize: maxWindowSize,
|
||||||
|
StreamWriteBufferMaxLen: defaultWriteBufferMaxLen,
|
||||||
|
HeartbeatInterval: defaultTimeout,
|
||||||
|
MaxHeartbeats: defaultRetries,
|
||||||
|
},
|
||||||
|
OriginConn: origin,
|
||||||
|
EdgeMuxConfig: MuxerConfig{
|
||||||
|
Timeout: testHandshakeTimeout,
|
||||||
|
IsClient: false,
|
||||||
|
Name: "edge",
|
||||||
|
Logger: logger.NewOutputWriter(logger.NewMockWriteManager()),
|
||||||
|
DefaultWindowSize: defaultWindowSize,
|
||||||
|
MaxWindowSize: maxWindowSize,
|
||||||
|
StreamWriteBufferMaxLen: defaultWriteBufferMaxLen,
|
||||||
|
HeartbeatInterval: defaultTimeout,
|
||||||
|
MaxHeartbeats: defaultRetries,
|
||||||
|
},
|
||||||
|
EdgeConn: edge,
|
||||||
|
doneC: make(chan struct{}),
|
||||||
|
}
|
||||||
|
assert.NoError(b, muxPair.Handshake(name))
|
||||||
|
muxPair.Serve(b)
|
||||||
|
|
||||||
|
b.ReportAllocs()
|
||||||
|
for i := 0; i < b.N; i++ {
|
||||||
|
stream, err := muxPair.OpenEdgeMuxStream(
|
||||||
|
[]Header{{Name: "test-header", Value: "headerValue"}},
|
||||||
|
nil,
|
||||||
|
)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("error in OpenStream: %s", err)
|
||||||
|
}
|
||||||
|
if len(stream.Headers) != 1 {
|
||||||
|
b.Fatalf("expected %d headers, got %d", 1, len(stream.Headers))
|
||||||
|
}
|
||||||
|
if stream.Headers[0].Name != "response-header" {
|
||||||
|
b.Fatalf("expected header name %s, got %s", "response-header", stream.Headers[0].Name)
|
||||||
|
}
|
||||||
|
if stream.Headers[0].Value != "responseValue" {
|
||||||
|
b.Fatalf("expected header value %s, got %s", "responseValue", stream.Headers[0].Value)
|
||||||
|
}
|
||||||
|
|
||||||
|
for k := 0; k < readN; k++ {
|
||||||
|
n, err := io.ReadFull(stream, responseBody)
|
||||||
|
if err != nil {
|
||||||
|
b.Fatalf("error from (*MuxedStream).Read: %s", err)
|
||||||
|
}
|
||||||
|
if n != len(responseBody) {
|
||||||
|
b.Fatalf("expected response body to have %d bytes, got %d", len(responseBody), n)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue