mqtt-tools / mqttwarn

A highly configurable MQTT message router, where the routing targets are notification plugins, primarily written in Python.
https://mqttwarn.readthedocs.io/
Eclipse Public License 2.0
958 stars 184 forks source link

Developing service plugins: Software tests and interactive invocation #526

Open amotl opened 3 years ago

amotl commented 3 years ago

Hi again,

@psyciknz mentioned at https://github.com/jpmens/mqttwarn/issues/516#issuecomment-863526629:

But what I might look at, and is probable a better direction for the project, is to create, in this case, a test_pushover.py test class for testing/debugging.

This can go into two directions. I hope that both variants will be helpful to you.

Software tests

8596c14a (from the "amo/service-tests" branch) adds some software tests for the pushover service plugin, with every real network interaction completely mocked. The corresponding tests can be invoked using

# Populate sandbox.
git clone https://github.com/jpmens/mqttwarn
git checkout amo/service-tests
python3 -m venv .venv
source .venv/bin/activate

# Install package for development and testing.
pip install --editable=.[test]

# Run all software tests for "pushover" service plugin.
pytest -vvv -k test_pushover

Interactive use

Since mqttwarn 0.10.0, it is possible to directly invoke notification plugins from the command line, as implemented by af3288bc. For the pushover notification plugin, that might look like

mqttwarn \
    --plugin=pushover \
    --data='{"title": "About", "message": "Hello world", "addrs": ["userkey", "token"], "priority": 6}'

For this to work, you will currently still have to configure a [config:pushover] section within your mqttwarn.ini. However, you can leave it completely empty, as the relevant parameters will be given on the command line. #527 will improve this situation once more - with that patch, service plugins can be invoked without needing any mqttwarn.ini configuration file at all.

With kind regards, Andreas.

psyciknz commented 3 years ago

Oh, a test written by someone that knows who to write a test, rather than my hack!!

Ok, um just need to see if I can pull in from that branch to mine, to confirm the change I made to the pushover.py for image decoding....and then I'll add a test for it.

So should I merge that branch (amo/service-tests) into my fix-pushover-images branch? I'm unclear if that's intended to be merged to master, or if it will stay standalone.

amotl commented 3 years ago

To confirm the change I made to the pushover.py for image decoding.

Please note that af3288b also includes a fix in that area.

So should I merge that branch (amo/service-tests) into my fix-pushover-images branch? I'm unclear if that's intended to be merged to master, or if it will stay standalone.

Hm, I am not sure, but probably yes, if you want to get that functionality. The patch will definitively be integrated into the main branch, I just don't know when I was thinking about to have it "ready". Maybe it is time right now, all further improvements can come later. So, #522 now is ready for integration.

With kind regards, Andreas.

amotl commented 3 years ago

Hi @psyciknz,

all outstanding patches have been integrated into the main branch.

Happy hacking and with kind regards, Andreas.

amotl commented 3 years ago

Hi again,

as outlined at [1], for invoking service plugins like mqttwarn_contrib.services.cloudflare_zone, which consume top-level settings from specific configuration sections, the machinery for invoking plugins in standalone mode is not sufficient yet.

Invoking that command without a configuration file option, i.e. --config=standalone.ini,

mqttwarn \
    --plugin=mqttwarn_contrib.services.cloudflare_zone \
    --data='{"addrs": ["0815", "www.example.org", ""], "message": "192.168.0.1"}'

will croak with

Traceback (most recent call last):
  File "/Users/amo/dev/daq-tools/sources/mqttwarn-contrib/.venv/bin/mqttwarn", line 33, in <module>
    sys.exit(load_entry_point('mqttwarn==0.25.0', 'console_scripts', 'mqttwarn')())
  File "/Users/amo/dev/daq-tools/sources/mqttwarn-contrib/.venv/lib/python3.9/site-packages/mqttwarn/commands.py", line 71, in run
    launch_plugin_standalone(plugin, data, configfile=options.get("--config"))
  File "/Users/amo/dev/daq-tools/sources/mqttwarn-contrib/.venv/lib/python3.9/site-packages/mqttwarn/commands.py", line 100, in launch_plugin_standalone
    run_plugin(config=config, name=plugin, data=data)
  File "/Users/amo/dev/daq-tools/sources/mqttwarn-contrib/.venv/lib/python3.9/site-packages/mqttwarn/core.py", line 752, in run_plugin
    response = module.plugin(srv, item)
  File "/Users/amo/dev/daq-tools/sources/mqttwarn-contrib/mqttwarn_contrib/services/cloudflare_zone.py", line 21, in plugin
    email       = item.config['auth-email']
KeyError: 'auth-email'

Currently, there is no way to make the machinery obtain those top-level settings from the command line.

With kind regards, Andreas.

[1] https://github.com/daq-tools/mqttwarn-contrib/blob/ce7b3ba69cafe8eacd1d06f12cd7a31baac0b968/HANDBOOK.md#running-interactively

amotl commented 3 years ago

Hi,

the situation outlined above has been improved with #534, which is part of mqttwarn 0.26.0 already.

Now, an additional set of --config arguments can be passed to mqttwarn.

# Launch "cloudflare_zone" service plugin from "mqttwarn-contrib"
pip install mqttwarn-contrib
mqttwarn \
    --plugin=mqttwarn_contrib.services.cloudflare_zone \
    --config='{"auth-email": "foo", "auth-key": "bar"}' \
    --options='{"addrs": ["0815", "www.example.org", ""], "message": "192.168.0.1"}'

With kind regards, Andreas.

amotl commented 2 years ago

Dear @psyciknz,

a074a49af315 was needed to make the example outlined above actually work. Do you think this satisfies your needs?

With kind regards, Andreas.

psyciknz commented 2 years ago

I think all is fine. It was a while ago all this was discussed. I've certainly not run up against any problems recently