mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-05 02:41:56 +00:00
test(integration): group /v1/messages contracts under tests/integration/messages_endpoint (#43352)
* test(integration): group /v1/messages contracts under tests/integration/messages Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(integration): make ci coverage census collect nested test dirs Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(integration): nest /v1/messages contracts under messages_endpoint/providers Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: kerry <kerry@berri.ai> Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com>
This commit is contained in:
parent
8d166258a6
commit
f12f7b5a03
18 changed files with 6 additions and 3 deletions
2
.github/scripts/assert_ci_coverage.py
vendored
2
.github/scripts/assert_ci_coverage.py
vendored
|
|
@ -516,7 +516,7 @@ def _integration_ownership(repo_root: pathlib.Path = REPO_ROOT) -> tuple[frozens
|
|||
str(path.relative_to(repo_root))
|
||||
for folders in groups.values()
|
||||
for folder in folders
|
||||
for path in (integration_root / folder).glob("test_*.py")
|
||||
for path in (integration_root / folder).rglob("test_*.py")
|
||||
)
|
||||
browser_manifest: Final = repo_root / "tests/e2e/ui/tests/integrationCritical/expected.json"
|
||||
browser_nodes: Final = json.loads(browser_manifest.read_text()) if browser_manifest.exists() else ()
|
||||
|
|
|
|||
|
|
@ -28,6 +28,8 @@ Provider contracts exercise actual TCP requests with synthetic credentials and l
|
|||
|
||||
Streaming checks send real HTTP transfer chunks, including one-byte partitions, fragmented tools, incomplete transfers and a cancellation barrier. They assert meaningful text, tool arguments, final usage and persisted cost. The Redis recovery case owns a separate database and Redis process, uses the supported one-second circuit-breaker recovery setting, waits for the real subscriber and verifies response data in Redis after restart. CircleCI reuses its existing Redis image for that extra process; it never pulls an image during tests
|
||||
|
||||
The `messages_endpoint/` directory holds `/v1/messages` endpoint contracts: native-provider backends under `providers/` (`anthropic`, `bedrock`, `gemini`) and the translation bridges (`responses_bridge`, `chat_bridge`) at the top level. It runs in the providers shard; `run.py` selects test files recursively under each scheduled directory
|
||||
|
||||
The sdk shard exercises the SDK's own HTTP clients against local protocol peers with no gateway in the path, so a case here fails only when the client library or its wire behavior changes. The HTTP/2 case runs a hypercorn TLS peer offering h2 and http/1.1 over ALPN, drives the sync and async httpx handlers at it with `LITELLM_HTTP2` off and on, and asserts the version both the client and the peer observed on the wire. Put a test here only when it needs no proxy, database or Redis; a case that reaches the gateway belongs in one of the other shards
|
||||
|
||||
The extensions shard uses the built-in generic callback and guardrail transports. It checks callback correlation and credential exclusion, guardrail rewriting and denial, retained OpenAI consumers and A2A wire versions. CircleCI runs it on parallel nodes, and each node starts its own database, Redis, upstream and proxy and runs its share of the group's files serially, split by recorded timings with `circleci tests split`. Tests keep the isolation of a serial run; they still must not assume a particular set of sibling files. `run.py <group> --list` prints a group's files and `run.py <group> <file>...` runs a subset of them
|
||||
|
|
|
|||
|
|
@ -10,6 +10,7 @@ OWNED_DIRECTORIES: Final = frozenset(
|
|||
"routing",
|
||||
"providers",
|
||||
"streaming",
|
||||
"messages_endpoint",
|
||||
"configuration",
|
||||
"mcp",
|
||||
"observability",
|
||||
|
|
|
|||
|
|
@ -14,7 +14,7 @@ GROUPS: Final = MappingProxyType(
|
|||
"management": ("management", "authorization", "configuration"),
|
||||
"accounting": ("pricing", "spend"),
|
||||
"database": ("database",),
|
||||
"providers": ("providers", "routing", "streaming"),
|
||||
"providers": ("providers", "routing", "streaming", "messages_endpoint"),
|
||||
"extensions": ("observability", "compatibility"),
|
||||
"mcp": ("mcp",),
|
||||
"sdk": ("sdk",),
|
||||
|
|
@ -37,7 +37,7 @@ def main() -> int:
|
|||
group_files: Final = tuple(
|
||||
str(path.relative_to(root))
|
||||
for folder in GROUPS[options.group]
|
||||
for path in sorted((root / "tests/integration" / folder).glob("test_*.py"))
|
||||
for path in sorted((root / "tests/integration" / folder).rglob("test_*.py"))
|
||||
)
|
||||
if options.list:
|
||||
print("\n".join(group_files))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue