from __future__ import annotations import os from pathlib import Path import pytest import requests from parity.client import can_reach_both, default_headers _DIR = Path(__file__).resolve().parent def pytest_configure(config): config._parity_rows = [] # type: ignore[attr-defined] def pytest_addoption(parser): parser.addoption( "--base-old", default=os.environ.get("ELEVATOR_BASE_OLD", "http://127.0.0.1:18080"), ) parser.addoption( "--base-new", default=os.environ.get("ELEVATOR_BASE_NEW", "http://127.0.0.1:18081"), ) @pytest.fixture(scope="session") def base_old(request): return str(request.config.getoption("--base-old")).rstrip("/") @pytest.fixture(scope="session") def base_new(request): return str(request.config.getoption("--base-new")).rstrip("/") @pytest.fixture(scope="session") def session_http(): s = requests.Session() s.headers.update(default_headers()) yield s s.close() @pytest.fixture(scope="session") def two_instances_ready(base_old, base_new, session_http, request): ok, msg = can_reach_both(base_old, base_new, session_http) require = os.environ.get("ELEVATOR_PARITY_REQUIRE_LIVE", "") if not ok and not require: pytest.skip(f"双端健康检查不通过(跳过用例): {msg}") if not ok and require: pytest.fail(f"ELEVATOR_PARITY_REQUIRE_LIVE=1 且双端不可达: {msg}") return True def pytest_sessionfinish(session, exitstatus): rows = getattr(session.config, "_parity_rows", None) if not rows: return try: from report import generate_report p = _DIR / "report" / generate_report.timestamped_name("parity") p.parent.mkdir(parents=True, exist_ok=True) generate_report.write_file( p, str(session.config.getoption("--base-old", default="")), str(session.config.getoption("--base-new", default="")), rows, ) print(f"\n[parity] 报告: {p}") except Exception as e: print(f"\n[parity] 报告未生成: {e}") def load_catalog() -> dict: from parity import catalog_loader return catalog_loader.load()