litellm/tests/rust-python-harness/shared/tracing/compare.py
yujonglee 2c30fe16b0
Merge pull request #38765 from BerriAI/litellm_ocr_sdk_parity_tests
test(harness): add OCR parity with migration strategy runners
2026-09-03 10:16:35 -07:00

57 lines
2.2 KiB
Python

from __future__ import annotations
from collections import Counter
from collections.abc import Mapping, Sequence
from dataclasses import dataclass
from typing import Final
@dataclass(frozen=True, slots=True)
class Operation:
name: str
started: int
finished: int
def compare_traces(
python: Sequence[Operation],
rust: Sequence[Operation],
mapping: Mapping[str, str],
required_order: Sequence[tuple[str, str]] = (),
) -> tuple[str, ...]:
python_names: Final = {operation.name for operation in python}
rust_names: Final = {operation.name for operation in rust}
problems: Final = (
*(f"unmapped Python operation: {name}" for name in sorted(python_names - mapping.keys())),
*(f"unmapped Rust operation: {name}" for name in sorted(rust_names - set(mapping.values()))),
*(f"ambiguous Rust operation: {name}" for name, count in Counter(mapping.values()).items() if count > 1),
*(
f"invalid interval: {operation.name}"
for operation in (*python, *rust)
if operation.started > operation.finished
),
)
if problems:
return problems
python_counts: Final = Counter(operation.name for operation in python)
rust_counts: Final = Counter(operation.name for operation in rust)
counts: Final = tuple(
f"call count differs for {name}: Python={python_counts[name]}, Rust={rust_counts[target]}"
for name, target in mapping.items()
if python_counts[name] != rust_counts[target]
)
ordering: Final = tuple(
f"{label}: required order {before} before {after} was not observed"
for before, after in required_order
for label, operations, first, second in (
("Python", python, before, after),
("Rust", rust, mapping.get(before), mapping.get(after)),
)
if not first
or not second
or not any(operation.name == first for operation in operations)
or not any(operation.name == second for operation in operations)
or max(operation.finished for operation in operations if operation.name == first)
> min(operation.started for operation in operations if operation.name == second)
)
return (*counts, *ordering)