|
@@ -15,6 +15,7 @@
|
|
# You should have received a copy of the GNU General Public License
|
|
# You should have received a copy of the GNU General Public License
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
# along with this program. If not, see <https://www.gnu.org/licenses/>.
|
|
|
|
|
|
|
|
+import datetime
|
|
import logging
|
|
import logging
|
|
import threading
|
|
import threading
|
|
import time
|
|
import time
|
|
@@ -66,6 +67,7 @@ def test__run(
|
|
mqtt_topic_prefix=mqtt_topic_prefix,
|
|
mqtt_topic_prefix=mqtt_topic_prefix,
|
|
homeassistant_discovery_prefix=homeassistant_discovery_prefix,
|
|
homeassistant_discovery_prefix=homeassistant_discovery_prefix,
|
|
homeassistant_node_id=homeassistant_node_id,
|
|
homeassistant_node_id=homeassistant_node_id,
|
|
|
|
+ poweroff_delay=datetime.timedelta(),
|
|
)
|
|
)
|
|
assert caplog.records[0].levelno == logging.INFO
|
|
assert caplog.records[0].levelno == logging.INFO
|
|
assert caplog.records[0].message == (
|
|
assert caplog.records[0].message == (
|
|
@@ -136,7 +138,7 @@ def test__run(
|
|
assert caplog.records[5].message == "registered MQTT callback for topic {}".format(
|
|
assert caplog.records[5].message == "registered MQTT callback for topic {}".format(
|
|
mqtt_topic_prefix + "/poweroff"
|
|
mqtt_topic_prefix + "/poweroff"
|
|
) + " triggering {}".format(
|
|
) + " triggering {}".format(
|
|
- systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING["poweroff"].action
|
|
|
|
|
|
+ systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING["poweroff"]
|
|
)
|
|
)
|
|
# dbus loop started?
|
|
# dbus loop started?
|
|
glib_loop_mock.assert_called_once_with()
|
|
glib_loop_mock.assert_called_once_with()
|
|
@@ -162,6 +164,7 @@ def test__run_tls(caplog, mqtt_host, mqtt_port, mqtt_disable_tls):
|
|
mqtt_topic_prefix="systemctl/hosts",
|
|
mqtt_topic_prefix="systemctl/hosts",
|
|
homeassistant_discovery_prefix="homeassistant",
|
|
homeassistant_discovery_prefix="homeassistant",
|
|
homeassistant_node_id="host",
|
|
homeassistant_node_id="host",
|
|
|
|
+ poweroff_delay=datetime.timedelta(),
|
|
)
|
|
)
|
|
assert caplog.records[0].levelno == logging.INFO
|
|
assert caplog.records[0].levelno == logging.INFO
|
|
assert caplog.records[0].message == (
|
|
assert caplog.records[0].message == (
|
|
@@ -188,6 +191,7 @@ def test__run_tls_default():
|
|
mqtt_topic_prefix="systemctl/hosts",
|
|
mqtt_topic_prefix="systemctl/hosts",
|
|
homeassistant_discovery_prefix="homeassistant",
|
|
homeassistant_discovery_prefix="homeassistant",
|
|
homeassistant_node_id="host",
|
|
homeassistant_node_id="host",
|
|
|
|
+ poweroff_delay=datetime.timedelta(),
|
|
)
|
|
)
|
|
# enabled by default
|
|
# enabled by default
|
|
mqtt_client_class().tls_set.assert_called_once_with(ca_certs=None)
|
|
mqtt_client_class().tls_set.assert_called_once_with(ca_certs=None)
|
|
@@ -219,6 +223,7 @@ def test__run_authentication(
|
|
mqtt_topic_prefix=mqtt_topic_prefix,
|
|
mqtt_topic_prefix=mqtt_topic_prefix,
|
|
homeassistant_discovery_prefix="discovery-prefix",
|
|
homeassistant_discovery_prefix="discovery-prefix",
|
|
homeassistant_node_id="node-id",
|
|
homeassistant_node_id="node-id",
|
|
|
|
+ poweroff_delay=datetime.timedelta(),
|
|
)
|
|
)
|
|
assert mqtt_loop_forever_mock.call_count == 1
|
|
assert mqtt_loop_forever_mock.call_count == 1
|
|
(mqtt_client,) = mqtt_loop_forever_mock.call_args[0]
|
|
(mqtt_client,) = mqtt_loop_forever_mock.call_args[0]
|
|
@@ -251,6 +256,7 @@ def _initialize_mqtt_client(
|
|
mqtt_topic_prefix=mqtt_topic_prefix,
|
|
mqtt_topic_prefix=mqtt_topic_prefix,
|
|
homeassistant_discovery_prefix="discovery-prefix",
|
|
homeassistant_discovery_prefix="discovery-prefix",
|
|
homeassistant_node_id="node-id",
|
|
homeassistant_node_id="node-id",
|
|
|
|
+ poweroff_delay=datetime.timedelta(),
|
|
)
|
|
)
|
|
while threading.active_count() > 1:
|
|
while threading.active_count() > 1:
|
|
time.sleep(0.01)
|
|
time.sleep(0.01)
|
|
@@ -272,16 +278,16 @@ def test__client_handle_message(caplog, mqtt_host, mqtt_port, mqtt_topic_prefix)
|
|
caplog.set_level(logging.DEBUG)
|
|
caplog.set_level(logging.DEBUG)
|
|
poweroff_message = MQTTMessage(topic=mqtt_topic_prefix.encode() + b"/poweroff")
|
|
poweroff_message = MQTTMessage(topic=mqtt_topic_prefix.encode() + b"/poweroff")
|
|
with unittest.mock.patch.object(
|
|
with unittest.mock.patch.object(
|
|
- systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING["poweroff"], "action",
|
|
|
|
- ) as poweroff_action_mock:
|
|
|
|
|
|
+ systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING["poweroff"], "trigger"
|
|
|
|
+ ) as poweroff_trigger_mock:
|
|
mqtt_client._handle_on_message(poweroff_message)
|
|
mqtt_client._handle_on_message(poweroff_message)
|
|
- poweroff_action_mock.assert_called_once_with()
|
|
|
|
|
|
+ poweroff_trigger_mock.assert_called_once_with(state=mqtt_client._userdata)
|
|
assert all(r.levelno == logging.DEBUG for r in caplog.records)
|
|
assert all(r.levelno == logging.DEBUG for r in caplog.records)
|
|
assert caplog.records[0].message == "received topic={} payload=b''".format(
|
|
assert caplog.records[0].message == "received topic={} payload=b''".format(
|
|
poweroff_message.topic
|
|
poweroff_message.topic
|
|
)
|
|
)
|
|
- assert caplog.records[1].message.startswith("executing action poweroff")
|
|
|
|
- assert caplog.records[2].message.startswith("completed action poweroff")
|
|
|
|
|
|
+ assert caplog.records[1].message == "executing action _MQTTActionSchedulePoweroff"
|
|
|
|
+ assert caplog.records[2].message == "completed action _MQTTActionSchedulePoweroff"
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("mqtt_host", ["mqtt-broker.local"])
|
|
@pytest.mark.parametrize("mqtt_host", ["mqtt-broker.local"])
|
|
@@ -291,7 +297,7 @@ def test__run_authentication_missing_username(mqtt_host, mqtt_port, mqtt_passwor
|
|
with unittest.mock.patch("paho.mqtt.client.Client"), unittest.mock.patch(
|
|
with unittest.mock.patch("paho.mqtt.client.Client"), unittest.mock.patch(
|
|
"systemctl_mqtt._dbus.get_login_manager"
|
|
"systemctl_mqtt._dbus.get_login_manager"
|
|
):
|
|
):
|
|
- with pytest.raises(ValueError):
|
|
|
|
|
|
+ with pytest.raises(ValueError, match=r"^Missing MQTT username$"):
|
|
systemctl_mqtt._run(
|
|
systemctl_mqtt._run(
|
|
mqtt_host=mqtt_host,
|
|
mqtt_host=mqtt_host,
|
|
mqtt_port=mqtt_port,
|
|
mqtt_port=mqtt_port,
|
|
@@ -300,6 +306,7 @@ def test__run_authentication_missing_username(mqtt_host, mqtt_port, mqtt_passwor
|
|
mqtt_topic_prefix="prefix",
|
|
mqtt_topic_prefix="prefix",
|
|
homeassistant_discovery_prefix="discovery-prefix",
|
|
homeassistant_discovery_prefix="discovery-prefix",
|
|
homeassistant_node_id="node-id",
|
|
homeassistant_node_id="node-id",
|
|
|
|
+ poweroff_delay=datetime.timedelta(),
|
|
)
|
|
)
|
|
|
|
|
|
|
|
|
|
@@ -309,27 +316,23 @@ def test_mqtt_message_callback_poweroff(caplog, mqtt_topic: str, payload: bytes)
|
|
message = MQTTMessage(topic=mqtt_topic.encode())
|
|
message = MQTTMessage(topic=mqtt_topic.encode())
|
|
message.payload = payload
|
|
message.payload = payload
|
|
with unittest.mock.patch.object(
|
|
with unittest.mock.patch.object(
|
|
- systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING["poweroff"], "action",
|
|
|
|
- ) as action_mock, caplog.at_level(logging.DEBUG):
|
|
|
|
|
|
+ systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING["poweroff"], "trigger"
|
|
|
|
+ ) as trigger_mock, caplog.at_level(logging.DEBUG):
|
|
systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING[
|
|
systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING[
|
|
"poweroff"
|
|
"poweroff"
|
|
].mqtt_message_callback(
|
|
].mqtt_message_callback(
|
|
- None, None, message # type: ignore
|
|
|
|
|
|
+ None, "state_dummy", message # type: ignore
|
|
)
|
|
)
|
|
- action_mock.assert_called_once_with()
|
|
|
|
|
|
+ trigger_mock.assert_called_once_with(state="state_dummy")
|
|
assert len(caplog.records) == 3
|
|
assert len(caplog.records) == 3
|
|
assert caplog.records[0].levelno == logging.DEBUG
|
|
assert caplog.records[0].levelno == logging.DEBUG
|
|
assert caplog.records[0].message == (
|
|
assert caplog.records[0].message == (
|
|
"received topic={} payload={!r}".format(mqtt_topic, payload)
|
|
"received topic={} payload={!r}".format(mqtt_topic, payload)
|
|
)
|
|
)
|
|
assert caplog.records[1].levelno == logging.DEBUG
|
|
assert caplog.records[1].levelno == logging.DEBUG
|
|
- assert caplog.records[1].message.startswith(
|
|
|
|
- "executing action {} ({!r})".format("poweroff", action_mock)
|
|
|
|
- )
|
|
|
|
|
|
+ assert caplog.records[1].message == "executing action _MQTTActionSchedulePoweroff"
|
|
assert caplog.records[2].levelno == logging.DEBUG
|
|
assert caplog.records[2].levelno == logging.DEBUG
|
|
- assert caplog.records[2].message.startswith(
|
|
|
|
- "completed action {} ({!r})".format("poweroff", action_mock)
|
|
|
|
- )
|
|
|
|
|
|
+ assert caplog.records[2].message == "completed action _MQTTActionSchedulePoweroff"
|
|
|
|
|
|
|
|
|
|
@pytest.mark.parametrize("mqtt_topic", ["system/command/poweroff"])
|
|
@pytest.mark.parametrize("mqtt_topic", ["system/command/poweroff"])
|
|
@@ -341,14 +344,14 @@ def test_mqtt_message_callback_poweroff_retained(
|
|
message.payload = payload
|
|
message.payload = payload
|
|
message.retain = True
|
|
message.retain = True
|
|
with unittest.mock.patch.object(
|
|
with unittest.mock.patch.object(
|
|
- systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING["poweroff"], "action",
|
|
|
|
- ) as action_mock, caplog.at_level(logging.DEBUG):
|
|
|
|
|
|
+ systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING["poweroff"], "trigger"
|
|
|
|
+ ) as trigger_mock, caplog.at_level(logging.DEBUG):
|
|
systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING[
|
|
systemctl_mqtt._MQTT_TOPIC_SUFFIX_ACTION_MAPPING[
|
|
"poweroff"
|
|
"poweroff"
|
|
].mqtt_message_callback(
|
|
].mqtt_message_callback(
|
|
None, None, message # type: ignore
|
|
None, None, message # type: ignore
|
|
)
|
|
)
|
|
- action_mock.assert_not_called()
|
|
|
|
|
|
+ trigger_mock.assert_not_called()
|
|
assert len(caplog.records) == 2
|
|
assert len(caplog.records) == 2
|
|
assert caplog.records[0].levelno == logging.DEBUG
|
|
assert caplog.records[0].levelno == logging.DEBUG
|
|
assert caplog.records[0].message == (
|
|
assert caplog.records[0].message == (
|