lolly/internal/server/pprof_impl_test.go
xfy 9f7090df67 test(handler,middleware,server,ssl,proxy): 扩展测试覆盖率
- handler: 添加 sendfile 和 static 处理器测试
- middleware/security: 添加访问控制、认证、请求头、限流测试
- server: 添加池、pprof、清理、状态、升级、vhost 测试
- ssl: 添加客户端验证、OCSP、SSL 测试
- proxy: 添加代理覆盖率补充测试

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-04-22 10:42:05 +08:00

263 lines
5.8 KiB
Go

// Package server 提供 pprof 实现的测试。
package server
import (
"bufio"
"bytes"
"sync"
"testing"
)
// TestStartCPUProfile 测试 startCPUProfile 函数
func TestStartCPUProfile(t *testing.T) {
t.Run("start and stop CPU profile", func(t *testing.T) {
var buf bytes.Buffer
err := startCPUProfile(&buf)
if err != nil {
t.Errorf("unexpected error starting CPU profile: %v", err)
}
// 停止 CPU profile
stopCPUProfile()
})
t.Run("start twice should not error", func(t *testing.T) {
var buf1, buf2 bytes.Buffer
err1 := startCPUProfile(&buf1)
if err1 != nil {
t.Errorf("unexpected error on first start: %v", err1)
}
// 第二次启动应该被忽略(已在采集)
err2 := startCPUProfile(&buf2)
if err2 != nil {
t.Errorf("unexpected error on second start: %v", err2)
}
stopCPUProfile()
})
t.Run("stop without start should not panic", func(t *testing.T) {
// 确保停止状态
stopCPUProfile()
// 再次停止应该安全
stopCPUProfile()
})
}
// TestStopCPUProfile 测试 stopCPUProfile 函数
func TestStopCPUProfile(t *testing.T) {
t.Run("stop when not active", func(t *testing.T) {
// 确保停止状态
stopCPUProfile()
// 再次停止应该安全
stopCPUProfile()
})
t.Run("stop when active", func(t *testing.T) {
var buf bytes.Buffer
err := startCPUProfile(&buf)
if err != nil {
t.Fatalf("failed to start CPU profile: %v", err)
}
stopCPUProfile()
// 验证可以再次启动
err = startCPUProfile(&buf)
if err != nil {
t.Errorf("failed to restart CPU profile after stop: %v", err)
}
stopCPUProfile()
})
}
// TestWriteHeapProfile 测试 writeHeapProfile 函数
func TestWriteHeapProfile(t *testing.T) {
t.Run("write heap profile", func(t *testing.T) {
var buf bytes.Buffer
// 写入 heap profile
writeHeapProfile(&buf)
// 验证有输出
if buf.Len() == 0 {
t.Error("expected heap profile output, got empty buffer")
}
})
t.Run("write heap profile multiple times", func(t *testing.T) {
var buf1, buf2 bytes.Buffer
writeHeapProfile(&buf1)
writeHeapProfile(&buf2)
// 两次都应该有输出
if buf1.Len() == 0 {
t.Error("expected heap profile output on first call")
}
if buf2.Len() == 0 {
t.Error("expected heap profile output on second call")
}
})
}
// TestWriteGoroutineProfile 测试 writeGoroutineProfile 函数
func TestWriteGoroutineProfile(t *testing.T) {
t.Run("write goroutine profile", func(t *testing.T) {
var buf bytes.Buffer
writeGoroutineProfile(&buf)
// 验证有输出
if buf.Len() == 0 {
t.Error("expected goroutine profile output, got empty buffer")
}
})
t.Run("write goroutine profile with spawned goroutines", func(t *testing.T) {
var buf bytes.Buffer
// 启动一些 goroutine
var wg sync.WaitGroup
for i := 0; i < 5; i++ {
wg.Add(1)
go func() {
defer wg.Done()
select {}
}()
}
writeGoroutineProfile(&buf)
// 应该有输出
if buf.Len() == 0 {
t.Error("expected goroutine profile output")
}
})
}
// TestWriteBlockProfile 测试 writeBlockProfile 函数
func TestWriteBlockProfile(t *testing.T) {
t.Run("write block profile", func(t *testing.T) {
var buf bytes.Buffer
writeBlockProfile(&buf)
// block profile 可能为空(如果没有阻塞操作)
// 所以我们只验证函数不会 panic
})
}
// TestWriteMutexProfile 测试 writeMutexProfile 函数
func TestWriteMutexProfile(t *testing.T) {
t.Run("write mutex profile", func(t *testing.T) {
var buf bytes.Buffer
writeMutexProfile(&buf)
// mutex profile 可能为空(如果没有锁竞争)
// 所以我们只验证函数不会 panic
})
}
// TestBufioWriterAdapter 测试 bufioWriterAdapter 结构体
func TestBufioWriterAdapter(t *testing.T) {
t.Run("write and flush", func(t *testing.T) {
var buf bytes.Buffer
bw := bufio.NewWriter(&buf)
writer := wrapBufioWriter(bw)
data := []byte("test data")
n, err := writer.Write(data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if n != len(data) {
t.Errorf("expected %d bytes written, got %d", len(data), n)
}
})
t.Run("write multiple times", func(t *testing.T) {
var buf bytes.Buffer
bw := bufio.NewWriter(&buf)
writer := wrapBufioWriter(bw)
data1 := []byte("first")
data2 := []byte("second")
n1, err1 := writer.Write(data1)
if err1 != nil {
t.Errorf("unexpected error on first write: %v", err1)
}
if n1 != len(data1) {
t.Errorf("expected %d bytes on first write, got %d", len(data1), n1)
}
n2, err2 := writer.Write(data2)
if err2 != nil {
t.Errorf("unexpected error on second write: %v", err2)
}
if n2 != len(data2) {
t.Errorf("expected %d bytes on second write, got %d", len(data2), n2)
}
})
}
// TestWrapBufioWriter 测试 wrapBufioWriter 函数
func TestWrapBufioWriter(t *testing.T) {
t.Run("wrap returns non-nil", func(t *testing.T) {
var buf bytes.Buffer
bw := bufio.NewWriter(&buf)
writer := wrapBufioWriter(bw)
if writer == nil {
t.Error("expected non-nil writer")
}
})
t.Run("wrapped writer implements io.Writer", func(t *testing.T) {
var buf bytes.Buffer
bw := bufio.NewWriter(&buf)
writer := wrapBufioWriter(bw)
// 测试写入
data := []byte("hello world")
n, err := writer.Write(data)
if err != nil {
t.Errorf("unexpected error: %v", err)
}
if n != len(data) {
t.Errorf("expected %d bytes, got %d", len(data), n)
}
})
}
// TestCPUProfileMutex 测试 CPU profile 的并发安全性
func TestCPUProfileMutex(t *testing.T) {
t.Run("concurrent start/stop", func(t *testing.T) {
var wg sync.WaitGroup
var buf bytes.Buffer
// 启动多个 goroutine 同时操作
for i := 0; i < 10; i++ {
wg.Add(2)
go func() {
defer wg.Done()
_ = startCPUProfile(&buf)
}()
go func() {
defer wg.Done()
stopCPUProfile()
}()
}
wg.Wait()
// 确保最终状态一致
stopCPUProfile()
})
}