litellm/tests/e2e/coverage_registry
Devin AI a6759ff3c3 docs(e2e): cite the Datadog schema source and scope the health row
Co-Authored-By: bot_apk <apk@cognition.ai>
2026-09-19 00:50:20 +00:00
..
__init__.py test(e2e): add coverage registry and collector (#32304) 2026-07-07 15:51:20 -04:00
collector.py fix(e2e-changed): keep the gate off suites the stack cannot run 2026-09-05 21:03:50 -07:00
guardrail.yaml test(guardrails): pin the presidio spend-log record and the UI's masked-entity persistence 2026-09-06 00:43:13 -07:00
llm_claude_code_compat.yaml test(e2e): replay a real tool-search assistant turn back to Bedrock Invoke (#36856) 2026-08-17 11:59:26 -07:00
llm_conversational.yaml test(e2e): cover Together reasoning_effort=none, json_schema, and cache-read pricing 2026-08-28 12:49:09 -07:00
llm_nonconversational.yaml test(e2e): cover bedrock batch files in govcloud 2026-09-17 20:16:09 +00:00
logging.yaml test(e2e): add logging e2e coverage (s3_v2, gcs_bucket, team langfuse callback, datadog failure) (#38552) 2026-08-29 09:43:44 -07:00
management_cases.py test: enforce isolated actors and stop OIDC process groups 2026-09-12 13:49:49 -07:00
mcp.yaml test(mcp): consolidate principal and Datadog regression coverage 2026-09-17 17:32:45 -07:00
mgmt.yaml fix(proxy): stop team admins raising an org team's max_budget under the org cap 2026-09-16 17:35:18 -07:00
other.yaml test(e2e): harden JWT fixtures and cover management lifecycles 2026-09-11 16:36:12 -07:00
quota_management.yaml test(e2e): register the poller batch cost join as its own uncovered cell 2026-09-09 16:23:45 -07:00
README.md docs(e2e): cite the Datadog schema source and scope the health row 2026-09-19 00:50:20 +00:00
registry.py ci: gate tests/e2e on zero basedpyright errors in pre-commit and lint CI 2026-07-11 10:25:22 -07:00
reliability.yaml chore: merge litellm_internal_staging into litellm_e2e_reliability_module_cells 2026-09-12 13:05:02 -07:00
schema.py test(e2e): cover bedrock batch files in govcloud 2026-09-17 20:16:09 +00:00
test_collector.py fix(e2e): exclude skipped tests from coverage-registry numerator 2026-07-30 22:19:30 -07:00

e2e coverage registry

This directory is the denominator for e2e test coverage: the set of behaviors we want covered, one row per behavior, checked into the repo so coverage is a number we can track instead of a guess. It implements the plan in the "E2E Coverage Tracking" note; the naming grammar lives in tests/e2e/CLAUDE.md.

The model

A cell is one customer-noticeable behavior a single e2e test can assert pass/fail on, for example llm.chat_completions.bedrock_converse.tool_use.stream.works. Cells are grouped module > feature > test, with LLM cells split into Core LLMs and Non-Core LLMs for dashboarding. Each cell carries a tier (P0/P1/P2), a source, and a fail_before_fix flag.

The rows live in per-prefix YAML files (llm_*.yaml, mgmt.yaml, mcp.yaml, reliability.yaml, quota_management.yaml, logging.yaml, guardrail.yaml, other.yaml) and validate against the discriminated union in schema.py, so an LLM row cannot carry a guardrail field and vice versa. llm rows with subject_endpoint of chat_completions, messages, or responses roll up to Core LLMs; all other LLM endpoints roll up to Non-Core LLMs. LLM endpoint, route, and capability values are typed in schema.py, so new taxonomy values require an explicit schema change. logging and guardrail are two id-prefixes that roll up into the single Logging & Guardrails dashboard module.

A test declares what it covers with a marker:

@pytest.mark.covers("llm.chat_completions.openai.tool_use.stream.works")
def test_openai_streaming_tool_calls(self) -> None:
    ...

The number

collector.py diffs the registry against those markers and reports coverage per module. It is static: a collect-only pass reads the markers, so it runs no test and needs no live proxy. Whether a covered cell currently passes or fails is a separate, live concern.

A skipped test asserts nothing, so its markers do not count. A cell is covered only when at least one test pytest would actually run declares it; a cell claimed by both a live test and a skipped one stays covered. Skip state comes from pytest's own evaluator, so skip and skipif resolve exactly as they do in the e2e run, which also means a skipif on an absent credential makes that cell uncovered in the environments where the test cannot run. Cells left uncovered this way are listed under the headline (and counted by litellm_e2e_coverage_skipped_markers) so an unskipped-pending gap is visible rather than inflating the number. The one skip the collector cannot see is pytest.skip() called from inside a test body, since it does not exist until the test runs.

cd tests/e2e && PYTHONPATH=. python -m coverage_registry.collector

Use --format loki after the e2e pytest run in the same Kubernetes job/pod to print structured stdout lines for Loki:

cd tests/e2e && PYTHONPATH=. python -m coverage_registry.collector --format loki --strict

This emits exactly one COVERAGE_TOTAL line and one COVERAGE_MODULE line per module in MODULE_ORDER, in that order. Loki uses log-safe module= labels from LOKI_MODULE_LABELS (core_llms, management_ui, etc.) so existing JSON and Prometheus consumers keep their human-readable module names unchanged.

The headline is overall coverage. The collector also lists markers that point at ids not in the registry, so a typo or an unenumerated behavior surfaces instead of being silently dropped.

Use strict mode in CI once existing draft markers are reconciled:

cd tests/e2e && PYTHONPATH=. python -m coverage_registry.collector --strict

Strict mode exits non-zero on @pytest.mark.covers(...) ids that are not checked into the registry. Add --fail-on-collection-errors when the job should also fail on pytest collection errors.

Provider x feature matrix: customer-run Bedrock combinations

The provider and feature combinations customers actually run get explicit cells, expanded here as incidents surface new ones. The current Bedrock set, seeded from a customer's production shape (regional us.anthropic.* inference-profile ids over both chat routes, provider response headers for AWS-side correlation, and the Test Connection probe for a responses-mode Bedrock Mantle deployment):

Cell Feature Covering test
llm.chat_completions.bedrock_converse.basic.nonstream.works regional us. id, Converse llm_translation/test_chat_completions_regression_e2e.py
llm.chat_completions.bedrock_converse.basic.stream.works regional us. id, Converse stream llm_translation/test_chat_completions_regression_e2e.py
llm.chat_completions.bedrock_invoke.basic.nonstream.works regional us. id, Invoke llm_translation/test_bedrock_provider_matrix_e2e.py
llm.chat_completions.bedrock_invoke.basic.stream.works regional us. id, Invoke stream llm_translation/test_bedrock_provider_matrix_e2e.py
llm.chat_completions.bedrock_converse.response_headers.nonstream.works llm_provider-* headers llm_translation/test_bedrock_provider_matrix_e2e.py
llm.chat_completions.bedrock_converse.response_headers.stream.works llm_provider-* headers, stream llm_translation/test_bedrock_provider_matrix_e2e.py
mgmt.model.test_connection.happy_path Test Connection, Bedrock Mantle management/test_model_test_connection_e2e.py

Status: this is a draft for review

The cells were enumerated from the codebase and the tiers are a first proposal. Known things to settle before treating the set as final:

  • tiers are proposed, not signed off; 125 P0 is a lot to prove fail-before-fix, so P0 may want tightening
  • a few cells need a support check or a prune (for example llm.embeddings.anthropic.* and reliability.perf.throughput.under_slo)
  • auth is covered in two places (other.auth.* and the mgmt authz assertions); the boundary needs a decision, and the auth cluster may deserve promotion to its own module
  • the P2 "niche" cells each stand in for a large tail of integrations/providers by design, so the denominator is deliberately P0-weighted rather than a full inventory

MCP migration acceptance (LIT-4506)

This matrix tracks the ten security/compatibility guards and the added JWT acceptance criteria. Registry membership means a desired behavior, not a passing execution record. Preserve the source/harness commits, SDK version, auth and transport topology, executed node IDs and live results with each PR. A skipped or unexecuted case remains pending. Integration contract IDs belong in tests/integration/contracts.json, not mcp.yaml; links below connect the two suites without merging their namespaces

Requirement Existing regression or owning suite Remaining acceptance and owner Required before
Principal discovery mcp/test_mcp_key_access_e2e.py, mcp/test_mcp_access_group_e2e.py, mcp/test_mcp_toolset_enforcement_e2e.py Run key/team/org/user controls on every configured replica; the E2E health check intersects with test-owned servers and proves grant visibility only, non-disclosure of unrelated servers is proven by integration contract other.mcp.health.restricted_keys_intersect_grants_in_both_modes (#41731); native/REST parity remains LIT-4506 Phase 0 and affected authorization changes
No self-attached unauthorized grants Management key authorization tests Read back unchanged server/toolset/access-group grants after rejected writes, LIT-4502 Affected grant capability activation
UI/API parity Admin MCP UI suite Same non-admin actor and permissions across both surfaces, LIT-3644 / LIT-4506 Affected UI capability activation
Server identity routing Saved-server lifecycle integration and resolver tests Cold routing, duplicate/unprefixed names, LIT-4500 Routing changes
Same-URL credential isolation Outbound credential resolver subject/server tests Observe distinct user/server credentials at actual upstream transport, LIT-4506 with LIT-3467 / LIT-3559 Affected auth capability activation
Fail-closed credentials LIT-4501 production-path tests; integration lifecycle owns warm credential-removal follow-up Observe rejection and zero upstream calls after persisted removal; refresh/challenge work remains LIT-4436 / LIT-4422 / LIT-3433 Phase 0 auth release
Upstream session continuity Existing controlled integration peer is stateless Observe upstream session ID across operations, LIT-3143 Stateful upstream activation
Real hooks/guardrails mcp/test_mcp_guardrail_e2e.py, LIT-4889 production-path tests Request-selected direct/virtual pre-call guard integration and removal of void assertions, LIT-4506 Phase 0 and changed guardrail paths
Discovery and execution permissions Key-denial and principal-toolset E2E; integration/compatibility/test_persisted_toolsets.py Preserve permitted calls and explicit denial, expand remaining protocol combinations, LIT-4506 Every authorization migration
Stateless/stateful combinations Stateless SDK-peer integration Explicit incoming/outgoing combinations and supported versions, LIT-3143 / LIT-3559 Affected transport activation
JWT canonical owner and restart LIT-3794 / LIT-3795 merged regressions Real process restart, cold cache, header precedence, expired/invalid JWT and inactive user, LIT-4506 Applicable Phase 0 auth release
No gateway JWT upstream Existing credential resolver/unit evidence Observe actual upstream headers across users and same-URL servers, LIT-4506 Applicable Phase 0 auth release
Uninterrupted OAuth and aggregate SSO mcp/test_mcp_chat_completion_oauth_e2e.py Immediate SDK continuation and aggregate SSO, LIT-3467 with LIT-4506 acceptance; missing browser login is not a pass Applicable Phase 0 auth release

The initial package does not close LIT-4506. Recheck all applicable rows before the execution plan's final acceptance step. Keep protocol conformance, canary and rollback evidence with their owners; a static registry percentage cannot authorize rollout

The E2E consolidation incorporates PR #34055's inventory and PR #35405's remaining Datadog input-schema guard. The telemetry argument removal and unskipping already landed in #38640. LIT-5052 requires the schema guard and all three affected real-Datadog tests, including seeded completion retrieval, to pass before closure. LIT-5749's runtime fix already landed in #38488; the principal tests add regression evidence