mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-18 04:44:37 +00:00
* feat(rust-bridge): scope catalog rules with a contextvar Co-Authored-By: Yujong Lee <yujong@berri.ai> * test(rust-bridge): select native integration routes with scoped rules Co-Authored-By: Yujong Lee <yujong@berri.ai> * test(rust-bridge): run the Rust extension suite without LITELLM_RUST Co-Authored-By: Yujong Lee <yujong@berri.ai> * test(rust-bridge): use scoped catalog rules in dispatch tests Co-Authored-By: Yujong Lee <yujong@berri.ai> * refactor(rust-bridge): keep catalog rules a static global and override them once per test Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
3 KiB
3 KiB
Invariants
- This directory tests the Rust path and nothing else. Treat the Python implementation of every route as already removed. Never call it on purpose, never run one request through both engines, and 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 asserts the call was served natively with
support.routing.assert_served_natively - Select the Rust path with
support.routing.native_route(...), which prependsRUST_REQUIREDrules tocatalog.RULESand restores them on exit. Each route folder'sconftest.pyapplies it to every test through an autouse fixture. A test outside a route folder wraps its whole body in onenative_route(...)block, and a child interpreter script assignscatalog.RULESonce at its top. Never select a backend by reading or settingLITELLM_RUST, callinglitellm.rust(...)or rebindingcatalog.RULESany other way. The rollout inlitellm/rust_bridge/catalog.pyis a product decision, and a test here must pass no matter what it says, including for a route markedPYTHON_ONLY catalog.RULESis static at runtime andnative_route(...)swaps a module global, so open it once per test and never per call. Two overlapping blocks, such as one per task inside anasyncio.gather, restore out of order and leave the wrong rules behind for later tests- A test whose subject is the rollout switch itself (env,
litellm.rust(...), catalog rules) is a unit test oflitellm/rust_bridge/configuration.pyorcatalog.pyand lives intests/unit/rust_bridge/ - A test lives here only when it cannot be written in Rust. That means it needs the Python public API, Python-owned state such as
litellm.cacheand callbacks, or 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
- Never parametrize one test across routes. Each route folder owns its tests, its
serverfixture, its request data and itscall - Call
_nativedirectly only for a case the public API cannot reach
Layout
Each route folder (ocr/, messages/, responses/, chat_completions/) uses the same file names, one concern per file
test_dispatch.pythe 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
Route data and the route's call live in <route>/data.py, and <route>/conftest.py owns the server fixture and the autouse native fixture. support/ holds only route-neutral helpers