discord-rss-bot/tests/conftest.py

73 lines
2.7 KiB
Python

from __future__ import annotations
import os
import shutil
import sys
import tempfile
from contextlib import suppress
from pathlib import Path
from typing import Any
import pytest
def pytest_addoption(parser: pytest.Parser) -> None:
"""Register custom command-line options for optional integration tests."""
parser.addoption(
"--run-real-git-backup-tests",
action="store_true",
default=False,
help="Run tests that push git backup state to a real repository.",
)
def pytest_configure(config: pytest.Config) -> None:
"""Configure test markers and isolate persistent app state per xdist worker."""
config.addinivalue_line(
"markers",
"real_git_backup_push: marks tests that push git backup state to a real git repo",
)
def pytest_sessionstart(session: pytest.Session) -> None:
"""Isolate persistent app state per xdist worker to avoid cross-worker test interference."""
worker_id: str = os.environ.get("PYTEST_XDIST_WORKER", "gw0")
worker_data_dir: Path = Path(tempfile.gettempdir()) / "discord-rss-bot-tests" / worker_id
# Start each worker from a clean state.
shutil.rmtree(worker_data_dir, ignore_errors=True)
worker_data_dir.mkdir(parents=True, exist_ok=True)
os.environ["DISCORD_RSS_BOT_DATA_DIR"] = str(worker_data_dir)
# If modules were imported before this hook (unlikely), force them to use
# the worker-specific location.
settings_module: Any = sys.modules.get("discord_rss_bot.settings")
if settings_module is not None:
settings_module.data_dir = str(worker_data_dir)
get_reader: Any = getattr(settings_module, "get_reader", None)
if get_reader is not None and hasattr(get_reader, "cache_clear"):
get_reader.cache_clear()
main_module: Any = sys.modules.get("discord_rss_bot.main")
if main_module is not None and settings_module is not None:
with suppress(Exception):
current_reader = getattr(main_module, "reader", None)
if current_reader is not None:
current_reader.close()
get_reader: Any = getattr(settings_module, "get_reader", None)
if callable(get_reader):
main_module.reader = get_reader()
def pytest_collection_modifyitems(config: pytest.Config, items: list[pytest.Item]) -> None:
"""Skip real git-repo push tests unless explicitly requested."""
if config.getoption("--run-real-git-backup-tests"):
return
skip_real_push = pytest.mark.skip(
reason="requires --run-real-git-backup-tests option to run",
)
for item in items:
if "real_git_backup_push" in item.keywords:
item.add_marker(skip_real_push)