Web/bench/synthetic_bench_test.go

166 lines
4.8 KiB
Go

package bench_test
import (
"io"
"strconv"
"strings"
"testing"
web "git.sharkk.net/Go/Web"
)
// BenchmarkSyntheticStaticGetRequest measures performance of simple GET request with static response
func BenchmarkSyntheticStaticGetRequest(b *testing.B) {
s := web.NewServer()
s.Get("/", func(ctx web.Context) error {
return ctx.String("Hello, World!")
})
b.ResetTimer()
for i := 0; i < b.N; i++ {
response := s.Request("GET", "/", nil, nil)
if response.Status() != 200 || string(response.Body()) != "Hello, World!" {
b.Fatalf("Invalid response: status=%d, body=%s", response.Status(), response.Body())
}
}
}
// BenchmarkSyntheticJSONResponse measures performance of JSON serialization and response
func BenchmarkSyntheticJSONResponse(b *testing.B) {
s := web.NewServer()
s.Get("/json", func(ctx web.Context) error {
ctx.Response().SetHeader("Content-Type", "application/json")
return ctx.String(`{"message":"Hello, World!","code":200,"success":true}`)
})
b.ResetTimer()
for i := 0; i < b.N; i++ {
response := s.Request("GET", "/json", nil, nil)
if response.Status() != 200 {
b.Fatalf("Invalid status: %d", response.Status())
}
}
}
// BenchmarkSyntheticPostWithBody measures performance of POST request with body processing
func BenchmarkSyntheticPostWithBody(b *testing.B) {
s := web.NewServer()
s.Post("/echo", func(ctx web.Context) error {
body := ctx.Request().Body()
return ctx.Bytes(body)
})
requestBody := strings.Repeat("Hello, World! ", 10)
b.ResetTimer()
for i := 0; i < b.N; i++ {
response := s.Request("POST", "/echo", nil, io.NopCloser(strings.NewReader(requestBody)))
if response.Status() != 200 || string(response.Body()) != requestBody {
b.Fatalf("Invalid response\nstatus=%d\nbody=%s", response.Status(), response.Body())
}
}
}
// BenchmarkSyntheticRouteParams measures performance of route parameter extraction
func BenchmarkSyntheticRouteParams(b *testing.B) {
s := web.NewServer()
s.Get("/users/:id/posts/:postId", func(ctx web.Context) error {
userId := ctx.Request().Param("id")
postId := ctx.Request().Param("postId")
return ctx.String(userId + ":" + postId)
})
b.ResetTimer()
for i := 0; i < b.N; i++ {
response := s.Request("GET", "/users/123/posts/456", nil, nil)
if response.Status() != 200 || string(response.Body()) != "123:456" {
b.Fatalf("Invalid response: status=%d, body=%s", response.Status(), response.Body())
}
}
}
// BenchmarkSyntheticMiddleware measures the impact of middleware chain
func BenchmarkSyntheticMiddleware(b *testing.B) {
s := web.NewServer()
// Add 5 middleware functions
for i := 0; i < 5; i++ {
s.Use(func(ctx web.Context) error {
return ctx.Next()
})
}
s.Get("/middleware-test", func(ctx web.Context) error {
return ctx.String("OK")
})
b.ResetTimer()
for i := 0; i < b.N; i++ {
response := s.Request("GET", "/middleware-test", nil, nil)
if response.Status() != 200 || string(response.Body()) != "OK" {
b.Fatalf("Invalid response: status=%d, body=%s", response.Status(), response.Body())
}
}
}
// BenchmarkSyntheticHeaders measures header handling performance
func BenchmarkSyntheticHeaders(b *testing.B) {
s := web.NewServer()
s.Get("/headers", func(ctx web.Context) error {
ctx.Response().SetHeader("X-Test-1", "Value1")
ctx.Response().SetHeader("X-Test-2", "Value2")
ctx.Response().SetHeader("X-Test-3", "Value3")
ctx.Response().SetHeader("Content-Type", "text/plain")
return ctx.String("Headers set")
})
b.ResetTimer()
for i := 0; i < b.N; i++ {
response := s.Request("GET", "/headers", []web.Header{
{"User-Agent", "Benchmark"},
{"Accept", "*/*"},
{"Authorization", "Bearer token12345"},
}, nil)
if response.Status() != 200 || response.Header("X-Test-1") != "Value1" {
b.Fatalf("Invalid response: status=%d", response.Status())
}
}
}
// BenchmarkSyntheticParallelRequests measures performance under concurrent load
func BenchmarkSyntheticParallelRequests(b *testing.B) {
s := web.NewServer()
s.Get("/", func(ctx web.Context) error {
return ctx.String("Hello, World!")
})
s.Get("/users/:id", func(ctx web.Context) error {
return ctx.String("User " + ctx.Request().Param("id"))
})
s.Post("/submit", func(ctx web.Context) error {
return ctx.String("Received " + string(ctx.Request().Body()))
})
b.ResetTimer()
b.RunParallel(func(pb *testing.PB) {
counter := 0
for pb.Next() {
var response web.Response
switch counter % 3 {
case 0:
response = s.Request("GET", "/", nil, nil)
case 1:
id := strconv.Itoa(counter & 0xff)
response = s.Request("GET", "/users/"+id, nil, nil)
case 2:
data := "data" + strconv.Itoa(counter&0xff)
response = s.Request("POST", "/submit", nil,
io.NopCloser(strings.NewReader(data)))
}
if response.Status() != 200 {
b.Fatalf("Invalid response: status=%d", response.Status())
}
counter++
}
})
}