OmniRoute/tests
Nick Sullivan 7b8055c7f8
fix(resilience): count STREAM_EARLY_EOF as a provider failure in combo routing (#9251)
* fix(resilience): count STREAM_EARLY_EOF as a provider failure in combo routing

A STREAM_EARLY_EOF is an upstream that accepted the request (HTTP 200), opened
the SSE stream, then closed it without emitting a single non-ping event. The
combo path classified it together with STREAM_READINESS_TIMEOUT through
isStreamReadinessFailureErrorBody(), and the readiness exemption in
shouldRecordProviderBreakerFailure meant the whole-provider circuit breaker
never saw it.

During a provider-wide outage that makes the breaker blind. Over a 7-day window
on our router we recorded 311 of these events, 302 of them on one model, 265
inside the upstream's published incident window — and the provider breaker sat
at CLOSED / failure_count=0 the entire time. Every request kept being dispatched
to the failing provider instead of shedding to the next combo target.

The two codes are different signals. The readiness probe is a pre-flight
liveness check on a connection we have not committed to, so failing it means
"this connection looks stale". An early EOF means the provider took the request
and then failed to serve it. The single-model path already treats it that way:
shouldTripProviderBreakerForResult has no readiness exemption, so a 502 early
EOF trips the breaker there. This makes the combo path consistent.

isStreamReadinessFailureErrorBody keeps matching both codes, because the
transient-retry and round-robin semaphore-cooldown paths in combo.ts do want
identical treatment for both. Only the breaker needs to tell them apart, so the
distinction is added as a narrow predicate and an optional argument rather than
by changing the shared classifier. Omitting the new argument reproduces the
previous behaviour exactly.

Follows the additive-override pattern established by the isProxyUnreachable
work, and leaves the existing exclusions for client aborts and plain 429s
untouched.

* test: register stream-early-eof-breaker in stryker tap.testFiles

The mutation test-coverage gate (check:mutation-test-coverage --strict)
detects unit tests that cover a mutated module but are missing from
stryker.conf.json tap.testFiles, so their mutant kills would not count.

comboPredicates.ts is one of the mutated modules, and the new
stream-early-eof-breaker.test.ts covers it, so the gate correctly flagged
the omission. 8376-econnrefused-breaker.test.ts -- the test this one is
modeled on -- is already registered; this just brings the new file in line.

No production code change.

---------

Co-authored-by: Nick Sullivan <nick@technick.ai>
Co-authored-by: diegosouzapw <8016841+diegosouzapw@users.noreply.github.com>
2026-08-04 18:07:09 -03:00
..
_helpers Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
_setup Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
benchmarks Release v3.8.2 (#2503) 2026-05-23 01:46:59 -03:00
boundary Release v3.8.47 (#6569) 2026-07-13 09:12:40 -03:00
e2e Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
fixtures Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
golden-set feat(compression): expand caveman parity and MCP metadata compression 2026-05-03 09:14:20 -03:00
helpers Fase 8 · Bloco B — suíte de correção (property + golden + SSE-correctness) (#3808) 2026-06-14 18:02:51 -03:00
homolog Add cliproxy provider exposure controls and manifest injection (#7329) 2026-07-17 03:04:00 -03:00
integration Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
live fix(security): resolve CodeQL ReDoS + URL sanitization alerts 2026-05-17 07:43:32 -03:00
llm-security Fase 8 · Bloco D — injection-guard em todas as rotas LLM + red-team (#3857) 2026-06-14 18:02:18 -03:00
load Release v3.8.45 (#6202) 2026-07-06 02:25:17 -03:00
manual Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
security feat: OmniRoute v1.0.0 — Intelligent AI Gateway & Universal LLM Proxy 2026-02-18 00:02:15 -03:00
snapshots fix(agentrouter): infer protocol from client endpoint 2026-08-02 15:10:54 -03:00
translator chore: apply PR 1495 and update changelog 2026-04-21 21:12:29 -03:00
unit fix(resilience): count STREAM_EARLY_EOF as a provider failure in combo routing (#9251) 2026-08-04 18:07:09 -03:00
_cp_mock_hook.mts Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
_cp_mock_module.mts Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
_run_dns_guard_test.sh Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00
e2e-tool-calls.sh Release v3.8.24 (#3747) 2026-06-13 17:27:40 -03:00
scratch_test.mjs refactor: implement path utilities, add custom date formatting, improve type safety, and unify database imports 2026-04-21 21:10:48 -03:00
theoldllm-stress.test.ts Release v3.8.49 (#7076) 2026-07-29 15:18:55 -03:00