Skip to content

Commit

Permalink
Fix/mqtt payload match (#295)
Browse files Browse the repository at this point in the history
* Fix matching anything token in non-json MQTT payload

* Add extra test for anything token

* Update docs
  • Loading branch information
michaelboulton committed Mar 17, 2019
1 parent 32a1c53 commit d7568cf
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 3 deletions.
23 changes: 22 additions & 1 deletion docs/source/mqtt.md
Original file line number Diff line number Diff line change
Expand Up @@ -114,6 +114,7 @@ The full list of keys for this block:
serialize into JSON.
- `qos`: QoS level for publishing. Defaults to 0 in paho-mqtt.


### Options for receiving MQTT messages

The `mqtt_response` key gives a topic and payload which should be received by
Expand All @@ -126,6 +127,14 @@ that timeout period, it is considered a failure.
If other messages on the same topic but with a different payload arrive in the
meantime, they are ignored and a warning will be logged.

```yaml
mqtt_response:
topic: /device/123/ping
json:
thing_1: abc
thing_2: 123
```

The keys which can be used:

- `topic`: The MQTT topic to subcribe to
Expand All @@ -136,6 +145,18 @@ The keys which can be used:
- `qos`: The level of QoS to subscribe to the topic with. This defaults to 1,
and it is unlikely that you will need to ever set this value manually.

While the `json` key will follow the same matching rules as
HTTP JSON responses, The special 'anything' token can be used with the
`payload` key just to check that there was _some_ response on a topic:

```yaml
mqtt_response:
topic: /device/123/ping
payload: !anything
```

Other type tokens such as `!anyint` will _not_ work.

## Mixing MQTT tests and HTTP tests

If the architecture of your program combines MQTT and HTTP, Tavern can
Expand All @@ -149,7 +170,7 @@ for it to say that a light has been turned on. When it receives this message, it
updates a database so that each future request to get the state of the device
will return the updated state.

```
```yaml
---

test_name: Make sure posting publishes mqtt message
Expand Down
39 changes: 39 additions & 0 deletions example/mqtt/test_mqtt.tavern.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -268,3 +268,42 @@ stages:
lights: !anyint
timeout: 3
qos: 1

---

test_name: Test can handle anything token

includes:
- !include common.yaml

paho-mqtt: *mqtt_spec

stages:
- name: Test checking for lights status with anyint
mqtt_publish:
topic: /device/123/status
mqtt_response:
topic: /device/123/status/response
json:
lights: !anything
timeout: 3
qos: 1

---

test_name: Test type token on non-json payload

includes:
- !include common.yaml

paho-mqtt: *mqtt_spec

stages:
- name: Test checking for lights status with anyint
mqtt_publish:
topic: /device/123/status
mqtt_response:
topic: /device/123/status/response
payload: !anything
timeout: 3
qos: 1
4 changes: 4 additions & 0 deletions tavern/_plugins/mqtt/response.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from tavern.util import exceptions
from tavern.response.base import BaseResponse
from tavern.util.dict_util import check_keys_match_recursive
from tavern.util.loader import ANYTHING

try:
LoadException = json.decoder.JSONDecodeError
Expand Down Expand Up @@ -109,6 +110,9 @@ def _await_response(self):
logger.warning(
"Message had payload '%s' but we expected no payload"
)
elif payload is ANYTHING:
logger.info("Got message on %s matching !anything token", topic)
break
elif msg.payload != payload:
if json_payload:
try:
Expand Down
4 changes: 2 additions & 2 deletions tox-integration.ini
Original file line number Diff line number Diff line change
Expand Up @@ -42,8 +42,8 @@ commands =

mqtt: tavern-ci --stdout test_mqtt.tavern.yaml
mqtt: python -c "from tavern.core import run; exit(run('test_mqtt.tavern.yaml', pytest_args=[]))"
mqtt_failures: tavern-ci --stdout test_mqtt_failures.tavern.yaml
mqtt_failures: python -c "from tavern.core import run; exit(run('test_mqtt_failures.tavern.yaml', pytest_args=[]))"
mqtt: tavern-ci --stdout test_mqtt_failures.tavern.yaml
mqtt: python -c "from tavern.core import run; exit(run('test_mqtt_failures.tavern.yaml', pytest_args=[]))"

generic: tavern-ci --stdout test_fixtures.tavern.yaml
generic: python -c "from tavern.core import run; exit(run('test_fixtures.tavern.yaml', pytest_args=[]))"
Expand Down

0 comments on commit d7568cf

Please sign in to comment.