screen-locker/screen_locker/tests/test_instance.py
Krzysztof kuhy Rudnicki aa3e290391 Document every test, split files at the cap
Real one-line docstrings stating what each test pins down. Files that
would pass 250 lines moved whole classes into _part2 siblings
(sick_panel, earned, poke_server, shutdown_reading,
manual_workout_dialog).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01WzxdWYdwRAtMg7ki6TKxuU
2026-11-01 21:11:34 +01:00

106 lines
2.9 KiB
Python

"""Tests for the single-instance lock."""
from __future__ import annotations
import logging
import os
from typing import TYPE_CHECKING
from screen_locker import _instance
if TYPE_CHECKING:
from pathlib import Path
import pytest
def test_the_first_run_takes_the_lock(tmp_path: Path) -> None:
"""The first process to ask gets the instance lock."""
lock = _instance.acquire(tmp_path / "instance.lock")
assert lock is not None
lock.release()
def test_a_second_run_stands_down(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
"""Otherwise a stray re-arm races a second window into existence."""
path = tmp_path / "instance.lock"
first = _instance.acquire(path)
with caplog.at_level(logging.WARNING):
second = _instance.acquire(path)
assert first is not None
assert second is None
assert any("already holds" in record.message for record in caplog.records)
first.release()
def test_the_lock_is_retakeable_after_release(tmp_path: Path) -> None:
"""A released lock can be acquired again."""
path = tmp_path / "instance.lock"
first = _instance.acquire(path)
assert first is not None
first.release()
second = _instance.acquire(path)
assert second is not None
second.release()
def test_an_unopenable_path_reports_failure_rather_than_raising(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
"""A lock path that cannot be opened returns None instead of raising."""
blocker = tmp_path / "blocker"
blocker.write_text("file", encoding="utf-8")
with caplog.at_level(logging.ERROR):
assert _instance.acquire(blocker / "instance.lock") is None
def test_releasing_twice_is_safe(tmp_path: Path) -> None:
"""Calling release a second time does not raise."""
lock = _instance.acquire(tmp_path / "instance.lock")
assert lock is not None
lock.release()
lock.release()
def test_the_lock_file_records_the_pid(tmp_path: Path) -> None:
"""The lock file contains the holder's PID."""
path = tmp_path / "instance.lock"
lock = _instance.acquire(path)
assert lock is not None
assert path.read_text(encoding="utf-8") == str(os.getpid())
lock.release()
def test_a_close_failure_is_reported_not_raised(
tmp_path: Path, caplog: pytest.LogCaptureFixture
) -> None:
"""A failing close during release is logged as a warning, not raised."""
lock = _instance.acquire(tmp_path / "instance.lock")
assert lock is not None
class Broken:
"""A file handle stand-in whose close always fails."""
def close(self) -> None:
"""Raise OSError to simulate a handle that cannot be closed."""
message = "cannot close"
raise OSError(message)
lock.handle.close()
lock.handle = Broken()
with caplog.at_level(logging.WARNING):
lock.release()
assert any("could not close" in record.message for record in caplog.records)