package config import ( "os" "path/filepath" "strings" "testing" ) func TestLoadUsesServicePortDefaults(t *testing.T) { t.Setenv("HTTP_ADDR", "") t.Setenv("APP_ENV", "test") tests := map[string]string{ "api": "0.0.0.0:58080", "callbacks": "0.0.0.0:58081", "worker": "0.0.0.0:58082", } for service, expected := range tests { cfg, err := Load(service) if err != nil { t.Fatalf("Load(%s) returned error: %v", service, err) } if cfg.HTTPAddr != expected { t.Fatalf("Load(%s).HTTPAddr = %s, want %s", service, cfg.HTTPAddr, expected) } } } func TestLoadAllowsTracingExporterToBeDisabled(t *testing.T) { t.Setenv("OTEL_EXPORTER_OTLP_ENDPOINT", "") cfg, err := Load("api") if err != nil { t.Fatal(err) } if cfg.OTLPEndpoint != "" { t.Fatalf("OTLPEndpoint = %q, want disabled exporter", cfg.OTLPEndpoint) } } func TestLoadRejectsInvalidDuration(t *testing.T) { t.Setenv("DEPENDENCY_TIMEOUT", "soon") if _, err := Load("api"); err == nil { t.Fatal("Load should reject an invalid duration") } } func TestLoadReadsSecretsFromAbsoluteFiles(t *testing.T) { secret := strings.Repeat("k", 40) path := filepath.Join(t.TempDir(), "ark-api-key") if err := os.WriteFile(path, []byte(secret+"\n"), 0o600); err != nil { t.Fatal(err) } t.Setenv("ARK_API_KEY", "") t.Setenv("ARK_API_KEY_FILE", path) databaseURL := "postgres://voice:secret@db.example.com:5432/voice?sslmode=verify-full" databasePath := filepath.Join(t.TempDir(), "database-url") if err := os.WriteFile(databasePath, []byte(databaseURL+"\r\n"), 0o600); err != nil { t.Fatal(err) } t.Setenv("DATABASE_URL", "") t.Setenv("DATABASE_URL_FILE", databasePath) cfg, err := Load("worker") if err != nil { t.Fatal(err) } if cfg.ArkAPIKey != secret { t.Fatalf("secret file value was not loaded") } if cfg.DatabaseURL != databaseURL { t.Fatalf("database URL file value was not loaded") } } func TestLoadRejectsAmbiguousSecretSources(t *testing.T) { path := filepath.Join(t.TempDir(), "redis-password") if err := os.WriteFile(path, []byte(strings.Repeat("r", 40)), 0o600); err != nil { t.Fatal(err) } t.Setenv("REDIS_PASSWORD", strings.Repeat("x", 40)) t.Setenv("REDIS_PASSWORD_FILE", path) if _, err := Load("api"); err == nil || !strings.Contains(err.Error(), "cannot both") { t.Fatalf("Load() error=%v, want ambiguous secret source rejection", err) } } func TestValidateRejectsUnknownEnvironment(t *testing.T) { cfg, err := Load("api") if err != nil { t.Fatalf("unexpected load error: %v", err) } cfg.Environment = "production-ish" if err := cfg.Validate(); err == nil { t.Fatal("Validate should reject an unknown environment") } } func TestProductionRejectsLocalDefaults(t *testing.T) { cfg, err := Load("api") if err != nil { t.Fatalf("unexpected load error: %v", err) } cfg.Environment = EnvironmentProd if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "HTTPS") { t.Fatalf("Validate() error = %v, want HTTPS production gate", err) } } func TestProductionAPIAcceptsHardenedConfiguration(t *testing.T) { cfg, err := Load("api") if err != nil { t.Fatalf("unexpected load error: %v", err) } cfg.Environment = EnvironmentProd cfg.DatabaseURL = "postgres://voice:secret@postgres.example.internal:5432/voice?sslmode=verify-full" cfg.RedisPassword = strings.Repeat("r", 40) cfg.AuthIssuerURL = "https://identity.example.com/realms/voice" cfg.AuthJWKSURL = "https://identity.example.com/realms/voice/certs" cfg.DeviceLocalSecret = strings.Repeat("d", 40) cfg.DeviceSecretDirectory = t.TempDir() cfg.RTCTokenSecret = strings.Repeat("t", 40) cfg.RTCTokenIssuer = "volcengine" cfg.RTCAppKey = strings.Repeat("v", 40) cfg.CursorSigningSecret = strings.Repeat("c", 40) cfg.ShareTokenSecret = strings.Repeat("h", 40) cfg.RTCAppID = "661e7ae5543cf00000000000" cfg.ObjectStoreEndpoint = "objects.internal.example.com:9000" cfg.ObjectStorePublic = "objects.example.com" cfg.ObjectStoreAccessKey = strings.Repeat("a", 40) cfg.ObjectStoreSecretKey = strings.Repeat("s", 40) cfg.ObjectStoreSecure = true cfg.ObjectStorePublicSecure = true cfg.EmbeddingProvider = "ark" cfg.ArkBaseURL = "https://ark.cn-beijing.volces.com/api/v3" cfg.ArkAPIKey = strings.Repeat("k", 40) cfg.ArkEmbeddingModel = "doubao-production-embedding" if err := cfg.Validate(); err != nil { t.Fatalf("Validate() returned error for hardened production config: %v", err) } } func TestProductionRejectsReusedSigningSecrets(t *testing.T) { cfg, err := Load("api") if err != nil { t.Fatalf("unexpected load error: %v", err) } cfg.Environment = EnvironmentProd cfg.DatabaseURL = "postgres://voice:secret@postgres.example.internal:5432/voice?sslmode=require" cfg.RedisPassword = strings.Repeat("r", 40) cfg.AuthIssuerURL = "https://identity.example.com/realms/voice" cfg.AuthJWKSURL = "https://identity.example.com/realms/voice/certs" cfg.DeviceLocalSecret = strings.Repeat("x", 40) cfg.DeviceSecretDirectory = t.TempDir() cfg.RTCTokenSecret = strings.Repeat("x", 40) cfg.RTCTokenIssuer = "volcengine" cfg.RTCAppKey = strings.Repeat("v", 40) cfg.CursorSigningSecret = strings.Repeat("x", 40) cfg.ShareTokenSecret = strings.Repeat("x", 40) cfg.RTCAppID = "661e7ae5543cf00000000000" cfg.ObjectStoreEndpoint = "objects.internal.example.com:9000" cfg.ObjectStorePublic = "objects.example.com" cfg.ObjectStoreAccessKey = strings.Repeat("a", 40) cfg.ObjectStoreSecretKey = strings.Repeat("s", 40) cfg.ObjectStoreSecure = true cfg.ObjectStorePublicSecure = true cfg.EmbeddingProvider = "ark" cfg.ArkBaseURL = "https://ark.cn-beijing.volces.com/api/v3" cfg.ArkAPIKey = strings.Repeat("k", 40) cfg.ArkEmbeddingModel = "doubao-production-embedding" if err := cfg.Validate(); err == nil || !strings.Contains(err.Error(), "distinct") { t.Fatalf("Validate() error = %v, want distinct-secret gate", err) } } func TestProductionWorkerRequiresRealArkContentGenerator(t *testing.T) { cfg, err := Load("worker") if err != nil { t.Fatalf("unexpected load error: %v", err) } cfg.Environment = EnvironmentProd cfg.DatabaseURL = "postgres://voice:secret@postgres.example.internal:5432/voice?sslmode=verify-full" cfg.RedisPassword = strings.Repeat("r", 40) cfg.AuthIssuerURL = "https://identity.example.com/realms/voice" cfg.AuthJWKSURL = "https://identity.example.com/realms/voice/certs" cfg.VoiceProvider = "volcengine" cfg.VolcRTCBaseURL = "https://rtc.volcengineapi.com" cfg.VolcAccessKeyID = strings.Repeat("a", 40) cfg.VolcSecretAccessKey = strings.Repeat("v", 40) cfg.VolcRTCRegion = "cn-north-1" cfg.VolcRTCAPIVersion = "2024-12-01" cfg.VolcVoiceChatTemplate = "/run/secrets/voice-chat-template.json" cfg.RTCAppID = "661e7ae5543cf00000000000" cfg.ObjectStoreEndpoint = "objects.internal.example.com:9000" cfg.ObjectStorePublic = "objects.example.com" cfg.ObjectStoreAccessKey = strings.Repeat("a", 40) cfg.ObjectStoreSecretKey = strings.Repeat("s", 40) cfg.ObjectStoreSecure = true cfg.ObjectStorePublicSecure = true if err = cfg.Validate(); err == nil || !strings.Contains(err.Error(), "content generation") { t.Fatalf("Validate() error=%v, want local content generator production gate", err) } cfg.ContentGenerator = "ark" cfg.ArkBaseURL = "https://ark.cn-beijing.volces.com/api/v3" cfg.ArkAPIKey = strings.Repeat("k", 40) cfg.ArkContentModel = "doubao-production-model" cfg.ContentSafetyProvider = "managed_http" cfg.ContentSafetyEndpoint = "https://content-safety.example.com/v1/classify" cfg.ContentSafetyAPIKey = strings.Repeat("p", 40) cfg.ContentSafetyPolicyRef = "elder-story-production-v1" cfg.EmbeddingProvider = "ark" cfg.ArkEmbeddingModel = "doubao-production-embedding" if err = cfg.Validate(); err != nil { t.Fatalf("Validate() rejected production Ark worker: %v", err) } } func TestWorkerManagedContentSafetyConfiguration(t *testing.T) { cfg, err := Load("worker") if err != nil { t.Fatal(err) } cfg.ContentSafetyProvider = "managed_http" if err = cfg.Validate(); err == nil || !strings.Contains(err.Error(), "content safety") { t.Fatalf("Validate() error=%v, want incomplete managed content safety rejection", err) } cfg.ContentSafetyEndpoint = "http://127.0.0.1:18080/v1/classify" cfg.ContentSafetyAPIKey = strings.Repeat("s", 40) cfg.ContentSafetyPolicyRef = "local-contract-test-v1" if err = cfg.Validate(); err != nil { t.Fatalf("Validate() rejected complete non-production managed content safety config: %v", err) } }