mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-20 05:56:56 +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:
@@ -0,0 +1,91 @@
|
||||
http:
|
||||
routers:
|
||||
llmgateway-router:
|
||||
rule: "PathPrefix(`/`)"
|
||||
entryPoints: ["web"]
|
||||
service: dummy-service
|
||||
middlewares: ["llmgateway"]
|
||||
priority: 1
|
||||
|
||||
llmgateway-real-router:
|
||||
rule: "Host(`real.localhost`)"
|
||||
entryPoints: ["web"]
|
||||
service: dummy-service
|
||||
middlewares: ["llmgateway-real"]
|
||||
priority: 100
|
||||
|
||||
services:
|
||||
# Placeholder upstream. Every route the plugin recognizes is
|
||||
# short-circuited by the middleware itself; this backend is never
|
||||
# actually reached by the requests the integration suite sends.
|
||||
dummy-service:
|
||||
loadBalancer:
|
||||
servers:
|
||||
- url: "http://mockopenai:8080"
|
||||
|
||||
middlewares:
|
||||
llmgateway:
|
||||
plugin:
|
||||
llmgateway:
|
||||
providers:
|
||||
openai:
|
||||
type: openai
|
||||
baseUrl: "http://mockopenai:8080"
|
||||
apiKey: "mock-openai-key"
|
||||
discovery: true
|
||||
models: ["gpt-mock"]
|
||||
anthropic:
|
||||
type: anthropic
|
||||
baseUrl: "http://mockanthropic:8080"
|
||||
apiKey: "mock-anthropic-key"
|
||||
models: ["claude-mock"]
|
||||
gemini:
|
||||
type: gemini
|
||||
baseUrl: "http://mockgemini:8080"
|
||||
apiKey: "mock-gemini-key"
|
||||
models: ["gemini-mock"]
|
||||
groups:
|
||||
eng:
|
||||
limits:
|
||||
requestsPerMinute: 1000
|
||||
limited:
|
||||
limits:
|
||||
requestsPerMinute: 3
|
||||
users:
|
||||
inline:
|
||||
- name: alice
|
||||
group: eng
|
||||
apiKey: "sk-int-alice"
|
||||
file: "/users/users.json"
|
||||
redis:
|
||||
address: "redis:6379"
|
||||
mcpServers:
|
||||
tool:
|
||||
url: "http://mocktool:8080"
|
||||
|
||||
# Second, separate middleware instance carrying only the optional
|
||||
# real-upstream smoke test's "uni" provider (task 7, INTEGRATION_REAL=1
|
||||
# gated). Kept isolated from the mock-backed "llmgateway" middleware
|
||||
# above so the always-on tests never depend on network egress.
|
||||
llmgateway-real:
|
||||
plugin:
|
||||
llmgateway:
|
||||
providers:
|
||||
uni:
|
||||
type: openai
|
||||
baseUrl: "https://llmgw.example.com"
|
||||
apiKey: ""
|
||||
# Explicit rather than discovered: resolution must not depend
|
||||
# on this container reaching the real upstream at Traefik
|
||||
# startup (offline dev machines, CI with no egress). The
|
||||
# actual chat completion call in task 7 still goes out live.
|
||||
models: ["deepseek-v4-flash-0731"]
|
||||
groups:
|
||||
eng:
|
||||
limits:
|
||||
requestsPerMinute: 1000
|
||||
users:
|
||||
inline:
|
||||
- name: alice-real
|
||||
group: eng
|
||||
apiKey: "sk-int-real"
|
||||
@@ -0,0 +1,18 @@
|
||||
entryPoints:
|
||||
web:
|
||||
address: ":80"
|
||||
|
||||
experimental:
|
||||
localPlugins:
|
||||
llmgateway:
|
||||
moduleName: github.com/lukaszraczylo/traefik-llmgateway
|
||||
|
||||
providers:
|
||||
file:
|
||||
filename: /etc/traefik/dynamic.yml
|
||||
watch: true
|
||||
|
||||
log:
|
||||
level: INFO
|
||||
|
||||
accessLog: {}
|
||||
Reference in New Issue
Block a user