Files
ds-galo/backend/internal/config/config_test.go
T
iu 6361e48b20 feat(observability): configurable logging, request ids and error logs
- internal/logging: LOG_LEVEL/LOG_FORMAT parsing and slog handler
- request_id middleware (X-Request-ID or generated, echoed) + debug access log
- httpx registers errors; middleware logs internal causes with request_id
- health excluded, objects/sse debug-only, no query/body/secrets in logs
- new observability capability spec; README/.env.example docs
2026-10-11 13:40:11 +03:00

179 lines
4.3 KiB
Go

package config
import (
"testing"
"time"
)
func setRequiredEnv(t *testing.T) {
t.Helper()
t.Setenv("JWT_SECRET", "test-secret")
t.Setenv("PG_PASSWORD", "test-pass")
}
func TestLoadStorageBackend(t *testing.T) {
t.Run("defaults to fs", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("STORAGE_BACKEND", "")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Storage.Backend != "fs" || cfg.Storage.FSRoot != "./data" {
t.Fatalf("storage = %+v", cfg.Storage)
}
})
t.Run("fs with root", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("STORAGE_BACKEND", "fs")
t.Setenv("FS_ROOT", "/var/lib/galo/objects")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Storage.Backend != "fs" || cfg.Storage.FSRoot != "/var/lib/galo/objects" {
t.Fatalf("storage = %+v", cfg.Storage)
}
})
t.Run("fs empty root falls back to default", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("STORAGE_BACKEND", "fs")
t.Setenv("FS_ROOT", "")
t.Setenv("URL_SECRET", "")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Storage.FSRoot != "./data" {
t.Fatalf("FSRoot = %q, want ./data", cfg.Storage.FSRoot)
}
})
t.Run("invalid backend", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("STORAGE_BACKEND", "gcs")
if _, err := Load(); err == nil {
t.Fatal("expected error for invalid backend")
}
})
t.Run("object url ttl", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("STORAGE_BACKEND", "")
t.Setenv("OBJECT_URL_TTL", "30m")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Storage.URLTTL != 30*time.Minute {
t.Fatalf("URLTTL = %v, want 30m", cfg.Storage.URLTTL)
}
})
}
func TestLoadDatabaseBackend(t *testing.T) {
t.Run("defaults to sqlite", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("DB_BACKEND", "")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Database.Backend != "sqlite" || cfg.Database.SQLitePath != "./galo.db" {
t.Fatalf("database = %+v", cfg.Database)
}
})
t.Run("postgres requires password", func(t *testing.T) {
t.Setenv("JWT_SECRET", "s")
t.Setenv("PG_PASSWORD", "")
t.Setenv("DB_BACKEND", "postgres")
if _, err := Load(); err == nil {
t.Fatal("expected error for postgres without PG_PASSWORD")
}
})
t.Run("sqlite with path", func(t *testing.T) {
t.Setenv("JWT_SECRET", "s")
t.Setenv("PG_PASSWORD", "")
t.Setenv("DB_BACKEND", "sqlite")
t.Setenv("SQLITE_PATH", "/data/galo.db")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Database.Backend != "sqlite" || cfg.Database.SQLitePath != "/data/galo.db" {
t.Fatalf("database = %+v", cfg.Database)
}
})
t.Run("sqlite empty path falls back to default", func(t *testing.T) {
t.Setenv("JWT_SECRET", "s")
t.Setenv("PG_PASSWORD", "")
t.Setenv("DB_BACKEND", "sqlite")
t.Setenv("SQLITE_PATH", "")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Database.SQLitePath != "./galo.db" {
t.Fatalf("SQLitePath = %q, want ./galo.db", cfg.Database.SQLitePath)
}
})
t.Run("invalid backend", func(t *testing.T) {
t.Setenv("JWT_SECRET", "s")
t.Setenv("PG_PASSWORD", "p")
t.Setenv("DB_BACKEND", "mysql")
if _, err := Load(); err == nil {
t.Fatal("expected error for invalid backend")
}
})
}
func TestLoadLog(t *testing.T) {
t.Run("defaults", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("LOG_LEVEL", "")
t.Setenv("LOG_FORMAT", "")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Log.Level != "info" || cfg.Log.Format != "json" {
t.Fatalf("log = %+v, want info/json", cfg.Log)
}
})
t.Run("custom values", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("LOG_LEVEL", "debug")
t.Setenv("LOG_FORMAT", "text")
cfg, err := Load()
if err != nil {
t.Fatalf("load: %v", err)
}
if cfg.Log.Level != "debug" || cfg.Log.Format != "text" {
t.Fatalf("log = %+v, want debug/text", cfg.Log)
}
})
t.Run("invalid level", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("LOG_LEVEL", "trace")
if _, err := Load(); err == nil {
t.Fatal("expected error for invalid LOG_LEVEL")
}
})
t.Run("invalid format", func(t *testing.T) {
setRequiredEnv(t)
t.Setenv("LOG_FORMAT", "xml")
if _, err := Load(); err == nil {
t.Fatal("expected error for invalid LOG_FORMAT")
}
})
}