mirror of
https://github.com/BerriAI/litellm.git
synced 2026-08-28 05:25:59 +00:00
fix(pre-commit): kill background jobs and remove their logs on interrupt
This commit is contained in:
parent
2f36625e7f
commit
a1f497c7c0
2 changed files with 67 additions and 2 deletions
|
|
@ -110,6 +110,14 @@ python_checks() {
|
|||
return $rc
|
||||
}
|
||||
|
||||
on_interrupt() {
|
||||
trap - INT TERM
|
||||
rm -f "${python_log:-}" "${dash_log:-}" "${gen_log:-}"
|
||||
kill 0 2>/dev/null
|
||||
exit 130
|
||||
}
|
||||
trap on_interrupt INT TERM
|
||||
|
||||
if [ -n "$litellm_py_files" ]; then
|
||||
python_log=$(mktemp)
|
||||
python_checks > "$python_log" 2>&1 &
|
||||
|
|
|
|||
|
|
@ -1,5 +1,9 @@
|
|||
import os
|
||||
import signal
|
||||
import subprocess
|
||||
import time
|
||||
from collections.abc import Callable
|
||||
from contextlib import suppress
|
||||
from pathlib import Path
|
||||
|
||||
import pytest
|
||||
|
|
@ -29,6 +33,11 @@ case "$*" in
|
|||
lint)
|
||||
[ "${STUB_FAIL:-}" = "make-lint" ] && exit 1
|
||||
[ -n "${STUB_BARRIER_DIR:-}" ] && barrier_sync python "dashboard genapi"
|
||||
if [ -n "${STUB_HANG_DIR:-}" ]; then
|
||||
echo "$$" > "$STUB_HANG_DIR/make.pid"
|
||||
touch "$STUB_HANG_DIR/make.started"
|
||||
sleep 60
|
||||
fi
|
||||
;;
|
||||
esac
|
||||
exit 0
|
||||
|
|
@ -99,13 +108,17 @@ def _sandbox(tmp_path: Path) -> tuple[Path, Path]:
|
|||
return repo, bin_dir
|
||||
|
||||
|
||||
def _run(repo: Path, bin_dir: Path, extra_env: dict[str, str]) -> subprocess.CompletedProcess[str]:
|
||||
env = {
|
||||
def _env(repo: Path, bin_dir: Path, extra_env: dict[str, str]) -> dict[str, str]:
|
||||
return {
|
||||
"PATH": os.pathsep.join([str(bin_dir), "/usr/bin", "/bin"]),
|
||||
"HOME": str(repo.parent),
|
||||
"STUB_BIN": str(bin_dir),
|
||||
**extra_env,
|
||||
}
|
||||
|
||||
|
||||
def _run(repo: Path, bin_dir: Path, extra_env: dict[str, str]) -> subprocess.CompletedProcess[str]:
|
||||
env = _env(repo, bin_dir, extra_env)
|
||||
return subprocess.run(
|
||||
[str(SCRIPT)],
|
||||
cwd=repo,
|
||||
|
|
@ -135,6 +148,50 @@ def test_all_blocks_passing_exits_zero(tmp_path: Path) -> None:
|
|||
assert proc.returncode == 0, proc.stdout + proc.stderr
|
||||
|
||||
|
||||
def _wait_until(predicate: Callable[[], bool], timeout_seconds: float) -> bool:
|
||||
deadline = time.monotonic() + timeout_seconds
|
||||
while time.monotonic() < deadline:
|
||||
if predicate():
|
||||
return True
|
||||
time.sleep(0.05)
|
||||
return predicate()
|
||||
|
||||
|
||||
def _pid_gone(pid: int) -> bool:
|
||||
try:
|
||||
os.kill(pid, 0)
|
||||
except ProcessLookupError:
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def test_interrupt_kills_background_jobs_and_removes_logs(tmp_path: Path) -> None:
|
||||
repo, bin_dir = _sandbox(tmp_path)
|
||||
hang_dir = tmp_path / "hang"
|
||||
hang_dir.mkdir()
|
||||
tmp_dir = tmp_path / "tmpdir"
|
||||
tmp_dir.mkdir()
|
||||
extra = {"STUB_HANG_DIR": str(hang_dir), "TMPDIR": str(tmp_dir)}
|
||||
proc = subprocess.Popen(
|
||||
[str(SCRIPT)],
|
||||
cwd=repo,
|
||||
env=_env(repo, bin_dir, extra),
|
||||
stdout=subprocess.DEVNULL,
|
||||
stderr=subprocess.DEVNULL,
|
||||
start_new_session=True,
|
||||
)
|
||||
try:
|
||||
assert _wait_until((hang_dir / "make.started").exists, 10)
|
||||
os.killpg(proc.pid, signal.SIGINT)
|
||||
assert proc.wait(timeout=10) != 0
|
||||
make_pid = int((hang_dir / "make.pid").read_text())
|
||||
assert _wait_until(lambda: _pid_gone(make_pid), 5)
|
||||
assert list(tmp_dir.iterdir()) == []
|
||||
finally:
|
||||
with suppress(ProcessLookupError, PermissionError):
|
||||
os.killpg(proc.pid, signal.SIGTERM)
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("fail", "message"),
|
||||
[
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue