Files
hermes-webui/tests/test_cron_import_shadowing.py
T

61 lines
2.1 KiB
Python

"""Regression coverage for top-level cron packages shadowing agent cron.jobs."""
from __future__ import annotations
import importlib
import sys
from pathlib import Path
def _drop_cron_modules() -> None:
for name in list(sys.modules):
if name == "cron" or name.startswith("cron."):
sys.modules.pop(name, None)
def _reset_cron_import_path_ready(routes) -> None:
routes._AGENT_CRON_IMPORT_PATH_READY = None
def test_agent_cron_import_path_prefers_agent_cron_over_plugin_shadow(monkeypatch, tmp_path):
import api.config as config
import api.routes as routes
agent_dir = tmp_path / "hermes-agent"
site_packages = tmp_path / "site-packages"
agent_cron = agent_dir / "cron"
shadow_cron = site_packages / "cron"
agent_cron.mkdir(parents=True)
shadow_cron.mkdir(parents=True)
(agent_cron / "__init__.py").write_text("", encoding="utf-8")
(agent_cron / "jobs.py").write_text(
"def list_jobs(include_disabled=False):\n"
" return [{'id': 'agent-cron', 'include_disabled': include_disabled}]\n",
encoding="utf-8",
)
(shadow_cron / "__init__.py").write_text("SHADOW_CRON = True\n", encoding="utf-8")
monkeypatch.setattr(config, "_AGENT_DIR", agent_dir)
monkeypatch.setattr(routes, "_AGENT_CRON_IMPORT_PATH_READY", None)
monkeypatch.syspath_prepend(str(agent_dir))
monkeypatch.syspath_prepend(str(site_packages))
_drop_cron_modules()
try:
shadowed_cron = importlib.import_module("cron")
assert Path(shadowed_cron.__file__).resolve() == shadow_cron / "__init__.py"
routes._ensure_agent_cron_import_path()
cron_jobs = importlib.import_module("cron.jobs")
assert Path(cron_jobs.__file__).resolve() == agent_cron / "jobs.py"
assert cron_jobs.list_jobs(include_disabled=True) == [
{"id": "agent-cron", "include_disabled": True}
]
sys_path_after_first_call = list(sys.path)
routes._ensure_agent_cron_import_path()
assert sys.path == sys_path_after_first_call
finally:
_drop_cron_modules()
_reset_cron_import_path_ready(routes)