From a546a1720faffda8ef1b5b63573a89c8e1947b93 Mon Sep 17 00:00:00 2001 From: "devin-ai-integration[bot]" <158243242+devin-ai-integration[bot]@users.noreply.github.com> Date: Wed, 7 Oct 2026 16:33:49 -0700 Subject: [PATCH] fix(ci): align misc unit tests with NativeCall bridge and widened e2e diff gates (#45180) * fix(ci): pass NativeCall to transcription bridge fakes in rust bridge tests Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * fix(ci): assert the broadened e2e harness and basedpyright diff gates from #45172 Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> * test(rust-bridge): pin every NativeCall field in transcription bridge fakes Co-Authored-By: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --------- Co-authored-by: Devin AI <158243242+devin-ai-integration[bot]@users.noreply.github.com> --- .../test_audio_transcription_rust_bridge.py | 103 +++++++++++------- tests/unit/test_lint_workflow_diff_gates.py | 36 +++++- 2 files changed, 94 insertions(+), 45 deletions(-) diff --git a/tests/unit/test_audio_transcription_rust_bridge.py b/tests/unit/test_audio_transcription_rust_bridge.py index 48832528cc8..31ad5b72cc9 100644 --- a/tests/unit/test_audio_transcription_rust_bridge.py +++ b/tests/unit/test_audio_transcription_rust_bridge.py @@ -9,10 +9,23 @@ import pytest import litellm from litellm.llms.bedrock.audio_transcription import BedrockAudioTranscriptionRustDispatch from litellm.rust_bridge import bindings, configuration +from litellm.rust_bridge.public_call import NativeCall from litellm.rust_bridge.transcription.native import NATIVE_ATRANSCRIPTION, NATIVE_TRANSCRIPTION MODEL: Final = "bedrock/mistral.voxtral-mini-3b-2507" AUDIO_FILE: Final = ("audio.wav", b"audio", "audio/wav") +TRANSCRIPTION_FIELDS: Final = frozenset( + { + "model", + "audio", + "api_key", + "api_base", + "custom_llm_provider", + "extra_headers", + "optional_params", + "timeout_seconds", + } +) class RustBridgeDeclined(Exception): @@ -38,23 +51,10 @@ def isolated_bridge(monkeypatch: pytest.MonkeyPatch) -> Generator[None]: class SyncBridge: def __init__(self, effect: BaseException | None = None) -> None: self._effect: Final = effect - self.calls: tuple[dict[str, object], ...] = () + self.calls: tuple[NativeCall, ...] = () - def __call__( - self, - model: str, - audio: dict[str, object], - api_key: str | None, - api_base: str | None, - custom_llm_provider: str | None, - extra_headers: dict[str, object] | None, - optional_params: dict[str, object], - timeout_seconds: float | None, - ) -> dict[str, object]: - self.calls = ( - *self.calls, - {"model": model, "audio": audio, "provider": custom_llm_provider, "timeout": timeout_seconds}, - ) + def __call__(self, call: NativeCall) -> dict[str, object]: + self.calls = (*self.calls, call) if self._effect is not None: raise self._effect return {"text": "rust"} @@ -62,20 +62,10 @@ class SyncBridge: class AsyncBridge: def __init__(self) -> None: - self.calls: tuple[str, ...] = () + self.calls: tuple[NativeCall, ...] = () - async def __call__( - self, - model: str, - audio: dict[str, object], - api_key: str | None, - api_base: str | None, - custom_llm_provider: str | None, - extra_headers: dict[str, object] | None, - optional_params: dict[str, object], - timeout_seconds: float | None, - ) -> dict[str, object]: - self.calls = (*self.calls, model) + async def __call__(self, call: NativeCall) -> dict[str, object]: + self.calls = (*self.calls, call) return {"text": "async rust"} @@ -98,15 +88,18 @@ def test_dispatch_marshals_audio_into_rust_call() -> None: response: Final = dispatch_sync() + expected: Final = { + "model": MODEL, + "audio": {"data": "YXVkaW8=", "format": "wav", "filename": "audio.wav"}, + "api_key": None, + "api_base": None, + "custom_llm_provider": "bedrock", + "extra_headers": None, + "optional_params": {"temperature": 0}, + "timeout_seconds": 5.0, + } assert response.text == "rust" - assert bridge.calls == ( - { - "model": MODEL, - "audio": {"data": "YXVkaW8=", "format": "wav", "filename": "audio.wav"}, - "provider": "bedrock", - "timeout": 5.0, - }, - ) + assert bridge.calls == (NativeCall(args=(), kwargs=expected, bound=expected),) @pytest.mark.parametrize("disable", ("process", "environment")) @@ -144,6 +137,36 @@ def test_upstream_error_maps_to_api_error() -> None: assert raised.value.status_code == 503 +@pytest.mark.asyncio +async def test_async_dispatch_marshals_audio_into_rust_call() -> None: + bridge: Final = AsyncBridge() + NATIVE_ATRANSCRIPTION.override(bridge) + + response: Final = await BedrockAudioTranscriptionRustDispatch().async_audio_transcriptions( + model=MODEL, + audio_file=AUDIO_FILE, + api_key=None, + api_base=None, + custom_llm_provider="bedrock", + extra_headers=None, + optional_params={"temperature": 0}, + timeout=5, + ) + + expected: Final = { + "model": MODEL, + "audio": {"data": "YXVkaW8=", "format": "wav", "filename": "audio.wav"}, + "api_key": None, + "api_base": None, + "custom_llm_provider": "bedrock", + "extra_headers": None, + "optional_params": {"temperature": 0}, + "timeout_seconds": 5.0, + } + assert response.text == "async rust" + assert bridge.calls == (NativeCall(args=(), kwargs=expected, bound=expected),) + + def test_bedrock_transcription_dispatches_to_rust_from_sdk_entrypoint() -> None: bridge: Final = SyncBridge() NATIVE_TRANSCRIPTION.override(bridge) @@ -152,7 +175,8 @@ def test_bedrock_transcription_dispatches_to_rust_from_sdk_entrypoint() -> None: assert isinstance(response, litellm.TranscriptionResponse) assert response.text == "rust" - assert bridge.calls[0]["model"] == MODEL.removeprefix("bedrock/") + assert bridge.calls[0].bound["model"] == MODEL.removeprefix("bedrock/") + assert frozenset(bridge.calls[0].bound) == TRANSCRIPTION_FIELDS @pytest.mark.asyncio @@ -163,7 +187,8 @@ async def test_bedrock_atranscription_dispatches_to_rust_from_sdk_entrypoint() - response: Final = await litellm.atranscription(model=MODEL, file=AUDIO_FILE) assert response.text == "async rust" - assert bridge.calls == (MODEL.removeprefix("bedrock/"),) + assert tuple(call.bound["model"] for call in bridge.calls) == (MODEL.removeprefix("bedrock/"),) + assert frozenset(bridge.calls[0].bound) == TRANSCRIPTION_FIELDS @pytest.mark.asyncio diff --git a/tests/unit/test_lint_workflow_diff_gates.py b/tests/unit/test_lint_workflow_diff_gates.py index 23cb8aa1a0b..7b1d7802d53 100644 --- a/tests/unit/test_lint_workflow_diff_gates.py +++ b/tests/unit/test_lint_workflow_diff_gates.py @@ -11,6 +11,7 @@ import pytest WORKFLOW: Final = Path(__file__).resolve().parents[2] / ".github" / "workflows" / "test-linting.yml" DIFF_GATE: Final = re.compile(r'git diff --name-only --diff-filter=\w+ "\$GATE_BASE_SHA" HEAD -- (.+?) \|') GATES: Final = tuple(tuple(shlex.split(gate.group(1))) for gate in DIFF_GATE.finditer(WORKFLOW.read_text())) +PYTHON_GATES: Final = tuple(gate for gate in GATES if gate[0].startswith(":(glob)")) def _git(cwd: Path, *args: str) -> str: @@ -41,13 +42,14 @@ def _changed_files_selected_by(tmp_path: Path, pathspecs: tuple[str, ...], files ) -def test_workflow_still_carries_the_ruff_format_e2e_basedpyright_and_claude_code_harness_diff_gates() -> None: - assert frozenset(_scoped_root(gate[0]) for gate in GATES) == frozenset( - {"litellm/", "tests/e2e/", "tests/e2e/claude_code/"} +def test_workflow_still_carries_the_ruff_format_e2e_basedpyright_and_e2e_harness_diff_gates() -> None: + assert len(GATES) == 3 + assert frozenset(gate[0] for gate in GATES) == frozenset( + {":(glob)litellm/**/*.py", ":(glob)tests/e2e/**/*.py", "tests/e2e"} ) -@pytest.mark.parametrize("pathspecs", GATES, ids=" ".join) +@pytest.mark.parametrize("pathspecs", PYTHON_GATES, ids=" ".join) def test_diff_gate_selects_top_level_and_nested_python_files_only(tmp_path: Path, pathspecs: tuple[str, ...]) -> None: root = _scoped_root(pathspecs[0]) top_level = f"{root}top_level_module.py" @@ -60,19 +62,41 @@ def test_diff_gate_selects_top_level_and_nested_python_files_only(tmp_path: Path assert selected == frozenset({top_level, nested}) +@pytest.mark.parametrize( + "trigger", + ( + "tests/e2e_harness/top_level_module.py", + "tests/e2e_harness/pkg/sub/nested_module.py", + "pyrightconfig.json", + ), +) +def test_e2e_basedpyright_gate_also_fires_on_harness_python_and_pyrightconfig(tmp_path: Path, trigger: str) -> None: + selected = _changed_files_selected_by( + tmp_path, + _gate_rooted_at("tests/e2e/"), + (trigger, "tests/e2e_harness/notes.md", "elsewhere/pyrightconfig.json", "tests/e2e_harnessish/module.py"), + ) + assert selected == frozenset({trigger}) + + @pytest.mark.parametrize( "trigger", ( "tests/e2e/claude_code/cron_vm/install_claude_code.sh", + "tests/e2e/notes.md", + "tests/e2e/pkg/sub/nested_module.py", + "tests/e2e_harness/claude_code/test_driver.py", "pyproject.toml", "uv.lock", ".github/workflows/test-linting.yml", ), ) -def test_claude_code_gate_also_fires_on_its_installer_dependency_manifests_and_workflow( +def test_e2e_harness_gate_fires_on_any_e2e_or_harness_file_its_dependency_manifests_and_workflow( tmp_path: Path, trigger: str ) -> None: selected = _changed_files_selected_by( - tmp_path, _gate_rooted_at("tests/e2e/claude_code/"), (trigger, "elsewhere/pyproject.toml", "tests/e2e/notes.md") + tmp_path, + _gate_rooted_at("tests/e2e"), + (trigger, "tests/e2e/ui/spec.ts", "tests/e2e/ui/pkg/page.py", "elsewhere/pyproject.toml", "tests/e2e_other/module.py"), ) assert selected == frozenset({trigger})