mirror of
https://github.com/lukaszraczylo/traefik-llmgateway.git
synced 2026-10-17 05:37:43 +00:00
fix(integration): green gate with tracked streaming skip, gemini coverage, robust probe
Addresses coordinator review of the Task 15 integration suite: 1 critical ruling, 5 important, 3 folded. make integration now exits 0. - integration_test.go: TestStreamingIncrementalityProbe restructured — content assertion (5 deltas + [DONE], in order) always runs; the raw-TCP timing assertion (unchanged, >=3 gaps >=100ms) is gated behind INTEGRATION_STREAMING=1 with t.Skipf naming traefik/traefik#10269, verified to still genuinely fail when re-armed (not silently disabled). - Makefile: integration-up/integration-wait moved from prerequisites into the integration recipe body as go test ./... -count=1 ok github.com/lukaszraczylo/traefik-llmgateway 6.065s sub-invocations with per-stage status capture, so integration-down always runs even when bring-up or the health wait fails; verified with a synthetic failure. Added .NOTPARALLEL (the integration targets are stateful). - translate_gemini.go: fixed the same yaegi multi-value-assignment panic shape as the prior sse.go fix, on the live max_tokens path. Added a gemini chat completion assertion to integration_test.go (renamed TestUnifiedChatAllProviders) so this path now runs under real Yaegi. - providers.go, translate_anthropic.go: documented the never-wrap contract on providerHTTPError/translateError (routes_unified.go asserts their concrete type directly; errors.As panics under yaegi on these). - integration_test.go: TestCrossReplicaLimits now FLUSHALLs Redis first, for idempotence under integration-keep. - mock/main.go: probe's header-terminator search now accumulates a rolling buffer across reads instead of only checking the latest one. - Folded: hot-reload deadline 10s -> 20s; dynamic.yml's real-upstream baseUrl is now a template (dynamic.yml.tmpl) rendered via INTEGRATION_REAL_BASEURL (default https://llmgw.example.com), not a hardcoded-only hostname. See task-15-report.md's addendum for full verification detail.
This commit is contained in:
@@ -341,6 +341,7 @@ func runProbe(target, apiKey, model string) int {
|
||||
}
|
||||
|
||||
var arrivals []time.Time
|
||||
var headerBuf []byte
|
||||
buf := make([]byte, 4096)
|
||||
headerDone := false
|
||||
for {
|
||||
@@ -348,12 +349,22 @@ func runProbe(target, apiKey, model string) int {
|
||||
if n > 0 {
|
||||
chunk := buf[:n]
|
||||
if !headerDone {
|
||||
if idx := bytes.Index(chunk, []byte("\r\n\r\n")); idx >= 0 {
|
||||
headerDone = true
|
||||
chunk = chunk[idx+4:]
|
||||
} else {
|
||||
chunk = nil
|
||||
// The "\r\n\r\n" header/body terminator is not guaranteed to
|
||||
// land inside a single Read: accumulate every read into a
|
||||
// rolling buffer and search that, not just the latest
|
||||
// chunk, so a terminator split across two reads is still
|
||||
// found instead of silently discarding both reads' bytes.
|
||||
headerBuf = append(headerBuf, chunk...)
|
||||
idx := bytes.Index(headerBuf, []byte("\r\n\r\n"))
|
||||
if idx < 0 {
|
||||
if readErr != nil {
|
||||
break
|
||||
}
|
||||
continue
|
||||
}
|
||||
headerDone = true
|
||||
chunk = headerBuf[idx+4:]
|
||||
headerBuf = nil
|
||||
}
|
||||
if len(chunk) > 0 && bytes.Contains(chunk, []byte("data:")) {
|
||||
arrivals = append(arrivals, time.Now())
|
||||
|
||||
Reference in New Issue
Block a user