Pre-generated values or dynamically calculated?

I’m new to Gatling and Scala (have a Java background) and have been trying to write a test that tests a series of things, have been ok so far but have run into a block and am not sure if it’s due to me not organizing things properly, or if I’m taking the wrong tack entirely.

I’m testing a RESTful type service, with these steps:

  1. Login type call

  2. Metadata upload call

  3. Data upload call (binary)

  4. I got to work, the credentials I’ve stored in a csv file and that works great. I’m pulling out specific user information that the response gives and storing that on the session.

  5. I got to work, using the previously stored data pus another feed csv file I’m composing the metadata call’s JSON properly. I’m also calculating an HMAC on the message body and putting that in the headers. This was a bit of challenge as I didn’t realize that the ${name} type stuff wasn’t evaluated the way I expected, so I changed that to use .exec(session => session.set(“theBody”, calculateBody(session(“loginInfo”)))) to assign the stuff I needed to the session based what was on the session from 1.

  6. This is where I’m running into problems. The upload call is a POST as an application/octet, with part of the binary file being static but the beginning portion of it being dynamic. And since the file sizes are mutliple megabytes, using a stream seemed like a good idea (there’s an .inputStreamBody(InputStream)) rather than passing around byte arrays. I thought the Session was kind of like a Java HttpSession in that I could assign objects to it, but that doesn’t seem to work.

In an exec I create my byte array and then create an InputStream that has my byte array and the binary file and do a session.set(“theInputStream”, inputStream), but when I try to access it I just get a key not found exception for “theInputStream”.

Is there a way I can pass objects forward through the simulation? I need to compose the body of the http post as an InputStream, then run a calculation on it, before I get to the exec(http("foo).post etc) part.

Or am I approaching this all wrong. The other way I could think of doing it is to basically pre-calculate all my potential inputs, This could be problematic as the IDs for some things that are part of the responses in 1 and 2 aren’t always consistent, but I might be able to change that for the purposes of load testing.

Thanks in advance.

3) This is where I'm running into problems. The upload call is a POST as
an application/octet, with part of the binary file being static but the
beginning portion of it being dynamic. And since the file sizes are
mutliple megabytes, using a stream seemed like a good idea (there's an
.inputStreamBody(InputStream)) rather than passing around byte arrays. I
thought the Session was kind of like a Java HttpSession in that I could
assign objects to it, but that doesn't seem to work.

Gatling session works quite like an HTTP Session, the main difference being
that Gatling Session is immutable:
https://github.com/excilys/gatling/wiki/Session#wiki-immutability

In an exec I create my byte array and then create an InputStream that has
my byte array and the binary file and do a session.set("theInputStream",
inputStream), but when I try to access it I just get a key not found
exception for "theInputStream".

My 2cents: https://github.com/excilys/gatling/wiki/Session#wiki-functions
You probably just discarded the new session that contains the IS, and
returned the original one.

Is there a way I can pass *objects *forward through the simulation? I
need to compose the body of the http post as an InputStream, then run a
calculation on it, before I get to the exec(http("foo).post etc) part.

Yep, of course. The Session is basically a Map[String, Any]

Or am I approaching this all wrong. The other way I could think of doing
it is to basically pre-calculate all my potential inputs, This could be
problematic as the IDs for some things that are part of the responses in 1
and 2 aren't always consistent, but I might be able to change that for the
purposes of load testing.

Check if you experience some lag in Gatling because of this runtime
computation, otherwise you can try to precompute the final result files.
Note that streaming is intended for use cases where one doesn't know the
final Content-Length.
If you can pre-generate the body content as files, you'd rather use a
FileBody so that Gatling can directly write on the socket from the file
system with zero-copy (no intermediate in-memory byte arrays).

Cheers,

Stéphane

Gatling session works quite like an HTTP Session, the main difference being that Gatling Session is immutable:
https://github.com/excilys/gatling/wiki/Session#wiki-immutability

Hm, then what I’m doing should work, strange.

My 2cents: https://github.com/excilys/gatling/wiki/Session#wiki-functions
You probably just discarded the new session that contains the IS, and returned the original one.

Shouldn’t be, I’m doing it the same way that worked earlier in my script, though maybe something with how the scenario is composed I’m missing (this part is in a repeat). But that makes sense, I’ll check. Aaaand I checked and yes there’s a missing period from one exec to the next… hides

That must be why a lot of code I see has the periods at the beginning of each line, easy to see if one isn’t there.

Yep, of course. The Session is basically a Map[String, Any]

Makes sense, is there a traditional javadoc type API document? Or I guess I could just check out the source code.

Check if you experience some lag in Gatling because of this runtime computation, otherwise you can try to precompute the final result files.
Note that streaming is intended for use cases where one doesn’t know the final Content-Length.If you can pre-generate the body content as files, you’d rather use a FileBody so that Gatling can directly write on the socket from the file system with zero-copy (no intermediate in-memory byte arrays).

Ok makes sense. Not sure if I can pre-generate the the entire file, as the first x bytes of the file will change based on unique identifiers assigned from previous server calls, I can pre-generate those, but if I want to test 2000 files each in 5 1MB chunks, that’s 10GB :smiley:

I can try it a few different ways to see what works best.

Thanks, appreciate it!

Gatling session works quite like an HTTP Session, the main difference

being that Gatling Session is immutable:
https://github.com/excilys/**gatling/wiki/Session#wiki-**immutability<https://github.com/excilys/gatling/wiki/Session#wiki-immutability>

Hm, then what I'm doing should work, strange.

My 2cents: https://github.com/excilys/gatling/wiki/Session#

wiki-functions<https://github.com/excilys/gatling/wiki/Session#wiki-functions>
You probably just discarded the new session that contains the IS, and
returned the original one.

Shouldn't be, I'm doing it the same way that worked earlier in my script,
though maybe something with how the scenario is composed I'm missing (this
part is in a repeat). But that makes sense, I'll check. Aaaand I checked
and yes there's a missing period from one exec to the next... *hides*

That must be why a lot of code I see has the periods at the beginning of
each line, easy to see if one isn't there.

Yep, of course. The Session is basically a Map[String, Any]

Makes sense, is there a traditional javadoc type API document? Or I guess
I could just check out the source code.

Can't say we're much into Scaladoc. Will hopefully improve for Gatling 2...
Until then, reading the code is the best way.

Check if you experience some lag in Gatling because of this runtime

computation, otherwise you can try to precompute the final result files.
Note that streaming is intended for use cases where one doesn't know the
final Content-Length.If you can pre-generate the body content as files,
you'd rather use a FileBody so that Gatling can directly write on the
socket from the file system with zero-copy (no intermediate in-memory byte
arrays).

Ok makes sense. Not sure if I can pre-generate the the entire file, as
the first x bytes of the file will change based on unique identifiers
assigned from previous server calls, I can pre-generate those, but if I
want to test 2000 files each in 5 1MB chunks, that's 10GB :smiley:

Ouch, that's a lot. Beware, you might end up benchmarking your drive...

I can try it a few different ways to see what works best.

Thanks, appreciate it!

You're welcome.
Have fun!

Ouch, that’s a lot. Beware, you might end up benchmarking your drive…

Oh there’s a lot more than one drive behind the server :slight_smile:

I get your meaning, and that’s part of the point of the exercise is to validate capability and identify the path for growth.

Feel free to post a gist of your code if you need help.