litellm/tests/rust-python-harness/shared/tracing/test_profiler.py
Yujong Lee fae3d224eb Merge remote-tracking branch 'origin/litellm_internal_staging' into litellm_python_version_ci
# Conflicts:
#	basedpyright-code-budget.json
#	tests/sdk_function_trace/profiler.py
#	tests/sdk_function_trace/test_profiler.py
2026-09-04 09:01:13 -07:00

141 lines
3.9 KiB
Python

from __future__ import annotations
import asyncio
import sys
import threading
from collections.abc import Callable
from functools import wraps
from pathlib import Path
from types import FunctionType
from typing import Final, ParamSpec, TypeVar, cast
import pytest
from .profiler import (
FunctionTraceEvent,
PythonProfiler,
_module_qualnames,
profile_python,
profile_python_function_usage,
)
_P = ParamSpec("_P")
_T = TypeVar("_T")
def _passthrough(function: Callable[_P, _T]) -> Callable[_P, _T]:
@wraps(function)
def wrapper(*args: _P.args, **kwargs: _P.kwargs) -> _T:
return function(*args, **kwargs)
return wrapper
class Decorated:
@_passthrough
def call(self) -> None:
return None
def _events_named(profiler: PythonProfiler, name: str) -> tuple[FunctionTraceEvent, ...]:
return tuple(event for event in profiler.events if event.function.endswith(name))
def test_profiler_keeps_repeated_calls() -> None:
def called() -> None:
return None
with profile_python(Path(__file__).parent) as profiler:
called()
called()
assert len(_events_named(profiler, "called")) == 2
def test_profiler_qualifies_decorated_methods_by_class() -> None:
with profile_python(Path(__file__).parent) as profiler:
Decorated().call()
assert any(event.function.endswith(" Decorated.call") for event in profiler.events)
assert _module_qualnames(__name__)[cast(FunctionType, Decorated.call.__wrapped__).__code__] == "Decorated.call"
def test_profiler_records_real_frame_ancestry() -> None:
def called() -> None:
return None
def outer() -> None:
called()
with profile_python(Path(__file__).parent) as profiler:
outer()
outer_event, called_event = (event for event in profiler.events if event.function.endswith(("outer", "called")))
assert called_event.parent_id == outer_event.id
def test_profiler_restores_previous_profiler_after_failure() -> None:
previous: Final = sys.getprofile()
with pytest.raises(RuntimeError, match="stop"):
with profile_python(Path(__file__).parent):
raise RuntimeError("stop")
assert sys.getprofile() is previous
def test_profiler_does_not_count_coroutine_resumption_as_another_call() -> None:
async def suspended() -> None:
await asyncio.sleep(0)
await asyncio.sleep(0)
with profile_python(Path(__file__).parent) as profiler:
asyncio.run(suspended())
assert len(_events_named(profiler, "suspended")) == 1
def test_profiler_preserves_parent_across_coroutine_suspension() -> None:
def called() -> None:
return None
async def suspended() -> None:
await asyncio.sleep(0)
called()
with profile_python(Path(__file__).parent) as profiler:
asyncio.run(suspended())
suspended_event: Final = _events_named(profiler, "suspended")[0]
called_event: Final = _events_named(profiler, "called")[0]
assert called_event.parent_id == suspended_event.id
def test_profiler_captures_worker_threads_when_enabled() -> None:
def called() -> None:
return None
with profile_python(Path(__file__).parent, threads=True) as profiler:
thread: Final = threading.Thread(target=called)
thread.start()
thread.join()
called_event: Final = _events_named(profiler, "called")[0]
assert called_event.parent_id is None
def test_function_usage_profiler_records_only_selected_functions() -> None:
def selected() -> None:
return None
def ignored() -> None:
return None
source_root: Final = Path(__file__).parent
function: Final = f"{Path(__file__).name}:{selected.__code__.co_firstlineno} {selected.__qualname__}"
with profile_python_function_usage(source_root, frozenset((function,))) as profiler:
selected()
ignored()
assert profiler.called == {function}