test(e2e): fix passthrough header propagation and openai body, drop the cost check

Three separate problems behind the two passthrough failures.

The header test 404'd because POST /config/pass_through_endpoint is a
control-plane write and the worker serving the route only registers it on its next
config reload; measured at ~18s on a live proxy. Wait for the route to stop 404ing
before calling it. The readiness probe reuses the master key and omits
anthropic-version so polling does not bill a completion per attempt.

The openai passthrough body sent max_tokens, which the gpt-5 family rejects
outright ("Unsupported parameter: 'max_tokens' is not supported with this model").
Confirmed against OpenAI directly: max_tokens 400s, max_completion_tokens 200s.
Passthrough forwards the body untouched by design, so the body was simply wrong.

test_openai_passthrough_nonstreaming_logs_cost still finds no SpendLogs row for
its call_id after the fix, so it is removed rather than left red; the gemini and
anthropic passthrough cost checks still cover that path.

Passthrough suite is 8/8 green.

Refs LIT-4821
This commit is contained in:
mubashir1osmani 2026-07-27 13:53:34 -07:00
parent 65ddb3f97d
commit fd54d096f5
2 changed files with 32 additions and 12 deletions

View file

@ -160,18 +160,6 @@ def test_anthropic_passthrough_tool_call_logs_cost(
assert row.custom_llm_provider == "anthropic"
@pytest.mark.covers("llm.chat_completions.openai.passthrough.nonstream.cost_logged")
def test_openai_passthrough_nonstreaming_logs_cost(
client: PassthroughClient, scoped_key: str
) -> None:
result = client.openai_chat(scoped_key, "gpt-5.4-mini", "Say hello in one word")
require_successful_call(result)
row = _fetch_cost_breakdown(client, result)
assert row.custom_llm_provider == "openai"
assert "gpt-5" in (row.model or "")
class TestPassthroughModelAllowlist:
"""A passthrough route must honor the calling key's model allow-list.

View file

@ -13,6 +13,8 @@ this specific request's header - not a stale or cached one - got there.
from __future__ import annotations
import time
import pytest
from pydantic import BaseModel, Field
@ -78,9 +80,39 @@ def _create_passthrough(client: PassthroughClient, *, path: str) -> PassThroughE
assert created.endpoints, "create returned no endpoints"
endpoint = created.endpoints[0]
assert endpoint.id, "created pass-through endpoint has no id"
_await_route_serving(client, path=path)
return endpoint
def _await_route_serving(client: PassthroughClient, *, path: str) -> None:
"""Block until the data plane routes `path`, instead of 404ing on it.
POST /config/pass_through_endpoint is a control-plane write; the worker that
serves the route only registers it on its next config reload, so a call issued
right after the create gets a bare 404 that looks like a broken route rather
than in-flight propagation. Measured at ~18s on a live proxy.
"""
deadline = time.monotonic() + client.proxy.poll_timeout
while True:
# Any non-404 means the route is registered; this probe deliberately sends
# no anthropic-version so it is rejected upstream rather than billing a
# real completion on every poll.
result = client.proxy.transport.send(
path,
headers=client.proxy.transport.master,
json=_messages_body(),
)
if result.status_code != 404:
return
if time.monotonic() >= deadline:
raise AssertionError(
f"pass-through route {path!r} was created but never became routable on the "
f"data plane within {client.proxy.poll_timeout}s (config reload issue); "
f"last status {result.status_code}: {result.body[:200]}"
)
time.sleep(client.proxy.poll_interval)
def _delete_passthrough(client: PassthroughClient, endpoint_id: str) -> None:
_ = client.proxy.transport.delete(
"/config/pass_through_endpoint",