mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 19:47:12 +01:00
test_passes_store_and_repo_root asserted
env["PYTHONPATH"].endswith("testsAndMisc"), which is a property of the
checkout's directory name rather than of the code. It fails in any
worktree, which is where ci-mirror runs its gates.
Assert against the value reindex.py actually computes,
Path(reindex.__file__).resolve().parents[2]. Exact equality is a
stronger check than the suffix match it replaces.
This was invisible until now because ci-mirror invoked
pytest_changed_packages.py with no arguments, and that script returns 0
on empty argv -- so the pre-push pytest stage never ran. The next commit
fixes the invocation.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01PJrqKERAo5QUeEHWS5Asgp
159 lines
5.7 KiB
Python
159 lines
5.7 KiB
Python
"""Tests for archwiki_rag.reindex."""
|
|
|
|
from __future__ import annotations
|
|
|
|
from pathlib import Path
|
|
import subprocess
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from python_pkg.archwiki_rag import reindex
|
|
from python_pkg.archwiki_rag.constants import DATA_SUBDIR, LOCK_FILENAME
|
|
|
|
MOD = "python_pkg.archwiki_rag.reindex"
|
|
|
|
|
|
def _write_lock(store: Path, contents: str) -> None:
|
|
"""Create a knowledge-rag instance lock file.
|
|
|
|
Parameters:
|
|
store (Path): Store root.
|
|
contents (str): Raw lock file body.
|
|
"""
|
|
data = store / DATA_SUBDIR
|
|
data.mkdir(parents=True, exist_ok=True)
|
|
(data / LOCK_FILENAME).write_text(contents, encoding="utf-8")
|
|
|
|
|
|
class TestReadLockPid:
|
|
def test_missing_lock(self, tmp_path: Path) -> None:
|
|
assert reindex.read_lock_pid(tmp_path) is None
|
|
|
|
def test_reads_pid(self, tmp_path: Path) -> None:
|
|
_write_lock(tmp_path, "4321\n")
|
|
assert reindex.read_lock_pid(tmp_path) == 4321
|
|
|
|
def test_non_numeric_lock(self, tmp_path: Path) -> None:
|
|
_write_lock(tmp_path, "not-a-pid\n")
|
|
assert reindex.read_lock_pid(tmp_path) is None
|
|
|
|
def test_empty_lock(self, tmp_path: Path) -> None:
|
|
_write_lock(tmp_path, "")
|
|
assert reindex.read_lock_pid(tmp_path) is None
|
|
|
|
|
|
class TestIsServerRunning:
|
|
def test_no_lock(self, tmp_path: Path) -> None:
|
|
assert reindex.is_server_running(tmp_path) is False
|
|
|
|
def test_live_process(self, tmp_path: Path) -> None:
|
|
_write_lock(tmp_path, "1\n") # pid 1 always exists
|
|
assert reindex.is_server_running(tmp_path) is True
|
|
|
|
def test_stale_lock_treated_as_free(self, tmp_path: Path) -> None:
|
|
_write_lock(tmp_path, "999999999\n")
|
|
assert reindex.is_server_running(tmp_path) is False
|
|
|
|
|
|
class TestLoadPerCore:
|
|
def test_divides_load_by_cpu_count(self, tmp_path: Path) -> None:
|
|
loadavg = tmp_path / "loadavg"
|
|
loadavg.write_text("8.00 4.00 2.00 3/1234 5678\n", encoding="utf-8")
|
|
with (
|
|
patch(f"{MOD}.LOADAVG_PATH", loadavg),
|
|
patch(f"{MOD}.os.cpu_count", return_value=4),
|
|
):
|
|
assert reindex.load_per_core() == 2.0
|
|
|
|
def test_missing_file_is_not_busy(self, tmp_path: Path) -> None:
|
|
with patch(f"{MOD}.LOADAVG_PATH", tmp_path / "absent"):
|
|
assert reindex.load_per_core() == 0.0
|
|
|
|
def test_unparseable_content_is_not_busy(self, tmp_path: Path) -> None:
|
|
loadavg = tmp_path / "loadavg"
|
|
loadavg.write_text("garbage\n", encoding="utf-8")
|
|
with patch(f"{MOD}.LOADAVG_PATH", loadavg):
|
|
assert reindex.load_per_core() == 0.0
|
|
|
|
def test_empty_file_is_not_busy(self, tmp_path: Path) -> None:
|
|
loadavg = tmp_path / "loadavg"
|
|
loadavg.write_text("", encoding="utf-8")
|
|
with patch(f"{MOD}.LOADAVG_PATH", loadavg):
|
|
assert reindex.load_per_core() == 0.0
|
|
|
|
def test_unknown_cpu_count_falls_back_to_one(self, tmp_path: Path) -> None:
|
|
loadavg = tmp_path / "loadavg"
|
|
loadavg.write_text("3.00 1.00 1.00 1/1 1\n", encoding="utf-8")
|
|
with (
|
|
patch(f"{MOD}.LOADAVG_PATH", loadavg),
|
|
patch(f"{MOD}.os.cpu_count", return_value=None),
|
|
):
|
|
assert reindex.load_per_core() == 3.0
|
|
|
|
|
|
class TestBlockingReason:
|
|
@patch(f"{MOD}.is_server_running", return_value=True)
|
|
def test_server_running_blocks(self, mock_running: MagicMock) -> None:
|
|
reason = reindex.blocking_reason(Path("/store"))
|
|
assert reason is not None
|
|
assert "already using this store" in reason
|
|
|
|
@patch(f"{MOD}.load_per_core", return_value=4.0)
|
|
@patch(f"{MOD}.is_server_running", return_value=False)
|
|
def test_busy_machine_blocks(
|
|
self,
|
|
mock_running: MagicMock,
|
|
mock_load: MagicMock,
|
|
) -> None:
|
|
reason = reindex.blocking_reason(Path("/store"))
|
|
assert reason is not None
|
|
assert "machine is busy" in reason
|
|
|
|
@patch(f"{MOD}.load_per_core", return_value=4.0)
|
|
@patch(f"{MOD}.is_server_running", return_value=False)
|
|
def test_ignore_load_overrides(
|
|
self,
|
|
mock_running: MagicMock,
|
|
mock_load: MagicMock,
|
|
) -> None:
|
|
assert reindex.blocking_reason(Path("/store"), ignore_load=True) is None
|
|
|
|
@patch(f"{MOD}.load_per_core", return_value=0.2)
|
|
@patch(f"{MOD}.is_server_running", return_value=False)
|
|
def test_idle_machine_is_clear(
|
|
self,
|
|
mock_running: MagicMock,
|
|
mock_load: MagicMock,
|
|
) -> None:
|
|
assert reindex.blocking_reason(Path("/store")) is None
|
|
|
|
|
|
class TestRunReindex:
|
|
def test_missing_interpreter(self) -> None:
|
|
with patch(f"{MOD}.KNOWLEDGE_RAG_PYTHON", Path("/nonexistent/python")):
|
|
assert reindex.run_reindex(Path("/store")) == 127
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
def test_passes_store_and_repo_root(self, mock_run: MagicMock) -> None:
|
|
mock_run.return_value = subprocess.CompletedProcess([], returncode=0)
|
|
with (
|
|
patch.object(Path, "exists", return_value=True),
|
|
patch.dict(f"{MOD}.os.environ", {}, clear=True),
|
|
):
|
|
assert reindex.run_reindex(Path("/store")) == 0
|
|
|
|
env = mock_run.call_args.kwargs["env"]
|
|
assert env["KNOWLEDGE_RAG_DIR"] == "/store"
|
|
expected_root = Path(reindex.__file__).resolve().parents[2]
|
|
assert env["PYTHONPATH"] == str(expected_root)
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
def test_prepends_to_existing_pythonpath(self, mock_run: MagicMock) -> None:
|
|
mock_run.return_value = subprocess.CompletedProcess([], returncode=3)
|
|
with (
|
|
patch.object(Path, "exists", return_value=True),
|
|
patch.dict(f"{MOD}.os.environ", {"PYTHONPATH": "/pre"}, clear=True),
|
|
):
|
|
assert reindex.run_reindex(Path("/store")) == 3
|
|
|
|
assert mock_run.call_args.kwargs["env"]["PYTHONPATH"].endswith(":/pre")
|