Publié le 20 Octobre 2015

J'utilise Gatling pour tester mon application (pour l'instant uniquement un service REST).

J'ai une liste de requêtes JSON dans un fichier et je veux que Gatling envoie chacune de ces requêtes à mon service REST.

Mon fichier contient une requête json par ligne. (ce n'est donc pas un fichier json valide mais chaque ligne est un objet json valide indépendamment).

Le problème est que mon fichier contient plusieurs milliers de lignes et qu'il ne tient pas entièrement en mémoire.

La solution que j'ai trouvé consiste à utiliser un "feeder" sur mesure qui va itérer sur les lignes du fichier est injecté chaque ligne json dans la session, de sorte qu'il sera très facile de former les requêtes HTTP.

Voilà ce que ça donne:

package com.patatos.gatling

import java.util.zip.GZIPInputStream

import io.gatling.core.Predef._
import io.gatling.core.action.builder.ActionBuilder
import io.gatling.core.structure.ChainBuilder
import io.gatling.http.Predef._
import io.gatling.http.action.HttpRequestActionBuilder
import io.gatling.http.request.Body

class MySimulation extends Simulation {
   val httpProtocol = http.baseURL("http://localhost:8080")

   private def sendRequest: HttpRequestActionBuilder = http("SendRequest")
      .put("/myservice")
      .header("Content-Type", "application/json")
      .body(StringBody("${json}"))
      .check(status is 200)
   }

   def samples: Iterator[String] = scala.io.Source.fromInputStream(
      new GZIPInputStream(getClass.getResourceAsStream("/gatling_input.gz"))
   ).getLines

   // iterator qui tourne en boucle sur le fichier d'input
   val feeder = Iterator.continually(samples)
      .flatten
      .map(json => Map("json" -> json))

   //scenario
   val scn = scenario("My Simulation").repeat(100000) {
      feed(feeder).exec(sendRequest)
   }

   setUp(scn.inject(atOnceUsers(4)))
      .protocols(httpProtocol)
      .assertions(global.successfulRequests.percent.is(100))

}

Voir les commentaires

Rédigé par Bliz

Publié dans #Scala

Repost 0

Publié le 8 Octobre 2015

Voilà le problème du jour j'ai un Iterator (par exemple qui itère sur les lignes d'un fichier) et j'ai besoin qu'une fois le fichier lu il recommence du début. Une sorte de rolling iterator.

Scala ne fournit pas de méthode directement pour permettre ce type de comportement mais on peut facilement l'implémenter en utilisant:

Iterator.continually[A](f: => A): A

Cette fonction génère un Iterator infini qui appelle f à chaque fois que next() est appelé.

On va donc l'utiliser pour produire un Iterator infini qui fournit un Iterator sur un fichier. On obtient ainsi un Iterator[Iterator[A]] et il ne reste plus qu'à le transformer en Iterator[A] à l'aide de la méthode flatten().

def lines = scala.io.Source.fromFile("monFichier.txt").getLines

def rolling[A](iter: => Iterator[A]): Iterator[A] =
  Iterator.continually(iter).flatten

for ( line <- rolling(lines) ) yield println(line) // runs forever

 

Voir les commentaires

Rédigé par Bliz

Publié dans #Scala

Repost 0