litellm/tests
yuneng-jiang 978aa2816b
test(e2e/ui): stop the suite failing on things that are not regressions (#39063)
* test(e2e/ui): stop the suite failing on things that are not regressions

Five tests in the UI suite fail for reasons that have nothing to do with the
product being broken, which is enough to keep the whole leg red.

Two need a premium proxy and fail hard without one: Regenerate Key renders
disabled when the proxy is unlicensed, and /model/new refuses a team-scoped
deployment. Both now skip without LITELLM_LICENSE, the way three other tests
in this suite already do.

Three consumed a seeded fixture: Delete key, Delete a team and remove a member
each destroyed the row they needed, so the retries CI runs with were guaranteed
to fail and the suite could not run twice against one database. They now create
what they destroy.

Top Virtual Keys ranks by spend and every mock deployment costs $0, so which
keys make the list came down to how ties happened to sort. It now sends its
traffic through a priced deployment and earns its place.

* test(e2e/ui): clean up the fixtures these tests create

Review caught two leaks: the priced deployment the usage test registers and
the user the team-admin test adds both outlived the run, so repeated runs
grew shared state that later routing and rosters can see.

Also brings in the paginated daily-activity read. /user/daily/activity pages
its per-key breakdown and the helper only read the first page, so the usage
test spent its full timeout blaming the rollup for a key the rollup wrote.

* test(e2e/ui): read the licence from the proxy, not the runner

Review pointed out that checking LITELLM_LICENSE in the runner's environment
describes the wrong machine: Playwright can be pointed at a proxy configured
somewhere else, and then the skip either hides coverage or runs a premium
test against an unlicensed target.

The admin session JWT already carries the premium_user claim the dashboard
itself reads to enable these controls, so both skips now use that.

* test(e2e/ui): clean up fixtures on the failure path too

Review caught both cleanups sitting at the end of the test body, where a
failing assertion skips them, and both discarding the response so a refused
delete passed quietly. They move to afterEach and assert the delete landed.

The priced deployment matters most: left behind it keeps its custom pricing
and goes on changing what later runs route and what they cost.

* test(e2e/ui): wait for the priced deployment to become routable

The Top Virtual Keys test registered a priced deployment and sent the key's
traffic through it on the next line, so on the deployed stack it failed with
"no healthy deployments for e2e-usage-priced-...": /model/new had written
the row but the router had not picked it up yet.

Polls a ping until the deployment answers before the test sends the request
it measures, matching what the addModel spec already does for a model added
through the UI. A ping that fails writes no spend log, so the retries cannot
move the ranking this test asserts.

* test(e2e/ui): register fixtures for cleanup before the step that can fail

Review found both helpers handing their id back to the caller to record, with
a failure-prone call in between: the priced deployment was registered after
the routability wait, and the added user after /team/member_add. Either
failing left the resource in the shared database with nothing tracking it.

Both now take the teardown list and add themselves as soon as the resource
exists, so the afterEach removes it however the rest of setup goes.

* test(e2e/ui): resolve the priced deployment for teardown by name

Review pointed out the remaining gap: /model/new can persist the deployment
and still answer non-2xx, and the id was only recorded after the response was
asserted, so that path left it behind with its custom pricing.

The name is now claimed before the request and teardown looks it up in
/model/info, so a create that saved without answering 2xx is still removed and
one that never saved is simply not there.

* test(e2e/ui): claim the member id before creating the user

/user/new can persist the user and still answer non-2xx, and the id is chosen
by the test rather than returned by the proxy, so registering it before the
call is what closes the last create-failure path.

Teardown now skips an id whose user is not there, so claiming it up front
cannot fail a run where the create never landed.

* test(e2e/ui): wait out the router reload when resolving a deployment to delete

/model/info answers from the router, not from the database, and /model/new
catches and logs a failed in-request reload while still answering 2xx. A
deployment can therefore be persisted and absent from the listing until the
next reload, which is where teardown was giving up and leaking it.

Teardown now retries the lookup for a little over one
PROXY_CONFIG_RELOAD_INTERVAL_SECONDS before treating the name as never
persisted, so the only names it skips are the ones that really are not there.

* test(e2e/ui): prove a stored credential survives a config reload before using it

The Test Connect assertion has been failing intermittently on the full-suite
runs. Artifacts from litellm-e2e-ui build 165 show the UI sending
litellm_credential_name and the proxy answering with the credential unapplied:
raw_request_api_base was https://api.openai.com/v1/ rather than the mock base
the credential carries, and the call died on an upstream 404 for the model. The
same credential had resolved on three probes eight seconds earlier.

The proxy's periodic credential refresh takes a database snapshot, prunes any
in-memory credential missing from it, then re-adds the snapshot. A credential
created while that is in flight gets pruned and stays gone until the next tick,
and load_credentials_from_list fails open onto the ambient key, so nothing in
the error names the credential.

The existing pre-check asked for three consecutive probe successes, but they
completed in under a second, so they could not span a refresh. Space them so
the run covers a whole interval, which is what proves the credential survived a
refresh and is therefore stable.

* test(e2e/ui): find a database-only deployment through the search listing

/model/info answers from the router, so a deployment that reached the database
while /model/new's in-request reload failed is invisible there, and waiting on
the next reload only helps if reconciliation eventually picks it up.

/v2/model/info?search= runs a bounded query against the model table and
deliberately returns rows the router does not hold, so it resolves those
deployments to the id /model/delete needs. Falling back to it removes the wait
as well: absent from both listings now means the deployment never persisted.

* test(e2e/ui): delete the temporary member without a lookup that can skip it

Teardown asked /user/info first and treated any non-2xx as absence, so a
transient failure on the lookup silently skipped the delete and left the user
behind, which is the leak the claimed id was meant to close.

/user/delete answers 404 for an id that is not there, so it can carry both
cases on its own: 404 means the create never persisted, and anything else that
is not 2xx now fails the teardown instead of passing quietly.

* test(e2e/ui): reach the database fallback when the router listing fails

Asserting on /model/info threw before the fallback could run, so a failure on
the router-backed listing aborted teardown and left the deployment persisted,
which is the leak the fallback was added to close.

The router listing is best-effort now: an unreadable response just falls
through to the search-backed one. That listing is the authoritative answer to
whether the deployment exists, so it is the one that has to be readable, and a
name missing from it is a create that never persisted.

---------

Co-authored-by: Claude <noreply@anthropic.com>
2026-09-01 12:34:57 -07:00
..
agent_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
audio_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
base_sdk_tests test(cli): cover the keyless token record and keep keyring to the cli extra 2026-08-20 03:45:00 -07:00
basic_proxy_startup_tests
batches_tests merge(litellm_internal_staging): reconcile batch observability with per-line resilience 2026-08-24 19:08:40 -04:00
benchmarks test(benchmarks): run shared logging executor inline to make CodSpeed measurements deterministic (#32435) 2026-07-09 11:14:22 +03:00
code_coverage_tests feat(guardrails): add Alice guardrail (#38898) 2026-09-01 12:33:39 -07:00
documentation_tests Merge remote-tracking branch 'origin/main' into litellm_bedrock_messages_disconnect_billing 2026-08-31 08:58:37 -07:00
e2e test(e2e/ui): stop the suite failing on things that are not regressions (#39063) 2026-09-01 12:34:57 -07:00
enterprise fix(batches): fill a managed batch page past rows that will not parse 2026-08-28 07:54:18 -07:00
guardrails_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
image_gen_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
integration test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
litellm-proxy-extras Merge pull request #31125 from BerriAI/litellm_/stoic-jones-7de871 2026-09-01 11:46:13 -07:00
litellm_utils_tests test(aiohttp): pin NO_PROXY so proxy env cannot hijack the refused-port probe 2026-08-28 12:45:46 -07:00
llm_responses_api_testing test(responses): use a reasoning-legal temperature in the gpt-5.5 extra_body merge test 2026-08-29 01:36:45 -07:00
llm_translation test(reasoning-effort-grid): bump the cell count for the four new Fable 5.1 cells 2026-09-01 18:28:33 +00:00
load_tests Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_ruff_dead_test_code 2026-08-24 09:46:56 -07:00
local_testing Merge pull request #31125 from BerriAI/litellm_/stoic-jones-7de871 2026-09-01 11:46:13 -07:00
logging_callback_tests test(gcs_pubsub): expect router_metadata key in spend logs fixture 2026-08-31 15:37:56 -07:00
mcp_tests Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_deflake_20260821 2026-08-27 09:17:37 +00:00
multi_instance_e2e_tests test: say whether a match= pattern is a regex or a literal (ruff RUF043) 2026-08-21 16:25:33 -07:00
ocr_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
openai_endpoints_tests test(responses): expect the bad-temperature 400 on a non-reasoning model 2026-08-29 01:58:15 -07:00
otel_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
pass_through_tests fix(anthropic_messages): dispatch deferred spend logging when the client disconnects mid-relay 2026-08-31 10:17:27 -07:00
pass_through_unit_tests test(websearch): carry a reasoned test-quality suppression on the router patch 2026-08-31 22:32:05 -07:00
proxy_admin_ui_tests test(access-groups): give each xdist worker its own fixture ids 2026-08-28 09:35:12 -07:00
proxy_behavior fix(proxy): reset a stuck team member's budget (#37971) 2026-08-25 09:50:09 -07:00
proxy_e2e_anthropic_messages_tests ci: lint the test tree for undefined names and fix all 30 (#37671) 2026-08-20 13:30:34 -07:00
proxy_migration_tests fix(ui): boot the UI image as an arbitrary uid by anchoring nginx writes under /tmp (#37982) 2026-08-24 11:57:36 -07:00
proxy_security_tests
proxy_unit_tests test(newrelic): cover static default_team_settings per-team routing (#38857) 2026-08-31 16:58:35 +00:00
router_unit_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
search_tests fix(search): harden bing_grounding auth, result cap, status, and cost 2026-08-24 12:26:07 -07:00
spend_tracking_tests
store_model_in_db_tests test: enforce F811 so a duplicate definition cannot silently replace the first 2026-08-21 12:06:19 -07:00
test_litellm feat(guardrails): add Alice guardrail (#38898) 2026-09-01 12:33:39 -07:00
unified_google_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
vector_store_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
windows_tests test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
__init__.py
_fake_openai_endpoint_server.py test(ci): serve /moderations from the canned OpenAI mock (#37739) 2026-08-20 16:58:38 -07:00
_flush_vcr_cache.py
_live_test_helpers.py
_openai_record_replay_proxy.py
_vcr_conftest_common.py
_vcr_redis_persister.py
_wait_helpers.py test: replace blind sleeps with deadline waits in callback and caching tests (#37660) 2026-08-20 18:48:43 +00:00
_ws_vcr.py test(realtime): record and replay websocket traffic in redis vcr cassettes (#32390) 2026-07-08 00:19:06 -07:00
eval_swe_bench.py
fake_openai_endpoint.py
gettysburg.wav
large_text.py
openai_batch_completions.jsonl
pyrightconfig.json
README.MD
test_anthropic_compaction_usage.py
test_budget_management.py
test_callbacks_on_proxy.py test: enforce F811 so a duplicate definition cannot silently replace the first 2026-08-21 12:06:19 -07:00
test_debug_warning.py
test_default_encoding_non_root.py
test_end_users.py ci: lint the test tree for undefined names and fix all 30 (#37671) 2026-08-20 13:30:34 -07:00
test_fallbacks.py test: enforce F811 so a duplicate definition cannot silently replace the first 2026-08-21 12:06:19 -07:00
test_gpt5_azure_temperature_support.py
test_health.py
test_keys.py test: fix staging CI regressions from #38182, #38144, #38265, #37962, and #37969 2026-08-25 23:01:20 -07:00
test_litellm_proxy_responses_config.py
test_logging.conf
test_models.py
test_new_vector_store_endpoints.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_openai_endpoints.py test: point the live web search, groq and vertex image suites at models that still exist (#37733) 2026-08-20 17:03:35 -07:00
test_organizations.py
test_otel_thread_leak.py
test_presidio_latency.py
test_proxy_server_non_root.py
test_ratelimit.py test: drop the cwd-relative sys.path.insert calls from the test suite (#37802) 2026-08-22 09:25:58 -07:00
test_resource_cleanup.py
test_service_logger_otel.py fix(langfuse): send v4 ingestion header for otel callback (#33907) 2026-07-18 20:36:51 -07:00
test_spend_logs.py
test_team.py test: add six ruff rules that catch tests which cannot fail (#37709) 2026-08-20 14:21:26 -07:00
test_team_logging.py test: enforce F811 so a duplicate definition cannot silently replace the first 2026-08-21 12:06:19 -07:00
test_team_members.py test: reject assertions on a caught error inside except (ruff PT017) 2026-08-21 13:35:08 -07:00
test_users.py test: enforce F811 so a duplicate definition cannot silently replace the first 2026-08-21 12:06:19 -07:00

In total litellm runs 1000+ tests

[02/20/2025] Update:

To make it easier to contribute and map what behavior is tested,

we've started mapping the litellm directory in tests/test_litellm

This folder can only run mock tests.