mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-22 06:06:59 +00:00
test: integration suite with real Traefik, redis-shared limits, streaming assertions
Adds integration/ (separate module): docker compose stack with real Traefik v3.5 + localPlugins, mock openai/anthropic/gemini/tool providers, shared Redis, and a raw-TCP streaming timing probe. 6/7 tests pass; streaming incrementality fails on a confirmed external yaegi/Traefik bug (see task-15-report.md), not a plugin defect. Fixes 4 real Yaegi-interpretation bugs surfaced by running the plugin under real Traefik for the first time (none caught by go test or yaegi-check, which never exercises chat/embeddings/streaming/Redis): - .traefik.yml: add basePkg (Traefik derives the yaegi binding identifier from the module path, not the package's own declared name; without this override the plugin never loads at all). - registry.go: resolveAgainst's multi-value return panicked yaegi on an inline string concatenation; assign to a local first. - routes_unified.go: errors.As panicked yaegi on interpreted pointer error types; use plain type assertions (both types are always returned bare, never wrapped). - sse.go: readSSE's dispatch closure hit the same multi-value-assignment panic as registry.go; split into separate statements. - resp.go: respErr as a defined string type was indistinguishable from a plain string in a yaegi type assertion, misreading every successful Redis SELECT reply as failed and silently disabling rate limiting; changed to a struct.
This commit is contained in:
+12
-1
@@ -368,7 +368,18 @@ func (m *modelRegistry) resolveAgainst(providerName, upstreamModel, requestedID
|
||||
if !allowed || !grp.allowsProvider(providerName) {
|
||||
return nil, "", "", errModelDenied
|
||||
}
|
||||
return m.adapters[providerName], upstreamModel, providerName + "/" + upstreamModel, nil
|
||||
// canonical is assigned to a local before the return, not inlined into
|
||||
// it: yaegi v0.16.1 panics ("reflect.Set: value of type
|
||||
// interp.valueInterface is not assignable to type string") building a
|
||||
// multi-value return tuple when one element is an inline string
|
||||
// concatenation of two parameters. The identical expression assigned
|
||||
// to a variable first, then returned, does not trigger it. Verified
|
||||
// empirically against yaegi v0.16.1 running this exact function under
|
||||
// real Traefik (Task 15's integration suite) — tools/yaegi-check never
|
||||
// exercises this call path (it only drives GET /v1/models), which is
|
||||
// why the existing yaegi gate never caught it.
|
||||
canonical := providerName + "/" + upstreamModel
|
||||
return m.adapters[providerName], upstreamModel, canonical, nil
|
||||
}
|
||||
|
||||
// warnCollisionOnce logs, at most once per colliding bare id for this
|
||||
|
||||
Reference in New Issue
Block a user