summaryrefslogtreecommitdiff
path: root/internal/config/config_test.go
diff options
context:
space:
mode:
Diffstat (limited to 'internal/config/config_test.go')
-rw-r--r--internal/config/config_test.go80
1 files changed, 77 insertions, 3 deletions
diff --git a/internal/config/config_test.go b/internal/config/config_test.go
index 2331b0f..1ecf70f 100644
--- a/internal/config/config_test.go
+++ b/internal/config/config_test.go
@@ -8,20 +8,25 @@ import (
func TestLoadAppliesDefaultsAndResolvesSecrets(t *testing.T) {
t.Setenv("TEST_UPSTREAM_KEY", "secret")
+ t.Setenv("TEST_UPSTREAM_URL", "https://example.com/v1")
+ t.Setenv("AIGW_SERVER_ADDRESS", "127.0.0.1:9090")
path := writeConfig(t, `{
- "providers": [{"id":"primary","protocol":"openai","base_url":"https://example.com/v1","api_key_env":"TEST_UPSTREAM_KEY"}],
+ "providers": [{"id":"primary","protocol":"openai","base_url_env":"TEST_UPSTREAM_URL","api_key_env":"TEST_UPSTREAM_KEY"}],
"models": [{"id":"example/model","routes":[{"provider":"primary","upstream_model":"model"}]}]
}`)
cfg, err := Load(path)
if err != nil {
t.Fatal(err)
}
- if cfg.Server.Address != ":8080" || cfg.Server.MaxBodyBytes == 0 {
+ if cfg.Server.Address != "127.0.0.1:9090" || cfg.Server.MaxBodyBytes == 0 {
t.Fatalf("defaults not applied: %+v", cfg.Server)
}
if cfg.Providers[0].APIKey != "secret" {
t.Fatal("provider secret was not resolved")
}
+ if cfg.Providers[0].BaseURL != "https://example.com/v1" {
+ t.Fatal("provider URL was not resolved")
+ }
if cfg.Models[0].Routes[0].Weight != 1 {
t.Fatalf("expected default route weight 1, got %d", cfg.Models[0].Routes[0].Weight)
}
@@ -40,11 +45,24 @@ func TestLoadRejectsUnknownFieldsAndTrailingData(t *testing.T) {
}
}
+func TestLoadRejectsLiteralExternalServiceValues(t *testing.T) {
+ for _, content := range []string{
+ `{"server":{"address":":9090"}}`,
+ `{"providers":[{"id":"primary","protocol":"openai","base_url":"https://example.test","api_key_env":"TEST_KEY"}]}`,
+ `{"billing":{"stripe":{"success_url":"https://console.example.test"}}}`,
+ } {
+ if _, err := Load(writeConfig(t, content)); err == nil {
+ t.Fatalf("expected literal external service value to be rejected: %s", content)
+ }
+ }
+}
+
func TestLoadControlPlaneModeWithoutStaticRoutes(t *testing.T) {
t.Setenv("AIGW_DATABASE_URL", "postgres://aigw:aigw@postgres/aigw")
t.Setenv("AIGW_REDIS_URL", "redis://redis:6379/0")
t.Setenv("AIGW_CREDENTIAL_KEY", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
t.Setenv("AIGW_ADMIN_TOKEN", "admin-secret")
+ t.Setenv("AIGW_PUBLIC_URL", "http://localhost:8080/admin/")
path := writeConfig(t, `{
"control_plane": {"enabled":true},
"admin": {"enabled":true}
@@ -90,9 +108,11 @@ func TestLoadResolvesStripeSecrets(t *testing.T) {
t.Setenv("AIGW_CREDENTIAL_KEY", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
t.Setenv("TEST_STRIPE_KEY", "rk_test_example")
t.Setenv("TEST_STRIPE_WEBHOOK", "whsec_example")
+ t.Setenv("TEST_STRIPE_SUCCESS", "https://console.example.test/admin/?topup=success")
+ t.Setenv("TEST_STRIPE_CANCEL", "https://console.example.test/admin/?topup=cancel")
path := writeConfig(t, `{
"control_plane":{"enabled":true},
- "billing":{"enabled":true,"stripe":{"enabled":true,"api_key_env":"TEST_STRIPE_KEY","webhook_secret_env":"TEST_STRIPE_WEBHOOK","success_url":"http://localhost/admin/?topup=success","cancel_url":"http://localhost/admin/?topup=cancel"}}
+ "billing":{"enabled":true,"stripe":{"enabled":true,"api_key_env":"TEST_STRIPE_KEY","webhook_secret_env":"TEST_STRIPE_WEBHOOK","success_url_env":"TEST_STRIPE_SUCCESS","cancel_url_env":"TEST_STRIPE_CANCEL"}}
}`)
cfg, err := Load(path)
if err != nil {
@@ -101,6 +121,21 @@ func TestLoadResolvesStripeSecrets(t *testing.T) {
if cfg.Billing.Stripe.APIKey != "rk_test_example" || cfg.Billing.Stripe.WebhookSecret != "whsec_example" {
t.Fatal("Stripe secrets were not resolved")
}
+ if cfg.Billing.Stripe.SuccessURL != "https://console.example.test/admin/?topup=success" || cfg.Billing.Stripe.CancelURL != "https://console.example.test/admin/?topup=cancel" {
+ t.Fatal("Stripe callback URLs were not resolved")
+ }
+}
+
+func TestLoadRejectsEmptyExternalServiceEnvironment(t *testing.T) {
+ t.Setenv("TEST_UPSTREAM_KEY", "secret")
+ t.Setenv("TEST_UPSTREAM_URL", "")
+ path := writeConfig(t, `{
+ "providers": [{"id":"primary","protocol":"openai","base_url_env":"TEST_UPSTREAM_URL","api_key_env":"TEST_UPSTREAM_KEY"}],
+ "models": [{"id":"example/model","routes":[{"provider":"primary","upstream_model":"model"}]}]
+}`)
+ if _, err := Load(path); err == nil {
+ t.Fatal("expected empty provider URL environment variable to be rejected")
+ }
}
func TestLoadRejectsBillingWithoutControlPlane(t *testing.T) {
@@ -110,6 +145,45 @@ func TestLoadRejectsBillingWithoutControlPlane(t *testing.T) {
}
}
+func TestVersionedExamplesResolveExternalServicesFromEnvironment(t *testing.T) {
+ t.Setenv("AIGW_SERVER_ADDRESS", "127.0.0.1:18081")
+ t.Setenv("AIGW_API_KEYS", `[{"key":"test","key_id":"key","tenant_id":"tenant","project_id":"project","scopes":["inference"]}]`)
+ t.Setenv("OPENAI_BASE_URL", "https://openai.example.test/v1")
+ t.Setenv("OPENAI_API_KEY", "openai-secret")
+ t.Setenv("ANTHROPIC_BASE_URL", "https://anthropic.example.test/v1")
+ t.Setenv("ANTHROPIC_API_KEY", "anthropic-secret")
+ staticConfig, err := Load(filepath.Join("..", "..", "config.example.json"))
+ if err != nil {
+ t.Fatalf("load static example: %v", err)
+ }
+ if staticConfig.Providers[0].BaseURL != "https://openai.example.test/v1" {
+ t.Fatalf("static provider URL = %q", staticConfig.Providers[0].BaseURL)
+ }
+
+ t.Setenv("AIGW_DATABASE_URL", "postgres://example:secret@postgres.example.test/aigw")
+ t.Setenv("AIGW_REDIS_URL", "redis://redis.example.test:6379/0")
+ t.Setenv("AIGW_CREDENTIAL_KEY", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA=")
+ t.Setenv("AIGW_ADMIN_TOKEN", "bootstrap-secret")
+ t.Setenv("AIGW_PUBLIC_URL", "https://console.example.test/admin/")
+ t.Setenv("AIGW_SMTP_FROM_ADDRESS", "no-reply@example.test")
+ t.Setenv("AIGW_SMTP_ADDRESS", "smtp.example.test:587")
+ t.Setenv("AIGW_SMTP_USERNAME", "")
+ t.Setenv("AIGW_SMTP_PASSWORD", "")
+ t.Setenv("AIGW_WEBAUTHN_RP_ID", "console.example.test")
+ t.Setenv("AIGW_WEBAUTHN_ORIGINS", "https://console.example.test")
+ t.Setenv("AIGW_STRIPE_API_KEY", "rk_test_example")
+ t.Setenv("AIGW_STRIPE_WEBHOOK_SECRET", "whsec_example")
+ t.Setenv("AIGW_STRIPE_SUCCESS_URL", "https://console.example.test/admin/?topup=success")
+ t.Setenv("AIGW_STRIPE_CANCEL_URL", "https://console.example.test/admin/?topup=cancel")
+ controlConfig, err := Load(filepath.Join("..", "..", "config.control.example.json"))
+ if err != nil {
+ t.Fatalf("load control-plane example: %v", err)
+ }
+ if controlConfig.Billing.Stripe.SuccessURL != "https://console.example.test/admin/?topup=success" {
+ t.Fatalf("Stripe success URL = %q", controlConfig.Billing.Stripe.SuccessURL)
+ }
+}
+
func writeConfig(t *testing.T, content string) string {
t.Helper()
path := filepath.Join(t.TempDir(), "config.json")