portfolio-optimiser/tests/test_costsim_loadbearing.py
2026-07-15 09:54:25 +02:00

45 lines
2.4 KiB
Python
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

"""S3.6 costsim (kostnadssimulering) — offline, MAF-free, deterministic load-bearing seams.
``costsim`` estimates token/cost for a portfolio run BEFORE running (what-if over the model-map ×
effort levels), with pricing as schema-validated config. It is MAF-free (reads ``model_map.json`` as
plain data via ``__file__``-relative path, never imports ``backends``/``budget``/``contracts``) —
proven load-bearing by BOTH the direct-import AST guard (``test_okf_is_maf_free`` covering
``costsim.py``) AND the transitive import-graph seam below.
"""
from __future__ import annotations
import subprocess
import sys
from pathlib import Path
_COSTSIM = Path(__file__).resolve().parents[1] / "src" / "portfolio_optimiser" / "costsim.py"
def test_costsim_registered_maf_free() -> None:
"""Meta: costsim.py is registered in the MAF-free guard list, so ``test_okf_is_maf_free``
actually scans it — otherwise the MAF-free claim would be green-but-dead (never checked)."""
from tests.test_okf import _MAF_FREE_MODULES
assert "costsim.py" in _MAF_FREE_MODULES
def test_costsim_import_is_maf_free() -> None:
"""The genuine transitive-import seam: loading costsim.py's module body in ISOLATION must NOT
pull ``agent_framework``/``mcp`` into ``sys.modules``. Loaded standalone via
``spec_from_file_location`` — NOT as ``portfolio_optimiser.costsim``, since the package
``__init__`` imports MAF-bound ``run``/``contracts`` and would mask costsim's own cleanliness.
The AST guard (``test_okf_is_maf_free``) only catches DIRECT imports; a transitive
``from portfolio_optimiser.contracts import ...`` in costsim would slip past it but trip THIS
check — ``exec_module`` runs costsim's import statements, so any MAF-bound import lands
``agent_framework`` in ``sys.modules``. Detach point: add such an import → RED."""
check = (
"import importlib.util, sys\n"
f"spec = importlib.util.spec_from_file_location('costsim_standalone', {str(_COSTSIM)!r})\n"
"mod = importlib.util.module_from_spec(spec)\n"
"spec.loader.exec_module(mod)\n"
"assert 'agent_framework' not in sys.modules, 'agent_framework leaked into costsim import graph'\n"
"assert 'mcp' not in sys.modules, 'mcp leaked into costsim import graph'\n"
)
result = subprocess.run([sys.executable, "-c", check], capture_output=True, text=True)
assert result.returncode == 0, result.stderr