Browse Source

upgrade paho-mqtt to no longer suppress exceptions occuring in mqtt callbacks

https://github.com/fphammerle/systemctl-mqtt/commit/5ee4c3748514ac989aafe32ce652b329325a9e44
https://github.com/eclipse/paho.mqtt.python/blob/v1.5.1/ChangeLog.txt#L4
Fabian Peter Hammerle 3 years ago
parent
commit
b49dbfa18c
5 changed files with 48 additions and 8 deletions
  1. 5 0
      CHANGELOG.md
  2. 1 0
      Dockerfile
  3. 8 8
      Pipfile.lock
  4. 1 0
      switchbot_mqtt/__init__.py
  5. 33 0
      tests/test_switchbot.py

+ 5 - 0
CHANGELOG.md

@@ -5,6 +5,11 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
 and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
 
 ## [Unreleased]
+### Changed
+- docker image:
+  - upgrade `paho-mqtt` to no longer suppress exceptions occuring in mqtt callbacks
+    ( https://github.com/eclipse/paho.mqtt.python/blob/v1.5.1/ChangeLog.txt#L4 )
+  - build stage: revert user after applying `chown` workaround for inter-stage copy
 
 ## [0.5.0] - 2020-11-22
 ### Added

+ 1 - 0
Dockerfile

@@ -34,6 +34,7 @@ RUN pipenv install --deploy --verbose \
 # > failed to copy files: failed to copy directory: Error processing tar file(exit status 1): Container ID ... cannot be mapped to a host ID
 USER 0
 RUN chown -R 0:0 $SOURCE_DIR_PATH
+USER build
 
 
 FROM $BASE_IMAGE

+ 8 - 8
Pipfile.lock

@@ -24,9 +24,9 @@
         },
         "paho-mqtt": {
             "hashes": [
-                "sha256:e3d286198baaea195c8b3bc221941d25a3ab0e1507fc1779bdb7473806394be4"
+                "sha256:9feb068e822be7b3a116324e01fb6028eb1d66412bf98595ae72698965cb1cae"
             ],
-            "version": "==1.5.0"
+            "version": "==1.5.1"
         },
         "pyswitchbot": {
             "hashes": [
@@ -117,11 +117,11 @@
         },
         "importlib-metadata": {
             "hashes": [
-                "sha256:030f3b1bdb823ecbe4a9659e14cc861ce5af403fe99863bae173ec5fe00ab132",
-                "sha256:caeee3603f5dcf567864d1be9b839b0bcfdf1383e3e7be33ce2dead8144ff19c"
+                "sha256:b8de9eff2b35fb037368f28a7df1df4e6436f578fa74423505b6c6a778d5b5dd",
+                "sha256:c2d6341ff566f609e89a2acb2db190e5e1d23d5409d6cc8d2fe34d72443876d4"
             ],
             "index": "pypi",
-            "version": "==2.1.0"
+            "version": "==2.1.1"
         },
         "iniconfig": {
             "hashes": [
@@ -200,10 +200,10 @@
         },
         "packaging": {
             "hashes": [
-                "sha256:4357f74f47b9c12db93624a82154e9b120fa8293699949152b22065d556079f8",
-                "sha256:998416ba6962ae7fbd6596850b80e17859a5753ba17c32284f67bfff33784181"
+                "sha256:05af3bb85d320377db281cf254ab050e1a7ebcbf5410685a9a407e18a1f81236",
+                "sha256:eb41423378682dadb7166144a4926e443093863024de508ca5c9737d6bc08376"
             ],
-            "version": "==20.4"
+            "version": "==20.7"
         },
         "pathlib2": {
             "hashes": [

+ 1 - 0
switchbot_mqtt/__init__.py

@@ -100,6 +100,7 @@ def _send_command(
     action: _SwitchbotAction,
 ) -> None:
     switchbot_device = switchbot.Switchbot(mac=switchbot_mac_address)
+    # pySwitchbot catches & logs bluetooth exceptions (see `test__send_command_bluetooth_error`)
     if action == _SwitchbotAction.ON:
         if not switchbot_device.turn_on():
             _LOGGER.error("failed to turn on switchbot %s", switchbot_mac_address)

+ 33 - 0
tests/test_switchbot.py

@@ -1,6 +1,7 @@
 import logging
 import unittest.mock
 
+import bluepy.btle
 import pytest
 
 import switchbot_mqtt
@@ -52,3 +53,35 @@ def test__send_command(caplog, mac_address, action, command_successful):
             switchbot_mac_address=mac_address,
             switchbot_state=expected_state,
         )
+
+
+@pytest.mark.parametrize("mac_address", ["aa:bb:cc:dd:ee:ff"])
+@pytest.mark.parametrize("action", [switchbot_mqtt._SwitchbotAction.ON])
+def test__send_command_bluetooth_error(caplog, mac_address, action):
+    """
+    paho.mqtt.python>=1.5.1 no longer implicitly suppresses exceptions in callbacks.
+    verify pySwitchbot catches exceptions raised in bluetooth stack.
+    https://github.com/Danielhiversen/pySwitchbot/blob/0.8.0/switchbot/__init__.py#L48
+    https://github.com/Danielhiversen/pySwitchbot/blob/0.8.0/switchbot/__init__.py#L94
+    """
+    with unittest.mock.patch(
+        "bluepy.btle.Peripheral",
+        side_effect=bluepy.btle.BTLEDisconnectError(
+            "Failed to connect to peripheral {}, addr type: random".format(mac_address)
+        ),
+    ), caplog.at_level(logging.ERROR):
+        switchbot_mqtt._send_command(
+            mqtt_client=None, switchbot_mac_address=mac_address, action=action
+        )
+    assert caplog.record_tuples == [
+        (
+            "switchbot",
+            logging.ERROR,
+            "Switchbot communication failed. Stopping trying.",
+        ),
+        (
+            "switchbot_mqtt",
+            logging.ERROR,
+            "failed to turn on switchbot {}".format(mac_address),
+        ),
+    ]