starnet/curlbench_test.go
2025-08-21 21:37:21 +08:00

199 lines
4.7 KiB
Go

package starnet
import (
"fmt"
"net/http"
"net/http/httptest"
"runtime"
"testing"
)
// BenchmarkGetRequest 测试单个 GET 请求的性能
func BenchmarkGetRequest(b *testing.B) {
// 创建测试服务器
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`OK`))
}))
defer server.Close()
// 重置计时器,排除设置代码的影响
b.ResetTimer()
// 报告内存分配情况
b.ReportAllocs()
// 运行基准测试
for i := 0; i < b.N; i++ {
resp, err := Get(server.URL, WithSkipTLSVerify(true))
if err != nil {
b.Errorf("Unexpected error: %v", err)
}
body := resp.Body().String()
if body != "OK" {
b.Errorf("Expected OK, got %v", body)
}
}
}
// BenchmarkGetRequestWithHeaders 测试带请求头的 GET 请求性能
func BenchmarkGetRequestWithHeaders(b *testing.B) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
// 验证请求头
if req.Header.Get("hello") != "world" {
rw.WriteHeader(http.StatusBadRequest)
return
}
rw.Write([]byte(`OK`))
}))
defer server.Close()
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
resp, err := Get(server.URL,
WithSkipTLSVerify(true),
WithHeader("hello", "world"),
WithUserAgent("hello world"))
if err != nil {
b.Errorf("Unexpected error: %v", err)
}
body := resp.Body().String()
if body != "OK" {
b.Errorf("Expected OK, got %v", body)
}
}
}
// BenchmarkPostRequest 测试 POST 请求的性能
func BenchmarkPostRequest(b *testing.B) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
// 读取并返回请求体
body := make([]byte, req.ContentLength)
req.Body.Read(body)
rw.Write(body)
}))
defer server.Close()
testData := "This is a test payload for POST request"
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
resp, err := Post(server.URL,
WithSkipTLSVerify(true),
WithBytes([]byte(testData)),
WithContentType("text/plain"))
if err != nil {
b.Errorf("Unexpected error: %v", err)
}
body := resp.Body().String()
if body != testData {
b.Errorf("Expected %s, got %v", testData, body)
}
}
}
// BenchmarkConcurrentRequests 测试并发请求性能
func BenchmarkConcurrentRequests(b *testing.B) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`OK`))
}))
defer server.Close()
b.ResetTimer()
b.ReportAllocs()
// 运行并发基准测试
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
resp, err := Get(server.URL, WithSkipTLSVerify(true))
if err != nil {
b.Errorf("Unexpected error: %v", err)
}
body := resp.Body().String()
if body != "OK" {
b.Errorf("Expected OK, got %v", body)
}
}
})
}
// BenchmarkMemoryUsage 专门测试内存使用情况
func BenchmarkMemoryUsage(b *testing.B) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write([]byte(`OK`))
}))
defer server.Close()
// 禁用默认的测试时间,只关注内存分配
b.ReportAllocs()
var memStatsStart, memStatsEnd runtime.MemStats
runtime.GC()
runtime.ReadMemStats(&memStatsStart)
for i := 0; i < b.N; i++ {
resp, err := Get(server.URL, WithSkipTLSVerify(true))
if err != nil {
b.Errorf("Unexpected error: %v", err)
}
body := resp.Body().String()
if body != "OK" {
b.Errorf("Expected OK, got %v", body)
}
}
runtime.GC()
runtime.ReadMemStats(&memStatsEnd)
// 计算每次操作的平均内存分配
allocsPerOp := float64(memStatsEnd.Mallocs-memStatsStart.Mallocs) / float64(b.N)
bytesPerOp := float64(memStatsEnd.TotalAlloc-memStatsStart.TotalAlloc) / float64(b.N)
b.ReportMetric(allocsPerOp, "allocs/op")
b.ReportMetric(bytesPerOp, "bytes/op")
}
// BenchmarkDifferentResponseSizes 测试不同响应大小的性能
func BenchmarkDifferentResponseSizes(b *testing.B) {
// 测试不同大小的响应
responseSizes := []int{100, 1024, 10240, 102400} // 100B, 1KB, 10KB, 100KB
for _, size := range responseSizes {
// 生成指定大小的响应数据
responseData := make([]byte, size)
for i := 0; i < size; i++ {
responseData[i] = 'A'
}
b.Run(fmt.Sprintf("Size_%d", size), func(b *testing.B) {
server := httptest.NewServer(http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) {
rw.Write(responseData)
}))
defer server.Close()
b.ResetTimer()
b.ReportAllocs()
for i := 0; i < b.N; i++ {
resp, err := Get(server.URL, WithSkipTLSVerify(true))
if err != nil {
b.Errorf("Unexpected error: %v", err)
}
body := resp.Body().Bytes()
if len(body) != size {
b.Errorf("Expected size %d, got %d", size, len(body))
}
}
})
}
}