def test_triggers_good_temp(report): t = Triggers( 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), ) }, ), report=report, ) with t: assert not t.is_alerting t.check( { TempName("mobo"): TempStatus( temp=TempCelsius(34.0), min=TempCelsius(40.0), max=TempCelsius(50.0), panic=TempCelsius(60.0), threshold=None, is_panic=False, is_threshold=False, ) } ) assert not t.is_alerting
def test_panic_on_empty_temp(report, sense_exec_shell_command): t = PanicTrigger( global_commands=AlertCommands( enter_cmd="printf '@%s' enter", leave_cmd="printf '@%s' leave" ), temp_commands={ TempName("mobo"): AlertCommands( enter_cmd=None, leave_cmd="printf '@%s' mobo leave" ) }, report=report, ) with sense_exec_shell_command(trigger) as (mock_exec_shell_command, get_stdout): with t: assert not t.is_alerting assert 0 == mock_exec_shell_command.call_count t.check({TempName("mobo"): None}) assert t.is_alerting assert mock_exec_shell_command.call_args_list == [ call("printf '@%s' enter") ] assert ["@enter"] == get_stdout() mock_exec_shell_command.reset_mock() assert not t.is_alerting assert mock_exec_shell_command.call_args_list == [ call("printf '@%s' mobo leave"), call("printf '@%s' leave"), ] assert ["@mobo@leave", "@leave"] == get_stdout()
def test_bad_temp(cls, report, sense_exec_shell_command): t = cls( global_commands=AlertCommands( enter_cmd="printf '@%s' enter", leave_cmd="printf '@%s' leave" ), temp_commands=dict( mobo=AlertCommands( enter_cmd="printf '@%s' mobo enter", leave_cmd="printf '@%s' mobo leave" ) ), report=report, ) with sense_exec_shell_command(trigger) as (mock_exec_shell_command, get_stdout): with t: assert not t.is_alerting t.check( dict( mobo=TempStatus( temp=TempCelsius(70.0), min=TempCelsius(40.0), max=TempCelsius(50.0), panic=TempCelsius(60.0), threshold=TempCelsius(55.0), is_panic=True, is_threshold=True, ) ) ) assert t.is_alerting assert mock_exec_shell_command.call_args_list == [ call("printf '@%s' mobo enter"), call("printf '@%s' enter"), ] assert ["@mobo@enter", "@enter"] == get_stdout() mock_exec_shell_command.reset_mock() t.check( dict( mobo=TempStatus( temp=TempCelsius(34.0), min=TempCelsius(40.0), max=TempCelsius(50.0), panic=TempCelsius(60.0), threshold=None, is_panic=False, is_threshold=False, ) ) ) assert not t.is_alerting assert mock_exec_shell_command.call_args_list == [ call("printf '@%s' mobo leave"), call("printf '@%s' leave"), ] assert ["@mobo@leave", "@leave"] == get_stdout() mock_exec_shell_command.reset_mock() assert 0 == mock_exec_shell_command.call_count
def test_threshold_on_empty_temp(report): t = ThresholdTrigger( global_commands=AlertCommands(enter_cmd=None, leave_cmd=None), temp_commands={TempName("mobo"): AlertCommands(enter_cmd=None, leave_cmd=None)}, report=report, ) with t: assert not t.is_alerting t.check({TempName("mobo"): None}) assert not t.is_alerting assert not t.is_alerting
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() mocked_triggers = cast(MagicMock, manager.triggers) 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
def test_good_temp(cls, report): t = cls( global_commands=AlertCommands(enter_cmd=None, leave_cmd=None), temp_commands=dict(mobo=AlertCommands(enter_cmd=None, leave_cmd=None)), report=report, ) with t: assert not t.is_alerting t.check( dict( mobo=TempStatus( temp=TempCelsius(34.0), min=TempCelsius(40.0), max=TempCelsius(50.0), panic=TempCelsius(60.0), threshold=None, is_panic=False, is_threshold=False, ) ) ) assert not t.is_alerting
def test_pkg_conf(pkg_conf: Path): daemon_cli_config = DaemonCLIConfig(pidfile=None, logfile=None, exporter_listen_host=None) parsed = parse_config(pkg_conf, daemon_cli_config) assert parsed == ParsedConfig( daemon=DaemonConfig( pidfile="/run/afancontrol.pid", logfile="/var/log/afancontrol.log", interval=5, exporter_listen_host=None, ), report_cmd= ('printf "Subject: %s\nTo: %s\n\n%b" ' '"afancontrol daemon report: %REASON%" root "%MESSAGE%" | sendmail -t' ), triggers=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), ) }, ), fans={ FanName("hdd"): PWMFanNorm( LinuxPWMFan( PWMDevice("/sys/class/hwmon/hwmon0/device/pwm2"), FanInputDevice( "/sys/class/hwmon/hwmon0/device/fan2_input"), ), pwm_line_start=PWMValue(100), pwm_line_end=PWMValue(240), never_stop=False, ) }, temps={ TempName("mobo"): FileTemp( "/sys/class/hwmon/hwmon0/device/temp1_input", min=TempCelsius(30.0), max=TempCelsius(40.0), panic=None, threshold=None, ) }, mappings={ MappingName("1"): FansTempsRelation( temps=[TempName("mobo")], fans=[FanSpeedModifier(fan=FanName("hdd"), modifier=0.6)], ) }, )
def test_minimal_config() -> None: daemon_cli_config = DaemonCLIConfig(pidfile=None, logfile=None, exporter_listen_host=None) config = """ [daemon] [actions] [temp:mobo] type = file path = /sys/class/hwmon/hwmon0/device/temp1_input [fan: case] pwm = /sys/class/hwmon/hwmon0/device/pwm2 fan_input = /sys/class/hwmon/hwmon0/device/fan2_input [mapping:1] fans = case*0.6, temps = mobo """ parsed = parse_config(path_from_str(config), daemon_cli_config) assert parsed == ParsedConfig( daemon=DaemonConfig( pidfile="/run/afancontrol.pid", logfile=None, exporter_listen_host=None, interval=5, ), report_cmd= ('printf "Subject: %s\nTo: %s\n\n%b" ' '"afancontrol daemon report: %REASON%" root "%MESSAGE%" | sendmail -t' ), triggers=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), ) }, ), fans={ FanName("case"): PWMFanNorm( LinuxPWMFan( PWMDevice("/sys/class/hwmon/hwmon0/device/pwm2"), FanInputDevice( "/sys/class/hwmon/hwmon0/device/fan2_input"), ), pwm_line_start=PWMValue(100), pwm_line_end=PWMValue(240), never_stop=True, ) }, temps={ TempName("mobo"): FileTemp( "/sys/class/hwmon/hwmon0/device/temp1_input", min=None, max=None, panic=None, threshold=None, ) }, mappings={ MappingName("1"): FansTempsRelation( temps=[TempName("mobo")], fans=[FanSpeedModifier(fan=FanName("case"), modifier=0.6)], ) }, )
def test_example_conf(example_conf: Path): daemon_cli_config = DaemonCLIConfig(pidfile=None, logfile=None, exporter_listen_host=None) parsed = parse_config(example_conf, daemon_cli_config) assert parsed == ParsedConfig( daemon=DaemonConfig( pidfile="/run/afancontrol.pid", logfile="/var/log/afancontrol.log", exporter_listen_host="127.0.0.1:8083", interval=5, ), report_cmd= ('printf "Subject: %s\nTo: %s\n\n%b" ' '"afancontrol daemon report: %REASON%" root "%MESSAGE%" | sendmail -t' ), triggers=TriggerConfig( global_commands=Actions( panic=AlertCommands(enter_cmd=None, leave_cmd=None), threshold=AlertCommands(enter_cmd=None, leave_cmd=None), ), temp_commands={ TempName("hdds"): Actions( panic=AlertCommands(enter_cmd=None, leave_cmd=None), threshold=AlertCommands(enter_cmd=None, leave_cmd=None), ), TempName("mobo"): Actions( panic=AlertCommands(enter_cmd=None, leave_cmd=None), threshold=AlertCommands(enter_cmd=None, leave_cmd=None), ), }, ), fans={ FanName("cpu"): PWMFanNorm( LinuxPWMFan( PWMDevice("/sys/class/hwmon/hwmon0/device/pwm1"), FanInputDevice( "/sys/class/hwmon/hwmon0/device/fan1_input"), ), pwm_line_start=PWMValue(100), pwm_line_end=PWMValue(240), never_stop=True, ), FanName("hdd"): PWMFanNorm( LinuxPWMFan( PWMDevice("/sys/class/hwmon/hwmon0/device/pwm2"), FanInputDevice( "/sys/class/hwmon/hwmon0/device/fan2_input"), ), pwm_line_start=PWMValue(100), pwm_line_end=PWMValue(240), never_stop=False, ), FanName("my_arduino_fan"): PWMFanNorm( ArduinoPWMFan( ArduinoConnection( ArduinoName("mymicro"), "/dev/ttyACM0", # linux # "/dev/cu.usbmodem14201", # macos baudrate=115200, status_ttl=5, ), pwm_pin=ArduinoPin(9), tacho_pin=ArduinoPin(3), ), pwm_line_start=PWMValue(100), pwm_line_end=PWMValue(240), never_stop=True, ), }, temps={ TempName("hdds"): HDDTemp( "/dev/sd?", min=TempCelsius(35.0), max=TempCelsius(48.0), panic=TempCelsius(55.0), threshold=None, hddtemp_bin="hddtemp", ), TempName("mobo"): FileTemp( "/sys/class/hwmon/hwmon0/device/temp1_input", min=TempCelsius(30.0), max=TempCelsius(40.0), panic=None, threshold=None, ), }, mappings={ MappingName("1"): FansTempsRelation( temps=[TempName("mobo"), TempName("hdds")], fans=[ FanSpeedModifier(fan=FanName("cpu"), modifier=1.0), FanSpeedModifier(fan=FanName("hdd"), modifier=0.6), FanSpeedModifier(fan=FanName("my_arduino_fan"), modifier=0.222), ], ), MappingName("2"): FansTempsRelation( temps=[TempName("hdds")], fans=[FanSpeedModifier(fan=FanName("hdd"), modifier=1.0)], ), }, )
def test_readonly_config() -> None: daemon_cli_config = DaemonCLIConfig( pidfile=None, logfile=None, exporter_listen_host=None ) config = """ [daemon] [actions] [temp:mobo] type = file path = /sys/class/hwmon/hwmon0/device/temp1_input [readonly_fan: cpu] pwm = /sys/class/hwmon/hwmon0/device/pwm1 fan_input = /sys/class/hwmon/hwmon0/device/fan1_input """ parsed = parse_config(path_from_str(config), daemon_cli_config) assert parsed == ParsedConfig( arduino_connections={}, daemon=DaemonConfig( pidfile="/run/afancontrol.pid", logfile=None, exporter_listen_host=None, interval=5, ), report_cmd=( 'printf "Subject: %s\nTo: %s\n\n%b" ' '"afancontrol daemon report: %REASON%" root "%MESSAGE%" | sendmail -t' ), triggers=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), ) }, ), fans={}, readonly_fans={ ReadonlyFanName("cpu"): ReadonlyPWMFanNorm( fan_speed=LinuxFanSpeed( FanInputDevice("/sys/class/hwmon/hwmon0/device/fan1_input") ), pwm_read=LinuxFanPWMRead( PWMDevice("/sys/class/hwmon/hwmon0/device/pwm1") ), ) }, temps={ TempName("mobo"): FilteredTemp( temp=FileTemp( "/sys/class/hwmon/hwmon0/device/temp1_input", min=None, max=None, panic=None, threshold=None, ), filter=NullFilter(), ) }, mappings={}, )