taverntesting/tavern

Feature Request: Support formatting in MQTT response topic

RFRIEDM-Trimble opened this issue · 3 comments

I am able to use variables to paramaterize the URL when doing HTTP tests. Additionally, when publishing via MQTT, the publish topic can be parameterized. However, the response topic does not allow parameters. All the examples and references to topics in MQTT land in tavern appear to hard code the topics.

  • In a production system, a device may make use of wildcards in the topic. A good example is publishing a config value from the cloud to an IoT device, where the topic includes some unique identifier
  • Another example is the request/reply model. In MQTTv3, a design pattern used has the ACK from the device including a UUID (correlation ID) in the topic name that is different for each MQTT request.

My goal is shown below in the minimal example.Topics may need to change from saved values, or perhaps from other areas such as conftest.py.

# conftest.py
import pytest

PING_THING = "foo"
PONG_THING = "bar"

@pytest.fixture
def get_ping_topic():
    return PING_THING
    
@pytest.fixture
def get_pong_topic():
    return PONG_THING
# test_mqtt.tavern.yaml
---
test_name: Test mqtt message response
paho-mqtt:
  client:
    transport: websockets
    client_id: tavern-tester
  connect:
    host: localhost
    port: 9001
    timeout: 3

stages:
  - name: step 1 - ping/pong
    mqtt_publish:
      # Use value from conftest.py
      topic: /device/123/{get_ping_topic}
      payload: ping
    mqtt_response:
      # Use value from conftest.py
      topic: /device/123/{get_ping_topic}
      save:
        json:
          first_val: "thing.device_id[0]"
      timeout: 5
  - name: step 2 - using saved data in topic
    mqtt_publish:
      # Use saved value from an earlier stage
      topic: /device/123/ping_{first_val}
      payload: ping
    mqtt_response:
      # Use saved value from an earlier stage
      topic: /device/123/pong_{first_val}
      timeout: 5

I am willing to discuss the work needed and doing the contribution. When I get a chance, I will create a branch with an integration test that this is failing on. I have not found any workaround yet.

This should already be formatted in mqtt/tavernhook.py so this not working is probably a bug

This should already be formatted in mqtt/tavernhook.py so this not working is probably a bug

Ok good to know I will add tests to see if I can isolate the failure. Cheers!

I've added a test for this in #808, I'm assuming that the reason your original code didn't work is because you're missing the 'usefixtures' (or the 'autouse=True' flag to the fixture)