mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-11 03:38:38 +00:00
* docs(proxy): describe /v1/decisions and /v1/systemone in Swagger UI Add summaries, descriptions, inlined request body schemas with examples and typed 200 responses to the decision routes and their aliases, so the OpenAPI document and the lazy snapshot show both request formats Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(proxy): cap _inlined schema walk depth for the recursion check Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: gate undocumented POST routes in the proxy OpenAPI document Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * ci: install the proxy extra before the OpenAPI docs gate Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(proxy): drop unused TypeIs import from proxy _types 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>
60 lines
2.3 KiB
Python
60 lines
2.3 KiB
Python
"""Tests for scripts/openapi_docs_gate.py.
|
|
|
|
The blame rule lives in scripts/lint_base_counts.py and is tested there; what is tested
|
|
here is the checker output parse and `introduced`, the diff scan that names the new
|
|
endpoint behind a breach.
|
|
"""
|
|
|
|
from pathlib import Path
|
|
from typing import Final
|
|
|
|
import openapi_docs_gate as gate
|
|
|
|
|
|
def test_editing_the_checker_rekeys_the_base_counts(tmp_path: Path) -> None:
|
|
checker: Final = tmp_path / "check.py"
|
|
checker.write_text("print('v1')\n")
|
|
before: Final = gate.checker_identity(checker).artifact_name("abc123")
|
|
checker.write_text("print('v2')\n")
|
|
assert gate.checker_identity(checker).artifact_name("abc123") != before
|
|
|
|
|
|
def test_parse_violations_skips_anything_that_is_not_a_finding_line() -> None:
|
|
out: Final = "Some warning from an import\nPOST /v1/decisions OA001\nPOST /v1/decisions OA003\nnot a line\n"
|
|
assert gate.parse_violations(out) == (
|
|
gate.Violation("POST", "/v1/decisions", "OA001"),
|
|
gate.Violation("POST", "/v1/decisions", "OA003"),
|
|
)
|
|
|
|
|
|
def test_count_by_rule_sums_findings_per_code() -> None:
|
|
violations: Final = (
|
|
gate.Violation("POST", "/a", "OA001"),
|
|
gate.Violation("POST", "/b", "OA001"),
|
|
gate.Violation("POST", "/b", "OA003"),
|
|
)
|
|
assert dict(gate.count_by_rule(violations)) == {"OA001": 2, "OA003": 1}
|
|
|
|
|
|
def test_introduced_keeps_only_routes_registered_on_added_lines() -> None:
|
|
diff: Final = (
|
|
"diff --git a/litellm/proxy/x.py b/litellm/proxy/x.py\n"
|
|
"--- a/litellm/proxy/x.py\n"
|
|
"+++ b/litellm/proxy/x.py\n"
|
|
"@@ -0,0 +3,2 @@\n"
|
|
'+@router.post("/v1/new")\n'
|
|
"+async def new(request: Request): ...\n"
|
|
"@@ -10,1 +20,1 @@\n"
|
|
'-@router.post("/v1/removed")\n'
|
|
)
|
|
violations: Final = (
|
|
gate.Violation("POST", "/v1/new", "OA001"),
|
|
gate.Violation("POST", "/v1/old", "OA001"),
|
|
gate.Violation("POST", "/v1/removed", "OA001"),
|
|
)
|
|
assert gate.introduced(violations, gate.added_text(diff)) == (gate.Violation("POST", "/v1/new", "OA001"),)
|
|
|
|
|
|
def test_introduced_does_not_match_a_path_that_is_only_a_prefix_of_an_added_one() -> None:
|
|
added: Final = gate.added_text('+@router.post("/v1/decisions/batch")\n')
|
|
assert gate.introduced((gate.Violation("POST", "/v1/decisions", "OA002"),), added) == ()
|