fix: config validation hardening and integration polish

- providers.go: validate provider names against ^[a-zA-Z0-9._-]+$ and
  reject reserved names (v1, mcp, a2a) that would shadow gateway routes;
  reject nil ProviderConfig map values at construction instead of
  panicking.
- mcp_a2a.go: apply the same name-pattern and reserved-name validation to
  mcpServers/agents keys, and reject nil TargetConfig/AgentConfig map
  values at construction.
- auth.go: reject nil GroupConfig map values at construction.
- provider_openai_test.go, mcp_a2a_test.go, auth_test.go: table-driven
  constructor-error coverage for the above.
- integration/integration_test.go: point the package doc at
  `make integration-up`/`integration-keep` instead of a bare
  `docker compose up -d --build`, which skips the dynamic.yml.tmpl
  render step and can run against a stale or absent dynamic.yml; add
  max_tokens to the gemini chat request so translate_gemini.go's
  hasMaxTokens=true branch is actually exercised under real Yaegi.
- translate_gemini.go: soften the max_tokens comment's verification claim
  to match what the integration suite actually now exercises.
This commit is contained in:
2026-08-20 13:57:56 +01:00
parent 730583d98e
commit ae4d6bab96
8 changed files with 202 additions and 23 deletions
+15
View File
@@ -160,6 +160,21 @@ func TestNewAuthStore_EmptyAPIKeyAfterResolution_ReturnsError(t *testing.T) {
}
}
// TestNewAuthStore_NilGroupConfig_ReturnsError covers a Groups map entry
// whose value is a nil *GroupConfig (a caller can construct this in Go, and
// Traefik's own YAML-to-struct decoding can leave a map value nil for an
// empty mapping entry) — newAuthStore must reject it as a constructor error
// rather than panic dereferencing gc.Limits on a nil gc.
func TestNewAuthStore_NilGroupConfig_ReturnsError(t *testing.T) {
cfg := &Config{
Providers: map[string]*ProviderConfig{"openai": {Type: "openai", APIKey: "k"}},
Groups: map[string]*GroupConfig{"eng": nil},
}
if _, err := newAuthStore(cfg); err == nil {
t.Fatal("want error for a nil GroupConfig value, got nil")
}
}
func TestNewAuthStore_NoUsers_OK(t *testing.T) {
cfg := &Config{
Providers: map[string]*ProviderConfig{"openai": {Type: "openai", APIKey: "k"}},