feeders

Hello,

J’ai deux fichiers : un fichier A (contient ID1) et un fichier B (contient ID2)

J’ai une URL de ce type :

http://…/…/{ID1}/{ID2}/home.html

Sachant que pour chaque ID1, il y a n ID2, j’aimerais boucler sur le fichier A, puis pour boucler sur le fichier ID2.

Hassen

Hello,

You were good until here. English is the preferred language here: )

J'ai deux fichiers : un fichier A (contient ID1) et un fichier B (contient
ID2)

J'ai une URL de ce type :

http://…/…/{ID1}/{ID2}/home.html

Sachant que pour chaque ID1, il y a n ID2, j'aimerais boucler sur le
fichier A, puis pour boucler sur le fichier ID2.

In english, the question is: "I have 2 files that I'd like to use as
feeders: one with some records with an id, and a second one whose records
contain a foreign key to the first file records. How do I join?".

I see 2 solutions.

First: you join upstream yourself, so you get one single file, where the
1*n records are merged into a single field.

Then, you can you use first file as a feeder, turn your second file into a
Map, and join into an exec.
You can reuse the utility methods here:
https://github.com/excilys/gatling/blob/master/gatling-core/src/main/scala/io/gatling/core/feeder/SeparatedValuesParser.scala

val file1 = csv("file1")

// file 2 is a Map[String, Record[String]]
val file2 =
SeparatedValuesParser.parse(GatlingFiles.feederResource("file2"),
',').groupBy(record => record("foreignKeyColumnName"))

feed(file1)
.exec(session =>
for {
id1 <- session("ID1").validate[String]
val recordsWithId1InFile2 = file2(id1)
val id2s = recordsWithId1InFile2.map(record => record("ID2"))
} yield session.set("concatenatedId2s", id2s.mkString("/"))
)
.exec(http("Catégorie Poney").get("/${ID1}/${concatenatedId2s}"))

Cheers,

Stéphane

Hello Stéphane,

Sorry, I did not know about posting in english. ;o)))

At work, I implemented the solution one. But I wanted something more flexible. I do not want to maintain a file with more than 400 entries.

Thanks for the quick answer. I will try tomorrow and let you know.

Best regards
Hassen

Have fun!

Hello Stéphane,

Theres is not foreign key in my case.

The files look like that :

file 1
languagecode,description
…,…
…,…

file 2
committeecode,description

…,…
…,…

I just want to iterate on all the records of the file 1 and for each record of the file 1, make an iteration on the file 2.

Regards
Hassen

Ahhhhhh

So that’s very easy: with Gatling 2, you can feed multiple records at once:
https://github.com/excilys/gatling/wiki/Gatling-2#wiki-http-misc

.feed(feeder2, sizeOfFeeder2)

then you’ll get committeecode1, committeecode2, committeecode3, etc.

In fact, i would like to have something like that :

languagecode1,committeecode1

languagecode1,committeecode2

languagecode1,committeecode3

languagecode2,committeecode1

languagecode2,committeecode2

languagecode2,committeecode3

languagecode3,committeecode1

languagecode3,committeecode2

languagecode3,committeecode3

PS : I am using Gatling 1.5.2 but I can change to 2.0.x if needed

In fact, i would like to have something like that :

languagecode1,committeecode1
languagecode1,committeecode2
languagecode1,committeecode3
.....
languagecode2,committeecode1
languagecode2,committeecode2
languagecode2,committeecode3
....
languagecode3,committeecode1
languagecode3,committeecode2
languagecode3,committeecode3

Yep, exactly what I answered.

PS : I am using Gatling 1.5.2 but I can change to 2.0.x if needed

Yep, have to, Gatling 2 FEATURE.

Bonjour Stéphane,

Thanks for your work, and please forgive my English. Hope it’s OK to post this as a response.

About feeding multiple records at once, how do you iterate through them? I try, for each of my users, to post the same files to web services, with a csv file containing the name of all files to post, with their respective service:

val scn = scenario(“scenario_name”)
.feed(usersList)
.feed(csv(“my_services_and_files.csv”), nb_lines)
.repeat(nb_lines, “file_index”)(
exec(
http(“request_global”)
.post("""/${service}${file_index}""")
.body(RawFileBody("""${file}${file_index}"""))
)
)

which gives me :“No attribute named ‘service’ is defined.”
I’m using gatling 2.0.0-M3.

Thanks

You don’t iterate: attribute names get suffixed with the index + 1.

?
Just use feed the same way as in Gatling 1.

Thanks for the quick reply.
But I don’t get it. The fact is that I have 636000 XML file names in my CSV feeder, in a particular order, and I need my user to POST each of them in that order.

I’ve tried:

scenario("…")
.repeat(csv.data.length) {
feed(csv)
.exec(
http(“address’”)
.post("…${csvcolumn}")

but the feeder is then a common resource shared between users. With the new feeder(csvFeeder, csvFeederLength), I would like to POST each csv entry, in order, by user. Is the solution to write 636000 POST with csvcolumn1, csvcolumn2 ?

Ah OK.

So what you want with your second file is not a feeder but a foreach loop: https://github.com/excilys/gatling/wiki/Structure-Elements#wiki-foreach

val seq = csv(“my_services_and_files.csv”).data.toSeq // beware, you get a Seq of Records[String] (= Map[String, String])

foreach(seq, “record”) {
// copy the record “fields” as session attributes
exec(session => session(“record”).validate[Map[String, String]].map(record => session.setAll(record.toSeq)))

}

Get it?

Stéphane

Get it!

Thanks for the help.

You’re welcome.
Have fun!

I used

.feed(csv(file2.csv), 22) to get all the data from file2

In session, I have something like that now :
committeecode1:value1,committeecode2;value2,…,committeecode22:value22

how to loop on this structure ?

Thanks in advance

You can’t.
If you want to loop, use the technique I described to Franck in this same thread.

Ok thanks for the answer.

H.

Hello Stephane,

val committees = csv(“committees.txt”).data.toSeq

foreach(committees, “committee”){
.exec(
http(“Request Committee”)
.get("${language}/${committee}/home.html")
.check(status.is(200))
)
}

${committee} return a map. How to get the key value or the value ?

Thanks

That was exactly the point of the following line in my previous answer to Franck :wink:

// copy the record “fields” as session attributes
exec(session => session(“record”).validate[Map[String, String]].map(record => session.setAll(record.toSeq)))