-
-
Notifications
You must be signed in to change notification settings - Fork 13
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Update mqttplugin.py to paho-mqtt version 2.0.0 #31
Conversation
Not sure why they did this but paho-mqtt 2.0.0 breaks ALL existing implementations. more info here https://github.com/eclipse/paho.mqtt.python/releases/tag/v2.0.0
Also when pip upgrading on w11 it also now has 2.0.0 |
Thanks for the PR -- can you please get the tests passing? First step will be updating the paho-mqtt version in requirements-test.txt. You should be able to test locally with If you're up for it, I think you'll be able to fix #32 at the same time by passing |
paho-mqtt now 2.0.0
I am Somewhat of a github novice and it is about time I figure more of it
out. I have a couple of projects I want to release.
I guess my first lesson is: testing with tox :)
…On Thu, Apr 25, 2024 at 4:26 PM Nathan Henrie ***@***.***> wrote:
Thanks for the PR -- can you please get the tests passing?
First step will be updating the paho-mqtt version in
requirements-test.txt. You should be able to test locally with tox.
If you're up for it, I think you'll be able to fix #32
<#32> at the same time
by passing initial_state to the parent class like so
<https://github.com/n8henrie/fauxmo/blob/51c1a35bb03f7ce06acf13726a97adceb4e72bb5/src/fauxmo/plugins/commandlineplugin.py#L105>
.
—
Reply to this email directly, view it on GitHub
<#31 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGJXT26WMAUVS6TAIBKLTTY7GGJ7AVCNFSM6AAAAABGIBI752VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANZYGMZDOOJZGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
… On Thu, Apr 25, 2024 at 4:26 PM Nathan Henrie ***@***.***> wrote:
Thanks for the PR -- can you please get the tests passing?
First step will be updating the paho-mqtt version in
requirements-test.txt. You should be able to test locally with tox.
If you're up for it, I think you'll be able to fix #32
<#32> at the same time
by passing initial_state to the parent class like so
<https://github.com/n8henrie/fauxmo/blob/51c1a35bb03f7ce06acf13726a97adceb4e72bb5/src/fauxmo/plugins/commandlineplugin.py#L105>
.
—
Reply to this email directly, view it on GitHub
<#31 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGJXT26WMAUVS6TAIBKLTTY7GGJ7AVCNFSM6AAAAABGIBI752VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANZYGMZDOOJZGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
It looks like the tests do not like version 1 so I'll bring it up to
version 2 . No biggie, I have already done that in some other code.
I wanted to use V1 just to reduce the possibility of breakage.
…On Thu, Apr 25, 2024 at 5:58 PM Jim Dodgen ***@***.***> wrote:
Also I did the #32
<#32> fix locally and
was able to add a device with no problems.
On Thu, Apr 25, 2024 at 4:26 PM Nathan Henrie ***@***.***>
wrote:
> Thanks for the PR -- can you please get the tests passing?
>
> First step will be updating the paho-mqtt version in
> requirements-test.txt. You should be able to test locally with tox.
>
> If you're up for it, I think you'll be able to fix #32
> <#32> at the same time
> by passing initial_state to the parent class like so
> <https://github.com/n8henrie/fauxmo/blob/51c1a35bb03f7ce06acf13726a97adceb4e72bb5/src/fauxmo/plugins/commandlineplugin.py#L105>
> .
>
> —
> Reply to this email directly, view it on GitHub
> <#31 (comment)>,
> or unsubscribe
> <https://github.com/notifications/unsubscribe-auth/AAGJXT26WMAUVS6TAIBKLTTY7GGJ7AVCNFSM6AAAAABGIBI752VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDANZYGMZDOOJZGY>
> .
> You are receiving this because you authored the thread.Message ID:
> ***@***.***>
>
|
Ok, a little into tox but a lot of strange errors so I figure I'm doing something wrong.
|
Oh darn, you're on Windows. It looks like you're using python310; you can run specifically this environment with Once all tests are passing, you'll also want to make sure the formatting is up to snuff: You can run both at the same time: |
I think the first hint is in your error message: |
I also have a ubuntu system. I'll try on that box
…On Fri, Apr 26, 2024 at 3:14 PM Nathan Henrie ***@***.***> wrote:
I think the first hint is in your error message: TypeError: missing a
required argument: 'callback_api_version' -- looks like the mqtt tests
need to be updated for the new version.
—
Reply to this email directly, view it on GitHub
<#31 (comment)>,
or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AAGJXT3B7KPO2OSV64WV6J3Y7LGTVAVCNFSM6AAAAABGIBI752VHI2DSMVQWIX3LMV43OSLTON2WKQ3PNVWWK3TUHMZDAOBQGE4DEMRTGY>
.
You are receiving this because you authored the thread.Message ID:
***@***.***>
|
Ok, I got it all set on my ubuntu box. I think I prefer the cli, too much
magic in the gui implementations.
Here is the tox -e py310,lint run
```
py310 installed: black==23.3.0,blinker==1.8.0,brotlipy==0.7.0,cachetools==5.3.3,certifi==2024.2.2,cffi==1.16.0,chardet==5.2.0,charset-normalizer==3.3.2,click==8.1.7,colorama==0.4.6,decorator==5.1.1,distlib==0.3.8,exceptiongroup==1.2.1,fauxmo @ https://github.com/n8henrie/fauxmo/archive/dev.zip,filelock==3.13.4,flake8==3.9.2,flake8-docstrings==1.7.0,flake8-import-order==0.18.2,Flask==2.1.3,httpbin==0.7.0,idna==3.7,iniconfig==2.0.0,itsdangerous==2.2.0,Jinja2==3.1.3,MarkupSafe==2.1.5,mccabe==0.6.1,mypy==1.2.0,mypy-extensions==1.0.0,packaging==24.0,paho-mqtt==2.0.0,pathspec==0.12.1,platformdirs==4.2.1,pluggy==1.5.0,pycodestyle==2.7.0,pycparser==2.22,pydocstyle==6.1.1,pyflakes==2.3.1,pyproject-api==1.6.1,pytest==7.3.0,raven==6.10.0,requests==2.28.2,six==1.16.0,snowballstemmer==2.2.0,tomli==2.0.1,tox==4.4.11,types-requests==2.28.11.17,types-urllib3==1.26.25.14,typing_extensions==4.11.0,urllib3==1.26.18,virtualenv==20.26.0,Werkzeug==2.0.3
py310 run-test-pre: PYTHONHASHSEED='3247594056'
py310 run-test: commands[0] | python -m pytest --showlocals tests/
============================= test session starts ==============================
platform linux -- Python 3.10.12, pytest-7.3.0, pluggy-1.5.0
cachedir: .tox/py310/.pytest_cache
rootdir: /home/jim/fauxmo-plugins
collected 7 items
tests/test_mqttplugin.py ..F.F [ 71%]
tests/test_restapiplugin.py .. [100%]
=================================== FAILURES ===================================
______________________________ test_mqtt_nostate _______________________________
mock_client = <MagicMock name='Client' spec='Client' id='132493816592992'>
@patch("mqttplugin.Client", autospec=True)
def test_mqtt_nostate(mock_client: MagicMock) -> None:
"""If state_cmd is not specified, loop_start is not called."""
mock_instance = mock_client.return_value
with open(config_path_str) as f:
config: dict = json.load(f)
device_conf = next(
device
for device in config["PLUGINS"]["MQTTPlugin"]["DEVICES"]
if device["mqtt_server"] == "mqtt.yes_auth.no_state"
)
device = MQTTPlugin(**device_conf)
mock_instance.loop_start.assert_not_called()
config = {'FAUXMO': {'ip_address': 'auto'}, 'PLUGINS': {'MQTTPlugin': {'DEVICES': [{'mqtt_client_id': 'test_client_1', 'mqtt_po...f_cmd': ['Device/Without/Auth/With/State', 'OFF'], ...}], 'path': '/Users/n8henrie/git/fauxmo-plugins/mqttplugin.py'}}}
device = MQTTPlugin(on_cmd='Device/With/Auth/No/State', on_value='ON', off_cmd='Device/With/Auth/No/State', off_value='OFF', st...cMock name='Client()' spec='Client' id='132493814628256'>, _name='MQTT Device with auth but no state_cmd', _port=12351)
device_conf = {'mqtt_port': 1883, 'mqtt_pw': 'MyPassword', 'mqtt_server': 'mqtt.yes_auth.no_state', 'mqtt_user': 'MyUser', ...}
f = <_io.TextIOWrapper name='tests/test_mqttplugin_config.json' mode='r' encoding='UTF-8'>
mock_client = <MagicMock name='Client' spec='Client' id='132493816592992'>
mock_instance = <NonCallableMagicMock name='Client()' spec='Client' id='132493814628256'>
tests/test_mqttplugin.py:80:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <MagicMock name='Client().loop_start' spec='function' id='132493814938880'>
def assert_not_called(self):
"""assert that the mock was never called.
"""
if self.call_count != 0:
msg = ("Expected '%s' to not have been called. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
raise AssertionError(msg)
E AssertionError: Expected 'loop_start' to not have been called. Called 1 times.
E Calls: [call()].
msg = "Expected 'loop_start' to not have been called. Called 1 times.\nCalls: [call()]."
self = <MagicMock name='Client().loop_start' spec='function' id='132493814938880'>
/usr/lib/python3.10/unittest/mock.py:890: AssertionError
______________________________ test_mqtt_clientid ______________________________
TypeError: missing a required argument: 'callback_api_version'
The above exception was the direct cause of the following exception:
mock_client = <MagicMock name='Client' spec='Client' id='132493812711040'>
@patch("mqttplugin.Client", autospec=True)
def test_mqtt_clientid(mock_client: MagicMock) -> None:
"""Ensure mqtt client id is properly set when configured."""
with open(config_path_str) as f:
config: dict = json.load(f)
device_conf = next(
device
for device in config["PLUGINS"]["MQTTPlugin"]["DEVICES"]
if device["mqtt_client_id"]
)
MQTTPlugin(**device_conf)
mock_client.assert_called_once_with(
client_id=device_conf["mqtt_client_id"]
)
config = {'FAUXMO': {'ip_address': 'auto'}, 'PLUGINS': {'MQTTPlugin': {'DEVICES': [{'mqtt_client_id': 'test_client_1', 'mqtt_po...f_cmd': ['Device/Without/Auth/With/State', 'OFF'], ...}], 'path': '/Users/n8henrie/git/fauxmo-plugins/mqttplugin.py'}}}
device_conf = {'mqtt_client_id': 'test_client_1', 'mqtt_port': 1883, 'mqtt_server': 'test.mosquitto.org', 'name': 'MQTT Study Light 1', ...}
f = <_io.TextIOWrapper name='tests/test_mqttplugin_config.json' mode='r' encoding='UTF-8'>
mock_client = <MagicMock name='Client' spec='Client' id='132493812711040'>
tests/test_mqttplugin.py:113:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/unittest/mock.py:941: in assert_called_once_with
return self.assert_called_with(*args, **kwargs)
args = ()
kwargs = {'client_id': 'test_client_1'}
self = <MagicMock name='Client' spec='Client' id='132493812711040'>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <MagicMock name='Client' spec='Client' id='132493812711040'>, args = ()
kwargs = {'client_id': 'test_client_1'}
expected = TypeError("missing a required argument: 'callback_api_version'")
actual = call('', (<CallbackAPIVersion.VERSION2: 2>, 'test_client_1'), {})
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x78809e81bd90>
cause = TypeError("missing a required argument: 'callback_api_version'")
def assert_called_with(self, /, *args, **kwargs):
"""assert that the last call was made with the specified arguments.
Raises an AssertionError if the args and keyword args passed in are
different to the last call to the mock."""
if self.call_args is None:
expected = self._format_mock_call_signature(args, kwargs)
actual = 'not called.'
error_message = ('expected call not found.\nExpected: %s\nActual: %s'
% (expected, actual))
raise AssertionError(error_message)
def _error_message():
msg = self._format_mock_failure_message(args, kwargs)
return msg
expected = self._call_matcher(_Call((args, kwargs), two=True))
actual = self._call_matcher(self.call_args)
if actual != expected:
cause = expected if isinstance(expected, Exception) else None
raise AssertionError(_error_message()) from cause
E AssertionError: expected call not found.
E Expected: Client(client_id='test_client_1')
E Actual: Client(<CallbackAPIVersion.VERSION2: 2>, client_id='test_client_1')
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x78809e81bd90>
actual = call('', (<CallbackAPIVersion.VERSION2: 2>, 'test_client_1'), {})
args = ()
cause = TypeError("missing a required argument: 'callback_api_version'")
expected = TypeError("missing a required argument: 'callback_api_version'")
kwargs = {'client_id': 'test_clientpy310 installed: black==23.3.0,blinker==1.8.0,brotlipy==0.7.0,cachetools==5.3.3,certifi==2024.2.2,cffi==1.16.0,chardet==5.2.0,charset-normalizer==3.3.2,click==8.1.7,colorama==0.4.6,decorator==5.1.1,distlib==0.3.8,exceptiongroup==1.2.1,fauxmo @ https://github.com/n8henrie/fauxmo/archive/dev.zip,filelock==3.13.4,flake8==3.9.2,flake8-docstrings==1.7.0,flake8-import-order==0.18.2,Flask==2.1.3,httpbin==0.7.0,idna==3.7,iniconfig==2.0.0,itsdangerous==2.2.0,Jinja2==3.1.3,MarkupSafe==2.1.5,mccabe==0.6.1,mypy==1.2.0,mypy-extensions==1.0.0,packaging==24.0,paho-mqtt==2.0.0,pathspec==0.12.1,platformdirs==4.2.1,pluggy==1.5.0,pycodestyle==2.7.0,pycparser==2.22,pydocstyle==6.1.1,pyflakes==2.3.1,pyproject-api==1.6.1,pytest==7.3.0,raven==6.10.0,requests==2.28.2,six==1.16.0,snowballstemmer==2.2.0,tomli==2.0.1,tox==4.4.11,types-requests==2.28.11.17,types-urllib3==1.26.25.14,typing_extensions==4.11.0,urllib3==1.26.18,virtualenv==20.26.0,Werkzeug==2.0.3
py310 run-test-pre: PYTHONHASHSEED='3247594056'
py310 run-test: commands[0] | python -m pytest --showlocals tests/
============================= test session starts ==============================
platform linux -- Python 3.10.12, pytest-7.3.0, pluggy-1.5.0
cachedir: .tox/py310/.pytest_cache
rootdir: /home/jim/fauxmo-plugins
collected 7 items
tests/test_mqttplugin.py ..F.F [ 71%]
tests/test_restapiplugin.py .. [100%]
=================================== FAILURES ===================================
______________________________ test_mqtt_nostate _______________________________
mock_client = <MagicMock name='Client' spec='Client' id='132493816592992'>
@patch("mqttplugin.Client", autospec=True)
def test_mqtt_nostate(mock_client: MagicMock) -> None:
"""If state_cmd is not specified, loop_start is not called."""
mock_instance = mock_client.return_value
with open(config_path_str) as f:
config: dict = json.load(f)
device_conf = next(
device
for device in config["PLUGINS"]["MQTTPlugin"]["DEVICES"]
if device["mqtt_server"] == "mqtt.yes_auth.no_state"
)
device = MQTTPlugin(**device_conf)
mock_instance.loop_start.assert_not_called()
config = {'FAUXMO': {'ip_address': 'auto'}, 'PLUGINS': {'MQTTPlugin': {'DEVICES': [{'mqtt_client_id': 'test_client_1', 'mqtt_po...f_cmd': ['Device/Without/Auth/With/State', 'OFF'], ...}], 'path': '/Users/n8henrie/git/fauxmo-plugins/mqttplugin.py'}}}
device = MQTTPlugin(on_cmd='Device/With/Auth/No/State', on_value='ON', off_cmd='Device/With/Auth/No/State', off_value='OFF', st...cMock name='Client()' spec='Client' id='132493814628256'>, _name='MQTT Device with auth but no state_cmd', _port=12351)
device_conf = {'mqtt_port': 1883, 'mqtt_pw': 'MyPassword', 'mqtt_server': 'mqtt.yes_auth.no_state', 'mqtt_user': 'MyUser', ...}
f = <_io.TextIOWrapper name='tests/test_mqttplugin_config.json' mode='r' encoding='UTF-8'>
mock_client = <MagicMock name='Client' spec='Client' id='132493816592992'>
mock_instance = <NonCallableMagicMock name='Client()' spec='Client' id='132493814628256'>
tests/test_mqttplugin.py:80:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <MagicMock name='Client().loop_start' spec='function' id='132493814938880'>
def assert_not_called(self):
"""assert that the mock was never called.
"""
if self.call_count != 0:
msg = ("Expected '%s' to not have been called. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
raise AssertionError(msg)
E AssertionError: Expected 'loop_start' to not have been called. Called 1 times.
E Calls: [call()].
msg = "Expected 'loop_start' to not have been called. Called 1 times.\nCalls: [call()]."
self = <MagicMock name='Client().loop_start' spec='function' id='132493814938880'>
/usr/lib/python3.10/unittest/mock.py:890: AssertionError
______________________________ test_mqtt_clientid ______________________________
TypeError: missing a required argument: 'callback_api_version'
The above exception was the direct cause of the following exception:
mock_client = <MagicMock name='Client' spec='Client' id='132493812711040'>
@patch("mqttplugin.Client", autospec=True)
def test_mqtt_clientid(mock_client: MagicMock) -> None:
"""Ensure mqtt client id is properly set when configured."""
with open(config_path_str) as f:
config: dict = json.load(f)
device_conf = next(
device
for device in config["PLUGINS"]["MQTTPlugin"]["DEVICES"]
if device["mqtt_client_id"]
)
MQTTPlugin(**device_conf)
mock_client.assert_called_once_with(
client_id=device_conf["mqtt_client_id"]
)
config = {'FAUXMO': {'ip_address': 'auto'}, 'PLUGINS': {'MQTTPlugin': {'DEVICES': [{'mqtt_client_id': 'test_client_1', 'mqtt_po...f_cmd': ['Device/Without/Auth/With/State', 'OFF'], ...}], 'path': '/Users/n8henrie/git/fauxmo-plugins/mqttplugin.py'}}}
device_conf = {'mqtt_client_id': 'test_client_1', 'mqtt_port': 1883, 'mqtt_server': 'test.mosquitto.org', 'name': 'MQTT Study Light 1', ...}
f = <_io.TextIOWrapper name='tests/test_mqttplugin_config.json' mode='r' encoding='UTF-8'>
mock_client = <MagicMock name='Client' spec='Client' id='132493812711040'>
tests/test_mqttplugin.py:113:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/unittest/mock.py:941: in assert_called_once_with
return self.assert_called_with(*args, **kwargs)
args = ()
kwargs = {'client_id': 'test_client_1'}
self = <MagicMock name='Client' spec='Client' id='132493812711040'>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <MagicMock name='Client' spec='Client' id='132493812711040'>, args = ()
kwargs = {'client_id': 'test_client_1'}
expected = TypeError("missing a required argument: 'callback_api_version'")
actual = call('', (<CallbackAPIVersion.VERSION2: 2>, 'test_client_1'), {})
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x78809e81bd90>
cause = TypeError("missing a required argument: 'callback_api_version'")
def assert_called_with(self, /, *args, **kwargs):
"""assert that the last call was made with the specified arguments.
Raises an AssertionError if the args and keyword args passed in are
different to the last call to the mock."""
if self.call_args is None:
expected = self._format_mock_call_signature(args, kwargs)
actual = 'not called.'
error_message = ('expected call not found.\nExpected: %s\nActual: %s'
% (expected, actual))
raise AssertionError(error_message)
def _error_message():
msg = self._format_mock_failure_message(args, kwargs)
return msg
expected = self._call_matcher(_Call((args, kwargs), two=True))
actual = self._call_matcher(self.call_args)
if actual != expected:
cause = expected if isinstance(expected, Exception) else None
raise AssertionError(_error_message()) from cause
E AssertionError: expected call not found.
E Expected: Client(client_id='test_client_1')
E Actual: Client(<CallbackAPIVersion.VERSION2: 2>, client_id='test_client_1')
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x78809e81bd90>
actual = call('', (<CallbackAPIVersion.VERSION2: 2>, 'test_client_1'), {})
args = ()
cause = TypeError("missing a required argument: 'callback_api_version'")
expected = TypeError("missing a required argument: 'callback_api_version'")
kwargs = {'client_id': 'test_client_1'}
self = <MagicMock name='Client' spec='Client' id='132493812711040'>
/usr/lib/python3.10/unittest/mock.py:929: AssertionError
=========================== short test summary info ============================
FAILED tests/test_mqttplugin.py::test_mqtt_nostate - AssertionError: Expected...
FAILED tests/test_mqttplugin.py::test_mqtt_clientid - AssertionError: expecte...
========================= 2 failed, 5 passed in 4.72s ==========================
ERROR: InvocationError for command /home/jim/fauxmo-plugins/.tox/py310/bin/python -m pytest --showlocals tests/ (exited with code 1)
lint installed: black==23.3.0,blinker==1.8.0,brotlipy==0.7.0,cachetools==5.3.3,certifi==2024.2.2,cffi==1.16.0,chardet==5.2.0,charset-normalizer==3.3.2,click==8.1.7,colorama==0.4.6,decorator==5.1.1,distlib==0.3.8,exceptiongroup==1.2.1,fauxmo @ https://github.com/n8henrie/fauxmo/archive/dev.zip,filelock==3.13.4,flake8==3.9.2,flake8-docstrings==1.7.0,flake8-import-order==0.18.2,Flask==2.1.3,httpbin==0.7.0,idna==3.7,iniconfig==2.0.0,itsdangerous==2.2.0,Jinja2==3.1.3,MarkupSafe==2.1.5,mccabe==0.6.1,mypy==1.2.0,mypy-extensions==1.0.0,packaging==24.0,paho-mqtt==2.0.0,pathspec==0.12.1,platformdirs==4.2.1,pluggy==1.5.0,pycodestyle==2.7.0,pycparser==2.22,pydocstyle==6.1.1,pyflakes==2.3.1,pyproject-api==1.6.1,pytest==7.3.0,raven==6.10.0,requests==2.28.2,six==1.16.0,snowballstemmer==2.2.0,tomli==2.0.1,tox==4.4.11,types-requests==2.28.11.17,types-urllib3==1.26.25.14,typing_extensions==4.11.0,urllib3==1.26.18,virtualenv==20.26.0,Werkzeug==2.0.3
lint run-test-pre: PYTHONHASHSEED='3247594056'
lint run-test: commands[0] | black --check --diff .
--- /home/jim/fauxmo-plugins/mqttplugin.py 2024-04-28 18:05:30.411522 +0000
+++ /home/jim/fauxmo-plugins/mqttplugin.py 2024-04-28 18:36:40.525998 +0000
@@ -132,11 +132,13 @@
self.status = "unknown"
self._subscribed = False
self.initial_state = initial_state
self.use_fake_state = use_fake_state
- self.client = Client(CallbackAPIVersion.VERSION2, client_id=mqtt_client_id)
+ self.client = Client(
+ CallbackAPIVersion.VERSION2, client_id=mqtt_client_id
+ )
if mqtt_user or mqtt_pw:
self.client.username_pw_set(mqtt_user, mqtt_pw)
self.client.on_connect = self.on_connect
self.client.on_subscribe = self.on_subscribe
self.client.on_message = self.on_message
@@ -155,17 +157,23 @@
def on_subscribe(
self,
client: Client,
userdata: str,
mid: int,
- reason_code_list, properties,
+ reason_code_list,
+ properties,
) -> None:
"""Set attribute to show that initial subscription is complete."""
self._subscribed = True
def on_connect(
- self, client: Client, userdata: str, flags: dict, reason_code: int, properties
+ self,
+ client: Client,
+ userdata: str,
+ flags: dict,
+ reason_code: int,
+ properties,py310 installed: black==23.3.0,blinker==1.8.0,brotlipy==0.7.0,cachetools==5.3.3,certifi==2024.2.2,cffi==1.16.0,chardet==5.2.0,charset-normalizer==3.3.2,click==8.1.7,colorama==0.4.6,decorator==5.1.1,distlib==0.3.8,exceptiongroup==1.2.1,fauxmo @ https://github.com/n8henrie/fauxmo/archive/dev.zip,filelock==3.13.4,flake8==3.9.2,flake8-docstrings==1.7.0,flake8-import-order==0.18.2,Flask==2.1.3,httpbin==0.7.0,idna==3.7,iniconfig==2.0.0,itsdangerous==2.2.0,Jinja2==3.1.3,MarkupSafe==2.1.5,mccabe==0.6.1,mypy==1.2.0,mypy-extensions==1.0.0,packaging==24.0,paho-mqtt==2.0.0,pathspec==0.12.1,platformdirs==4.2.1,pluggy==1.5.0,pycodestyle==2.7.0,pycparser==2.22,pydocstyle==6.1.1,pyflakes==2.3.1,pyproject-api==1.6.1,pytest==7.3.0,raven==6.10.0,requests==2.28.2,six==1.16.0,snowballstemmer==2.2.0,tomli==2.0.1,tox==4.4.11,types-requests==2.28.11.17,types-urllib3==1.26.25.14,typing_extensions==4.11.0,urllib3==1.26.18,virtualenv==20.26.0,Werkzeug==2.0.3
py310 run-test-pre: PYTHONHASHSEED='3247594056'
py310 run-test: commands[0] | python -m pytest --showlocals tests/
============================= test session starts ==============================
platform linux -- Python 3.10.12, pytest-7.3.0, pluggy-1.5.0
cachedir: .tox/py310/.pytest_cache
rootdir: /home/jim/fauxmo-plugins
collected 7 items
tests/test_mqttplugin.py ..F.F [ 71%]
tests/test_restapiplugin.py .. [100%]
=================================== FAILURES ===================================
______________________________ test_mqtt_nostate _______________________________
mock_client = <MagicMock name='Client' spec='Client' id='132493816592992'>
@patch("mqttplugin.Client", autospec=True)
def test_mqtt_nostate(mock_client: MagicMock) -> None:
"""If state_cmd is not specified, loop_start is not called."""
mock_instance = mock_client.return_value
with open(config_path_str) as f:
config: dict = json.load(f)
device_conf = next(
device
for device in config["PLUGINS"]["MQTTPlugin"]["DEVICES"]
if device["mqtt_server"] == "mqtt.yes_auth.no_state"
)
device = MQTTPlugin(**device_conf)
mock_instance.loop_start.assert_not_called()
config = {'FAUXMO': {'ip_address': 'auto'}, 'PLUGINS': {'MQTTPlugin': {'DEVICES': [{'mqtt_client_id': 'test_client_1', 'mqtt_po...f_cmd': ['Device/Without/Auth/With/State', 'OFF'], ...}], 'path': '/Users/n8henrie/git/fauxmo-plugins/mqttplugin.py'}}}
device = MQTTPlugin(on_cmd='Device/With/Auth/No/State', on_value='ON', off_cmd='Device/With/Auth/No/State', off_value='OFF', st...cMock name='Client()' spec='Client' id='132493814628256'>, _name='MQTT Device with auth but no state_cmd', _port=12351)
device_conf = {'mqtt_port': 1883, 'mqtt_pw': 'MyPassword', 'mqtt_server': 'mqtt.yes_auth.no_state', 'mqtt_user': 'MyUser', ...}
f = <_io.TextIOWrapper name='tests/test_mqttplugin_config.json' mode='r' encoding='UTF-8'>
mock_client = <MagicMock name='Client' spec='Client' id='132493816592992'>
mock_instance = <NonCallableMagicMock name='Client()' spec='Client' id='132493814628256'>
tests/test_mqttplugin.py:80:
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <MagicMock name='Client().loop_start' spec='function' id='132493814938880'>
def assert_not_called(self):
"""assert that the mock was never called.
"""
if self.call_count != 0:
msg = ("Expected '%s' to not have been called. Called %s times.%s"
% (self._mock_name or 'mock',
self.call_count,
self._calls_repr()))
raise AssertionError(msg)
E AssertionError: Expected 'loop_start' to not have been called. Called 1 times.
E Calls: [call()].
msg = "Expected 'loop_start' to not have been called. Called 1 times.\nCalls: [call()]."
self = <MagicMock name='Client().loop_start' spec='function' id='132493814938880'>
/usr/lib/python3.10/unittest/mock.py:890: AssertionError
______________________________ test_mqtt_clientid ______________________________
TypeError: missing a required argument: 'callback_api_version'
The above exception was the direct cause of the following exception:
mock_client = <MagicMock name='Client' spec='Client' id='132493812711040'>
@patch("mqttplugin.Client", autospec=True)
def test_mqtt_clientid(mock_client: MagicMock) -> None:
"""Ensure mqtt client id is properly set when configured."""
with open(config_path_str) as f:
config: dict = json.load(f)
device_conf = next(
device
for device in config["PLUGINS"]["MQTTPlugin"]["DEVICES"]
if device["mqtt_client_id"]
)
MQTTPlugin(**device_conf)
mock_client.assert_called_once_with(
client_id=device_conf["mqtt_client_id"]
)
config = {'FAUXMO': {'ip_address': 'auto'}, 'PLUGINS': {'MQTTPlugin': {'DEVICES': [{'mqtt_client_id': 'test_client_1', 'mqtt_po...f_cmd': ['Device/Without/Auth/With/State', 'OFF'], ...}], 'path': '/Users/n8henrie/git/fauxmo-plugins/mqttplugin.py'}}}
device_conf = {'mqtt_client_id': 'test_client_1', 'mqtt_port': 1883, 'mqtt_server': 'test.mosquitto.org', 'name': 'MQTT Study Light 1', ...}
f = <_io.TextIOWrapper name='tests/test_mqttplugin_config.json' mode='r' encoding='UTF-8'>
mock_client = <MagicMock name='Client' spec='Client' id='132493812711040'>
tests/test_mqttplugin.py:113:
```
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
/usr/lib/python3.10/unittest/mock.py:941: in assert_called_once_with
return self.assert_called_with(*args, **kwargs)
args = ()
kwargs = {'client_id': 'test_client_1'}
self = <MagicMock name='Client' spec='Client' id='132493812711040'>
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
self = <MagicMock name='Client' spec='Client' id='132493812711040'>, args = ()
kwargs = {'client_id': 'test_client_1'}
expected = TypeError("missing a required argument: 'callback_api_version'")
actual = call('', (<CallbackAPIVersion.VERSION2: 2>, 'test_client_1'), {})
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x78809e81bd90>
cause = TypeError("missing a required argument: 'callback_api_version'")
def assert_called_with(self, /, *args, **kwargs):
"""assert that the last call was made with the specified arguments.
Raises an AssertionError if the args and keyword args passed in are
different to the last call to the mock."""
if self.call_args is None:
expected = self._format_mock_call_signature(args, kwargs)
actual = 'not called.'
error_message = ('expected call not found.\nExpected: %s\nActual: %s'
% (expected, actual))
raise AssertionError(error_message)
def _error_message():
msg = self._format_mock_failure_message(args, kwargs)
return msg
expected = self._call_matcher(_Call((args, kwargs), two=True))
actual = self._call_matcher(self.call_args)
if actual != expected:
cause = expected if isinstance(expected, Exception) else None
raise AssertionError(_error_message()) from cause
E AssertionError: expected call not found.
E Expected: Client(client_id='test_client_1')
E Actual: Client(<CallbackAPIVersion.VERSION2: 2>, client_id='test_client_1')
_error_message = <function NonCallableMock.assert_called_with.<locals>._error_message at 0x78809e81bd90>
actual = call('', (<CallbackAPIVersion.VERSION2: 2>, 'test_client_1'), {})
args = ()
cause = TypeError("missing a required argument: 'callback_api_version'")
expected = TypeError("missing a required argument: 'callback_api_version'")
kwargs = {'client_id': 'test_client_1'}
self = <MagicMock name='Client' spec='Client' id='132493812711040'>
/usr/lib/python3.10/unittest/mock.py:929: AssertionError
=========================== short test summary info ============================
FAILED tests/test_mqttplugin.py::test_mqtt_nostate - AssertionError: Expected...
FAILED tests/test_mqttplugin.py::test_mqtt_clientid - AssertionError: expecte...
========================= 2 failed, 5 passed in 4.72s ==========================
ERROR: InvocationError for command /home/jim/fauxmo-plugins/.tox/py310/bin/python -m pytest --showlocals tests/ (exited with code 1)
lint installed: black==23.3.0,blinker==1.8.0,brotlipy==0.7.0,cachetools==5.3.3,certifi==2024.2.2,cffi==1.16.0,chardet==5.2.0,charset-normalizer==3.3.2,click==8.1.7,colorama==0.4.6,decorator==5.1.1,distlib==0.3.8,exceptiongroup==1.2.1,fauxmo @ https://github.com/n8henrie/fauxmo/archive/dev.zip,filelock==3.13.4,flake8==3.9.2,flake8-docstrings==1.7.0,flake8-import-order==0.18.2,Flask==2.1.3,httpbin==0.7.0,idna==3.7,iniconfig==2.0.0,itsdangerous==2.2.0,Jinja2==3.1.3,MarkupSafe==2.1.5,mccabe==0.6.1,mypy==1.2.0,mypy-extensions==1.0.0,packaging==24.0,paho-mqtt==2.0.0,pathspec==0.12.1,platformdirs==4.2.1,pluggy==1.5.0,pycodestyle==2.7.0,pycparser==2.22,pydocstyle==6.1.1,pyflakes==2.3.1,pyproject-api==1.6.1,pytest==7.3.0,raven==6.10.0,requests==2.28.2,six==1.16.0,snowballstemmer==2.2.0,tomli==2.0.1,tox==4.4.11,types-requests==2.28.11.17,types-urllib3==1.26.25.14,typing_extensions==4.11.0,urllib3==1.26.18,virtualenv==20.26.0,Werkzeug==2.0.3
lint run-test-pre: PYTHONHASHSEED='3247594056'
lint run-test: commands[0] | black --check --diff .
--- /home/jim/fauxmo-plugins/mqttplugin.py 2024-04-28 18:05:30.411522 +0000
+++ /home/jim/fauxmo-plugins/mqttplugin.py 2024-04-28 18:36:40.525998 +0000
@@ -132,11 +132,13 @@
self.status = "unknown"
self._subscribed = False
self.initial_state = initial_state
self.use_fake_state = use_fake_state
- self.client = Client(CallbackAPIVersion.VERSION2, client_id=mqtt_client_id)
+ self.client = Client(
+ CallbackAPIVersion.VERSION2, client_id=mqtt_client_id
+ )
if mqtt_user or mqtt_pw:
self.client.username_pw_set(mqtt_user, mqtt_pw)
self.client.on_connect = self.on_connect
self.client.on_subscribe = self.on_subscribe
self.client.on_message = self.on_message
@@ -155,17 +157,23 @@
def on_subscribe(
self,
client: Client,
userdata: str,
mid: int,
- reason_code_list, properties,
+ reason_code_list,
+ properties,
) -> None:
"""Set attribute to show that initial subscription is complete."""
self._subscribed = True
def on_connect(
- self, client: Client, userdata: str, flags: dict, reason_code: int, properties
+ self,
+ client: Client,
+ userdata: str,
+ flags: dict,
+ reason_code: int,
+ properties,
) -> None:
"""Subscribe to state command on connect (or reconnect)."""
if self.state_cmd is not None:
```
self.client.subscribe(self.state_cmd)
@@ -225,6 +233,6 @@
return state
if self.use_fake_state is True:
return super().get_state()
- return "unknown"
\ No newline at end of file
+ return "unknown"
would reformat /home/jim/fauxmo-plugins/mqttplugin.py
Oh no! 💥 💔 💥
1 file would be reformatted, 6 files would be left unchanged.
ERROR: InvocationError for command /home/jim/fauxmo-plugins/.tox/lint/bin/black --check --diff . (exited with code 1)
…___________________________________ summary ____________________________________
ERROR: py310: commands failed
ERROR: lint: commands failed
) -> None:
"""Subscribe to state command on connect (or reconnect)."""
if self.state_cmd is not None:
self.client.subscribe(self.state_cmd)
@@ -225,6 +233,6 @@
return state
if self.use_fake_state is True:
return super().get_state()
- return "unknown"
\ No newline at end of file
+ return "unknown"
would reformat /home/jim/fauxmo-plugins/mqttplugin.py
Oh no! 💥 💔 💥
1 file would be reformatted, 6 files would be left unchanged.
ERROR: InvocationError for command /home/jim/fauxmo-plugins/.tox/lint/bin/black --check --diff . (exited with code 1)
___________________________________ summary ____________________________________
ERROR: py310: commands failed
ERROR: lint: commands failed
_1'}
self = <MagicMock name='Client' spec='Client' id='132493812711040'>
/usr/lib/python3.10/unittest/mock.py:929: AssertionError
=========================== short test summary info ============================
FAILED tests/test_mqttplugin.py::test_mqtt_nostate - AssertionError: Expected...
FAILED tests/test_mqttplugin.py::test_mqtt_clientid - AssertionError: expecte...
========================= 2 failed, 5 passed in 4.72s ==========================
ERROR: InvocationError for command /home/jim/fauxmo-plugins/.tox/py310/bin/python -m pytest --showlocals tests/ (exited with code 1)
lint installed: black==23.3.0,blinker==1.8.0,brotlipy==0.7.0,cachetools==5.3.3,certifi==2024.2.2,cffi==1.16.0,chardet==5.2.0,charset-normalizer==3.3.2,click==8.1.7,colorama==0.4.6,decorator==5.1.1,distlib==0.3.8,exceptiongroup==1.2.1,fauxmo @ https://github.com/n8henrie/fauxmo/archive/dev.zip,filelock==3.13.4,flake8==3.9.2,flake8-docstrings==1.7.0,flake8-import-order==0.18.2,Flask==2.1.3,httpbin==0.7.0,idna==3.7,iniconfig==2.0.0,itsdangerous==2.2.0,Jinja2==3.1.3,MarkupSafe==2.1.5,mccabe==0.6.1,mypy==1.2.0,mypy-extensions==1.0.0,packaging==24.0,paho-mqtt==2.0.0,pathspec==0.12.1,platformdirs==4.2.1,pluggy==1.5.0,pycodestyle==2.7.0,pycparser==2.22,pydocstyle==6.1.1,pyflakes==2.3.1,pyproject-api==1.6.1,pytest==7.3.0,raven==6.10.0,requests==2.28.2,six==1.16.0,snowballstemmer==2.2.0,tomli==2.0.1,tox==4.4.11,types-requests==2.28.11.17,types-urllib3==1.26.25.14,typing_extensions==4.11.0,urllib3==1.26.18,virtualenv==20.26.0,Werkzeug==2.0.3
lint run-test-pre: PYTHONHASHSEED='3247594056'
lint run-test: commands[0] | black --check --diff .
--- /home/jim/fauxmo-plugins/mqttplugin.py 2024-04-28 18:05:30.411522 +0000
+++ /home/jim/fauxmo-plugins/mqttplugin.py 2024-04-28 18:36:40.525998 +0000
@@ -132,11 +132,13 @@
self.status = "unknown"
self._subscribed = False
self.initial_state = initial_state
self.use_fake_state = use_fake_state
- self.client = Client(CallbackAPIVersion.VERSION2, client_id=mqtt_client_id)
+ self.client = Client(
+ CallbackAPIVersion.VERSION2, client_id=mqtt_client_id
+ )
if mqtt_user or mqtt_pw:
self.client.username_pw_set(mqtt_user, mqtt_pw)
self.client.on_connect = self.on_connect
self.client.on_subscribe = self.on_subscribe
self.client.on_message = self.on_message
@@ -155,17 +157,23 @@
def on_subscribe(
self,
client: Client,
userdata: str,
mid: int,
- reason_code_list, properties,
+ reason_code_list,
+ properties,
) -> None:
"""Set attribute to show that initial subscription is complete."""
self._subscribed = True
def on_connect(
- self, client: Client, userdata: str, flags: dict, reason_code: int, properties
+ self,
+ client: Client,
+ userdata: str,
+ flags: dict,
+ reason_code: int,
+ properties,
) -> None:
"""Subscribe to state command on connect (or reconnect)."""
if self.state_cmd is not None:
self.client.subscribe(self.state_cmd)
@@ -225,6 +233,6 @@
return state
if self.use_fake_state is True:
return super().get_state()
- return "unknown"
\ No newline at end of file
+ return "unknown"
would reformat /home/jim/fauxmo-plugins/mqttplugin.py
Oh no! 💥 💔 💥
1 file would be reformatted, 6 files would be left unchanged.
ERROR: InvocationError for command /home/jim/fauxmo-plugins/.tox/lint/bin/black --check --diff . (exited with code 1)
___________________________________ summary ____________________________________
ERROR: py310: commands failed
ERROR: lint: commands failed
```
|
Yes, that's the same error: |
Not familiar with how tox works. Is it looking for the actual "callback_api_version" instead of "CallbackAPIVersion" ? |
tox just sets up a clean temporary environment for running the test suite, which is implemented in pytest. You can use pytest directly for local testing. You'll need to look into and modify the mqtt test file in the tests directory. |
Fixed in 141220f |
Not sure why they did this but paho-mqtt 2.0.0 breaks ALL existing implementations. more info here
https://github.com/eclipse/paho.mqtt.python/releases/tag/v2.0.0
Description
During a reinstall of Raspbian and install of my code
installing paho-mqtt brought in version 2.0.0 which broke a few things.
On raspbian:
pip install paho-mqtt
also on an existing ubuntu system:
pip install paho-mqtt --upgrade
both are now 2.0.0
Status
I'm using this new version
Related Issues
My other use of paho-mqtt have been upgraded to VERSION2.
I did not want to do this to mqttplugin at this time.
To keep this change simple, three lines if changed code
Todos
VERSION2 in the future
Steps to Test or Reproduce
install/upgrade paho-mqtt version 2.0.0
run your stuff
Other notes