Batch 1 - Crash/data corruption: - Add nil/empty config guards in server and app - Protect against fasthttp buffer mutation in logging - Ensure mimeutil falls back before caching empty MIME - Make proxy health checker and resolver tolerate nil cfg - Prevent Lua EMERG/ALERT/CRIT log levels from killing process Batch 2 - Concurrency/race conditions: - Add focused race tests for compression pool, ssl/ocsp, server proxies slice, Lua timer cancel, and TCP socket connect - Fix Lua timer active race and socket ConnectAsync race Batch 3 - Resource leaks/functional damage: - Track and stop rate limiter cleanup goroutines on shutdown - Add tests for proxy connection count leaks, server pool deadlock, Linux sendfile integrity, WebSocket frame data loss, stream UDP stop deadlock, and upstream name mismatch - Fix stream ListenTCP/upstream lookup and UDP shutdown Batch 4 - High severity technical debt: - Add nil guard in security headers middleware - Validate sliding window divisor and add tests - Protect static handler fields with existing RWMutex - Avoid mutating live HostClient.Addr on DNS updates - Fix slow start Start/Stop and resolver restart - Initialize variable fallback context maps - Add tests for request_id/time_local and logging file handle close Also: - Relax integration variable performance threshold under race detector - Update benchmark plan docs for new stream ListenTCP signature Verification: - make test: pass - go test -race -count=1 ./internal/...: pass - make lint: 0 issues - make build: success
111 lines
2.6 KiB
Go
111 lines
2.6 KiB
Go
// Package lua 提供 ngx.log API 测试
|
|
package lua
|
|
|
|
import (
|
|
"bytes"
|
|
"strings"
|
|
"testing"
|
|
|
|
"github.com/rs/zerolog"
|
|
"github.com/stretchr/testify/assert"
|
|
"github.com/stretchr/testify/require"
|
|
"github.com/valyala/fasthttp"
|
|
"rua.plus/lolly/internal/testutil"
|
|
)
|
|
|
|
// mockRequestCtxForLog 创建模拟的 RequestCtx
|
|
func mockRequestCtxForLog() *fasthttp.RequestCtx {
|
|
return testutil.NewRequestCtx("GET", "/")
|
|
}
|
|
|
|
// TestNgxLogAPIWithoutLogger 测试无 logger 的情况
|
|
func TestNgxLogAPIWithoutLogger(t *testing.T) {
|
|
engine, err := NewEngine(DefaultConfig())
|
|
require.NoError(t, err)
|
|
defer engine.Close()
|
|
|
|
ctx := mockRequestCtxForLog()
|
|
luaCtx := NewContext(engine, ctx)
|
|
|
|
// 创建无 logger 的 API
|
|
api := newNgxLogAPI(ctx, luaCtx, nil)
|
|
L := engine.GetLStateForTest()
|
|
RegisterNgxLogAPI(L, api)
|
|
|
|
// 测试日志 - 不应 panic
|
|
err = L.DoString(`
|
|
ngx.log(ngx.INFO, "message without logger")
|
|
`)
|
|
assert.NoError(t, err)
|
|
}
|
|
|
|
// TestNgxLogEmergDoesNotExit 验证 ngx.EMERG 不会导致进程退出。
|
|
func TestNgxLogEmergDoesNotExit(t *testing.T) {
|
|
engine, err := NewEngine(DefaultConfig())
|
|
require.NoError(t, err)
|
|
defer engine.Close()
|
|
|
|
ctx := mockRequestCtxForLog()
|
|
luaCtx := NewContext(engine, ctx)
|
|
|
|
var buf bytes.Buffer
|
|
logger := zerolog.New(&buf)
|
|
|
|
api := newNgxLogAPI(ctx, luaCtx, &logger)
|
|
L := engine.GetLStateForTest()
|
|
RegisterNgxLogAPI(L, api)
|
|
|
|
// 不应 panic 或退出进程
|
|
err = L.DoString(`
|
|
ngx.log(ngx.EMERG, "emergency message")
|
|
ngx.log(ngx.ALERT, "alert message")
|
|
ngx.log(ngx.CRIT, "critical message")
|
|
`)
|
|
require.NoError(t, err)
|
|
|
|
output := buf.String()
|
|
if !strings.Contains(output, "emergency message") {
|
|
t.Error("expected emerg message to be logged")
|
|
}
|
|
}
|
|
|
|
// TestNgxLogAPIIntegration 集成测试
|
|
func TestNgxLogAPIIntegration(t *testing.T) {
|
|
engine, err := NewEngine(DefaultConfig())
|
|
require.NoError(t, err)
|
|
defer engine.Close()
|
|
|
|
ctx := mockRequestCtxForLog()
|
|
luaCtx := NewContext(engine, ctx)
|
|
|
|
var buf bytes.Buffer
|
|
logger := zerolog.New(&buf)
|
|
|
|
api := newNgxLogAPI(ctx, luaCtx, &logger)
|
|
L := engine.GetLStateForTest()
|
|
RegisterNgxLogAPI(L, api)
|
|
|
|
// 综合测试
|
|
err = L.DoString(`
|
|
-- 记录日志
|
|
ngx.log(ngx.INFO, "Starting request")
|
|
|
|
-- 输出内容
|
|
ngx.say("Line 1")
|
|
ngx.print("Line 2")
|
|
ngx.say("")
|
|
|
|
-- 使用常量
|
|
ngx.say("HTTP OK: " .. ngx.HTTP_OK)
|
|
ngx.say("HTTP NOT FOUND: " .. ngx.HTTP_NOT_FOUND)
|
|
`)
|
|
require.NoError(t, err)
|
|
|
|
// 验证输出
|
|
output := string(luaCtx.OutputBuffer)
|
|
assert.Contains(t, output, "Line 1")
|
|
assert.Contains(t, output, "Line 2")
|
|
assert.Contains(t, output, "HTTP OK: 200")
|
|
assert.Contains(t, output, "HTTP NOT FOUND: 404")
|
|
}
|