test: 补充真实功能验证测试
- ErrorMetrics 并发安全测试 - AsyncLogWriter 错误指标真实记录测试 - HTTP Server 超时配置真实验证 - Prometheus 指标 HTTP 端点真实测试 - 日志文件输出真实写入测试
This commit is contained in:
136
internal/log/log_integration_test.go
Normal file
136
internal/log/log_integration_test.go
Normal file
@@ -0,0 +1,136 @@
|
||||
package log
|
||||
|
||||
import (
|
||||
"log/slog"
|
||||
"os"
|
||||
"path/filepath"
|
||||
"strings"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestInitWithConfig_FileOutput_Real(t *testing.T) {
|
||||
logDir := t.TempDir()
|
||||
logFile := filepath.Join(logDir, "test.log")
|
||||
|
||||
cfg := Config{
|
||||
Level: "info",
|
||||
Output: logFile,
|
||||
MaxSize: 1, // 1MB
|
||||
}
|
||||
|
||||
// 初始化日志
|
||||
InitWithConfig(cfg)
|
||||
|
||||
// 写入日志
|
||||
Info("test message", "key", "value")
|
||||
Error("error message", "err", "test error")
|
||||
|
||||
// 验证文件被创建
|
||||
if _, err := os.Stat(logFile); os.IsNotExist(err) {
|
||||
t.Fatal("Log file was not created")
|
||||
}
|
||||
|
||||
// 读取文件内容
|
||||
content, err := os.ReadFile(logFile)
|
||||
if err != nil {
|
||||
t.Fatalf("Failed to read log file: %v", err)
|
||||
}
|
||||
|
||||
// 验证内容
|
||||
contentStr := string(content)
|
||||
if !strings.Contains(contentStr, "test message") {
|
||||
t.Error("Log file missing 'test message'")
|
||||
}
|
||||
if !strings.Contains(contentStr, "key") {
|
||||
t.Error("Log file missing 'key' field")
|
||||
}
|
||||
}
|
||||
|
||||
func TestSanitizeAttrs_Real(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
key string
|
||||
value string
|
||||
expected string
|
||||
}{
|
||||
{
|
||||
name: "token should be redacted",
|
||||
key: "api_token",
|
||||
value: "secret123",
|
||||
expected: "[REDACTED]",
|
||||
},
|
||||
{
|
||||
name: "password should be redacted",
|
||||
key: "user_password",
|
||||
value: "mypassword",
|
||||
expected: "[REDACTED]",
|
||||
},
|
||||
{
|
||||
name: "normal key should not be redacted",
|
||||
key: "user_name",
|
||||
value: "john",
|
||||
expected: "john",
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
attr := slog.String(tt.key, tt.value)
|
||||
sanitized := sanitizeAttrs(nil, attr)
|
||||
|
||||
if sanitized.Value.String() != tt.expected {
|
||||
t.Errorf("sanitizeAttrs() = %q, want %q", sanitized.Value.String(), tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func TestIsSensitive_Real(t *testing.T) {
|
||||
sensitiveKeys := []string{
|
||||
"token",
|
||||
"password",
|
||||
"secret",
|
||||
"api_key",
|
||||
"private_key",
|
||||
}
|
||||
|
||||
nonSensitiveKeys := []string{
|
||||
"name",
|
||||
"id",
|
||||
"timestamp",
|
||||
"message",
|
||||
}
|
||||
|
||||
for _, key := range sensitiveKeys {
|
||||
if !IsSensitive(key) {
|
||||
t.Errorf("IsSensitive(%q) = false, want true", key)
|
||||
}
|
||||
}
|
||||
|
||||
for _, key := range nonSensitiveKeys {
|
||||
if IsSensitive(key) {
|
||||
t.Errorf("IsSensitive(%q) = true, want false", key)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestParseLevel_Real(t *testing.T) {
|
||||
tests := []struct {
|
||||
input string
|
||||
expected slog.Level
|
||||
}{
|
||||
{"debug", slog.LevelDebug},
|
||||
{"info", slog.LevelInfo},
|
||||
{"warn", slog.LevelWarn},
|
||||
{"error", slog.LevelError},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.input, func(t *testing.T) {
|
||||
level := parseLevel(tt.input)
|
||||
if level != tt.expected {
|
||||
t.Errorf("parseLevel(%q) = %d, want %d", tt.input, level, tt.expected)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user