diff --git a/scripts/ci/soft_deadlock_detector.py b/scripts/ci/soft_deadlock_detector.py index ac4c6d992a..45630bec27 100644 --- a/scripts/ci/soft_deadlock_detector.py +++ b/scripts/ci/soft_deadlock_detector.py @@ -84,6 +84,13 @@ def _default_runner(cmd, **kwargs): # pragma: no cover - trivial default return subprocess.run(cmd, **kwargs) +def _now(): + """Horloge du détecteur, injectable en test (fixtures ancrées à une date + fixe : sans injection, un test de main() devient rouge 24 h après sa + rédaction, le churn des fixtures sortant de la fenêtre --window-hours).""" + return datetime.now(timezone.utc) + + def _parse_ts(value: str) -> datetime: """ISO-8601 GitHub (« 2026-09-05T20:21:00Z ») -> datetime UTC aware. @@ -272,7 +279,7 @@ def main(argv: Optional[list] = None) -> int: help="rc=2 si au moins une détection (pour cron)") args = parser.parse_args(argv) - now = datetime.now(timezone.utc) + now = _now() try: prs = fetch_open_prs(args.repo, limit=args.limit) candidates = analyze( diff --git a/scripts/tests/test_soft_deadlock_detector.py b/scripts/tests/test_soft_deadlock_detector.py index 3a2dc33e2c..298455440a 100644 --- a/scripts/tests/test_soft_deadlock_detector.py +++ b/scripts/tests/test_soft_deadlock_detector.py @@ -207,6 +207,11 @@ def fake_runner(cmd, **kwargs): {"commits": [{"committedDate": _ts(100)}]})) _patch_runner(monkeypatch, fake_runner) + # Ancrer l'horloge de main() au NOW des fixtures : sans injection, le + # now réel dérive d'un jour et le churn (commentaires à <24 h de NOW) + # sort de la fenêtre — la conjonction casse et le test rougit 24 h + # après sa rédaction (mesuré le 2026-10-02 sur main, rc 0 != 2). + monkeypatch.setattr(sdd, "_now", lambda: NOW) assert sdd.main(["--fail-on-findings", "--limit", "10"]) == 2 assert sdd.main(["--limit", "10"]) == 0 capsys.readouterr() # vide le buffer : la sortie --json doit être seule