portfolio-optimiser/tests/test_portfolio_live.py
Kjell Tore Guttormsen 37547fe292
refactor(examples): replace sector-specific example material with generic, fictitious examples
The context sets, the packaged knowledge bases and the example bundles are
replaced by one fictitious example set about IT operations in an invented
organisation: three context sets (serverrom-2027, driftsavtale-2027 and the
two-base drift-og-avtale-2027), two synthetic knowledge bases under
src/portfolio_optimiser/data/kunnskapsbaser and two example bundles under
src/portfolio_optimiser/data/bundles. Numbers, codes and structural values in
tests and fixtures are kept; names, ids and wording change. Dated measurement
documents that only recorded runs on the replaced material are deleted.

Gate figures measured on the new set are not comparable with earlier ones.
The exclusion gate from the previous commit is green: 0 tracked files hit
outside the shared/ subtree.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-23 15:04:21 +02:00

40 lines
1.9 KiB
Python

"""Fase 3 — GATED live Azure portfolio run (SC7 / SC9).
NOT default CI: skips cleanly without a configured Foundry endpoint + deployment. When set,
``run_portfolio`` fans out over the reference portfolio on the REAL ``azure`` profile (one
project, hard token-capped per D6). SC9 is unchanged — this arm stays skipped offline.
**``PORTFOLIO_LIVE_FULL_RUN`` added 14.08 (økt 40), and the reason is this file, not the new one.**
This test passes NO ``client_factory``, so it drives the real Azure backend: it is a PAID run, and
until now it fired on the same two variables as ``test_foundry_profile_live.py``'s one-word probe.
That is exactly the collapse the new full-run gate was designed to prevent — an operator exporting
the pair to run the CHEAP rung would have paid for this fan-out too, from a bare ``uv run pytest``.
The rule the sibling file states must hold for EVERY paid arm, or it is not a rule; leaving this one
on the two-var pair would have made the CLAUDE.md invariant half-true the day it was written.
Truthiness, not presence (Fase 4b): an exported-but-empty value must not arm a paid run.
"""
import os
import pytest
from portfolio_optimiser.run import PortfolioResult, run_portfolio
_ENDPOINT = os.environ.get("PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT")
_DEPLOYMENT = os.environ.get("PORTFOLIO_FOUNDRY_DEPLOYMENT")
_OPTED_IN = bool(os.environ.get("PORTFOLIO_LIVE_FULL_RUN"))
_NO_FOUNDRY = not (_ENDPOINT and _DEPLOYMENT and _OPTED_IN)
@pytest.mark.skipif(
_NO_FOUNDRY,
reason=(
"paid fan-out not armed (set PORTFOLIO_LIVE_FULL_RUN=1 alongside "
"PORTFOLIO_FOUNDRY_PROJECT_ENDPOINT + PORTFOLIO_FOUNDRY_DEPLOYMENT)"
),
)
async def test_portfolio_live_azure_fanout() -> None:
# No client_factory -> the real AZURE backend is used; hard-capped per D6.
result = await run_portfolio(["KONTOR-IT-E1"], "azure", max_tokens=2000)
assert isinstance(result, PortfolioResult)
assert len(result.runs) == 1