Exemple #1
0
def test_publish_preparing_for_shutdown_homeassistant_config(
    topic_prefix, discovery_prefix, node_id, hostname
):
    state = systemctl_mqtt._State(
        mqtt_topic_prefix=topic_prefix,
        homeassistant_discovery_prefix=discovery_prefix,
        homeassistant_node_id=node_id,
        poweroff_delay=datetime.timedelta(),
    )
    mqtt_client = unittest.mock.MagicMock()
    with unittest.mock.patch(
        "systemctl_mqtt._utils.get_hostname", return_value=hostname
    ):
        state.publish_preparing_for_shutdown_homeassistant_config(
            mqtt_client=mqtt_client
        )
    assert mqtt_client.publish.call_count == 1
    publish_args, publish_kwargs = mqtt_client.publish.call_args
    assert not publish_args
    assert publish_kwargs["retain"]
    assert (
        publish_kwargs["topic"]
        == discovery_prefix
        + "/binary_sensor/"
        + node_id
        + "/preparing-for-shutdown/config"
    )
    assert json.loads(publish_kwargs["payload"]) == {
        "unique_id": "systemctl-mqtt/" + node_id + "/logind/preparing-for-shutdown",
        "state_topic": topic_prefix + "/preparing-for-shutdown",
        "payload_on": "true",
        "payload_off": "false",
        "name": node_id + " preparing for shutdown",
    }
def test_poweroff_trigger(delay):
    action = systemctl_mqtt._MQTTActionSchedulePoweroff()
    with unittest.mock.patch("systemctl_mqtt._dbus.schedule_shutdown"
                             ) as schedule_shutdown_mock:
        action.trigger(state=systemctl_mqtt._State(
            mqtt_topic_prefix="systemctl/hostname",
            homeassistant_discovery_prefix="homeassistant",
            homeassistant_node_id="node",
            poweroff_delay=delay,
        ))
    schedule_shutdown_mock.assert_called_once_with(action="poweroff",
                                                   delay=delay)
def test_mqtt_topic_suffix_action_mapping_poweroff(topic_suffix,
                                                   expected_action_arg):
    mqtt_action = systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING[
        topic_suffix]
    login_manager_mock = unittest.mock.MagicMock()
    with unittest.mock.patch("systemctl_mqtt._dbus.get_login_manager",
                             return_value=login_manager_mock):
        mqtt_action.trigger(state=systemctl_mqtt._State(
            mqtt_topic_prefix="systemctl/hostname",
            homeassistant_discovery_prefix="homeassistant",
            homeassistant_node_id="node",
            poweroff_delay=datetime.timedelta(),
        ))
    assert login_manager_mock.ScheduleShutdown.call_count == 1
    schedule_args, schedule_kwargs = login_manager_mock.ScheduleShutdown.call_args
    assert len(schedule_args) == 2
    assert schedule_args[0] == expected_action_arg
    assert not schedule_kwargs
Exemple #4
0
def test_shutdown_lock():
    lock_fd = unittest.mock.MagicMock()
    with unittest.mock.patch("systemctl_mqtt._dbus.get_login_manager"):
        state = systemctl_mqtt._State(
            mqtt_topic_prefix="any",
            homeassistant_discovery_prefix=None,
            homeassistant_node_id=None,
            poweroff_delay=datetime.timedelta(),
        )
        state._login_manager.Inhibit.return_value = lock_fd
        state.acquire_shutdown_lock()
    state._login_manager.Inhibit.assert_called_once_with(
        "shutdown", "systemctl-mqtt", "Report shutdown via MQTT", "delay"
    )
    assert state._shutdown_lock == lock_fd
    # https://dbus.freedesktop.org/doc/dbus-python/dbus.types.html#dbus.types.UnixFd.take
    lock_fd.take.return_value = "fdnum"
    with unittest.mock.patch("os.close") as close_mock:
        state.release_shutdown_lock()
    close_mock.assert_called_once_with("fdnum")
Exemple #5
0
def test_publish_preparing_for_shutdown_get_fail(caplog):
    login_manager_mock = unittest.mock.MagicMock()
    login_manager_mock.Get.side_effect = dbus.DBusException("mocked")
    with unittest.mock.patch(
        "systemctl_mqtt._dbus.get_login_manager", return_value=login_manager_mock
    ):
        state = systemctl_mqtt._State(
            mqtt_topic_prefix="any",
            homeassistant_discovery_prefix=None,
            homeassistant_node_id=None,
            poweroff_delay=datetime.timedelta(),
        )
    mqtt_client_mock = unittest.mock.MagicMock()
    state.publish_preparing_for_shutdown(mqtt_client=None)
    mqtt_client_mock.publish.assert_not_called()
    assert len(caplog.records) == 1
    assert caplog.records[0].levelno == logging.ERROR
    assert (
        caplog.records[0].message
        == "failed to read logind's PreparingForShutdown property: mocked"
    )
Exemple #6
0
def test_prepare_for_shutdown_handler(caplog, active):
    with unittest.mock.patch("systemctl_mqtt._dbus.get_login_manager"):
        state = systemctl_mqtt._State(
            mqtt_topic_prefix="any",
            homeassistant_discovery_prefix=None,
            homeassistant_node_id=None,
            poweroff_delay=datetime.timedelta(),
        )
    mqtt_client_mock = unittest.mock.MagicMock()
    state.register_prepare_for_shutdown_handler(mqtt_client=mqtt_client_mock)
    # pylint: disable=no-member,comparison-with-callable
    connect_to_signal_kwargs = state._login_manager.connect_to_signal.call_args[1]
    assert connect_to_signal_kwargs["signal_name"] == "PrepareForShutdown"
    handler_function = connect_to_signal_kwargs["handler_function"]
    assert handler_function.func == state._prepare_for_shutdown_handler
    with unittest.mock.patch.object(
        state, "acquire_shutdown_lock"
    ) as acquire_lock_mock, unittest.mock.patch.object(
        state, "release_shutdown_lock"
    ) as release_lock_mock:
        handler_function(dbus.types.Boolean(active))
    if active:
        acquire_lock_mock.assert_not_called()
        release_lock_mock.assert_called_once_with()
    else:
        acquire_lock_mock.assert_called_once_with()
        release_lock_mock.assert_not_called()
    mqtt_client_mock.publish.assert_called_once_with(
        topic="any/preparing-for-shutdown",
        payload="true" if active else "false",
        retain=True,
    )
    assert len(caplog.records) == 1
    assert caplog.records[0].levelno == logging.ERROR
    assert caplog.records[0].message.startswith(
        "failed to publish on any/preparing-for-shutdown"
    )