Ctrl K
ComunidadGuías…

internal/config/connection_pool_entry_test.go

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
package config_test

import (
	"testing"

	"github.com/router-for-me/CLIProxyAPI/v8/internal/config"
)

// TestPerEntryConnectionPoolAccepted pins the per-credential opt-in shape: the
// global pool stays off while a single api-keys entry turns pooling on for itself.
func TestPerEntryConnectionPoolAccepted(t *testing.T) {
	raw := []byte(`config-version: 8
api-keys:
  codex:
    - name: ollama
      base-url: "https://ollama.com/v1"
      proxy-url: "direct"
      connection-pool:
        enabled: true
        idle-conn-timeout: "300s"
        max-idle-conns-per-host: 2
      keys:
        - api-key: "ollama-key"
`)
	if err := config.ValidateV8Config(raw); err != nil {
		t.Fatalf("ValidateV8Config: %v", err)
	}
	cfg, err := config.ParseConfigBytes(raw)
	if err != nil {
		t.Fatalf("ParseConfigBytes: %v", err)
	}
	if len(cfg.CodexKey) != 1 || cfg.CodexKey[0].ConnectionPool == nil {
		t.Fatalf("per-entry connection-pool not parsed: %+v", cfg.CodexKey)
	}
	pool := cfg.CodexKey[0].ConnectionPool
	if pool.Enabled == nil || !*pool.Enabled {
		t.Fatalf("enabled not parsed: %+v", pool)
	}
	if pool.IdleConnTimeout != "300s" {
		t.Fatalf("idle-conn-timeout = %q, want 300s", pool.IdleConnTimeout)
	}
	if pool.MaxIdleConnsPerHost == nil || *pool.MaxIdleConnsPerHost != 2 {
		t.Fatalf("max-idle-conns-per-host not parsed: %+v", pool)
	}
	if errLegacy := config.ValidateV8Config([]byte("config-version: 8\nrequests:\n  proxy-connection-pool:\n    enabled: true\n")); errLegacy == nil {
		t.Fatal("a global pooling switch must not exist")
	}
}

// TestPerEntryConnectionPoolRejectsUnknownKey keeps KnownFields strict inside the
// new nested block.
func TestPerEntryConnectionPoolRejectsUnknownKey(t *testing.T) {
	raw := []byte(`config-version: 8
api-keys:
  codex:
    - name: k
      keys:
        - api-key: "k"
      connection-pool:
        enabled: true
        idle-timeout: "30s"
`)
	if err := config.ValidateV8Config(raw); err == nil {
		t.Fatal("unknown nested key must be rejected")
	}
}

// TestEmptyConnectionPoolBlockStaysOptIn pins that a block with no fields is still an
// opt-in (it asks for the defaults), including when it stands alone. A nil result here
// silently disabled pooling for `connection-pool: {}`.
func TestEmptyConnectionPoolBlockStaysOptIn(t *testing.T) {
	raw := []byte(`config-version: 8
api-keys:
  codex:
    - name: empty
      base-url: "https://ollama.com/v1"
      connection-pool: {}
      keys:
        - api-key: "empty-group"
        - api-key: "empty-key"
          connection-pool: {}
`)
	cfg, err := config.ParseConfigBytes(raw)
	if err != nil {
		t.Fatalf("ParseConfigBytes: %v", err)
	}
	if len(cfg.CodexKey) != 2 {
		t.Fatalf("codex keys = %d, want 2", len(cfg.CodexKey))
	}
	for _, key := range cfg.CodexKey {
		pool := key.ConnectionPool
		if pool == nil {
			t.Fatalf("key %q lost its empty connection-pool block", key.APIKey)
		}
		if pool.Enabled != nil || pool.IdleConnTimeout != "" || pool.MaxIdleConnsPerHost != nil {
			t.Fatalf("key %q empty block = %+v, want unset fields", key.APIKey, pool)
		}
	}
}

// TestPerKeyConnectionPoolOverridesGroup pins per-key control inside one provider
// group: keys may switch pooling on or off independently, and a partial override keeps
// inheriting the group values it does not mention.
func TestPerKeyConnectionPoolOverridesGroup(t *testing.T) {
	raw := []byte(`config-version: 8
api-keys:
  codex:
    - name: ollama
      base-url: "https://ollama.com/v1"
      connection-pool:
        enabled: true
        idle-conn-timeout: "300s"
        max-idle-conns-per-host: 2
      keys:
        - api-key: "inherits-group"
        - api-key: "opts-out"
          connection-pool:
            enabled: false
        - api-key: "partial"
          connection-pool:
            idle-conn-timeout: "60s"
        - api-key: "null-subkey"
          connection-pool:
            idle-conn-timeout: null
            max-idle-conns-per-host: 4
        - api-key: "empty-block"
          connection-pool: {}
`)
	cfg, err := config.ParseConfigBytes(raw)
	if err != nil {
		t.Fatalf("ParseConfigBytes: %v", err)
	}
	byKey := map[string]*config.ProxyConnectionPoolConfig{}
	for i := range cfg.CodexKey {
		byKey[cfg.CodexKey[i].APIKey] = cfg.CodexKey[i].ConnectionPool
	}

	inherits := byKey["inherits-group"]
	if inherits == nil || inherits.Enabled == nil || !*inherits.Enabled || inherits.IdleConnTimeout != "300s" {
		t.Fatalf("key without an override must inherit the group block, got %+v", inherits)
	}

	optedOut := byKey["opts-out"]
	if optedOut == nil || optedOut.Enabled == nil || *optedOut.Enabled {
		t.Fatalf("per-key opt-out not honoured, got %+v", optedOut)
	}

	partial := byKey["partial"]
	if partial == nil || partial.Enabled == nil || !*partial.Enabled {
		t.Fatalf("partial override must keep the group's enabled value, got %+v", partial)
	}
	if partial.IdleConnTimeout != "60s" {
		t.Fatalf("partial override idle = %q, want 60s", partial.IdleConnTimeout)
	}
	if partial.MaxIdleConnsPerHost == nil || *partial.MaxIdleConnsPerHost != 2 {
		t.Fatalf("partial override must inherit max-idle-conns-per-host, got %+v", partial)
	}

	// An empty per-key block only overrides nothing, so it inherits the whole group block.
	empty := byKey["empty-block"]
	if empty == nil || empty.Enabled == nil || !*empty.Enabled || empty.IdleConnTimeout != "300s" {
		t.Fatalf("empty per-key block must inherit the group block, got %+v", empty)
	}

	nullSubkey := byKey["null-subkey"]
	if nullSubkey == nil || nullSubkey.Enabled == nil || !*nullSubkey.Enabled {
		t.Fatalf("null-subkey override must inherit group enabled, got %+v", nullSubkey)
	}
	if nullSubkey.IdleConnTimeout != "300s" {
		t.Fatalf("null sub-key must inherit group idle-conn-timeout 300s, got %q", nullSubkey.IdleConnTimeout)
	}
	if nullSubkey.MaxIdleConnsPerHost == nil || *nullSubkey.MaxIdleConnsPerHost != 4 {
		t.Fatalf("null-subkey override max-idle-conns-per-host = %v, want 4", nullSubkey.MaxIdleConnsPerHost)
	}
}

func TestCredentialDeduplicationPreservesDistinctConnectionPools(t *testing.T) {
	raw := []byte(`gemini-api-key:
  - api-key: "shared-gemini-key"
    base-url: "https://example.invalid"
    connection-pool:
      enabled: true
      max-idle-conns-per-host: 2
  - api-key: "shared-gemini-key"
    base-url: "https://example.invalid"
    connection-pool:
      enabled: true
      max-idle-conns-per-host: 5
  - api-key: "shared-gemini-key"
    base-url: "https://example.invalid"
    connection-pool:
      enabled: true
      max-idle-conns-per-host: 5
vertex-api-key:
  - api-key: "shared-vertex-key"
    base-url: "https://vertex.example.invalid"
    connection-pool:
      enabled: true
      max-idle-conns-per-host: 2
  - api-key: "shared-vertex-key"
    base-url: "https://vertex.example.invalid"
    connection-pool:
      enabled: true
      max-idle-conns-per-host: 6
  - api-key: "shared-vertex-key"
    base-url: "https://vertex.example.invalid"
    connection-pool:
      enabled: true
      max-idle-conns-per-host: 6
`)
	cfg, err := config.ParseConfigBytes(raw)
	if err != nil {
		t.Fatalf("ParseConfigBytes: %v", err)
	}
	if len(cfg.GeminiKey) != 2 {
		t.Fatalf("len(GeminiKey) = %d, want 2", len(cfg.GeminiKey))
	}
	if cfg.GeminiKey[0].ConnectionPool == nil || cfg.GeminiKey[0].ConnectionPool.MaxIdleConnsPerHost == nil || *cfg.GeminiKey[0].ConnectionPool.MaxIdleConnsPerHost != 2 {
		t.Fatalf("GeminiKey[0].ConnectionPool = %+v, want max-idle-conns-per-host=2", cfg.GeminiKey[0].ConnectionPool)
	}
	if cfg.GeminiKey[1].ConnectionPool == nil || cfg.GeminiKey[1].ConnectionPool.MaxIdleConnsPerHost == nil || *cfg.GeminiKey[1].ConnectionPool.MaxIdleConnsPerHost != 5 {
		t.Fatalf("GeminiKey[1].ConnectionPool = %+v, want max-idle-conns-per-host=5", cfg.GeminiKey[1].ConnectionPool)
	}
	if len(cfg.VertexCompatAPIKey) != 2 {
		t.Fatalf("len(VertexCompatAPIKey) = %d, want 2", len(cfg.VertexCompatAPIKey))
	}
	if cfg.VertexCompatAPIKey[0].ConnectionPool == nil || cfg.VertexCompatAPIKey[0].ConnectionPool.MaxIdleConnsPerHost == nil || *cfg.VertexCompatAPIKey[0].ConnectionPool.MaxIdleConnsPerHost != 2 {
		t.Fatalf("VertexCompatAPIKey[0].ConnectionPool = %+v, want max-idle-conns-per-host=2", cfg.VertexCompatAPIKey[0].ConnectionPool)
	}
	if cfg.VertexCompatAPIKey[1].ConnectionPool == nil || cfg.VertexCompatAPIKey[1].ConnectionPool.MaxIdleConnsPerHost == nil || *cfg.VertexCompatAPIKey[1].ConnectionPool.MaxIdleConnsPerHost != 6 {
		t.Fatalf("VertexCompatAPIKey[1].ConnectionPool = %+v, want max-idle-conns-per-host=6", cfg.VertexCompatAPIKey[1].ConnectionPool)
	}
}