lolly/internal/config/load_test.go
xfy e8fbbf368c fix(config,server): merge defaults on Load and fix monitoring registration
Two related fixes that must land together:

1. config.Load() now starts from DefaultConfig() before unmarshaling
   YAML. This ensures missing top-level fields (Performance,
   Monitoring, Resolver) use their documented defaults instead of
   zero values. Most importantly, file_cache is no longer silently
   disabled when users omit the performance: section.

2. startSingleMode() now checks Monitoring.Status.Enabled instead of
   Path/Allow to decide whether to register the status endpoint.
   Without this change, fix #1 would have caused a regression where
   the status handler is registered even when monitoring is disabled,
   because DefaultConfig() sets Path and Allow defaults.

Also replace remaining log.Printf in status.go and lua/api_timer.go
with zerolog to follow project logging conventions.

Added tests:
- config/load_test.go: verifies defaults are applied, explicit values
  override defaults, and monitoring stays disabled by default.
- server/monitoring_registration_test.go: verifies /_status is only
  registered when enabled and remains reachable with static handler
  on path: /.
2026-06-11 15:08:57 +08:00

105 lines
2.7 KiB
Go

package config
import (
"os"
"path/filepath"
"testing"
"time"
)
func TestLoad_MergesDefaults(t *testing.T) {
tmpDir := t.TempDir()
path := filepath.Join(tmpDir, "minimal.yaml")
content := `
servers:
- listen: ":8080"
`
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
t.Fatalf("write config: %v", err)
}
cfg, err := Load(path)
if err != nil {
t.Fatalf("Load failed: %v", err)
}
if cfg.Performance.FileCache.MaxEntries == 0 {
t.Error("Performance.FileCache.MaxEntries should have default value")
}
if cfg.Performance.FileCache.MaxSize == 0 {
t.Error("Performance.FileCache.MaxSize should have default value")
}
if cfg.Performance.FileCache.Inactive == 0 {
t.Error("Performance.FileCache.Inactive should have default value")
}
if cfg.Monitoring.Status.Path != "/_status" {
t.Errorf("Monitoring.Status.Path = %q, want %q", cfg.Monitoring.Status.Path, "/_status")
}
if cfg.Monitoring.Pprof.Path != "/debug/pprof" {
t.Errorf("Monitoring.Pprof.Path = %q, want %q", cfg.Monitoring.Pprof.Path, "/debug/pprof")
}
if cfg.Resolver.Valid == 0 {
t.Error("Resolver.Valid should have default value")
}
}
func TestLoad_ExplicitOverridesDefault(t *testing.T) {
tmpDir := t.TempDir()
path := filepath.Join(tmpDir, "explicit.yaml")
content := `
performance:
file_cache:
max_entries: 500
max_size: 52428800
inactive: 120s
servers:
- listen: ":8080"
`
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
t.Fatalf("write config: %v", err)
}
cfg, err := Load(path)
if err != nil {
t.Fatalf("Load failed: %v", err)
}
if cfg.Performance.FileCache.MaxEntries != 500 {
t.Errorf("MaxEntries = %d, want 500", cfg.Performance.FileCache.MaxEntries)
}
if cfg.Performance.FileCache.MaxSize != 52428800 {
t.Errorf("MaxSize = %d, want 52428800", cfg.Performance.FileCache.MaxSize)
}
if cfg.Performance.FileCache.Inactive != 120*time.Second {
t.Errorf("Inactive = %v, want 120s", cfg.Performance.FileCache.Inactive)
}
}
func TestLoad_MonitoringDisabledByDefault(t *testing.T) {
tmpDir := t.TempDir()
path := filepath.Join(tmpDir, "minimal.yaml")
content := `
servers:
- listen: ":8080"
`
if err := os.WriteFile(path, []byte(content), 0o644); err != nil {
t.Fatalf("write config: %v", err)
}
cfg, err := Load(path)
if err != nil {
t.Fatalf("Load failed: %v", err)
}
// 默认值 Path 存在,但 Enabled 应为 false
if cfg.Monitoring.Status.Enabled {
t.Error("Monitoring.Status.Enabled should be false by default")
}
if cfg.Monitoring.Pprof.Enabled {
t.Error("Monitoring.Pprof.Enabled should be false by default")
}
if cfg.Monitoring.Status.Path != "/_status" {
t.Errorf("Monitoring.Status.Path = %q, want %q", cfg.Monitoring.Status.Path, "/_status")
}
}