Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
70 changes: 65 additions & 5 deletions scripts/lean/tests/test_lean_exec.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,56 @@
"LEAN_EXEC_MIN_FREE_GB": "0",
}

# Skip motive par POPULATION NATIVE d'admission (#19382, durci c.184) :
# les 5 tests suivants dependent d'une admission qui ne partage pas le
# cap machine avec des lean etrangers. La porte du cap (`lean_exec.py:1628`,
# `if native_pop + budget > cap`) refuse le test si un job voisin (autre
# runner sur la meme machine po-2026 wsl-2 a wsl-5, cf job 111974793791
# rouge de #19373) detient deja 1+ lean dans la population native.
#
# Le skip vise maintenant la bonne condition (population native > 0), pas
# la latence du scan (la latence 15 s du body etait rapportee, pas
# mesuree dans un log -- un scan de 3 lean prends ~300 ms, le skip sur
# latence ne protege rien). Le monkey-patch `neutralized_native_pop`
# simule la population native = 0 dans la session pytest, comme
# `LEAN_EXEC_WSL=off` neutralise deja la population WSL dans le
# sous-processus. Fallback skip : si le patch echoue, on skip avec le
# compte mesure dans le motif.
_ADMISSION_NATIVE_POP_SKIP_THRESHOLD = 0


@pytest.fixture
def neutralized_native_pop(monkeypatch):
"""Neutralise la population native (lean/lake vivants de l'hote) pour
les tests d'admission qui dependent d'un cap machine deterministe.
Idem `LEAN_EXEC_WSL=off` pour la population WSL (cf lean_exec.py:265).
Le monkey-patch evite le cap refuse par les lean etrangers (jobs
voisins sur la meme machine po-2026 wsl-2 a wsl-5, job 111974793791
fondateur)."""
monkeypatch.setattr(
le, "scan_native_population",
lambda: (0, "neutralized: test (monkeypatch)"),
)


@pytest.fixture(scope="module")
def native_pop_count() -> int:
"""Compte la population native reelle du runner (pour le motif de skip
fallback). Mesure une fois par module pytest."""
n, _src = le.scan_native_population()
return n


def _skip_if_native_pop_nonempty(n: int) -> None:
if n > _ADMISSION_NATIVE_POP_SKIP_THRESHOLD:
pytest.skip(
f"runner porte {n} lean/lake etrangers dans la population "
f"native (seuil {_ADMISSION_NATIVE_POP_SKIP_THRESHOLD}) : "
f"le cap machine `native_pop + budget > cap` refuse "
f"l'admission partagee. Mesure ai-01 (2026-10-06) = 0. "
f"Famille reste declenchee, skip motive -- voir #19382."
)


def _env(state: Path, **extra) -> dict:
env = os.environ.copy()
Expand Down Expand Up @@ -149,7 +199,9 @@ def test_bound_command_inserts_kjobs():
# Admission machine-wide — deux worktrees concurrents
# ---------------------------------------------------------------------------

def test_admission_cap_machine_wide_two_worktrees():
def test_admission_cap_machine_wide_two_worktrees(
neutralized_native_pop, native_pop_count):
_skip_if_native_pop_nonempty(native_pop_count)
with tempfile.TemporaryDirectory() as td:
state = Path(td) / "state"
w1, w2, w3 = (Path(td) / n for n in ("w1", "w2", "w3"))
Expand Down Expand Up @@ -537,8 +589,10 @@ def _find_toolchain() -> str | None:
return None


def test_positive_control_real_lake():
def test_positive_control_real_lake(
neutralized_native_pop, native_pop_count):
"""Une compilation ciblee REELLE passe sous le budget et publie ses metriques."""
_skip_if_native_pop_nonempty(native_pop_count)
# Reserve 3 (arbitrage #15666) : un print+return rend « passed » sans
# rien controler -- pire que pas de controle. pytest.skip rend un « s »
# visible dans le rapport.
Expand Down Expand Up @@ -933,9 +987,11 @@ def _wait_for(condition, timeout_s: float = 30.0, what: str = "condition"):
assert condition(), f"{what} non atteinte sous {timeout_s} s"


def test_queue_wait_admits_after_release():
def test_queue_wait_admits_after_release(
neutralized_native_pop, native_pop_count):
"""--wait : le demandeur attend en file, est admis quand le cap se
libere, et publie son temps d'attente."""
_skip_if_native_pop_nonempty(native_pop_count)
with tempfile.TemporaryDirectory() as td:
state = Path(td) / "state"
cap = dict(LEAN_EXEC_CAP=1, LEAN_EXEC_BUDGET=1)
Expand All @@ -957,9 +1013,11 @@ def test_queue_wait_admits_after_release():
assert res.get("queue_wait_s", 0.0) >= 0.5, res


def test_queue_timeout_refuses():
def test_queue_timeout_refuses(
neutralized_native_pop, native_pop_count):
"""Delai de file depasse = refus explicite 'wait timeout' (jamais
d'attente infinie)."""
_skip_if_native_pop_nonempty(native_pop_count)
with tempfile.TemporaryDirectory() as td:
state = Path(td) / "state"
cap = dict(LEAN_EXEC_CAP=1, LEAN_EXEC_BUDGET=1)
Expand All @@ -981,9 +1039,11 @@ def test_queue_timeout_refuses():
assert first.wait(timeout=60) == le.EXIT_TIMEOUT


def test_queue_full_refuses():
def test_queue_full_refuses(
neutralized_native_pop, native_pop_count):
"""File bornee : queue_max atteint = refus explicite du 3e demandeur,
jamais de croissance silencieuse de la file."""
_skip_if_native_pop_nonempty(native_pop_count)
with tempfile.TemporaryDirectory() as td:
state = Path(td) / "state"
cap = dict(LEAN_EXEC_CAP=1, LEAN_EXEC_BUDGET=1,
Expand Down
Loading