litellm/litellm
yuneng-jiang 4b3355bdc6
test(e2e): prove the virtual key lifecycle on every gateway replica (#40023)
* test(e2e): prove the virtual key lifecycle on every replica

Walks one virtual key through create, read, partial update, clear, enforce
and delete against a live proxy and database, reading every write back on
every gateway replica.

The management suite already had single write-then-read tests for keys, but
none of them proved that a partial /key/update leaves the untouched fields
alone, that an explicit null clears a field, or that a write is visible on
more than the one gateway that took it.

Adds read_back_everywhere to the shared ProxyClient: it polls a GET path on
every URL in PROXY_REPLICA_URLS until each replica's parsed body satisfies
the caller's predicate, and fails naming the replica that never converged.
The CLEAR sentinel in the e2e models makes an explicit JSON null expressible
in a body the transport otherwise strips of None fields.

Documents /key/update's merge patch semantics on the endpoint docstring.

* test(e2e): prove key revocation and field preservation on every replica

Applies the findings from an adversarial review of the first commit.

The delete step only checked that chat was refused on the gateway that took
the write, so it would have passed while a sibling gateway kept serving the
deleted key. It now serves one call from every replica first, so each has the
key cached and the delete has something to revoke everywhere, then polls every
replica for the refusal.

The file also carried its own poll loop that tested the deadline before
attempting, so it gave up one attempt early and skipped the attempt landing
exactly on the deadline. It now shares the harness helper, which is generic
over the polled value rather than over a parsed body, so the same loop covers
both the info read-back and the chat refusal.

The model the enforcement step registers now carries a unique marker in its
alias, matching every other deployment this suite creates, so concurrent runs
never share one model group.

The docstring sentence claimed an explicit null clears any field. It does not:
the metadata-backed fields merge into stored metadata, where a null is a silent
no-op, and only the key's own columns clear. Regenerating the dashboard types
picks up the corrected text.

* fix(e2e): delete a deployment that never becomes servable

Registering a model posts /model/new and then waits for every replica to list
it. When that wait timed out the deployment already existed in the database but
its id had never been returned, so no caller could delete it and the row
outlived the run. It is now deleted before the failure propagates.

Found by review on the key lifecycle suite, whose module fixture registers a
deployment this way, but every caller of the shared helper had the same
exposure.

* docs(e2e): drop the duplicated notes from the lifecycle docstrings

The delete method restated what the warm-up helper already explains, and the
module restated the merge patch rule that the endpoint and the request model
both document.
2026-09-07 11:30:46 -07:00
..
a2a_protocol Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5_r4 2026-09-02 23:32:10 +00:00
anthropic_interface fix(anthropic_endpoints): return Anthropic type:error envelope for /v1/messages errors 2026-08-31 16:23:36 -07:00
assistants refactor(typing): replace Any with proven types in 89 more backend files 2026-09-02 23:08:42 +00:00
batch_completion
batches fix(batches): claim the batch cost spend row in the database before charging 2026-09-05 18:58:11 -07:00
caching Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5_r4 2026-09-04 21:02:19 -07:00
completion_extras fix(bridge): carry provider metadata on streamed chats and keep served ids in spend logs 2026-09-05 19:21:40 -07:00
compression refactor(typing): replace Any with proven types in 89 more backend files 2026-09-02 23:08:42 +00:00
containers Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_decrease_anys_opus5_r4 2026-09-02 23:32:10 +00:00
endpoints/speech/speech_to_completion_bridge refactor(speech): freeze httpx response header dicts (LIT002) 2026-08-31 21:12:53 -07:00
evals
experimental_mcp_client chore: merge origin/litellm_internal_staging into litellm_decrease_anys_opus5_r4 2026-09-04 18:59:35 -07:00
files refactor(typing): replace Any with proven types in 42 more backend files 2026-09-02 15:35:01 +00:00
fine_tuning refactor(typing): replace Any with proven types in 89 more backend files 2026-09-02 23:08:42 +00:00
google_genai refactor(types): replace Any with precise types across 73 modules 2026-09-01 11:05:02 +00:00
images refactor(typing): replace Any with proven types in 89 more backend files 2026-09-02 23:08:42 +00:00
integrations fix(azure_sentinel): split batches under the 1MB ingestion cap (#39880) 2026-09-05 17:15:36 -07:00
interactions refactor(typing): replace Any with proven types in 42 more backend files 2026-09-02 15:35:01 +00:00
litellm_core_utils fix: capture provider request id in failure logging payloads (#40045) 2026-09-07 11:12:34 -07:00
llms Merge pull request #39839 from BerriAI/litellm_async_remote_image_fetch 2026-09-07 10:55:04 -07:00
models feat(mcp): add opt-in per-server oauth relay discovery (#39936) 2026-09-05 18:04:35 -07:00
ocr test(ocr): add SDK callback E2E parity (#40061) 2026-09-07 11:23:12 -07:00
passthrough Merge origin/litellm_internal_staging into litellm_techdebt_20260901 2026-09-01 19:38:19 +00:00
proxy test(e2e): prove the virtual key lifecycle on every gateway replica (#40023) 2026-09-07 11:30:46 -07:00
proxy_auth
rag chore: merge origin/litellm_internal_staging into litellm_decrease_anys_opus5_r4 2026-09-04 18:59:35 -07:00
realtime_api Merge pull request #39851 from BerriAI/litellm_fix_realtime_backend_close_hang 2026-09-05 09:51:15 -07:00
repositories fix(router): serialize heuristic tuning quota filters for Prisma 2026-09-07 10:08:19 -07:00
rerank_api fix(rerank): adopt declared authenticating providers in arerank instead of resolving them 2026-09-01 14:47:59 -07:00
responses Merge pull request #39850 from BerriAI/litellm_fix_realtime_reasoning_double_bill 2026-09-07 10:55:20 -07:00
router_strategy Merge pull request #40014 from BerriAI/litellm_lit_7036_retry_policy_400s 2026-09-07 09:38:43 -07:00
router_utils Merge pull request #39983 from BerriAI/litellm_lit_7081_azure_ai_gpt_6_astra_pricing 2026-09-06 01:27:22 -07:00
rust_bridge refactor(rust): remove per-request enablement arguments (#39928) 2026-09-07 10:43:45 -07:00
sandbox
search fix(search): forward search-tool params through the router, complete Parallel AI v1 param mapping (#37883) 2026-09-01 21:46:46 -07:00
secret_managers chore: merge origin/litellm_internal_staging into litellm_decrease_anys_opus5_r4 2026-09-04 18:59:35 -07:00
skills refactor(typing): replace Any with proven types in 42 more backend files 2026-09-02 15:35:01 +00:00
types fix: capture provider request id in failure logging payloads (#40045) 2026-09-07 11:12:34 -07:00
vector_store_files refactor(typing): replace Any with proven types in 42 more backend files 2026-09-02 15:35:01 +00:00
vector_stores Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_python_version_ci 2026-09-03 00:16:19 -07:00
videos refactor(videos): make video upload param keyword-only on public edit fns 2026-08-24 15:55:07 -07:00
__init__.py Revert "perf: lazy-load SDK symbols so import litellm stays under 60 MB RSS (…" 2026-09-05 16:07:09 -07:00
_internal_context.py
_lazy_imports.py fix(lazy_imports): type import_map as Mapping to stay under the LIT001 budget 2026-09-05 16:12:45 -07:00
_lazy_imports_registry.py Revert "perf: lazy-load SDK symbols so import litellm stays under 60 MB RSS (…" 2026-09-05 16:07:09 -07:00
_logging.py fix(proxy): stop leaking internal exception details to clients (#39380) 2026-09-02 17:32:00 -07:00
_redis.py fix(redis): coerce env var string types and fix param discovery through decorator wrappers (#30644) 2026-08-31 20:51:31 -07:00
_redis_credential_provider.py refactor(typing): replace Any with proven types in 89 more backend files 2026-09-02 23:08:42 +00:00
_service_logger.py chore: merge origin/litellm_internal_staging into litellm_decrease_anys_opus5_r4 2026-09-04 18:59:35 -07:00
_uuid.py
_version.py
anthropic_beta_headers_config.json
anthropic_beta_headers_manager.py
blog_posts.json
budget_manager.py
constants.py fix: capture provider request id in failure logging payloads (#40045) 2026-09-07 11:12:34 -07:00
cost.json
cost_calculator.py Merge pull request #30856 from emerzon/litellm_vertex_lyria_models 2026-09-05 23:12:25 -07:00
exceptions.py refactor(typing): replace Any with proven types in 89 more backend files 2026-09-02 23:08:42 +00:00
main.py Merge pull request #39839 from BerriAI/litellm_async_remote_image_fetch 2026-09-07 10:55:04 -07:00
model_prices_and_context_window_backup.json chore: merge litellm_internal_staging into litellm_mistral_voxtral_tts_speech 2026-09-06 03:24:55 -07:00
policy_templates_backup.json
provider_endpoints_support_backup.json fix(ocr): send each provider a health-check document it accepts 2026-09-04 22:52:12 -07:00
py.typed
router.py Merge pull request #38755 from BerriAI/litellm_mistral_voxtral_tts_speech 2026-09-07 09:38:57 -07:00
scheduler.py
setup_wizard.py feat(models): add Claude Fable 5.1 across Anthropic, Bedrock, Vertex AI, and Azure AI 2026-09-01 18:07:06 +00:00
timeout.py
utils.py Merge pull request #38755 from BerriAI/litellm_mistral_voxtral_tts_speech 2026-09-07 09:38:57 -07:00