Difficulties upgrading from Gatling 3.3.1 to 3.4.1

Hi,

We have problems upgrading from Gatling version 3.3.1 to 3.4.1. When I just update the version in our SBT file to 3.4.1, the Gatling scripts don’t compile anymore.

Looking into the error messages it seems to do with our custom feeders.

We used to have the following code working:

/* Credential feeder based on environment variables */
val envCredentialFeeder: FeederBuilder =
Iterator.continually(Map(“username” → EnvValues.userName, “password” → EnvValues.password))

feed(envCredentialFeeder)
.exec(
http(requestName)
.post(authUri)
.formParamSeq(Seq((“username”, “${username}”), (“password”, “${password}”)))
.check(status.is(200))
.check(jsonPath("$.access_token").saveAs(“accessToken”))
.check(jsonPath("$.refresh_token").saveAs(“refreshToken”))
.check(jsonPath("$.token_type").saveAs(“tokenType”)))

Now in version 3.4.1 it complains that the created feeder is of type Iterator[Map[String, String]]

Does anyone have an idea how to fix this?

Thanks in advance,

Hans

Don’t play with Gatling internal types such as FeederBuilder, they are subject to changes.

val envCredentialFeeder: Iterator[Map[String, String]] =
Iterator.continually(Map(“username” → EnvValues.userName, “password” → EnvValues.password))

feed(envCredentialFeeder)

Thank you for the reply. Not using the Gatling types makes it a bit more complicated for us. We build in some flexibility.

/* Credential feeder based on environment variables */
val envCredentialFeeder: Iterator[Map[String, String]] =
Iterator
.continually(Map(“username” → EnvValues.userName, “password” → EnvValues.password))

/* Credential feeder based on username, password file */
def fileCredentialFeeder(filename: String): BatchableFeederBuilder[String]#F = csv(filename).circular

/* The BearerAuth call is part of the BaseLib, as it is used to provide authentication to standard calls.
Testing of the login call it self, should be code in the com.simacan.services.authapi folder.
*/
def bearerAuth(
requestName: String = “bearerAuth”,
credentialFeeder: Iterator[Map[String, String]] = envCredentialFeeder,
realmPath: String = EnvValues.realmPathComp.getOrElse("")): ChainBuilder = {
val authUri = s"${EnvValues.authApiURI}/api/v1/auth/${realmPath}password"

feed(credentialFeeder)
.exec(
http(requestName)
.post(authUri)
.formParamSeq(Seq((“username”, “${username}”), (“password”, “${password}”)))
.check(status.is(200))
.check(jsonPath("$.access_token").saveAs(“accessToken”))
.check(jsonPath("$.refresh_token").saveAs(“refreshToken”))
.check(jsonPath("$.token_type").saveAs(“tokenType”)))
}

And then we can choose in our actual script which feeder to use

so in the test script it self,
exec(bearerAuth(“test”, fileCredentialFeeder, “test”)
or
exec(bearAuth(“envcred”, envCredentialFeeder, "demo’)

In this case the FeederBuilder is the type in common, or is there a better solution?

Kind regards,

Hans

FeederBuilder is () => Feeder[Any] so you can have
val envCredentialFeeder: FeederBuilder = () =>
Iterator
.continually(Map(“username” → EnvValues.userName, “password” → EnvValues.password))

Stéphane,

Thanks for the suggestion.

However in this case we again are using the internal type FeederBuilder, aren’t we? Didn’t you suggest not to “play-around” in the previous reply.

Yes, you’re right.

Actually, your original issue is that you assumed that we would always have feed(A) and feed(B) that would work in a way that A and B would have a common super type. This is not the case and can’t be expected: we want to have overloaded methods that take different kinds of parameters.

What would be safe would be to rely on ActionBuilder (but you don’t have to have it explicit):

val myFeed = if (cond) feed(A) else feed(B)

exec(myFeed)

Get it?

I think I get it.
I always thought there is a difference between:

exec(
feed(…)
.exec(…)
)

and

exec(
feed(…)
)
.exec(…)