2021-10-26 12:58:36 +02:00
|
|
|
from contextlib import ExitStack
|
|
|
|
from unittest.mock import MagicMock, patch, sentinel
|
|
|
|
|
|
|
|
import pytest
|
|
|
|
|
|
|
|
import afancontrol.manager
|
|
|
|
from afancontrol.config import (
|
|
|
|
Actions,
|
|
|
|
AlertCommands,
|
|
|
|
FanName,
|
|
|
|
FanSpeedModifier,
|
|
|
|
FansTempsRelation,
|
|
|
|
MappingName,
|
|
|
|
TempName,
|
|
|
|
TriggerConfig,
|
|
|
|
)
|
|
|
|
from afancontrol.manager import Manager
|
|
|
|
from afancontrol.metrics import Metrics
|
|
|
|
from afancontrol.pwmfannorm import PWMFanNorm, PWMValueNorm
|
|
|
|
from afancontrol.report import Report
|
|
|
|
from afancontrol.temp import FileTemp, TempCelsius, TempStatus
|
|
|
|
from afancontrol.trigger import Triggers
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.fixture
|
|
|
|
def report():
|
|
|
|
return MagicMock(spec=Report)
|
|
|
|
|
|
|
|
|
|
|
|
def test_manager(report):
|
|
|
|
mocked_case_fan = MagicMock(spec=PWMFanNorm)()
|
|
|
|
mocked_mobo_temp = MagicMock(spec=FileTemp)()
|
|
|
|
mocked_metrics = MagicMock(spec=Metrics)()
|
|
|
|
|
|
|
|
with ExitStack() as stack:
|
|
|
|
stack.enter_context(
|
|
|
|
patch.object(afancontrol.manager, "Triggers", spec=Triggers)
|
|
|
|
)
|
|
|
|
|
|
|
|
manager = Manager(
|
|
|
|
arduino_connections={},
|
|
|
|
fans={FanName("case"): mocked_case_fan},
|
|
|
|
readonly_fans={},
|
|
|
|
temps={TempName("mobo"): mocked_mobo_temp},
|
|
|
|
mappings={
|
|
|
|
MappingName("1"): FansTempsRelation(
|
|
|
|
temps=[TempName("mobo")],
|
|
|
|
fans=[FanSpeedModifier(fan=FanName("case"), modifier=0.6)],
|
|
|
|
)
|
|
|
|
},
|
|
|
|
report=report,
|
|
|
|
triggers_config=TriggerConfig(
|
|
|
|
global_commands=Actions(
|
|
|
|
panic=AlertCommands(enter_cmd=None, leave_cmd=None),
|
|
|
|
threshold=AlertCommands(enter_cmd=None, leave_cmd=None),
|
|
|
|
),
|
|
|
|
temp_commands={
|
|
|
|
TempName("mobo"): Actions(
|
|
|
|
panic=AlertCommands(enter_cmd=None, leave_cmd=None),
|
|
|
|
threshold=AlertCommands(enter_cmd=None, leave_cmd=None),
|
|
|
|
)
|
|
|
|
},
|
|
|
|
),
|
|
|
|
metrics=mocked_metrics,
|
|
|
|
)
|
|
|
|
|
|
|
|
stack.enter_context(manager)
|
|
|
|
|
|
|
|
manager.tick()
|
|
|
|
|
2021-10-26 14:11:39 +02:00
|
|
|
mocked_triggers = manager.triggers # type: MagicMock
|
2021-10-26 12:58:36 +02:00
|
|
|
assert mocked_triggers.check.call_count == 1
|
|
|
|
assert mocked_case_fan.__enter__.call_count == 1
|
|
|
|
assert mocked_metrics.__enter__.call_count == 1
|
|
|
|
assert mocked_metrics.tick.call_count == 1
|
|
|
|
assert mocked_case_fan.__exit__.call_count == 1
|
|
|
|
assert mocked_metrics.__exit__.call_count == 1
|
|
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize(
|
|
|
|
"temps, mappings, expected_fan_speeds",
|
|
|
|
[
|
|
|
|
(
|
|
|
|
{
|
|
|
|
TempName("cpu"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.42 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
),
|
|
|
|
TempName("hdd"): None, # a failing sensor
|
|
|
|
},
|
|
|
|
{
|
|
|
|
MappingName("all"): FansTempsRelation(
|
|
|
|
temps=[TempName("cpu"), TempName("hdd")],
|
|
|
|
fans=[FanSpeedModifier(fan=FanName("rear"), modifier=1.0)],
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{FanName("rear"): PWMValueNorm(1.0)},
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{
|
|
|
|
TempName("cpu"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.42 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
MappingName("all"): FansTempsRelation(
|
|
|
|
temps=[TempName("cpu")],
|
|
|
|
fans=[FanSpeedModifier(fan=FanName("rear"), modifier=1.0)],
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{FanName("rear"): PWMValueNorm(0.42)},
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{
|
|
|
|
TempName("cpu"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.42 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{
|
|
|
|
MappingName("all"): FansTempsRelation(
|
|
|
|
temps=[TempName("cpu")],
|
|
|
|
fans=[FanSpeedModifier(fan=FanName("rear"), modifier=0.6)],
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{FanName("rear"): PWMValueNorm(0.42 * 0.6)},
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{
|
|
|
|
TempName("cpu"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.42 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
),
|
|
|
|
TempName("mobo"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.52 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
),
|
|
|
|
TempName("hdd"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.12 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
MappingName("all"): FansTempsRelation(
|
|
|
|
temps=[TempName("cpu"), TempName("mobo"), TempName("hdd")],
|
|
|
|
fans=[FanSpeedModifier(fan=FanName("rear"), modifier=1.0)],
|
|
|
|
)
|
|
|
|
},
|
|
|
|
{FanName("rear"): PWMValueNorm(0.52)},
|
|
|
|
),
|
|
|
|
(
|
|
|
|
{
|
|
|
|
TempName("cpu"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.42 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
),
|
|
|
|
TempName("mobo"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.52 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
),
|
|
|
|
TempName("hdd"): TempStatus(
|
|
|
|
min=TempCelsius(30),
|
|
|
|
max=TempCelsius(50),
|
|
|
|
temp=TempCelsius((50 - 30) * 0.12 + 30),
|
|
|
|
panic=None,
|
|
|
|
threshold=None,
|
|
|
|
is_panic=False,
|
|
|
|
is_threshold=False,
|
|
|
|
),
|
|
|
|
},
|
|
|
|
{
|
|
|
|
MappingName("1"): FansTempsRelation(
|
|
|
|
temps=[TempName("cpu"), TempName("hdd")],
|
|
|
|
fans=[FanSpeedModifier(fan=FanName("rear"), modifier=1.0)],
|
|
|
|
),
|
|
|
|
MappingName("2"): FansTempsRelation(
|
|
|
|
temps=[TempName("mobo"), TempName("hdd")],
|
|
|
|
fans=[FanSpeedModifier(fan=FanName("rear"), modifier=0.6)],
|
|
|
|
),
|
|
|
|
},
|
|
|
|
{FanName("rear"): PWMValueNorm(0.42)},
|
|
|
|
),
|
|
|
|
],
|
|
|
|
)
|
|
|
|
def test_fan_speeds(report, temps, mappings, expected_fan_speeds):
|
|
|
|
mocked_case_fan = MagicMock(spec=PWMFanNorm)()
|
|
|
|
mocked_mobo_temp = MagicMock(spec=FileTemp)()
|
|
|
|
mocked_metrics = MagicMock(spec=Metrics)()
|
|
|
|
|
|
|
|
with ExitStack() as stack:
|
|
|
|
stack.enter_context(
|
|
|
|
patch.object(afancontrol.manager, "Triggers", spec=Triggers)
|
|
|
|
)
|
|
|
|
|
|
|
|
manager = Manager(
|
|
|
|
arduino_connections={},
|
|
|
|
fans={fan_name: mocked_case_fan for fan_name in expected_fan_speeds.keys()},
|
|
|
|
readonly_fans={},
|
|
|
|
temps={temp_name: mocked_mobo_temp for temp_name in temps.keys()},
|
|
|
|
mappings=mappings,
|
|
|
|
report=report,
|
|
|
|
triggers_config=sentinel.some_triggers_config,
|
|
|
|
metrics=mocked_metrics,
|
|
|
|
)
|
|
|
|
|
|
|
|
stack.enter_context(manager)
|
|
|
|
|
|
|
|
assert expected_fan_speeds == pytest.approx(
|
|
|
|
dict(manager._map_temps_to_fan_speeds(temps))
|
|
|
|
)
|