litellm/tests/e2e/coverage_registry/schema.py
mubashir1osmani 28f012bb52
test(true_rabbit): cover passthrough headers, batch assume-role, gemini, vllm, bedrock guardrails, batch rate-limit mapping (#33843)
* test(e2e): cover passthrough headers, batch assume-role, gemini, vllm, bedrock guardrails, batch rate-limit mapping

Add parent-package e2e suites for the six feature gaps: pass-through header forwarding via /config/pass_through_endpoint, Bedrock batch STS assume-role, Gemini chat + files, hosted_vllm batch/files, Bedrock guardrail pre_call blocks (plus restored content-filter team opt-out), and OpenAI batch RPM 429 body mapping. Registry cells and LiteLLMParamsBody/TeamMetadata fields updated so markers collect cleanly.

* test(e2e): cover LIT-4587 gaps for redis, responses, tpm cache, apply_guardrail, langfuse

Adds customer-shaped live e2e for apply_guardrail, responses store+metadata TTL,
TPM excluding cached tokens, redis-backed RPM, redis circuit-breaker path,
Langfuse spend, Cohere chat, virtual-key auth, file content download, hosted_vllm
chat, and Nova Sonic realtime. Registry cells updated for the new markers.

* test(e2e): drive LIT-4587 gap suites on Anthropic to avoid Gemini quota flakes

Redis RPM, circuit-breaker path, virtual-key auth, responses metadata, and
Langfuse driver models now use Anthropic haiku so local runs stay green when
Gemini daily quota is exhausted.

* test(e2e): drop Langfuse spend suite; feature is being deprecated

Remove test_langfuse_e2e.py, logging.langfuse registry cells, and the
langfuse-only conftest driver/credentials fixtures.

* test(e2e): fold provider/batch feature tests into their endpoint suites

Keep the e2e layout endpoint- and suite-scoped instead of one file per
provider or feature

Move the virtual-key auth case into access_control/test_access_control_e2e.py
as TestVirtualKeyAuth (replacing an incomplete stub) and drop the standalone
test_virtual_key_auth_e2e.py

Fold the five per-file batch suites (file content, RPM 429 mapping, Bedrock
assume-role, Gemini files, hosted_vllm batch) into batches/test_batches_e2e.py.
The hosted_vllm batch case is skipped for now since it needs a live vLLM server
(HOSTED_VLLM_API_BASE) the e2e environment does not provision; it and the
gemini-files and RPM-mapping cases reference LIT-3382 / LIT-3266 where relevant

Merge the cohere, gemini and hosted_vllm chat cases into
llm_translation/test_chat_completions_regression_e2e.py so /chat/completions
coverage lives in one endpoint file, and repoint the coverage_registry source
fields to the new homes

Move the shared CacheControl / TextBlock / RichMessage request blocks into the
root models.py (re-exported from endpoints_client) so quota_management can use
them without a cross-suite import, which also clears the basedpyright errors in
test_tpm_excludes_cached_tokens_e2e.py; type the httpbin echo body in
test_passthrough_headers_e2e.py with a pydantic model to drop the Any-typed
json.loads path

* test(e2e): address review feedback and re-home virtual-key coverage

Replace the tautological Bedrock assume-role batch id assertion (`startswith(...)
or batch.id`, always true) with a managed-id shape check, since the unified
target_model_names path re-encodes the id rather than returning a raw ARN

Raise the batch RPM-mapping test's rpm_limit above one so the file upload can no
longer consume the key's sole request unit before batch create runs; the batch
create then clears the generic per-request limiter and the batch limiter is what
returns the "Batch rate limit exceeded" body the assertions check

Set exercised_on to [] on the pass-through header test; it drives a pass-through
endpoint, not /chat/completions

Move the virtual-key valid_allows / invalid_denied cells from other.yaml to
mgmt.yaml as mgmt.virtual_key.* so TestVirtualKeyAuth rolls up under Management,
and point its covers marker at the new ids
2026-07-20 16:15:55 -07:00

205 lines
4.4 KiB
Python

"""Registry row schema: the contract every denominator cell validates against.
A cell is one customer-noticeable behavior a single e2e test can assert pass/fail
on. `module` is the id's segment-1 prefix (eight of them); dashboard rollups can
split or merge those prefixes. The union is discriminated on `module`, so an LLM
row cannot carry a guardrail field and vice versa.
"""
from __future__ import annotations
from enum import Enum
from typing import Annotated, Literal
from pydantic import BaseModel, ConfigDict, Field, TypeAdapter
class Tier(str, Enum):
P0 = "P0"
P1 = "P1"
P2 = "P2"
class FailBeforeFix(str, Enum):
proven = "proven"
unproven = "unproven"
LlmEndpoint = Literal[
"chat_completions",
"messages",
"responses",
"embeddings",
"batches",
"files",
"rerank",
"images_generations",
"audio_speech",
"audio_transcriptions",
"moderations",
"realtime",
]
LlmRoute = Literal[
"anthropic",
"azure_foundry",
"azure_openai",
"bedrock_converse",
"bedrock_invoke",
"cohere",
"gemini",
"hosted_vllm",
"openai",
"together_ai",
"vertex",
]
LlmCapability = Literal[
"assume_role",
"basic",
"count_tokens",
"long_context_1m",
"mid_conversation_system",
"pdf_input",
"prompt_cache_1h",
"prompt_cache_5m",
"service_tier",
"structured_output",
"thinking",
"thinking_with_tool_use",
"tool_search",
"tool_use",
"vision",
"web_search",
]
class _Base(BaseModel):
model_config = ConfigDict(frozen=True, extra="forbid")
id: str
tier: Tier
assertions: tuple[str, ...]
source: str
rationale: str = ""
fail_before_fix: FailBeforeFix = FailBeforeFix.unproven
supported: bool = True
class LlmCell(_Base):
module: Literal["llm"]
subject_endpoint: LlmEndpoint
route: LlmRoute
capability: LlmCapability
streaming: Literal["stream", "nonstream", "na"]
class MgmtCell(_Base):
module: Literal["mgmt"]
surface: Literal["api", "ui"]
class McpCell(_Base):
module: Literal["mcp"]
operation: str
auth_family: Literal["none", "api_key", "bearer", "oauth"]
class ReliabilityCell(_Base):
module: Literal["reliability"]
behavior: str
variant: str
exercised_on: tuple[str, ...]
class QuotaCell(_Base):
module: Literal["quota_management"]
behavior: Literal["ratelimit", "budget", "spend_tracking"]
variant: str
exercised_on: tuple[str, ...]
class LoggingCell(_Base):
module: Literal["logging"]
event: str
exercised_on: tuple[str, ...]
class GuardrailCell(_Base):
module: Literal["guardrail"]
hook_point: str
exercised_on: tuple[str, ...]
class OtherCell(_Base):
module: Literal["other"]
area: str
Cell = Annotated[
LlmCell
| MgmtCell
| McpCell
| ReliabilityCell
| QuotaCell
| LoggingCell
| GuardrailCell
| OtherCell,
Field(discriminator="module"),
]
CELL_ADAPTER: TypeAdapter[Cell] = TypeAdapter(Cell)
CORE_LLM_ENDPOINTS: frozenset[str] = frozenset(
{
"chat_completions",
"messages",
"responses",
}
)
PREFIX_ROLLUP: dict[str, str] = {
"mcp": "MCPs",
"mgmt": "Management/UI",
"reliability": "Reliability & Performance",
"quota_management": "Quota Management",
"logging": "Logging & Guardrails",
"guardrail": "Logging & Guardrails",
"other": "Other",
}
MODULE_ORDER: tuple[str, ...] = (
"Core LLMs",
"Non-Core LLMs",
"MCPs",
"Management/UI",
"Reliability & Performance",
"Quota Management",
"Logging & Guardrails",
"Other",
)
LOKI_MODULE_LABELS: dict[str, str] = {
"Core LLMs": "core_llms",
"Non-Core LLMs": "non_core_llms",
"MCPs": "mcp",
"Management/UI": "management_ui",
"Reliability & Performance": "reliability_performance",
"Quota Management": "quota_management",
"Logging & Guardrails": "logging_guardrails",
"Other": "other",
}
def dashboard_module(cell: Cell) -> str:
"""Return the Grafana/reporting module for a registry cell."""
if isinstance(cell, LlmCell):
if cell.subject_endpoint in CORE_LLM_ENDPOINTS:
return "Core LLMs"
return "Non-Core LLMs"
return PREFIX_ROLLUP[cell.module]
def loki_module_label(module: str) -> str:
"""Return the log-safe Loki label for a dashboard module."""
return LOKI_MODULE_LABELS[module]