mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-20 05:56:56 +00:00
test: testify table-driven coverage for low-coverage branches
Lifts all 14 functions the operator flagged as <75% (measured at ed2119c)
to >=75%, using table-driven tests (require for fatals, assert for checks):
- limits.go: failPolicyGet (50.0% -> 100.0%)
- provider_gemini.go: httpClient (0.0% -> 100.0%)
- redis_store.go: get (71.4% -> 78.6%)
- resp.go: dialTimeoutFor, respDeadlineExceededErr.{Error,Timeout,Temporary},
ensureConnLocked, getBatch (66.7-30.0% -> 91.3-100.0%)
- routes_media.go: resolveMediaRequest (50.0% -> 100.0%)
- routes_unified.go: unifiedCostMicros (66.7% -> 100.0%)
- translate_anthropic.go: isTruthy, toFloat64 (50.0/33.3% -> 100.0%)
- translate_gemini.go: geminiToolConfigFromOpenAI (66.7% -> 100.0%)
resp_test.go adds a hand-rolled fakeConn (net.Conn with injectable
Write/SetDeadline errors) to reach two respClient error branches a real
TCP connection cannot be coaxed into deterministically.
Total coverage: 90.7% -> 92.4% (no regression; report has the full
per-file table). Zero production-code changes. Existing tests untouched:
every diff is a pure addition of new test functions and their imports.
Gates: go test -count=1 (pass), -race (pass, 5x incl. an isolated
baseline-vs-branch comparison after one flaky run implicated pre-existing
registry_test.go timing tests this task never touched), gofmt/vet (clean),
golangci-lint incl. gosec and fieldalignment (0 issues), make yaegi-check
(OK), make integration (pass, untouched-green).
This commit is contained in:
@@ -17,6 +17,8 @@ import (
|
||||
"sync"
|
||||
"testing"
|
||||
"time"
|
||||
|
||||
"github.com/stretchr/testify/assert"
|
||||
)
|
||||
|
||||
// newUnifiedRequest builds a POST request against the unified routes,
|
||||
@@ -1609,3 +1611,48 @@ func TestCacheCaptureWriter_ImplicitStatus_CapturesContentType(t *testing.T) {
|
||||
t.Errorf("contentType = %q, want %q (must be captured on the implicit-200 path too)", cw.contentType, "application/json")
|
||||
}
|
||||
}
|
||||
|
||||
// TestUnifiedCostMicros covers ruling (d)'s two-id price lookup order:
|
||||
// canonical ("provider/model") first, falling back to bare — the upstream
|
||||
// model id alone — only when canonical has no configured price at all, in
|
||||
// neither overrides nor the built-in table.
|
||||
func TestUnifiedCostMicros(t *testing.T) {
|
||||
u := usage{prompt: 1_000_000, completion: 1_000_000}
|
||||
|
||||
cases := []struct {
|
||||
overrides map[string]*ModelPricing
|
||||
name string
|
||||
canonical string
|
||||
bare string
|
||||
want int64
|
||||
}{
|
||||
{
|
||||
name: "canonical override price wins over bare",
|
||||
canonical: "openai/gpt-5",
|
||||
bare: "gpt-5",
|
||||
overrides: map[string]*ModelPricing{
|
||||
"openai/gpt-5": {InputPerM: 1, OutputPerM: 2},
|
||||
},
|
||||
want: 3_000_000, // (1M prompt * $1/M) + (1M completion * $2/M), in micros
|
||||
},
|
||||
{
|
||||
name: "canonical unpriced falls back to bare's built-in price",
|
||||
canonical: "unknown-provider/gpt-5",
|
||||
bare: "gpt-5",
|
||||
overrides: nil,
|
||||
want: costMicros("gpt-5", u, nil),
|
||||
},
|
||||
{
|
||||
name: "neither id priced returns zero",
|
||||
canonical: "unknown-provider/unknown-model",
|
||||
bare: "unknown-model",
|
||||
overrides: nil,
|
||||
want: 0,
|
||||
},
|
||||
}
|
||||
for _, c := range cases {
|
||||
t.Run(c.name, func(t *testing.T) {
|
||||
assert.Equal(t, c.want, unifiedCostMicros(c.canonical, c.bare, u, c.overrides))
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user