mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-07-04 11:43:10 +02:00
The previous two fix attempts (removing -n 4 xdist parallelism, ruling
out a Python 3.12-vs-3.14 difference) both targeted the wrong cause for
the coverage gap on _alarm_display.py:71. The actual bug:
_restore_display() was never mocked in the _block_extra_devices fixture
shared by test_alarm_part2/3/4.py, so every test exercising
on_close()/_lock.close() ran the REAL _restore_display(), which calls
the REAL shutil.which('xset'). My dev machine has /usr/bin/xset
installed, so it always hit the "found" branch by accident; the CI
runner doesn't, so it always hit the "missing" branch instead, and
there was no dedicated unit test for the "found" path at all.
Fix: mock _restore_display in that fixture (matching its already-mocked
siblings _restore_fans/_restore_alarm_audio/turn_off_plug), and add a
dedicated, hermetic test for the xset-found branch that doesn't depend
on whether the running machine actually has xset on PATH. Side benefit:
the test suite no longer makes a real `xset s on` subprocess call on
the developer's desktop as an untracked side effect of running tests.
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01A7vbgtFfZmfxJtN5DdtJky
147 lines
5.2 KiB
Python
147 lines
5.2 KiB
Python
"""Tests for _alarm_display.py — DDC/CI and DPMS display power helpers."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from python_pkg.wake_alarm._alarm_display import (
|
|
_ddcutil_power_on,
|
|
_restore_display,
|
|
_wake_display,
|
|
)
|
|
|
|
|
|
class TestDdcutilPowerOn:
|
|
"""Tests for _ddcutil_power_on."""
|
|
|
|
def test_skips_when_ddcutil_missing(self) -> None:
|
|
"""_ddcutil_power_on does nothing when ddcutil is not on PATH."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value=None,
|
|
),
|
|
patch("python_pkg.wake_alarm._alarm_display.subprocess.run") as mock_run,
|
|
):
|
|
_ddcutil_power_on()
|
|
mock_run.assert_not_called()
|
|
|
|
def test_runs_setvcp_when_ddcutil_present(self) -> None:
|
|
"""_ddcutil_power_on sends setvcp D6 01 when ddcutil is found."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value="/usr/bin/ddcutil",
|
|
),
|
|
patch("python_pkg.wake_alarm._alarm_display.subprocess.run") as mock_run,
|
|
):
|
|
_ddcutil_power_on()
|
|
mock_run.assert_called_once()
|
|
cmd = mock_run.call_args[0][0]
|
|
assert cmd == ["/usr/bin/ddcutil", "setvcp", "D6", "01"]
|
|
|
|
def test_logs_success_when_returncode_zero(self) -> None:
|
|
"""_ddcutil_power_on logs success when setvcp returns 0."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value="/usr/bin/ddcutil",
|
|
),
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.subprocess.run",
|
|
return_value=MagicMock(returncode=0),
|
|
),
|
|
):
|
|
_ddcutil_power_on()
|
|
|
|
def test_handles_timeout(self) -> None:
|
|
"""_ddcutil_power_on does not raise on TimeoutExpired."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value="/usr/bin/ddcutil",
|
|
),
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.subprocess.run",
|
|
side_effect=subprocess.TimeoutExpired(cmd="ddcutil", timeout=10),
|
|
),
|
|
):
|
|
_ddcutil_power_on() # must not raise
|
|
|
|
def test_handles_oserror(self) -> None:
|
|
"""_ddcutil_power_on does not raise on OSError."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value="/usr/bin/ddcutil",
|
|
),
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.subprocess.run",
|
|
side_effect=OSError("no device"),
|
|
),
|
|
):
|
|
_ddcutil_power_on() # must not raise
|
|
|
|
|
|
class TestDisplayHelpers:
|
|
"""Tests for _wake_display and _restore_display when xset is absent."""
|
|
|
|
def test_wake_display_skips_when_xset_missing(self) -> None:
|
|
"""_wake_display skips xset commands but still attempts ddcutil."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value=None,
|
|
),
|
|
patch("python_pkg.wake_alarm._alarm_display.subprocess.run") as mock_run,
|
|
):
|
|
_wake_display()
|
|
mock_run.assert_not_called()
|
|
|
|
def test_wake_display_runs_ddcutil_and_xset_commands(self) -> None:
|
|
"""_wake_display runs ddcutil setvcp, xset dpms force on, xset s off."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value="/usr/bin/xset",
|
|
),
|
|
patch("python_pkg.wake_alarm._alarm_display.subprocess.run") as mock_run,
|
|
):
|
|
_wake_display()
|
|
# 1 ddcutil setvcp call + 2 xset calls
|
|
assert mock_run.call_count == 3
|
|
call_args = [call[0][0] for call in mock_run.call_args_list]
|
|
assert ["/usr/bin/xset", "setvcp", "D6", "01"] in call_args
|
|
assert ["/usr/bin/xset", "dpms", "force", "on"] in call_args
|
|
assert ["/usr/bin/xset", "s", "off"] in call_args
|
|
|
|
def test_restore_display_skips_when_xset_missing(self) -> None:
|
|
"""_restore_display does nothing when xset is not on PATH."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value=None,
|
|
),
|
|
patch("python_pkg.wake_alarm._alarm_display.subprocess.run") as mock_run,
|
|
):
|
|
_restore_display()
|
|
mock_run.assert_not_called()
|
|
|
|
def test_restore_display_runs_xset_s_on_when_present(self) -> None:
|
|
"""_restore_display re-enables the screensaver via xset when present."""
|
|
with (
|
|
patch(
|
|
"python_pkg.wake_alarm._alarm_display.shutil.which",
|
|
return_value="/usr/bin/xset",
|
|
),
|
|
patch("python_pkg.wake_alarm._alarm_display.subprocess.run") as mock_run,
|
|
):
|
|
_restore_display()
|
|
mock_run.assert_called_once_with(
|
|
["/usr/bin/xset", "s", "on"],
|
|
check=False,
|
|
capture_output=True,
|
|
timeout=5,
|
|
)
|