mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 23:27:01 +01:00
test_cups_queue.py 458 -> 167, partitioned at class boundaries into _actions (the four shell-out primitives) and _backend (health check and error-log scanning). test_cups_queue_part2.py 278 -> 131, with the four _handle_* dispatchers moving to _handlers. No MOD changed: unlike the source splits, every patched name already lives in the module each file names, so this is a pure partition. The two part-numbered survivors are renamed for what they cover. Pass count is 402 before and after. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
165 lines
6.2 KiB
Python
165 lines
6.2 KiB
Python
"""Tests for brother_printer.cups_queue - stale backend error detection.
|
|
|
|
Split from test_cups_queue.py under the 250-line cap.
|
|
"""
|
|
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from python_pkg.brother_printer.cups_queue import (
|
|
_check_cups_backend_errors,
|
|
_find_backend_error_in_log,
|
|
_is_cups_printer_healthy,
|
|
)
|
|
|
|
MOD = "python_pkg.brother_printer.cups_queue"
|
|
|
|
|
|
class TestIsCupsPrinterHealthy:
|
|
@patch(f"{MOD}.shutil.which", return_value=None)
|
|
def test_no_lpstat(self, m: MagicMock) -> None:
|
|
assert _is_cups_printer_healthy("B") is False
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/lpstat")
|
|
def test_healthy(self, w: MagicMock, mock_run: MagicMock) -> None:
|
|
mock_run.return_value = MagicMock(
|
|
stdout="printer BrotherHL1110 is idle. enabled since Mon\n",
|
|
)
|
|
assert _is_cups_printer_healthy("BrotherHL1110") is True
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/lpstat")
|
|
def test_not_healthy(self, w: MagicMock, mock_run: MagicMock) -> None:
|
|
mock_run.return_value = MagicMock(
|
|
stdout="printer BrotherHL1110 disabled\n",
|
|
)
|
|
assert _is_cups_printer_healthy("BrotherHL1110") is False
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/lpstat")
|
|
def test_timeout(self, w: MagicMock, mock_run: MagicMock) -> None:
|
|
mock_run.side_effect = subprocess.TimeoutExpired("lpstat", 5)
|
|
assert _is_cups_printer_healthy("B") is False
|
|
|
|
|
|
class TestFindBackendErrorInLog:
|
|
def test_no_errors(self) -> None:
|
|
lines = ["[2025-01-01] Completed job\n"]
|
|
err, _, _ = _find_backend_error_in_log(lines)
|
|
assert err == ""
|
|
|
|
def test_backend_error(self) -> None:
|
|
lines = [
|
|
"[2025-01-01] Completed job",
|
|
"[2025-01-02] backend errors for BrotherHL1110",
|
|
]
|
|
err, ts, success_ts = _find_backend_error_in_log(lines)
|
|
assert "backend errors" in err
|
|
assert ts == "2025-01-02"
|
|
assert success_ts == "2025-01-01"
|
|
|
|
def test_stopped_with_status(self) -> None:
|
|
lines = [
|
|
"[2025-01-02] stopped with status 1",
|
|
]
|
|
err, ts, _ = _find_backend_error_in_log(lines)
|
|
assert "stopped with status" in err
|
|
assert ts == "2025-01-02"
|
|
|
|
def test_error_no_timestamp(self) -> None:
|
|
lines = ["backend errors no timestamp here"]
|
|
err, ts, _ = _find_backend_error_in_log(lines)
|
|
assert "backend errors" in err
|
|
assert ts == ""
|
|
|
|
def test_completed_with_total(self) -> None:
|
|
lines = [
|
|
"[2025-01-01] page total 10",
|
|
"[2025-01-02] backend errors",
|
|
]
|
|
_, _, success_ts = _find_backend_error_in_log(lines)
|
|
assert success_ts == "2025-01-01"
|
|
|
|
def test_no_success_after_error(self) -> None:
|
|
lines = [
|
|
"[2025-01-02] backend errors",
|
|
]
|
|
_, _, success_ts = _find_backend_error_in_log(lines)
|
|
assert success_ts == ""
|
|
|
|
def test_completed_no_timestamp(self) -> None:
|
|
lines = [
|
|
"Completed job",
|
|
"[2025-01-02] backend errors",
|
|
]
|
|
_, _, success_ts = _find_backend_error_in_log(lines)
|
|
assert success_ts == ""
|
|
|
|
|
|
class TestCheckCupsBackendErrors:
|
|
@patch(f"{MOD}._is_cups_printer_healthy", return_value=True)
|
|
def test_healthy_printer(self, m: MagicMock) -> None:
|
|
has_errors, _ = _check_cups_backend_errors("B")
|
|
assert has_errors is False
|
|
|
|
@patch(f"{MOD}._find_backend_error_in_log", return_value=("", "", ""))
|
|
@patch(f"{MOD}._is_cups_printer_healthy", return_value=False)
|
|
def test_no_log_file(self, h: MagicMock, f: MagicMock) -> None:
|
|
with patch(f"{MOD}.Path") as mock_path:
|
|
mock_log = MagicMock()
|
|
mock_log.exists.return_value = False
|
|
mock_path.return_value = mock_log
|
|
has_errors, _ = _check_cups_backend_errors("B")
|
|
assert has_errors is False
|
|
|
|
@patch(
|
|
f"{MOD}._find_backend_error_in_log", return_value=("error", "2025-01-02", "")
|
|
)
|
|
@patch(f"{MOD}._is_cups_printer_healthy", return_value=False)
|
|
def test_has_errors(self, h: MagicMock, f: MagicMock) -> None:
|
|
with patch(f"{MOD}.Path") as mock_path:
|
|
mock_log = MagicMock()
|
|
mock_log.exists.return_value = True
|
|
mock_log.read_text.return_value = "log content"
|
|
mock_path.return_value = mock_log
|
|
has_errors, _ = _check_cups_backend_errors("B")
|
|
assert has_errors is True
|
|
|
|
@patch(
|
|
f"{MOD}._find_backend_error_in_log",
|
|
return_value=("error", "2025-01-01", "2025-01-02"),
|
|
)
|
|
@patch(f"{MOD}._is_cups_printer_healthy", return_value=False)
|
|
def test_success_after_error(self, h: MagicMock, f: MagicMock) -> None:
|
|
with patch(f"{MOD}.Path") as mock_path:
|
|
mock_log = MagicMock()
|
|
mock_log.exists.return_value = True
|
|
mock_log.read_text.return_value = "log content"
|
|
mock_path.return_value = mock_log
|
|
has_errors, _ = _check_cups_backend_errors("B")
|
|
assert has_errors is False
|
|
|
|
@patch(f"{MOD}._is_cups_printer_healthy", return_value=False)
|
|
def test_oserror_reading_log(self, h: MagicMock) -> None:
|
|
with patch(f"{MOD}.Path") as mock_path:
|
|
mock_log = MagicMock()
|
|
mock_log.exists.return_value = True
|
|
mock_log.read_text.side_effect = OSError("fail")
|
|
mock_path.return_value = mock_log
|
|
has_errors, _ = _check_cups_backend_errors("B")
|
|
assert has_errors is False
|
|
|
|
@patch(f"{MOD}._find_backend_error_in_log", return_value=("", "", ""))
|
|
@patch(f"{MOD}._is_cups_printer_healthy", return_value=False)
|
|
def test_no_backend_error_in_log(self, h: MagicMock, f: MagicMock) -> None:
|
|
with patch(f"{MOD}.Path") as mock_path:
|
|
mock_log = MagicMock()
|
|
mock_log.exists.return_value = True
|
|
mock_log.read_text.return_value = "clean log"
|
|
mock_path.return_value = mock_log
|
|
has_errors, _ = _check_cups_backend_errors("B")
|
|
assert has_errors is False
|