Dynamic message feed for custom protocol (TCIL) not working

Hello,

I’m trying to implement stress test for one our applications using Gatling Enterprise. We use specific IATA message format (EDIFACT) and non-standard protocol - TCIL. The stress test works fine with single EDIFACT message, but application would cache the response for this message and thus stress test is not giving real capacity of the application. Therefore I’m trying to randomize the messages that are injected using feeder: I have a CSV file with file names that are containing EDIFACT messages:

val tcilProtocol = tcil
.remote(“X.X.X.X”, XXXXX) //Test System
.replyTimeout(60000)

val feeder = csv(“messagelist.csv”).random

val scn = scenario(“SimpleTAMCRQScenario”)
.feed(feeder)
.exec(tcil(“SimpleTAMCRQScenarioOneReq”).requestReply.message( scala.io.Source.fromInputStream(getClass.getResourceAsStream("/MM/${MessageFile}")).getLines.mkString)
.check(substring(“TAMCRR”))
)

This is not working - what ever syntax I’ve tried! I’m not able to get my file names randomly from CSV and getting null-pointer exception. And it seems that the problem is not with the syntax - ${MessageFile} should indeed return one of the values from CSV. I had a look into the code (I’m newbie in SCALA) and it seems that there is something missing in TCIL protocol implementation for dynamic feed support…

Does anyone know what has to be implemented in the protocol class so that dynamic variable would be returned to the scenario? Or perhaps any other ideas on how to get random message to inject from the file?

Thanks in advance,

Nikolai

I’m not sure about the tcil protocol, but what I can see is that getClass.getResourceAsStream as nothing to do with Gatling, hence it cannot know about the Gatling session or the Gatling Expression Language.

First, ensure you have a “MessageFile” header in your CSV (csv feeder need the first line to be the session variable name)

Second, read your MessageFile file value in a custom session value (ie, the part that transforms the file name to the string)

Then, use that string your message.

Hope this helps!

Cheers!

.message takes a Body like in HTTP protocol.

What you’re should be doing is simply .message(StringBody("/MM/#{MessageFile}"))

(beware that I used the #{} Gatling EL for 3.7 instead of the deprecated ${} you have to use if you’re still using 3.6 or older).

1 Like

I’ve tried that syntax too! It wasn’t working along with getting file content - looks like @sbrevet explanation is absolutely correct. I’ve done that work around and it’s working for me: I’m picking random file name from CSV and injecting EDIFACT message that is in that file.

I don’t think I can use .message(StringBody("/MM/#{MessageFile}")) directly since #{MessageFile} contains file name with the message, not the message itself - thus all that code to get the content of the file. Perhaps there is a method that can read file internally and return a body?

Perhaps RawFileBody is more suitable, in that case.

.message(RawFileBody("/MM/#{MessageFile}"))

1 Like

Absolutely, my bad. Also, you don’t need the head slash:

 .message(RawFileBody("MM/#{MessageFile}"))

Yes, I’ve found that I don’t need first slash empirically! LOL! :slight_smile: But if you get the file with scala you need that one - a bit strange but understandable.

Well, both ways are working now - I mean that I’m able to pick random EDIFACT message for injection.
However, I face a problem at the next stage (in both cases) - it looks like nothing reaches targeted system. Messages seem to be rejected by enterprise service bus (SI).

If I use getClass.getResourceAsStream("/MM/TAMCRQ_MSG1.txt") and do dynamic feed - injection is working fine - our backend receives it and replies - full test chain is working.

If I use session variable and feeder to get file name (I’ve reduced the list of message to TAMCRQ_MSG1.txt only - to make sure that it’s the same message that works). Then I use same getResourceAsStream() to get the message. With this scenario nothing seems to be injected. Gatling gives OK=0, KO=0 all the time:

`2022-02-22 10:55:58 5s elapsed
---- Requests ------------------------------------------------------------------

> Global (OK=0 KO=0 )
> ---- SimpleTAMCRQScenario ------------------------------------------------------
> [ ] 0%
> waiting: 150285 / active: 0 / done: 15
> ================================================================================`

With RawFileBody scenario I’m getting only KOs:

`2022-02-22 11:34:22 5s elapsed
---- Requests ------------------------------------------------------------------

> Global (OK=0 KO=15 )
> SimpleTAMCRQScenarioOneReq (OK=0 KO=15 )
> ---- Errors --------------------------------------------------------------------
> substring(TAMCRR).find.exists, found nothing 15 (100.0%)

# ---- SimpleTAMCRQScenario ------------------------------------------------------
[ ] 0%
waiting: 150285 / active: 0 / done: 15`

I yet don’t understand why no injection happens in second case, but for the 3rd case I suspect that RawFileBody formats message a bit differently from StringBody - and the message is rejected.
What I need, I think, is StringFileBody(…) but I haven’t found anything like this in the documentation.

Any idea how to overcome this problem? I also tried to hard-code the file name in the RawFileBody, to see if the problem comes from the feeder - but result is the same - all KOs - meaning message was rejected.

In case of RawFileBody you may need to define your own Content-Type header corresponding to the actual content. And your server may filter the request by this same header.

Do you have an example how to define Content-Type? I don’t think I need any header for the message - whole message including headers is in the text file in the resources directory. And it is passing through our Enterprise Bus OK if injected in this way:

.message(StringBody(scala.io.Source.fromInputStream(getClass.getResourceAsStream("/MM/TAMCRQ_MSG1.txt")).getLines.mkString

with RawFileBody Enterprise Bus is rejecting the message saying that it’s header is not recognized and thus it can’t understand the message type and route it to the backend.
I’m going to intercept the traffic with WireShark and compare the message in both cases.
For me it looks like mkString is fixing something in the file format (perhaps carriage returns or something like that)

There’s no Content-Type in TCIL.
Now, I do have several questions:

  1. which version of Gatling Enterprise are you using?
  2. which version of Gatling TCIL are you using?
  3. is Gatling TCIL codecs up-to-date?

Also, the fact that using StringBody where you read lines and then recombine them works while using RawFileBody to directly send the raw bytes makes me believe the former is cleaning up some unexpected bytes in the raw source. Windows Carriage Return?

  1. It turned out that I’m using Gatling plug-in 3.7.4 with Maven 3.8
  2. I made a discovery looking into our repository: I’m using Gatling-tcil 1.4.1 released 22-FEB-18 by Stephane Landelle!!! :slight_smile: It seems you have been in the same company! :slight_smile:
  3. For the plugins I’m not sure how to check. I see this in pom.xml
  <pluginRepositories>
        <pluginRepository>
            <id>GatlingCorp</id>
            <url>http://repository.gatling.io/683f72c0-d622-4911-8170-4522e1141f9e/content/repositories/releases</url>
        </pluginRepository>
    </pluginRepositories>

I’ve just made it working - It’s not just windows carriage returns, but line feeds as well. I have reformatted the file into single string - and RawFileBody provides the good message that is accepted!!

File is not very readable now, but it is working. I will try to pre-format files internally.