mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-25 05:54:53 +00:00
4.1 KiB
4.1 KiB
Scope
- This directory tests the Rust path end to end through the Python public API, plus the dispatch tests below, and nothing else
- A test belongs here only when it cannot be written in Rust, meaning it needs
- the Python public API
- Python-owned state such as
litellm.cacheand callbacks - the process boundary (fork, threads, event loops)
- Anything checkable from the Rust side goes in the crate's own tests
- The wire is the local recording server. No test here reaches a real provider
Rust only
- Outside the dispatch tests, treat every route's Python implementation as already removed
- never call it on purpose
- never run one request through both engines
- never compare Python and Rust outputs, headers, cache keys or logs
- A test that would still pass with Python serving the call does not belong here
- Every test except the dispatch tests asserts native serving with
support.routing.assert_served_natively
Dispatch tests
- They check which path a public call takes under given rules
- each route folder's
test_dispatch.py test_dispatch.pyat the top, which testsPublicDispatchwith stub routestest_public_entries.pyat the top, which runs every route's public call forms through one table
- each route folder's
- They pass
rules=to a dispatch directly or wrap the whole test in onesupport.routing.routed(...)block, and they stub the native bindings - They may call Python, since the choice between the two paths is what they test
- They live here until they can run in
tests/unit/without the compiled extension
Selecting a path
- Use
support.routing.native_route(...), which prependsRUST_REQUIREDrules tocatalog.RULESand restores them on exit- route folders apply it to every test through the autouse fixture in their
conftest.py - a test outside a route folder wraps its whole body in one
native_route(...)block - a child interpreter script assigns
catalog.RULESonce at its top
- route folders apply it to every test through the autouse fixture in their
- Dispatch tests use
support.routing.routed(...)instead, which setscatalog.RULESto exactly the rules given - Open either once per test, never per call. They swap a module global, so overlapping blocks (one per task in an
asyncio.gather) restore out of order and leak rules into later tests - Never select a backend through
LITELLM_RUST,litellm.rust(...)or any other rebinding ofcatalog.RULES - No test here depends on the rollout switch
- only no rule,
PYTHON_ONLYandRUST_REQUIREDpick a path without it, so those are the only rollouts used here - Rust with Python fallback needs the switch, so it is not reachable from this directory
- what
LITELLM_RUSTandlitellm.rust(...)mean is tested intests/unit/rust_bridge/test_configuration.py, mostly throughdecide, which takes both as plain values
- only no rule,
- Tests pass whatever the shipped rollout in
litellm/rust_bridge/catalog.pysays, including for aPYTHON_ONLYroute
Layout
- One folder per route (
ocr/,messages/,responses/,chat_completions/), all using the same file namestest_dispatch.pywhich path the rules pick for each public call, and that the call reaches the native routetest_requests.pyPython inputs that reach the wiretest_failures.pyerrors raised to the caller and rejection before provider IOtest_settings.pyglobals, env, named credentials and their precedencetest_streaming.pystream relay, early close and stream-time loggingtest_callbacks.pythe logger hook contracttest_body_hooks.pyhandler body hooks such as interceptors and agentic loopstest_lifecycle.pycancellation, concurrency, context and nested callstest_cache.pythe configured cache seen from this route
embeddings/holds onlytest_dispatch.pyso far<route>/data.pyholds the route's request data and itscall<route>/conftest.pyowns theserverfixture and the autousenativefixturesupport/holds only route-neutral helpers- Never parametrize one test across routes, except in
test_public_entries.py, whose subject is that every route serves its public call forms the same way - Call
_nativedirectly only for a case the public API cannot reach