mirror of
https://github.com/kuhyx/testsAndMisc.git
synced 2026-11-10 21:07:03 +01:00
test_cups_service.py 390 -> 172 (usblp port status to _port), part2 261 -> 115 (status mapping and discovery out), part3 260 -> 105 (the four healthy-port cases out). part3 was one 235-line class, so it split by method rather than by class. The four part-numbered files are renamed for what they cover; three of them now name _cups_fallback, matching where the code moved earlier. The first run after the part2 split reported 400, not 402: the moved classes needed subprocess and get_status_info that my hand-written import block had dropped. Fixed, and the count is 402 again. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_011w2Pj4Ek3ZNMQVYcFHgXDY
173 lines
6.2 KiB
Python
173 lines
6.2 KiB
Python
"""Tests for brother_printer.cups_service - pyusb info and service control."""
|
|
|
|
from __future__ import annotations
|
|
|
|
import subprocess
|
|
from unittest.mock import MagicMock, patch
|
|
|
|
from python_pkg.brother_printer.cups_service import (
|
|
_ensure_cups_running,
|
|
_get_pyusb_device_info,
|
|
is_cups_scheduler_running,
|
|
start_cups,
|
|
)
|
|
|
|
MOD = "python_pkg.brother_printer.cups_service"
|
|
|
|
|
|
class TestGetPyusbDeviceInfo:
|
|
def test_found(self) -> None:
|
|
import sys as _sys
|
|
|
|
mock_usb = MagicMock()
|
|
mock_dev = MagicMock()
|
|
mock_dev.product = "HL-1110"
|
|
mock_dev.serial_number = "SN123"
|
|
mock_usb.core.find.return_value = mock_dev
|
|
with patch.dict(_sys.modules, {"usb": mock_usb, "usb.core": mock_usb.core}):
|
|
result = _get_pyusb_device_info()
|
|
assert result["product"] == "HL-1110"
|
|
assert result["serial"] == "SN123"
|
|
|
|
def test_import_error(self) -> None:
|
|
import sys as _sys
|
|
|
|
mock_usb = MagicMock()
|
|
mock_usb.core.find.side_effect = ImportError("no usb")
|
|
with patch.dict(_sys.modules, {"usb": mock_usb, "usb.core": mock_usb.core}):
|
|
result = _get_pyusb_device_info()
|
|
assert result == {}
|
|
|
|
def test_not_found(self) -> None:
|
|
import sys as _sys
|
|
|
|
mock_usb = MagicMock()
|
|
mock_usb.core.find.return_value = None
|
|
with patch.dict(_sys.modules, {"usb": mock_usb, "usb.core": mock_usb.core}):
|
|
result = _get_pyusb_device_info()
|
|
assert result == {}
|
|
|
|
def test_none_product_serial(self) -> None:
|
|
import sys as _sys
|
|
|
|
mock_usb = MagicMock()
|
|
mock_dev = MagicMock()
|
|
mock_dev.product = None
|
|
mock_dev.serial_number = None
|
|
mock_usb.core.find.return_value = mock_dev
|
|
with patch.dict(_sys.modules, {"usb": mock_usb, "usb.core": mock_usb.core}):
|
|
result = _get_pyusb_device_info()
|
|
assert result["product"] == ""
|
|
assert result["serial"] == ""
|
|
|
|
def test_oserror(self) -> None:
|
|
import sys as _sys
|
|
|
|
mock_usb = MagicMock()
|
|
mock_usb.core.find.side_effect = OSError("usb fail")
|
|
with patch.dict(_sys.modules, {"usb": mock_usb, "usb.core": mock_usb.core}):
|
|
result = _get_pyusb_device_info()
|
|
assert result == {}
|
|
|
|
def test_value_error(self) -> None:
|
|
import sys as _sys
|
|
|
|
mock_usb = MagicMock()
|
|
mock_usb.core.find.side_effect = ValueError("bad")
|
|
with patch.dict(_sys.modules, {"usb": mock_usb, "usb.core": mock_usb.core}):
|
|
result = _get_pyusb_device_info()
|
|
assert result == {}
|
|
|
|
|
|
class TestIsCupsSchedulerRunning:
|
|
@patch(f"{MOD}.shutil.which", return_value=None)
|
|
def test_no_lpstat(self, m: MagicMock) -> None:
|
|
assert is_cups_scheduler_running() is False
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/lpstat")
|
|
def test_running(self, w: MagicMock, mock_run: MagicMock) -> None:
|
|
mock_run.return_value = MagicMock(stdout="scheduler is running")
|
|
assert is_cups_scheduler_running() is True
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/lpstat")
|
|
def test_not_running(self, w: MagicMock, mock_run: MagicMock) -> None:
|
|
mock_run.return_value = MagicMock(stdout="scheduler is not running")
|
|
assert is_cups_scheduler_running() 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", 3)
|
|
assert is_cups_scheduler_running() is False
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/lpstat")
|
|
def test_oserror(self, w: MagicMock, mock_run: MagicMock) -> None:
|
|
mock_run.side_effect = OSError("fail")
|
|
assert is_cups_scheduler_running() is False
|
|
|
|
|
|
class TestStartCups:
|
|
@patch(f"{MOD}.shutil.which", return_value=None)
|
|
def test_no_systemctl(self, m: MagicMock) -> None:
|
|
assert start_cups() is False
|
|
|
|
@patch(f"{MOD}.time.sleep")
|
|
@patch(f"{MOD}.is_cups_scheduler_running")
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/systemctl")
|
|
def test_success(
|
|
self,
|
|
w: MagicMock,
|
|
mock_run: MagicMock,
|
|
mock_is_running: MagicMock,
|
|
s: MagicMock,
|
|
) -> None:
|
|
mock_run.return_value = MagicMock()
|
|
mock_is_running.return_value = True
|
|
assert start_cups() is True
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/systemctl")
|
|
def test_timeout(self, w: MagicMock, mock_run: MagicMock) -> None:
|
|
mock_run.side_effect = subprocess.TimeoutExpired("systemctl", 15)
|
|
assert start_cups() is False
|
|
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/systemctl")
|
|
def test_called_process_error(self, w: MagicMock, mock_run: MagicMock) -> None:
|
|
mock_run.side_effect = subprocess.CalledProcessError(1, "systemctl")
|
|
assert start_cups() is False
|
|
|
|
@patch(f"{MOD}.time.sleep")
|
|
@patch(f"{MOD}.is_cups_scheduler_running", return_value=False)
|
|
@patch(f"{MOD}.subprocess.run")
|
|
@patch(f"{MOD}.shutil.which", return_value="/usr/bin/systemctl")
|
|
def test_never_starts(
|
|
self,
|
|
w: MagicMock,
|
|
mock_run: MagicMock,
|
|
is_running: MagicMock,
|
|
s: MagicMock,
|
|
) -> None:
|
|
mock_run.return_value = MagicMock()
|
|
assert start_cups() is False
|
|
|
|
|
|
class TestEnsureCupsRunning:
|
|
@patch(f"{MOD}.is_cups_scheduler_running", return_value=True)
|
|
def test_already_running(self, m: MagicMock) -> None:
|
|
assert _ensure_cups_running() is True
|
|
|
|
@patch(f"{MOD}.start_cups", return_value=True)
|
|
@patch(f"{MOD}.is_cups_scheduler_running", return_value=False)
|
|
def test_needs_start(self, is_running: MagicMock, st: MagicMock) -> None:
|
|
assert _ensure_cups_running() is True
|
|
|
|
@patch(f"{MOD}.start_cups", return_value=False)
|
|
@patch(f"{MOD}.is_cups_scheduler_running", return_value=False)
|
|
def test_start_fails(self, is_running: MagicMock, st: MagicMock) -> None:
|
|
assert _ensure_cups_running() is False
|