MQTT gatling multiple connections to different devices

Hello,

According to the documentation, I can understand the device information are provided at the protocol level, so the load generated will be only for the same connection. Would it be possible to create load for multiple connections, i.e., something like mqtt(“Connecting”).connect.clientId(“xx”).credentials(“xx”,“xx”)?

Thanks,
Karthik Nathan

clientId and credentials’ username and password all take Expressions so they are dynamic fields and you can pass Gatling EL String or functions.

The credentials get configured at the SetUp right, so if I needed to have multiple devices, like 600 connected to a broker, how would that work? According to my understanding mqtt(“connect”) does not take in clientid and credentials, or do they?

According to https://github.com/gatling/gatling/blob/main/gatling-mqtt/src/main/scala/io/gatling/mqtt/action/builder/ConnectBuilder.scala, the mqtt request api(mqtt(“requestName”)) does not have the parameters that mqttProtocol has access to namely clientId(“id”) and credentials("${userName}", “${password}”).

Thanks,

Each virtual user simulates a device.
Inject the clientId, userName and password attribute, eg with a feeder, before the connect action.

The thing is that I create these devices via a http request then use the session object to retreive the credentials, an example is shown below:

scenario(“MQTT Test”).exec(
http(“Set up MQTT Connections”)
.post(hostName)
.body(StringBody("{“name”: “do l”,“permissions”: [{“channelId”:""+channelId+"",“publish”: true, “subscribe”: true}],“description”: “test”}"))
.exec((session: io.gatling.core.session.Session) => {
mqtt(“Connecting”).connect
.cleanSession(true)
.clientId(session(“clientId”).as[String])
.credentials(session(“username”).as[String],session(“password”).as[String]))
.exec(mqtt(“Subscribing”).subscribe(“channels/”+channelId+"/subscribe"))
})

You’re not using the Gatling DSL properly.

From https://gatling.io/docs/gatling/reference/current/general/scenario/:

Gatling DSL components are immutable ActionBuilder(s) that have to be chained altogether and are only built once on startup. The result is a workflow chain of Action(s). These builders don’t do anything by themselves, they don’t trigger any side effect, they are just definitions. As a result, creating such DSL components at runtime in functions is completely meaningless. If you want conditional paths in your execution flow, use the proper DSL components (doIf, randomSwitch, etc)

exec { session =>
  if (someSessionBasedCondition(session)) {
    // just create a builder that is immediately discarded, hence doesn't do anything
    // you should be using a doIf here
    http("Get Homepage").get("[http://github.com/gatling/gatling](http://github.com/gatling/gatling)")
  }
  session
}

This is correct:

scenario(“MQTT Test”).exec(
http(“Set up MQTT Connections”)
.post(hostName)
.body(StringBody("{“name”: “do l”,“permissions”: [{“channelId”:""+channelId+"",“publish”: true, “subscribe”: true}],“description”: “test”}"))
.exec(
mqtt(“Connecting”).connect
.cleanSession(true)
.clientId("${clientId}")
.credentials("${username}", “${password}”)
)
.exec(mqtt(“Subscribing”).subscribe(“channels/”+channelId+"/subscribe"))

or if you really want to use functions:

scenario(“MQTT Test”).exec(
http(“Set up MQTT Connections”)
.post(hostName)
.body(StringBody("{“name”: “do l”,“permissions”: [{“channelId”:""+channelId+"",“publish”: true, “subscribe”: true}],“description”: “test”}"))
.exec(
mqtt(“Connecting”).connect
.cleanSession(true)
.clientId(session => session(“clientId”).as[String])
.credentials(session => session(“username”).as[String], session => session(“password”).as[String])
)
.exec(mqtt(“Subscribing”).subscribe(“channels/”+channelId+"/subscribe"))

Thanks for the information. To clarify, to use gatling mqtt on enterprise, do we need to use the gatling-mqtt maven plugin? if so, is there a specific version as I see that there is some interference causing by that dependency:
full rebuild may help if ‘AssertionSupport.class’ was compiled against an incompatible version of io.gatling.commons.shared.unstable.model.stats.assertion.
6924 [ERROR] import io.gatling.core.Predef._

You must use the same version for gatling-mqtt and the rest of your Gatling modules.
And then, you must use a version that’s supported in Gatling Enterprise releases. Latest Gatling Enterprise 1.15.3 supports Gatling 3.3, 3.4., 3.5 and 3.6.

I’m sorry, but I am still confused on how to use the mqtt module in maven. I have imported following dependencies:

io.gatling gatling-mqtt 3.6.1 io.gatling.highcharts gatling-charts-highcharts 3.2.1

src/test/scala


maven-jar-plugin
3.2.0

net.alchim31.maven scala-maven-plugin 4.4.1 testCompile all -Xss100M -target:jvm-1.8 -deprecation -feature -unchecked -language:implicitConversions -language:postfixOps io.gatling.frontline frontline-maven-plugin 1.2.3 package io.gatling gatling-maven-plugin 3.1.2 integration-test test ${project.basedir}/src/test/resources true ${simulation_class}

Yet, you still have

io.gatling
gatling-mqtt
3.6.1

io.gatling.highcharts
gatling-charts-highcharts
3.2.1

You must use 3.6.1 everywhere.

Thanks for the clarification.
According to your response for have multiple devices connect.

This is correct:

scenario(“MQTT Test”).exec(
http(“Set up MQTT Connections”)
.post(hostName)
.body(StringBody("{“name”: “do l”,“permissions”: [{“channelId”:""+channelId+"",“publish”: true, “subscribe”: true}],“description”: “test”}"))
.exec(
mqtt(“Connecting”).connect
.cleanSession(true)
.clientId("${clientId}")
.credentials("${username}", “${password}”)
)
.exec(mqtt(“Subscribing”).subscribe(“channels/”+channelId+"/subscribe"))

or if you really want to use functions:

scenario(“MQTT Test”).exec(
http(“Set up MQTT Connections”)
.post(hostName)
.body(StringBody("{“name”: “do l”,“permissions”: [{“channelId”:""+channelId+"",“publish”: true, “subscribe”: true}],“description”: “test”}"))
.exec(
mqtt(“Connecting”).connect
.cleanSession(true)
.clientId(session => session(“clientId”).as[String])
.credentials(session => session(“username”).as[String], session => session(“password”).as[String])

)
.exec(mqtt(“Subscribing”).subscribe(“channels/”+channelId+"/subscribe"))

error: value cleanSession is not a member of io.gatling.mqtt.action.builder.ConnectBuilder
3248 [ERROR] possible cause: maybe a semicolon is missing before value cleanSession?
3249 [ERROR] .cleanSession(true)

Is it possible to use session variables inside the mqttProtocol? I have a file of clientIds,usernames and passwords and need to pass them to mqtt protocol’s clientId and credentials method. Is it possible to do this?