litellm/tests/test_litellm/proxy/management_endpoints
ryan-crabbe-berri c40828509b
fix(reset_budget_job): atomic budget cascade with chunked reset scans (#36287)
* fix(reset_budget_job): advance budget_reset_at atomically with the spend cascade

A postgres timeout mid-cascade previously left LiteLLM_BudgetTable rows
stamped for the next window while team member, enduser, org and tag spend
stayed at cap, so every later tick skipped them until the window rolled
over. All cascade writes and the budget_reset_at advance now share one
prisma batch transaction; a failed run persists nothing and the rows stay
due for the next ~10 minute tick. Cache and counter invalidation runs only
after commit, and the catch-all enduser log line now names the cascade.

* fix(reset_budget_job): elect one runner per tick and chunk the reset scans

Every pod and worker previously ran the reset job every ~10 minutes,
each fetching every expired row with no limit and writing one giant
transaction at the same calendar-aligned boundary; that concurrency is
what piled up postgres lock contention and timeouts. The job now takes
the shared PodLockManager redis lock (no redis keeps the old behavior),
and each phase walks its due rows in 500-row chunks, one transaction per
chunk, stopping when a chunk is short, makes no forward progress, or
hits the per-run cap; leftovers wait for the next tick.

* chore(lint): ratchet budget ceilings down for fixed violations

* fix(reset_budget_job): harden chunk loop, fail open on redis errors, heartbeat the lock

Review fixes on the two prior commits. Reset scans now skip rows with no
budget_duration, so permanently due rows can neither starve a phase nor
have a lifetime cap zeroed every tick. Chunk progress counts rows whose
new budget_reset_at actually cleared the cutoff, so a zero-length
duration cannot burn the per-run chunk cap. A failed lock acquire only
skips the run when another pod verifiably holds the lock; a broken redis
runs unguarded instead of silently disabling resets fleet-wide. Partial
row failures report real progress and fire the failure hook without
killing the phase. The leader re-asserts the lock between phases and
stops if another pod took over, and the budget window advance uses
update_many so a tier deleted mid-chunk cannot abort the transaction.
Lint budget ceilings re-ratcheted for the net-fixed violations.

* fix(reset_budget_job): renew the leader lease and reject non-positive budget durations

Bot review follow-ups. PodLockManager now extends the lock TTL when the
holding pod re-acquires, via an atomic compare-and-expire script with a
plain SET fallback, so a run longer than the TTL keeps its lease instead
of silently sharing the job with another pod. The positive-duration
validation that team member endpoints already had is hoisted to
management common_utils and applied to key, internal user, budget,
customer and team intake, so a tenant can no longer create zero-duration
budgets whose permanently due rows starve other tenants' resets. Such
durations now return 400 at intake; existing rows are untouched.

* refactor(reset_budget_job): defer leader election to a follow-up PR

* fix(reset_budget_job): satisfy strict lint gates

String defaults for the two getenv calls (PLW1508) and the chunk
outcome returns moved to try/else (TRY300).
2026-08-10 14:42:36 -07:00
..
management_v1 test(proxy): guard management_v1 against fastapi names removed in supported releases 2026-08-08 21:15:56 -07:00
policy_endpoints style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
scim fix(scim): stop provisioning nested group ids as internal users (#34997) 2026-07-29 09:38:17 -07:00
search_endpoints test(proxy): type the search tool test helpers and record lookups with AsyncMock 2026-08-05 23:40:16 -07:00
usage_endpoints fix(proxy): reject user_id=None on non-admin analytics endpoints (cross-tenant disclosure) 2026-04-30 23:54:01 +02:00
test_access_group_endpoints.py update test cases to match new behaviour. The earlier test cases assumed the cache stores a pydantic object 2026-04-28 21:08:46 +00:00
test_access_group_management.py fix(proxy): report when a model write does not survive the post-write reload 2026-07-28 18:52:06 -07:00
test_activity_tenant_scoping.py fix(proxy): deny agent access when key and team grants resolve to nothing (#36221) 2026-08-07 20:44:11 +00:00
test_auto_router_endpoints.py feat(auto-router): track turns per complexity tier (LIT-5302) (#36209) 2026-08-07 17:03:34 -07:00
test_budget_endpoints.py fix(reset_budget_job): atomic budget cascade with chunked reset scans (#36287) 2026-08-10 14:42:36 -07:00
test_cache_settings_endpoints.py fix(ui): reflect REDIS_* env cache config and stop the UI overwriting the stored password (#34160) 2026-07-21 18:36:26 -07:00
test_callback_management_endpoints.py fix(galileo): use ingest traces API and standard logging payload (#29651) 2026-06-05 09:03:17 -07:00
test_common_daily_activity.py feat(ptu): gate PTU flat-cost attribution behind an opt-in env var (#36138) 2026-08-10 12:23:20 -07:00
test_common_utils.py fix(reset_budget_job): atomic budget cascade with chunked reset scans (#36287) 2026-08-10 14:42:36 -07:00
test_compliance_endpoints.py fix(proxy): match multi-mode guardrail_mode without false-COMPLIANT (#32832) 2026-07-10 16:41:28 -07:00
test_config_override_endpoints.py fix(audit): label vault POST as updated when DB row exists 2026-05-01 02:44:47 +00:00
test_coordination_redis_endpoints.py fix(proxy): give proxy_admin_viewer read parity with proxy_admin (#35851) 2026-08-05 18:33:55 +00:00
test_cost_tracking_settings.py test(proxy): add regression tests for management_endpoints edge cases (#32976) 2026-07-13 15:05:13 -07:00
test_credential_migration.py feat(proxy): add AES-256-GCM at-rest credential encryption with versioned format and re-encryption migration (#31215) 2026-06-29 20:14:22 +02:00
test_customer_budget.py feat(proxy): type Customer Management response_model for OpenAPI coverage (#31043) 2026-06-30 09:58:01 -07:00
test_customer_endpoints.py fix(reset_budget_job): atomic budget cascade with chunked reset scans (#36287) 2026-08-10 14:42:36 -07:00
test_delete_callbacks_endpoint.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_delete_verification_tokens_failed.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_encryption_endpoints.py feat(proxy): add AES-256-GCM at-rest credential encryption with versioned format and re-encryption migration (#31215) 2026-06-29 20:14:22 +02:00
test_entraid_app_roles.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_gateway_request_endpoints.py feat(sgr): make the gateway middleware the source of truth for successful requests (#35717) 2026-08-05 12:40:47 -07:00
test_internal_user_endpoints.py fix(reset_budget_job): atomic budget cascade with chunked reset scans (#36287) 2026-08-10 14:42:36 -07:00
test_key_management_endpoints.py fix(reset_budget_job): atomic budget cascade with chunked reset scans (#36287) 2026-08-10 14:42:36 -07:00
test_mcp_management_endpoints.py fix(mcp): annotate connected-app reachability on the gateway connect page (#34867) 2026-07-31 05:38:54 +00:00
test_model_management_endpoints.py feat(auto-router): let operators replace the LLM classifier's system prompt (#35855) 2026-08-05 19:48:11 +00:00
test_org_admin_team_access.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_organization_endpoints.py feat(organization): add RESTful PATCH /v2/organization/{organization_id} (#32350) 2026-07-23 04:53:20 +00:00
test_policy_endpoints.py style: run black formatter on files from main merge 2026-04-17 13:02:59 -07:00
test_project_org_authz.py fix(tests): use canonical litellm_enterprise import path (#27699) 2026-05-12 12:32:57 -07:00
test_ptu_model_settings.py feat(ptu): gate PTU flat-cost attribution behind an opt-in env var (#36138) 2026-08-10 12:23:20 -07:00
test_router_settings_endpoints.py feat: routing groups ui 2026-05-04 18:09:14 -07:00
test_saml_sso.py feat(proxy): add SAML 2.0 SSO for the admin UI (#31429) 2026-07-24 12:51:28 -07:00
test_tag_management_endpoints.py refactor(test): tighten typing on the tag list verification token double 2026-07-31 09:52:46 -07:00
test_team_callback_endpoints.py fix(team-callbacks): actually stop logging when disable_logging is called (#35520) 2026-08-03 11:02:51 -07:00
test_team_default_params.py feat(teams): apply default organization to new teams from default team settings (#35540) 2026-08-03 12:57:12 -07:00
test_team_endpoints.py fix(reset_budget_job): atomic budget cascade with chunked reset scans (#36287) 2026-08-10 14:42:36 -07:00
test_team_model_alias_merge.py chore(oss): litellm oss staging 120626 (#30292) 2026-06-12 09:49:25 -07:00
test_tool_management_endpoints.py fix(tool-management): drop unsupported prisma select kwarg from team lookup (#35293) 2026-07-31 11:42:52 -07:00
test_ui_sso.py feat(teams): apply default organization to new teams from default team settings (#35540) 2026-08-03 12:57:12 -07:00
test_workflow_management_endpoints.py fix(proxy): give proxy_admin_viewer read parity with proxy_admin (#35851) 2026-08-05 18:33:55 +00:00