MQTT-FIX-T01: make main MQTT client lifecycle idempotent

This commit is contained in:
tliu93 committed 2026-10-11 23:34:13 +02:00
1 parent 48071685f1
commit 876754be56
8 files changed
+629 -76

No files matched your search

+11 -11
View File
@@ -143,7 +143,7 @@ def test_unsubscribe_unknown_topic_is_noop() -> None:
# ---------------------------------------------------------------------------
def _extract_on_message(manager: MqttManager, settings) -> object:
def _extract_on_message(manager: MqttManager, settings) -> tuple[object, MagicMock]:
"""Connect with a mocked paho client and return the on_message callback that
was registered on the client mock."""
mock_client = MagicMock()
@@ -153,7 +153,7 @@ def _extract_on_message(manager: MqttManager, settings) -> object:
manager.connect(settings)
# The callback was assigned as: client.on_message = _on_message
return mock_client.on_message
return mock_client.on_message, mock_client
def test_on_message_dispatches_to_registered_handler() -> None:
@@ -168,10 +168,10 @@ def test_on_message_dispatches_to_registered_handler() -> None:
manager.subscribe("dsmr/json", handler)
on_message = _extract_on_message(manager, settings)
on_message, client = _extract_on_message(manager, settings)
msg = _make_mqtt_message("dsmr/json", b'{"id": 1}')
on_message(MagicMock(), None, msg) # simulate paho calling the callback
on_message(client, None, msg) # simulate paho calling the callback
assert received_payloads == [b'{"id": 1}']
@@ -183,11 +183,11 @@ def test_on_message_ignores_unknown_topic() -> None:
handler = MagicMock()
manager.subscribe("other/topic", handler)
on_message = _extract_on_message(manager, settings)
on_message, client = _extract_on_message(manager, settings)
msg = _make_mqtt_message("unknown/topic", b"data")
# Must not raise
on_message(MagicMock(), None, msg)
on_message(client, None, msg)
handler.assert_not_called()
@@ -201,11 +201,11 @@ def test_on_message_swallows_handler_exception() -> None:
raise RuntimeError("handler exploded")
manager.subscribe("dsmr/json", bad_handler)
on_message = _extract_on_message(manager, settings)
on_message, client = _extract_on_message(manager, settings)
msg = _make_mqtt_message("dsmr/json", b"{}")
# This must not raise
on_message(MagicMock(), None, msg)
on_message(client, None, msg)
def test_on_message_does_not_crash_on_handler_exception_multiple_calls() -> None:
@@ -221,13 +221,13 @@ def test_on_message_does_not_crash_on_handler_exception_multiple_calls() -> None
raise ValueError("first call fails")
manager.subscribe("dsmr/json", flaky_handler)
on_message = _extract_on_message(manager, settings)
on_message, client = _extract_on_message(manager, settings)
msg1 = _make_mqtt_message("dsmr/json", b"first")
msg2 = _make_mqtt_message("dsmr/json", b"second")
on_message(MagicMock(), None, msg1) # should not raise despite exception in handler
on_message(MagicMock(), None, msg2) # handler called again
on_message(client, None, msg1) # should not raise despite exception in handler
on_message(client, None, msg2) # handler called again
assert call_count[0] == 2