mirror of
https://github.com/BerriAI/litellm.git
synced 2026-10-08 03:08:45 +00:00
fix(tests): match the lowercased bind error in the owned-proxy port-race retry (#45097)
Co-authored-by: mateo-berri <277851410+mateo-berri@users.noreply.github.com>
This commit is contained in:
parent
086bcd2a47
commit
736da28ac1
2 changed files with 31 additions and 8 deletions
|
|
@ -119,7 +119,7 @@ def _stop(process: subprocess.Popen[bytes]) -> None:
|
|||
|
||||
|
||||
_PORT_ATTEMPTS: Final = 3
|
||||
_BIND_COLLISION: Final = os.strerror(errno.EADDRINUSE)
|
||||
_BIND_COLLISION: Final = os.strerror(errno.EADDRINUSE).lower()
|
||||
|
||||
|
||||
def _free_port() -> int:
|
||||
|
|
@ -151,7 +151,7 @@ def _launch(command: tuple[str, ...], root: Path, environment: Mapping[str, str]
|
|||
|
||||
|
||||
def _lost_port_race(exit_code: int | None, log: Path) -> bool:
|
||||
return exit_code is not None and _BIND_COLLISION in log.read_text()
|
||||
return exit_code is not None and _BIND_COLLISION in log.read_text().lower()
|
||||
|
||||
|
||||
def _wait_until_ready(launch: _Launch) -> None:
|
||||
|
|
|
|||
|
|
@ -1,8 +1,10 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import errno
|
||||
import importlib
|
||||
import os
|
||||
import socket
|
||||
from collections.abc import Iterator
|
||||
from pathlib import Path
|
||||
from types import ModuleType
|
||||
from typing import Final
|
||||
|
|
@ -10,7 +12,6 @@ from typing import Final
|
|||
import pytest
|
||||
|
||||
TESTS_DIR: Final = Path(__file__).resolve().parents[2]
|
||||
BIND_ERROR_LINE: Final = f"ERROR: {OSError(errno.EADDRINUSE, os.strerror(errno.EADDRINUSE))}\n"
|
||||
UNRELATED_CRASH: Final = "Traceback (most recent call last):\nModuleNotFoundError: No module named 'litellm'\n"
|
||||
|
||||
|
||||
|
|
@ -20,19 +21,41 @@ def process_module(monkeypatch: pytest.MonkeyPatch) -> ModuleType:
|
|||
return importlib.import_module("integration._support.process")
|
||||
|
||||
|
||||
async def _refused_bind(port: int) -> OSError | None:
|
||||
try:
|
||||
await asyncio.get_running_loop().create_server(asyncio.Protocol, "127.0.0.1", port)
|
||||
except OSError as refused:
|
||||
return refused
|
||||
return None
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def bind_error_line() -> Iterator[str]:
|
||||
with socket.socket() as held:
|
||||
held.bind(("127.0.0.1", 0))
|
||||
held.listen()
|
||||
refused: Final = asyncio.run(_refused_bind(held.getsockname()[1]))
|
||||
assert refused is not None and refused.errno == errno.EADDRINUSE
|
||||
yield f"ERROR: {refused}\n"
|
||||
|
||||
|
||||
def _written_log(directory: Path, text: str) -> Path:
|
||||
log: Final = directory / "owned-proxy.log"
|
||||
log.write_text(text)
|
||||
return log
|
||||
|
||||
|
||||
def test_lost_port_race_matches_the_bind_error_the_server_logs(process_module: ModuleType, tmp_path: Path) -> None:
|
||||
assert process_module._lost_port_race(1, _written_log(tmp_path, BIND_ERROR_LINE))
|
||||
def test_lost_port_race_matches_the_bind_error_the_server_logs(
|
||||
process_module: ModuleType, bind_error_line: str, tmp_path: Path
|
||||
) -> None:
|
||||
assert process_module._lost_port_race(1, _written_log(tmp_path, bind_error_line))
|
||||
|
||||
|
||||
def test_lost_port_race_ignores_an_exit_for_another_reason(process_module: ModuleType, tmp_path: Path) -> None:
|
||||
assert not process_module._lost_port_race(1, _written_log(tmp_path, UNRELATED_CRASH))
|
||||
|
||||
|
||||
def test_lost_port_race_needs_the_process_to_have_exited(process_module: ModuleType, tmp_path: Path) -> None:
|
||||
assert not process_module._lost_port_race(None, _written_log(tmp_path, BIND_ERROR_LINE))
|
||||
def test_lost_port_race_needs_the_process_to_have_exited(
|
||||
process_module: ModuleType, bind_error_line: str, tmp_path: Path
|
||||
) -> None:
|
||||
assert not process_module._lost_port_race(None, _written_log(tmp_path, bind_error_line))
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue