mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-03 02:22:24 +00:00
test(integration): read team member alert deliveries without a shared accumulator
This commit is contained in:
parent
5a5dd41052
commit
8b083c9523
2 changed files with 15 additions and 20 deletions
|
|
@ -35,6 +35,9 @@ class Mailbox:
|
|||
port: int
|
||||
received: SimpleQueue[Delivery]
|
||||
|
||||
def pending(self) -> int:
|
||||
return self.received.qsize()
|
||||
|
||||
def drain(self) -> tuple[Delivery, ...]:
|
||||
return tuple(self.received.get_nowait() for _ in range(self.received.qsize()))
|
||||
|
||||
|
|
@ -64,14 +67,15 @@ def smtp_sink() -> Generator[Mailbox, None, None]:
|
|||
|
||||
def _session(self) -> None:
|
||||
self._reply("220 integration-smtp ready")
|
||||
# rebind-ok: the SMTP envelope is built across MAIL/RCPT lines and reset after DATA or RSET.
|
||||
sender = ""
|
||||
recipients: tuple[str, ...] = ()
|
||||
while True:
|
||||
raw: Final = self.rfile.readline()
|
||||
if not raw:
|
||||
return
|
||||
line = raw.decode().rstrip("\r\n")
|
||||
verb = line.split(" ", 1)[0].upper()
|
||||
line: Final = raw.decode().rstrip("\r\n")
|
||||
verb: Final = line.split(" ", 1)[0].upper()
|
||||
if verb in {"EHLO", "HELO"}:
|
||||
self._reply("250 integration-smtp")
|
||||
elif verb == "MAIL":
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ import pytest
|
|||
import yaml
|
||||
from integration._support.client import Gateway, eventually
|
||||
from integration._support.database import read_rows
|
||||
from integration._support.mail import Delivery, Mailbox, smtp_sink
|
||||
from integration._support.mail import smtp_sink
|
||||
from integration._support.process import owned_proxy
|
||||
|
||||
MEMBER_BUDGET: Final = 0.10
|
||||
|
|
@ -20,11 +20,6 @@ def _membership_spend(user_id: str, team_id: str) -> float:
|
|||
return float(str(rows[0]["spend"])) if rows else 0.0
|
||||
|
||||
|
||||
def _deliveries_for(mailbox: Mailbox, seen: list[Delivery]) -> list[Delivery]:
|
||||
seen.extend(mailbox.drain())
|
||||
return seen
|
||||
|
||||
|
||||
def test_team_member_budget_thresholds_email_member_and_configured_recipients(gateway: Gateway, tmp_path: Path) -> None:
|
||||
member_email: Final = f"member-{uuid.uuid4().hex}@integration.test"
|
||||
finance_email: Final = f"finance-{uuid.uuid4().hex}@integration.test"
|
||||
|
|
@ -49,7 +44,6 @@ def test_team_member_budget_thresholds_email_member_and_configured_recipients(ga
|
|||
)
|
||||
candidate.post("/team/member_add", {"team_id": team_id, "member": {"user_id": user_id, "role": "user"}})
|
||||
key: Final = scenario.key(team_id=team_id, user_id=user_id)
|
||||
received: Final[list[Delivery]] = []
|
||||
|
||||
first: Final = candidate.request(
|
||||
"POST",
|
||||
|
|
@ -62,7 +56,7 @@ def test_team_member_budget_thresholds_email_member_and_configured_recipients(ga
|
|||
eventually(
|
||||
lambda: _membership_spend(user_id, team_id), lambda spend: spend == pytest.approx(CALL_COST), seconds=70
|
||||
)
|
||||
assert _deliveries_for(mailbox, received) == [], "no threshold is reached before the first call is recorded"
|
||||
assert mailbox.drain() == (), "no threshold is reached before the first call is recorded"
|
||||
|
||||
second: Final = candidate.request(
|
||||
"POST",
|
||||
|
|
@ -71,9 +65,8 @@ def test_team_member_budget_thresholds_email_member_and_configured_recipients(ga
|
|||
key=key,
|
||||
)
|
||||
assert second.status_code == 200, second.text
|
||||
halfway: Final = eventually(
|
||||
lambda: _deliveries_for(mailbox, received), lambda values: len(values) >= 1, seconds=30
|
||||
)
|
||||
eventually(mailbox.pending, lambda count: count >= 1, seconds=30)
|
||||
halfway: Final = mailbox.drain()
|
||||
assert [delivery.recipients for delivery in halfway] == [(member_email,)], halfway
|
||||
assert "50%" in halfway[0].subject, halfway[0].subject
|
||||
assert f"${MEMBER_BUDGET}" in halfway[0].html, halfway[0].html
|
||||
|
|
@ -90,14 +83,12 @@ def test_team_member_budget_thresholds_email_member_and_configured_recipients(ga
|
|||
key=key,
|
||||
)
|
||||
assert third.status_code == 422 and third.json()["error"]["type"] == "budget_exceeded", third.text
|
||||
capped: Final = eventually(
|
||||
lambda: _deliveries_for(mailbox, received), lambda values: len(values) >= 3, seconds=30
|
||||
)
|
||||
hundred: Final = capped[1:]
|
||||
assert all("100%" in delivery.subject for delivery in hundred), capped
|
||||
eventually(mailbox.pending, lambda count: count >= 2, seconds=30)
|
||||
hundred: Final = mailbox.drain()
|
||||
assert all("100%" in delivery.subject for delivery in hundred), hundred
|
||||
assert {recipient for delivery in hundred for recipient in delivery.recipients} == {
|
||||
member_email,
|
||||
finance_email,
|
||||
}, capped
|
||||
}, hundred
|
||||
assert all(member_email in delivery.html and f"${MEMBER_BUDGET}" in delivery.html for delivery in hundred)
|
||||
assert len(capped) == 3, capped
|
||||
assert len(hundred) == 2, hundred
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue