mirror of
https://github.com/BerriAI/litellm.git
synced 2026-09-25 01:02:15 +00:00
test(integration): aggregated team daily activity reports whole-range team spend in one page (Pylon #7224)
Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
8efad109b4
commit
6939792d26
2 changed files with 84 additions and 0 deletions
|
|
@ -287,6 +287,9 @@
|
|||
"tests/integration/spend/test_filtered_ledger.py::test_rotated_keys_users_and_model_groups_preserve_success_failure_cache_ledger": [
|
||||
"quota_management.spend_tracking.filtered_ledger_preserves_owner_identity_and_totals"
|
||||
],
|
||||
"tests/integration/spend/test_team_daily_activity_aggregated.py::test_aggregated_team_activity_reports_the_whole_range_team_spend_in_one_page": [
|
||||
"quota_management.spend_tracking.team_daily_activity_aggregated_reports_whole_range_team_spend"
|
||||
],
|
||||
"tests/integration/management/test_partial_update_sequences.py::test_restricted_actor_cannot_detach_key_from_project": [
|
||||
"mgmt.key.update.project_detach_denied_to_restricted_actor"
|
||||
],
|
||||
|
|
|
|||
|
|
@ -0,0 +1,81 @@
|
|||
import uuid
|
||||
from datetime import datetime, timedelta, timezone
|
||||
from hashlib import sha256
|
||||
from typing import Final
|
||||
|
||||
import pytest
|
||||
from integration._support.client import Gateway, eventually, object_value
|
||||
from integration._support.database import read_rows
|
||||
|
||||
|
||||
@pytest.mark.covers("quota_management.spend_tracking.team_daily_activity_aggregated_reports_whole_range_team_spend")
|
||||
def test_aggregated_team_activity_reports_the_whole_range_team_spend_in_one_page(gateway: Gateway) -> None:
|
||||
with gateway.scenario() as scenario:
|
||||
model: Final = scenario.model(input_cost_per_token=0.001, output_cost_per_token=0.002)
|
||||
team: Final = scenario.team(models=[model])
|
||||
keys: Final = tuple(scenario.key(team_id=team, models=[model]) for _ in range(2))
|
||||
digests: Final = tuple(sha256(key.encode()).hexdigest() for key in keys)
|
||||
for key in keys:
|
||||
for _ in range(2):
|
||||
reply: Final = gateway.chat(model, key=key, text=f"team activity {uuid.uuid4().hex}")
|
||||
assert reply["usage"]["total_tokens"] == 40, reply
|
||||
logged: Final = eventually(
|
||||
lambda: read_rows('SELECT spend FROM "LiteLLM_SpendLogs" WHERE team_id=%s', (team,)),
|
||||
lambda values: len(values) == 4,
|
||||
seconds=70,
|
||||
)
|
||||
assert sum(float(row["spend"]) for row in logged) == pytest.approx(0.24)
|
||||
daily: Final = eventually(
|
||||
lambda: read_rows(
|
||||
'SELECT api_key, spend, successful_requests FROM "LiteLLM_DailyTeamSpend" WHERE team_id=%s', (team,)
|
||||
),
|
||||
lambda values: sum(float(row["spend"]) for row in values) >= 0.24 - 1e-9,
|
||||
seconds=70,
|
||||
)
|
||||
assert sorted(row["api_key"] for row in daily) == sorted(digests), daily
|
||||
assert all(float(row["spend"]) == pytest.approx(0.12) and row["successful_requests"] == 2 for row in daily)
|
||||
today: Final = datetime.now(timezone.utc)
|
||||
response: Final = gateway.request(
|
||||
"GET",
|
||||
"/team/daily/activity/aggregated",
|
||||
params={
|
||||
"team_ids": team,
|
||||
"start_date": (today - timedelta(days=1)).strftime("%Y-%m-%d"),
|
||||
"end_date": (today + timedelta(days=1)).strftime("%Y-%m-%d"),
|
||||
"timezone": "0",
|
||||
},
|
||||
)
|
||||
assert response.status_code == 200, response.text
|
||||
body: Final = object_value(response.json())
|
||||
metadata: Final = object_value(body["metadata"])
|
||||
assert (
|
||||
metadata["total_spend"],
|
||||
metadata["total_prompt_tokens"],
|
||||
metadata["total_completion_tokens"],
|
||||
metadata["total_tokens"],
|
||||
metadata["total_api_requests"],
|
||||
metadata["total_successful_requests"],
|
||||
metadata["total_failed_requests"],
|
||||
metadata["page"],
|
||||
metadata["total_pages"],
|
||||
metadata["has_more"],
|
||||
) == (pytest.approx(0.24), 80, 80, 160, 4, 4, 0, 1, 1, False), response.text
|
||||
results: Final = body["results"]
|
||||
assert isinstance(results, list) and len(results) == 1, response.text
|
||||
day: Final = object_value(results[0])
|
||||
assert object_value(day["metrics"])["spend"] == pytest.approx(0.24), response.text
|
||||
entities: Final = object_value(object_value(day["breakdown"])["entities"])
|
||||
assert set(entities) == {team}, response.text
|
||||
team_bucket: Final = object_value(entities[team])
|
||||
team_metrics: Final = object_value(team_bucket["metrics"])
|
||||
assert (team_metrics["spend"], team_metrics["api_requests"], team_metrics["successful_requests"]) == (
|
||||
pytest.approx(0.24),
|
||||
4,
|
||||
4,
|
||||
), response.text
|
||||
per_key: Final = object_value(team_bucket["api_key_breakdown"])
|
||||
assert set(per_key) == set(digests), response.text
|
||||
assert tuple(object_value(object_value(per_key[digest])["metrics"])["spend"] for digest in digests) == (
|
||||
pytest.approx(0.12),
|
||||
pytest.approx(0.12),
|
||||
), response.text
|
||||
Loading…
Add table
Reference in a new issue