Files
Agent-System/internal/config/config_test.go
T
weichenandCursor fe0bb3a503 fix(config): layer root and env compose files with expanded overrides
Load agent/cursor env overrides in config loader; pass root .env plus
environment-specific env files in env-service; align compose env_file mounts.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-09-13 02:55:18 +00:00

147 lines
4.7 KiB
Go

package config_test
import (
"os"
"path/filepath"
"testing"
"time"
"chat-agent-system/internal/config"
)
func TestConfigLoadDefaultsAndFile(t *testing.T) {
tmpDir := t.TempDir()
envPath := filepath.Join(tmpDir, ".env")
envContent := `ENV=dev
DATA_DIR=./data/test_data
AGENT_BACKEND=pi-agent
AGENT_TIMEOUT=15m
KB_DB_PORT=55432
`
if err := os.WriteFile(envPath, []byte(envContent), 0o644); err != nil {
t.Fatalf("failed to write test env: %v", err)
}
cfg, err := config.Load(envPath)
if err != nil {
t.Fatalf("unexpected error loading config: %v", err)
}
if cfg.Env != "dev" {
t.Errorf("expected Env 'dev', got %q", cfg.Env)
}
if cfg.DataDir != "./data/test_data" {
t.Errorf("expected DataDir './data/test_data', got %q", cfg.DataDir)
}
if cfg.AgentBackend != "pi-agent" {
t.Errorf("expected AgentBackend 'pi-agent', got %q", cfg.AgentBackend)
}
if cfg.AgentTimeout != 15*time.Minute {
t.Errorf("expected AgentTimeout 15m, got %v", cfg.AgentTimeout)
}
if cfg.KbDbPort != 55432 {
t.Errorf("expected KbDbPort 55432, got %d", cfg.KbDbPort)
}
}
func TestConfigLoadDSNOverrides(t *testing.T) {
t.Setenv("APP_DB_DSN", "postgres://app_user:secret_pass@system-db:5432/agent_system_dev?sslmode=disable")
t.Setenv("POSTGRES_SHARED_KB_DSN", "postgres://kb_user:kb_pass@shuimu-kb-shared:5432/regulations?sslmode=disable")
t.Setenv("HTTP_ADDR", ":9090")
t.Setenv("PI_AGENT_RUNNER_URL", "http://pi-agent:18865")
cfg, err := config.Load("/dev/null")
if err != nil {
t.Fatalf("unexpected error loading config: %v", err)
}
if cfg.ContextDbHost != "system-db" || cfg.ContextDbPort != 5432 || cfg.ContextDbUser != "app_user" || cfg.ContextDbName != "agent_system_dev" {
t.Fatalf("unexpected context db config: %+v", cfg)
}
if cfg.KbDbHost != "shuimu-kb-shared" || cfg.KbDbPort != 5432 || cfg.KbDbUser != "kb_user" || cfg.KbDbName != "regulations" {
t.Fatalf("unexpected kb db config: %+v", cfg)
}
if cfg.HTTPPort != 9090 || cfg.HTTPHost != "0.0.0.0" {
t.Fatalf("expected HTTP 0.0.0.0:9090, got %s:%d", cfg.HTTPHost, cfg.HTTPPort)
}
if cfg.PiAgentRunnerURL != "http://pi-agent:18865" {
t.Fatalf("expected pi-agent runner url override, got %q", cfg.PiAgentRunnerURL)
}
}
func TestConfigLoadRuntimeEnvironmentOverrides(t *testing.T) {
t.Setenv("ENV", "dev")
t.Setenv("AGENT_TIMEOUT", "47m")
t.Setenv("CURSOR_API_KEY", "cursor-test-key")
t.Setenv("CURSOR_MODEL", "cursor-test-model")
t.Setenv("CURSOR_BIN", "/test/cursor")
t.Setenv("CURSOR_BRIDGE_BIN", "/test/cursor-bridge.mjs")
t.Setenv("PI_AGENT_BRIDGE_BIN", "/test/pi-bridge.mjs")
t.Setenv("EMBEDDING_MODEL", "embedding-test-model")
t.Setenv("RERANKER_MODEL", "reranker-test-model")
cfg, err := config.Load("/dev/null")
if err != nil {
t.Fatalf("unexpected error loading config: %v", err)
}
if cfg.AgentTimeout != 47*time.Minute {
t.Fatalf("expected environment AgentTimeout 47m, got %v", cfg.AgentTimeout)
}
if cfg.CursorAPIKey != "cursor-test-key" || cfg.CursorModel != "cursor-test-model" || cfg.CursorBin != "/test/cursor" || cfg.CursorBridgeBin != "/test/cursor-bridge.mjs" {
t.Fatalf("cursor environment overrides were not applied")
}
if cfg.PiAgentBridgeBin != "/test/pi-bridge.mjs" {
t.Fatalf("pi bridge environment override was not applied")
}
if cfg.EmbeddingModel != "embedding-test-model" || cfg.RerankerModel != "reranker-test-model" {
t.Fatalf("retrieval model environment overrides were not applied")
}
}
func TestConfigLoadCORSDefaultsForDev(t *testing.T) {
cfg, err := config.Load("/dev/null")
if err != nil {
t.Fatalf("unexpected error: %v", err)
}
if len(cfg.CORSAllowedOrigins) == 0 {
t.Fatal("expected default CORS origins for dev")
}
}
func TestConfigLoadRejectsAllowInMemoryInMain(t *testing.T) {
t.Setenv("ENV", "main")
t.Setenv("KB_DB_PASSWORD", "kb-prod-secret-xyz")
t.Setenv("CONTEXT_DB_PASSWORD", "ctx-prod-secret-xyz")
t.Setenv("ADMIN_PASSWORD", "admin-prod-secret-xyz")
t.Setenv("ALLOW_IN_MEMORY", "true")
_, err := config.Load("/dev/null")
if err == nil {
t.Fatal("expected config load to fail when ALLOW_IN_MEMORY=true in main")
}
}
func TestConfigLoadRejectsWeakSecretsOutsideDev(t *testing.T) {
t.Setenv("ENV", "main")
t.Setenv("KB_DB_PASSWORD", "")
t.Setenv("CONTEXT_DB_PASSWORD", "")
t.Setenv("ADMIN_PASSWORD", "")
_, err := config.Load("/dev/null")
if err == nil {
t.Fatal("expected config load to fail for missing secrets in main env")
}
}
func TestConfigLoadRejectsProductionDatabasePlaceholder(t *testing.T) {
t.Setenv("ENV", "prod")
t.Setenv("KB_DB_PASSWORD", "kb-prod-secret-xyz")
t.Setenv("CONTEXT_DB_PASSWORD", "prod_highly_secure_db_pass")
t.Setenv("ADMIN_PASSWORD", "admin-prod-secret-xyz")
_, err := config.Load("/dev/null")
if err == nil {
t.Fatal("expected config load to reject the documented production database placeholder")
}
}