afancontrol/tests/pwmfan/test_linux.py
2021-10-26 12:58:36 +02:00

154 lines
4.0 KiB
Python

from contextlib import ExitStack
from unittest.mock import MagicMock
import pytest
from afancontrol.pwmfan import (
FanInputDevice,
LinuxFanPWMRead,
LinuxFanPWMWrite,
LinuxFanSpeed,
PWMDevice,
PWMValue,
)
from afancontrol.pwmfannorm import PWMFanNorm
@pytest.fixture
def pwm_path(temp_path):
# pwm = /sys/class/hwmon/hwmon0/pwm2
pwm_path = temp_path / "pwm2"
pwm_path.write_text("0\n")
return pwm_path
@pytest.fixture
def pwm_enable_path(temp_path):
pwm_enable_path = temp_path / "pwm2_enable"
pwm_enable_path.write_text("0\n")
return pwm_enable_path
@pytest.fixture
def fan_input_path(temp_path):
# fan_input = /sys/class/hwmon/hwmon0/fan2_input
fan_input_path = temp_path / "fan2_input"
fan_input_path.write_text("1300\n")
return fan_input_path
@pytest.fixture
def fan_speed(fan_input_path):
return LinuxFanSpeed(fan_input=FanInputDevice(str(fan_input_path)))
@pytest.fixture
def pwm_read(pwm_path):
return LinuxFanPWMRead(pwm=PWMDevice(str(pwm_path)))
@pytest.fixture
def pwm_write(pwm_path):
pwm_write = LinuxFanPWMWrite(pwm=PWMDevice(str(pwm_path)))
# We write to the pwm_enable file values without newlines,
# but when they're read back, they might contain newlines.
# This hack below is to simulate just that: the written values should
# contain newlines.
original_pwm_enable = pwm_write._pwm_enable
pwm_enable = MagicMock(wraps=original_pwm_enable)
pwm_enable.write_text = lambda text: original_pwm_enable.write_text(text + "\n")
pwm_write._pwm_enable = pwm_enable
return pwm_write
@pytest.fixture
def pwmfan_norm(fan_speed, pwm_read, pwm_write):
return PWMFanNorm(
fan_speed,
pwm_read,
pwm_write,
pwm_line_start=PWMValue(100),
pwm_line_end=PWMValue(240),
never_stop=False,
)
@pytest.mark.parametrize("pwmfan_fixture", ["fan_speed", "pwmfan_norm"])
def test_get_speed(pwmfan_fixture, fan_speed, pwmfan_norm, fan_input_path):
fan = locals()[pwmfan_fixture]
fan_input_path.write_text("721\n")
assert 721 == fan.get_speed()
@pytest.mark.parametrize("pwmfan_fixture", ["pwm_write", "pwmfan_norm"])
@pytest.mark.parametrize("raises", [True, False])
def test_enter_exit(
raises, pwmfan_fixture, pwm_write, pwmfan_norm, pwm_enable_path, pwm_path
):
fan = locals()[pwmfan_fixture]
class Exc(Exception):
pass
with ExitStack() as stack:
if raises:
stack.enter_context(pytest.raises(Exc))
stack.enter_context(fan)
assert "1" == pwm_enable_path.read_text().strip()
assert "255" == pwm_path.read_text()
value = dict(pwm_write=100, pwmfan_norm=0.39)[pwmfan_fixture] # 100/255 ~= 0.39
fan.set(value)
assert "1" == pwm_enable_path.read_text().strip()
assert "100" == pwm_path.read_text()
if raises:
raise Exc()
assert "0" == pwm_enable_path.read_text().strip()
assert "100" == pwm_path.read_text() # `fancontrol` doesn't reset speed
def test_get_set_pwmfan(pwm_read, pwm_write, pwm_path):
pwm_write.set(142)
assert "142" == pwm_path.read_text()
pwm_path.write_text("132\n")
assert 132 == pwm_read.get()
pwm_write.set_full_speed()
assert "255" == pwm_path.read_text()
with pytest.raises(ValueError):
pwm_write.set(256)
with pytest.raises(ValueError):
pwm_write.set(-1)
def test_get_set_pwmfan_norm(pwmfan_norm, pwm_path):
pwmfan_norm.set(0.42)
assert "101" == pwm_path.read_text()
pwm_path.write_text("132\n")
assert pytest.approx(0.517, 0.01) == pwmfan_norm.get()
pwmfan_norm.set_full_speed()
assert "255" == pwm_path.read_text()
assert 238 == pwmfan_norm.set(0.99)
assert "238" == pwm_path.read_text()
assert 255 == pwmfan_norm.set(1.0)
assert "255" == pwm_path.read_text()
assert 255 == pwmfan_norm.set(1.1)
assert "255" == pwm_path.read_text()
assert 0 == pwmfan_norm.set(-0.1)
assert "0" == pwm_path.read_text()