From 8429cf04d523ba05a3c03eae94bac3ff657f8911 Mon Sep 17 00:00:00 2001 From: Krzysztof kuhy Rudnicki Date: Sat, 11 Jul 2026 17:20:01 +0200 Subject: [PATCH] Fix ScreenLocker test-factory log_file isolation flake MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit create_locker (+ _relaxed_day / _early_bird variants) patched Path.resolve to return tmp_path, but ScreenLocker.__init__ computes script_dir = Path(__file__).resolve().parent — the .parent turned the intended per-test tmp_path into tmp_path.parent, pytest's session-shared temp base. Every factory-built locker therefore shared ONE workout_log.json, so any test that wrote a log polluted it and test_saves_pending_marker's `assert not locker.log_file.exists()` passed or failed purely by random ordering (pytest-randomly). The flake was invisible until now because CI died at conftest import (missing crdt_sync) before any test ran; fixing that import in the prior commit exposed it. Reproduced deterministically at CI seed 2701400184. Fix: resolve() now returns tmp_path / "screen_locker" so .parent is the unique per-test tmp_path — each locker gets its own log_file. Also stops tests writing workout_log.json into the real source tree. Verified 747 passed across seeds 2701400184/1/42/999/123456 (was 1 failed at the CI seed). Co-Authored-By: Claude Opus 4.8 (1M context) Claude-Session: https://claude.ai/code/session_018PMRRVVkeRyrSaaqueMZKG --- screen_locker/tests/conftest.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/screen_locker/tests/conftest.py b/screen_locker/tests/conftest.py index 9302d39..3b24803 100644 --- a/screen_locker/tests/conftest.py +++ b/screen_locker/tests/conftest.py @@ -305,7 +305,7 @@ def create_locker( ) -> ScreenLocker: """Create a ScreenLocker instance with early bird paths disabled.""" with ( - patch.object(Path, "resolve", return_value=tmp_path), + patch.object(Path, "resolve", return_value=tmp_path / "screen_locker"), patch.object(ScreenLocker, "has_logged_today", return_value=has_logged), patch.object( ScreenLocker, @@ -344,7 +344,7 @@ def create_locker_relaxed_day( The autouse ``_mock_weekly_logic`` fixture is overridden here. """ with ( - patch.object(Path, "resolve", return_value=tmp_path), + patch.object(Path, "resolve", return_value=tmp_path / "screen_locker"), patch.object(ScreenLocker, "has_logged_today", return_value=has_logged), patch.object(ScreenLocker, "_is_sick_day_today", return_value=False), patch.object(ScreenLocker, "_is_early_bird_pending", return_value=False), @@ -383,7 +383,7 @@ def create_locker_early_bird( is_early_bird_log = state in ("log_active", "log_expired") is_early_bird_time = state == "log_active" with ( - patch.object(Path, "resolve", return_value=tmp_path), + patch.object(Path, "resolve", return_value=tmp_path / "screen_locker"), patch.object(ScreenLocker, "has_logged_today", return_value=has_logged), patch.object(ScreenLocker, "_is_sick_day_today", return_value=False), patch.object(