Reputation: 1
I want to set MQTT connect as a Jmeter property and use this connection in other thread which will post messages concurrently to MQTT broker. What I want to implement is
What I have done so far is using MQTT connect, Publish samplers and MQTT disconnect in same thread group. But when running multiple threads messages are getting failed to publish for other than thread-1.
Please let me know if there is any way to implement this.
Upvotes: 0
Views: 874
Reputation: 1
Below is the solution we came to with Java-developer, who dived into the plugin source code.
Test plan structure:
Test plan
- setUp Thread Group
- - MQTT Connect Sampler
- - JSR223 Sampler Set Props
- Thread Group Pub
- - Once Only Controller
- - - JSR223 Sampler Get Props
- - MQTT Pub Sampler
- tearDown Thread Group
- - JSR223 Sampler Get Props
- - MQTT DisConnect Sampler
JSR223 Sampler Set Props Groovy code:
props.put('mqtt_connection', vars.getObject('conn'));
props.put('mqtt_client_id', vars.getObject('clientId'));
JSR223 Sampler Get Props Groovy code:
vars.putObject('conn', props.get('mqtt_connection'));
vars.putObject('clientId', props.get('mqtt_client_id'));
You can save the following xml content as a jmx-file and open in JMeter:
<?xml version="1.0" encoding="UTF-8"?>
<jmeterTestPlan version="1.2" properties="5.0" jmeter="5.6.3">
<hashTree>
<TestPlan guiclass="TestPlanGui" testclass="TestPlan" testname="Test Plan">
<boolProp name="TestPlan.serialize_threadgroups">true</boolProp>
<boolProp name="TestPlan.tearDown_on_shutdown">true</boolProp>
<elementProp name="TestPlan.user_defined_variables" elementType="Arguments" guiclass="ArgumentsPanel" testclass="Arguments" testname="User Defined Variables">
<collectionProp name="Arguments.arguments"/>
</elementProp>
</TestPlan>
<hashTree>
<SetupThreadGroup guiclass="SetupThreadGroupGui" testclass="SetupThreadGroup" testname="setUp Thread Group">
<intProp name="ThreadGroup.num_threads">1</intProp>
<intProp name="ThreadGroup.ramp_time">1</intProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
<stringProp name="ThreadGroup.on_sample_error">stoptest</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
<stringProp name="LoopController.loops">1</stringProp>
<boolProp name="LoopController.continue_forever">false</boolProp>
</elementProp>
</SetupThreadGroup>
<hashTree>
<net.xmeter.samplers.ConnectSampler guiclass="net.xmeter.gui.ConnectSamplerUI" testclass="net.xmeter.samplers.ConnectSampler" testname="MQTT Connect Sampler">
<stringProp name="mqtt.server">${mqtt_ip}</stringProp>
<stringProp name="mqtt.port">${mqtt_port}</stringProp>
<stringProp name="mqtt.version">3.1</stringProp>
<stringProp name="mqtt.conn_timeout">10</stringProp>
<stringProp name="mqtt.protocol">TCP</stringProp>
<stringProp name="mqtt.ws_path"></stringProp>
<boolProp name="mqtt.dual_ssl_authentication">false</boolProp>
<stringProp name="mqtt.clientcert_file_path"></stringProp>
<stringProp name="mqtt.clientcert_password"></stringProp>
<stringProp name="mqtt.user_name">${mqtt_user}</stringProp>
<stringProp name="mqtt.password">${mqtt_password}</stringProp>
<stringProp name="mqtt.client_id_prefix">jmeter_</stringProp>
<boolProp name="mqtt.client_id_suffix">true</boolProp>
<stringProp name="mqtt.conn_keep_alive">300</stringProp>
<stringProp name="mqtt.conn_attampt_max">0</stringProp>
<stringProp name="mqtt.reconn_attampt_max">0</stringProp>
<stringProp name="mqtt.conn_clean_session">true</stringProp>
</net.xmeter.samplers.ConnectSampler>
<hashTree/>
<JSR223Sampler guiclass="TestBeanGUI" testclass="JSR223Sampler" testname="JSR223 Sampler Set Props">
<stringProp name="cacheKey">true</stringProp>
<stringProp name="filename"></stringProp>
<stringProp name="parameters"></stringProp>
<stringProp name="script">props.put('mqtt_connection', vars.getObject('conn'));
props.put('mqtt_client_id', vars.getObject('clientId'));</stringProp>
<stringProp name="scriptLanguage">groovy</stringProp>
<stringProp name="TestPlan.comments">Set "global" properties accessible by all threads with broker connection and and client id</stringProp>
</JSR223Sampler>
<hashTree/>
</hashTree>
<ThreadGroup guiclass="ThreadGroupGui" testclass="ThreadGroup" testname="Thread Group Pub">
<stringProp name="TestPlan.comments">Publish events</stringProp>
<stringProp name="ThreadGroup.num_threads">${threads}</stringProp>
<intProp name="ThreadGroup.ramp_time">1</intProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">false</boolProp>
<stringProp name="ThreadGroup.on_sample_error">continue</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
<intProp name="LoopController.loops">-1</intProp>
<boolProp name="LoopController.continue_forever">false</boolProp>
</elementProp>
</ThreadGroup>
<hashTree>
<OnceOnlyController guiclass="OnceOnlyControllerGui" testclass="OnceOnlyController" testname="Once Only Controller">
<stringProp name="TestPlan.comments">Things to do only in the first loop of each thread</stringProp>
</OnceOnlyController>
<hashTree>
<JSR223Sampler guiclass="TestBeanGUI" testclass="JSR223Sampler" testname="JSR223 Sampler Get Props">
<stringProp name="cacheKey">true</stringProp>
<stringProp name="filename"></stringProp>
<stringProp name="parameters"></stringProp>
<stringProp name="script">vars.putObject('conn', props.get('mqtt_connection'));
vars.putObject('clientId', props.get('mqtt_client_id'));</stringProp>
<stringProp name="scriptLanguage">groovy</stringProp>
<stringProp name="TestPlan.comments">Get properties with broker connection and client id</stringProp>
</JSR223Sampler>
<hashTree/>
</hashTree>
<net.xmeter.samplers.PubSampler guiclass="net.xmeter.gui.PubSamplerUI" testclass="net.xmeter.samplers.PubSampler" testname="MQTT Pub Sampler">
<stringProp name="mqtt.topic_name">${TOPIC}</stringProp>
<stringProp name="mqtt.qos_level">1</stringProp>
<boolProp name="mqtt.add_timestamp">false</boolProp>
<stringProp name="mqtt.message_type">String</stringProp>
<stringProp name="mqtt.message_type_fixed_length">1024</stringProp>
<stringProp name="mqtt.message_to_sent">${MESSAGE}</stringProp>
<boolProp name="mqtt.retained_message">false</boolProp>
<stringProp name="TestPlan.comments">Send events</stringProp>
</net.xmeter.samplers.PubSampler>
<hashTree/>
</hashTree>
<PostThreadGroup guiclass="PostThreadGroupGui" testclass="PostThreadGroup" testname="tearDown Thread Group">
<intProp name="ThreadGroup.num_threads">1</intProp>
<intProp name="ThreadGroup.ramp_time">1</intProp>
<boolProp name="ThreadGroup.same_user_on_next_iteration">true</boolProp>
<stringProp name="ThreadGroup.on_sample_error">stoptest</stringProp>
<elementProp name="ThreadGroup.main_controller" elementType="LoopController" guiclass="LoopControlPanel" testclass="LoopController" testname="Loop Controller">
<stringProp name="LoopController.loops">1</stringProp>
<boolProp name="LoopController.continue_forever">false</boolProp>
</elementProp>
</PostThreadGroup>
<hashTree>
<JSR223Sampler guiclass="TestBeanGUI" testclass="JSR223Sampler" testname="JSR223 Sampler Get Props">
<stringProp name="cacheKey">true</stringProp>
<stringProp name="filename"></stringProp>
<stringProp name="parameters"></stringProp>
<stringProp name="script">vars.putObject('conn', props.get('mqtt_connection'));
vars.putObject('clientId', props.get('mqtt_client_id'));</stringProp>
<stringProp name="scriptLanguage">groovy</stringProp>
<stringProp name="TestPlan.comments">Get properties with broker connection and client id</stringProp>
</JSR223Sampler>
<hashTree/>
<net.xmeter.samplers.DisConnectSampler guiclass="net.xmeter.gui.DisConnectSamplerUI" testclass="net.xmeter.samplers.DisConnectSampler" testname="MQTT DisConnect Sampler">
<stringProp name="TestPlan.comments">Close mqtt connection</stringProp>
</net.xmeter.samplers.DisConnectSampler>
<hashTree/>
</hashTree>
</hashTree>
</hashTree>
</jmeterTestPlan>
Upvotes: 0
Reputation: 168147
I don't think that:
is a good idea because well-behaved JMeter test must represent real life usage of your application and each JMeter thread (virtual user) must represent an MQTT-enabled device which establishes its own connection to the broker. If the "messages are getting failed to publish" it indicates problem either with your test setup (parameterization, correlation, whatever) or with your MQTT broker so first of all I would check:
See Testing the MQTT Messaging Broker for IoT - A Guide article for more details.
If you're still looking for a way of passing the MQTT connection between thread groups you can do this using JSR223 Test Elements and the following code:
To save the connection into a property:
props.put('connection', vars.getObject('conn'))
To get the connection object from the property:
vars.putObject('conn', props.get('connection'))
Upvotes: 2