mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
test(e2e): run harness unit tests without a live proxy
The autouse session fixture skipped the whole tests/e2e session when no proxy answered, which also skipped test_lifecycle.py, a pure unit test of run_case that never touches the proxy. A regression test that silently skips gives no signal, so the skip now lives in pytest_runtest_setup gated on the same e2e marker the spend-log truncate guard already uses: live tests skip when no proxy is up while harness unit coverage always runs. The liveness probe is cached with lru_cache so it still runs once per session
This commit is contained in:
parent
0fd91d5b73
commit
7951221f9a
1 changed files with 28 additions and 14 deletions
|
|
@ -1,7 +1,9 @@
|
|||
"""Shared fixtures for all live e2e suites under tests/e2e/.
|
||||
|
||||
Design rule: skip on environment, fail on behavior. If the proxy is unreachable
|
||||
the whole session skips; once a request reaches the proxy, behavior is asserted.
|
||||
Design rule: skip on environment, fail on behavior. Live tests (marked `e2e`)
|
||||
skip when no proxy answers; once a request reaches the proxy, behavior is
|
||||
asserted. Pure unit coverage of the harness itself carries no `e2e` marker and
|
||||
runs regardless of whether a proxy is up.
|
||||
|
||||
Lifecycle: the `resources` fixture maps the init -> run -> teardown contract
|
||||
(lifecycle.E2ECase) onto pytest - setup is init(), the test body is run(), and
|
||||
|
|
@ -11,6 +13,7 @@ Each suite provides its own `client` fixture (a lifecycle.ResourceClient); these
|
|||
shared fixtures build on it.
|
||||
"""
|
||||
|
||||
import functools
|
||||
import sys
|
||||
from pathlib import Path
|
||||
from typing import Iterator
|
||||
|
|
@ -32,6 +35,29 @@ def pytest_configure(config: pytest.Config) -> None:
|
|||
)
|
||||
|
||||
|
||||
@functools.lru_cache(maxsize=1)
|
||||
def _proxy_skip_reason() -> str | None:
|
||||
"""Probe the proxy once per session. None if it answers, else a skip reason."""
|
||||
try:
|
||||
resp = requests.get(f"{PROXY_BASE_URL}/health/liveliness", timeout=5)
|
||||
except requests.RequestException as exc:
|
||||
return f"No live proxy at {PROXY_BASE_URL}: {exc}"
|
||||
if resp.status_code >= 500:
|
||||
return f"Proxy at {PROXY_BASE_URL} returned {resp.status_code}"
|
||||
return None
|
||||
|
||||
|
||||
def pytest_runtest_setup(item: pytest.Item) -> None:
|
||||
"""Skip `e2e`-marked tests unless a proxy answers its liveness probe. Unmarked
|
||||
tests (unit coverage of the harness) don't touch the proxy, so they run even
|
||||
when none is up."""
|
||||
if item.get_closest_marker("e2e") is None:
|
||||
return
|
||||
reason = _proxy_skip_reason()
|
||||
if reason is not None:
|
||||
pytest.skip(reason)
|
||||
|
||||
|
||||
def pytest_runtest_call(item: pytest.Item) -> None:
|
||||
"""Mark that an e2e test body actually ran (not skipped at setup). Skipped
|
||||
sessions never reach this hook, so the session-finish cleanup can use it as a
|
||||
|
|
@ -66,18 +92,6 @@ def pytest_sessionfinish(session: pytest.Session, exitstatus: int) -> None:
|
|||
sys.path.remove(spend_dir)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session", autouse=True)
|
||||
def require_live_proxy() -> None:
|
||||
"""Skip the entire session unless a proxy answers its liveness probe."""
|
||||
try:
|
||||
resp = requests.get(f"{PROXY_BASE_URL}/health/liveliness", timeout=5)
|
||||
except requests.RequestException as exc:
|
||||
pytest.skip(f"No live proxy at {PROXY_BASE_URL}: {exc}")
|
||||
return
|
||||
if resp.status_code >= 500:
|
||||
pytest.skip(f"Proxy at {PROXY_BASE_URL} returned {resp.status_code}")
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def resources(client: GatewayProvider) -> Iterator[ResourceManager]:
|
||||
"""init -> run -> teardown: create a manager, run the test, release resources.
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue