mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
test(e2e): xfail the known team multi-window failure and isolate member teardown
Greptile flagged two issues in the mirrored split-gateway commit. The team multi-window budget test documents a real /team/new write bug (budget_limits go straight to the Json? column and Prisma 500s, unlike the json.dumps'd key and /team/update paths) and was left as an unconditional hard failure, which would turn any live-proxy CI run red; mark it xfail(strict=True) like the custom-pricing isolation test so the suite stays green while the bug persists and flips to a failure the moment the write is fixed and the marker should go. The class-scoped member fixture in test_team_member_budget_e2e.py tore down its key, user, and team sequentially with no exception isolation, so a failed delete_key would strand the user and team on the long-lived shared proxy. Route cleanup through a ResourceManager: register each delete progressively and run them LIFO best-effort in a finally, so a partial-setup failure still releases what came before and one failed delete never blocks the rest.
This commit is contained in:
parent
385b4ff464
commit
c7ff2cc083
2 changed files with 28 additions and 13 deletions
|
|
@ -21,6 +21,7 @@ import pytest
|
|||
from budget_client import BudgetClient, is_budget_block
|
||||
from e2e_config import unique_marker
|
||||
from e2e_http import Success, require_successful_call
|
||||
from lifecycle import ResourceManager
|
||||
from models import ChatBody, ChatMessage
|
||||
|
||||
pytestmark = pytest.mark.e2e
|
||||
|
|
@ -41,16 +42,23 @@ class _Member:
|
|||
@pytest.fixture(scope="class")
|
||||
def member(client: BudgetClient) -> Iterator[_Member]:
|
||||
"""A team with a large budget plus one member capped at a tiny per-team budget,
|
||||
and that member's key. Shared across the class; torn down when it finishes."""
|
||||
marker = unique_marker()
|
||||
team_id = client.create_team(alias=f"e2e-team-member-{marker}", max_budget=TEAM_BUDGET)
|
||||
user_id = client.create_user(max_budget=TEAM_BUDGET)
|
||||
client.add_team_member(team_id, user_id, max_budget_in_team=MEMBER_BUDGET)
|
||||
key = client.generate_key(team_id=team_id, user_id=user_id)
|
||||
yield _Member(team_id=team_id, user_id=user_id, key=key)
|
||||
client.delete_key(key)
|
||||
client.delete_user(user_id)
|
||||
client.delete_team(team_id)
|
||||
and that member's key. Shared across the class; torn down when it finishes.
|
||||
Cleanups register progressively and run LIFO best-effort through ResourceManager,
|
||||
so a partial-setup failure still releases what came before and one failed delete
|
||||
never strands the rest on the shared proxy."""
|
||||
resources = ResourceManager(client=client.gateway)
|
||||
try:
|
||||
marker = unique_marker()
|
||||
team_id = client.create_team(alias=f"e2e-team-member-{marker}", max_budget=TEAM_BUDGET)
|
||||
resources.defer(lambda: client.delete_team(team_id))
|
||||
user_id = client.create_user(max_budget=TEAM_BUDGET)
|
||||
resources.defer(lambda: client.delete_user(user_id))
|
||||
client.add_team_member(team_id, user_id, max_budget_in_team=MEMBER_BUDGET)
|
||||
key = client.generate_key(team_id=team_id, user_id=user_id)
|
||||
resources.defer(lambda: client.delete_key(key))
|
||||
yield _Member(team_id=team_id, user_id=user_id, key=key)
|
||||
finally:
|
||||
resources.teardown()
|
||||
|
||||
|
||||
def _send(client: BudgetClient, key: str) -> str | None:
|
||||
|
|
|
|||
|
|
@ -7,10 +7,11 @@ the tight window's cap is exceeded, then - once the 30s elapses and the reset jo
|
|||
and calls flow again. This exercises the reset_budget_windows TEAM branch (raw SQL over
|
||||
LiteLLM_TeamTable.budget_limits, the literal #25109 path), which had no live coverage.
|
||||
|
||||
Currently fails at team creation: /team/new writes the raw window list straight to the
|
||||
Fails at team creation today: /team/new writes the raw window list straight to the
|
||||
Json? column, where Prisma rejects it (500), unlike the key path and /team/update which
|
||||
json.dumps it first. Left failing rather than weakened - it passes once that write is
|
||||
fixed.
|
||||
json.dumps it first. Marked xfail(strict=True) so the suite stays green while the bug
|
||||
persists and flips to a failure the moment the write is fixed and the marker should be
|
||||
removed.
|
||||
"""
|
||||
|
||||
import time
|
||||
|
|
@ -32,6 +33,12 @@ def _call(client: BudgetClient, key: str):
|
|||
return client.chat(key, "claude-haiku-4-5", f"team-window {unique_marker()}", max_tokens=16)
|
||||
|
||||
|
||||
@pytest.mark.xfail(
|
||||
strict=True,
|
||||
reason="known proxy bug: /team/new writes budget_limits straight to the Json? "
|
||||
"column and Prisma rejects it (500), unlike the key path and /team/update which "
|
||||
"json.dumps first; remove this marker once that write is fixed",
|
||||
)
|
||||
def test_team_short_window_blocks_then_resets(client: BudgetClient, resources: ResourceManager) -> None:
|
||||
team_id = client.create_team(
|
||||
alias=f"e2e-team-window-{unique_marker()}",
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue