litellm/tests/unit/tracing/test_queries.py
moe-berri 22ad3c5fff
refactor(lens): connect LiteLLM to the independent Lens service (#45529)
* feat(lens): consume the independent Lens service and shared UI

* fix(lens): keep embedded setup stable and vendor UI before builds

* chore(lens): pin embedded UI provenance to published Lens source

* fix(lens): complete embedded UI extraction across CI builds

* docs(lens): record latest main and removal-boundary validation

* fix(lens): wire external chart credentials and ingestion modes

* test(lens): cover adapter failures and fix extraction CI

* docs(lens): refresh bundled chart setup instructions

* test(lens): restore gateway adapter test package marker

* build(lens): pin clean-cut UI and supported storage chart

* test(ui): await guardrail scope menu before checking options

* perf(lens): omit unused trace-team lookup from product requests

* docs(lens): record final-image adapter permission checks

* test(lens): assert delegated investigation authorization

* refactor(lens): remove copied trace runtime and preserve spend logging

* test(lens): verify independent gateway image upgrades and outages

* test(lens): pin the chart qualification database image

* fix(lens): update embedded UI metadata filters

* test: wait for Lens chart pod identity convergence

* fix(e2e): select Lens chart pods by deployment ownership

* fix(e2e): select Helm migration ownership for Lens upgrades

* test(lens): retain migration Jobs through rollout assertions

* docs(helm): require existing database for migration hooks

* test(lens): qualify release boundaries with embedded navigation update

* docs(lens): record browser qualification for embedded tabs

* fix(lens): remove unrelated CI and guardrail test changes

* test(lens): give qualification tenants unique key aliases

* feat(lens): embed the latest canonical Lens interface

* fix(lens): qualify split inference through the gateway

* fix(lens): preserve scoped auth and isolate delegated credentials

* chore(lens): remove unrelated documentation and lint changes

* fix(lens): bound concurrent forwarding buffers through response delivery

* fix(lens): preserve OAuth2 dispatch without inference policies

* chore(lens): adopt current shared onboarding UI

* fix(lens): refresh shared setup UI and review context

* fix(lens): bound uploads before gateway authentication

* docs(lens): remove extraction evidence from the gateway repo

* docs(lens): refresh shared setup prompt for paired releases
2026-10-09 16:17:05 -07:00

58 lines
2.1 KiB
Python

from typing import Final
import pytest
from pydantic import ValidationError
from litellm.tracing.queries import TRACE_AGENTS
@pytest.mark.parametrize("count", (0, "9007199254740993", 2**64 - 1))
def test_agent_rows_normalize_counts_without_precision_loss(count: int | str) -> None:
result: Final = TRACE_AGENTS.response.validate_python(
{"data": [{"agent_name": "agent", "runs": count, "failed_runs": 0, "last_seen_ms": 1, "frameworks": ["otel"]}]}
)
row: Final = result.data[0]
assert row.runs == int(count)
assert row.frameworks == ("otel",)
with pytest.raises(ValidationError):
row.agent_name = "changed"
@pytest.mark.parametrize("count", (-1, "18446744073709551616", "1.5"))
def test_agent_rows_reject_invalid_counts(count: int | str) -> None:
with pytest.raises(ValidationError):
TRACE_AGENTS.response.validate_python(
{"data": [{"agent_name": "agent", "runs": count, "failed_runs": 0, "last_seen_ms": 1}]}
)
def test_dictionary_validation_keeps_required_nullable_and_optional_fields_distinct() -> None:
from pydantic import TypeAdapter
from litellm.tracing.generated.types import SpanDetail, SpanErrorPage
result: Final = TypeAdapter(SpanDetail).validate_python(
{
"span_id": "span",
"input": "",
"output": "",
"attributes": {"key": "value"},
"input_ui": {"kind": "messages", "messages": [{"role": "user", "content": "hello"}]},
"output_ui": {"kind": "text", "text": "answer"},
}
)
assert result["input_ui"] == {"kind": "messages", "messages": ({"role": "user", "content": "hello"},)}
assert result["attributes"] == {"key": "value"}
assert (
TypeAdapter(SpanErrorPage).validate_python(
{
"span_id": "span",
"message": "error",
"total_chars": 5,
"next_cursor": None,
}
)["next_cursor"]
is None
)
with pytest.raises(ValidationError):
TypeAdapter(SpanErrorPage).validate_python({"span_id": "span", "message": "error", "total_chars": 5})