Stop the suite writing into the real incident log
Some checks failed
dependency freshness / dependencies on newest stable (push) Has been cancelled
md-naming / markdown naming convention (push) Has been cancelled
pre-commit / pre-commit (push) Has been cancelled
Tests / test (push) Has been cancelled

report_leetcode_incident appends to leetcode_bonus_incidents.log at the repo
root -- a real artifact you read to find out why an hour went missing.
test_budget_resolve.py drives the fail-closed path without stubbing it, so the
first full run put two fabricated incidents into the live file.

The file is gitignored, so nothing would ever have failed to warn about this.
It was caught by reading the file after deploying, not by any test.

Redirected with an autouse fixture rather than per-test patches, for the same
reason _isolate_filesystem is autouse: enumerating the tests that need it is
the version of this that breaks the next time someone adds one.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Fp6zWH9zW1AkGdDyKjrbi8
This commit is contained in:
Krzysztof Rudnicki 2026-08-30 15:30:22 +02:00
parent 63321f16cc
commit 755c5d60cf
2 changed files with 55 additions and 1 deletions

View File

@ -0,0 +1,48 @@
"""Autouse redirect for the bonus-incident log.
``report_leetcode_incident`` appends to ``leetcode_bonus_incidents.log`` at the
repo root, which is a real artifact the user reads to find out why an hour went
missing. Left unpatched, any test that drives the fail-closed path writes into
it -- and because the file is gitignored, nothing would ever fail to warn you.
That happened: the first run of ``test_budget_resolve.py`` put two fabricated
incidents into the live file.
Redirected here rather than in each test for the same reason
``_isolate_filesystem`` exists: enumerating the tests that need it is the
version of this that goes wrong the next time someone adds one.
Split into its own module to keep ``conftest.py`` inside the 250-line cap;
``conftest`` imports the fixture by name, which is what registers it.
"""
from __future__ import annotations
from typing import TYPE_CHECKING
from unittest.mock import patch
import pytest
if TYPE_CHECKING:
from collections.abc import Iterator
from pathlib import Path
@pytest.fixture(autouse=True)
def _isolate_incidents(tmp_path: Path) -> Iterator[None]:
"""Point the incident log at a per-test file.
Args:
tmp_path: pytest's temporary directory.
Yields:
None, with the log redirected and the reported-incident memo cleared so
one test's rate limit cannot mute the next.
"""
from steam_backlog_enforcer import _bonus_incident
_bonus_incident.reset_reported()
with patch.object(
_bonus_incident, "INCIDENT_LOG", tmp_path / "leetcode_bonus_incidents.log"
):
yield
_bonus_incident.reset_reported()

View File

@ -21,13 +21,19 @@ from unittest.mock import MagicMock, patch
import pytest
# Imported for its autouse side effect: naming it here registers it.
from steam_backlog_enforcer.tests._isolate_incidents import _isolate_incidents
from steam_backlog_enforcer.tests._isolate_playtime import _isolate_playtime
from steam_backlog_enforcer.tests._no_subprocess import _block_real_subprocesses
from steam_backlog_enforcer.tests._no_workout_http import _no_workout_http
# Re-exported so ruff --fix does not delete the imports above: pytest
# registers autouse fixtures by name, so they look unused to the linter.
__all__ = ["_block_real_subprocesses", "_isolate_playtime", "_no_workout_http"]
__all__ = [
"_block_real_subprocesses",
"_isolate_incidents",
"_isolate_playtime",
"_no_workout_http",
]
from steam_backlog_enforcer.tests._total_block_paths import (
BLOCK,