Gatling Get web service - scala

I have tried to create a simple Gatling Script mentioned below,
package computerdatabase.advanced
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import scala.util.matching.Regex
import scala.concurrent.duration._
class getSampleTest extends Simulation{
val httpProtocol = http
.baseURL("https://xyz.com")
.header("Content-Type","application/json")
.header("Accept"," application/json ")
.header("Accept-Charset","utf-8n")
.acceptLanguageHeader("en-us","en;q=0.5")
.acceptEncodingHeader("gzip", "deflate")
.connection("keep-alive")
val scn = scenario("XYZ")
.group("XYZ Group") {
exec(http("XYZ-PAge").get("/profile/services").check(status.is(200)))
}
setUp(scn.inject(
rampUsersPerSec(1) to(10) during(5),
constantUsersPerSec(10) during(5)
).protocols(httpProtocol))
}
but i am getting an error saying that -->
value header is not a member of io.gatling.http.config.httpProtocolBuilder
may be a semicolon is missing before'value header'
.header("Content-Type","application/json")

No, this is not the compiler error message you get with such code (this is the error you got with the first tentative you posted on the Gatling mailing list).
Here, you get "too many arguments for method acceptLanguageHeader" (and acceptEncodingHeader) as those take only one parameter:
.acceptLanguageHeader("en-us, en;q=0.5")
.acceptEncodingHeader("gzip, deflate")

Related

Gatling exec with session

I need to make a request in Gatling, in which I'm able to access session items (without the expression language). I need to do this, because I want to inject data into a ByteArrayBody request from a csv feeder. To demonstrate my problem, I have a small example (without the actual need of the session).
The following scenario runs fine:
val scnBase: ScenarioBuilder = scenario("Test scneario").repeat(1){
exec(http("Http Test test").get("http://google.de/"))
}
But that one doesn't (I get the exception There were no requests sent during the simulation, reports won't be generated):
val scnBase: ScenarioBuilder = scenario("Test scneario").repeat(1){
exec(session => {
http("Http Test test").get("http://google.de/")
session
})
}
I run my simulations in IntelliJ (which worked fine so far) and in the following (here minimized) simulation file:
package test.scala
import java.text.SimpleDateFormat
import java.util.Date
import io.gatling.core.Predef._
import io.gatling.core.body.ByteArrayBody
import io.gatling.core.structure.ScenarioBuilder
import io.gatling.http.Predef._
import io.gatling.http.protocol.HttpProtocolBuilder
import org.slf4j.LoggerFactory
import test.scala.TerminalTesterRequest.url
import test.scala.requests._
import test.scala.util.CharsetConverter
import scala.concurrent.duration._
import scala.language.postfixOps
class MySimulation extends Simulation {
//base URL (actually this URL is different, but it's not important)
val ecmsServerUri = "http://0.0.0.0"
//base Protocol
val httpProtocol: HttpProtocolBuilder = http
.baseUrl(ecmsServerUri)
.inferHtmlResources(BlackList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.(t|o)tf""", """.*\.png"""), WhiteList())
.acceptHeader("*/*")
.acceptEncodingHeader("gzip, deflate")
.acceptLanguageHeader("en,en-US;q=0.7,de-DE;q=0.3")
.userAgentHeader("Mozilla/4.0 (compatible; MSIE 6.0; MS Web Services Client Protocol 2.0.50727.8762)")
val scnBase: ScenarioBuilder = scenario("Test scneario").repeat(1){
exec(session => {
http("Http Test test").get("http://google.de/")
session
})
}
setUp(
scnBase.inject(constantUsersPerSec(1) during(1 seconds)).protocols(httpProtocol)
).maxDuration(5 minutes)
}
How can I run an exec request with the information of the session (or at least the data from the feeder)? I'm using Gatling 3.1.1
Build whatever you need in a function and put the result in the session, then refer that value in the actual request
val feeder = csv("foo.csv")
scenario("Test scenario")
.feed(feeder)
.exec(buildPostData)
.exec(http("Http Test test")
.post(createApiURL)
.body(ByteArrayBody("${postData}"))
.check(status.is(200))
)
def buildPostData: Expression[Session] = session => {
val postData: Array[Byte] =
... // getting values from csv record: session("csvHeader").as[String]
session.set("postData", postData)
}

Akka HTTP client - Unmarshal with Play JSON

I am using Akka HTTP as a client to do a POST request and parse the answer. I am using Play JSON and I get the following compiler error:
could not find implicit value for parameter um: akka.http.scaladsl.unmarshalling.Unmarshaller[akka.http.javadsl.model.ResponseEntity,B]
[ERROR] Unmarshal(response.entity).to[B].recoverWith {
This is the dependency I added to use Play JSON instead of Spray:
"de.heikoseeberger" %% "akka-http-play-json"
My class definition is:
class HttpClient(implicit val system: ActorSystem, val materializer: Materializer) extends PlayJsonSupport {
and the method definition is:
private def parseResponse[B](response: HttpResponse)(implicit reads: Reads[B]): Future[B] = {
if (response.status().isSuccess) {
Unmarshal(response.entity).to[B].recoverWith {
....
In the imports I have:
import play.api.libs.json._
import scala.concurrent.ExecutionContext.Implicits.global
import de.heikoseeberger.akkahttpplayjson.PlayJsonSupport._
It seems to me that I have the required implicits in scope. The Marshal part has a similar logic (but with Writes instead of Reads) and compiles fine. What am I missing?
Check your other imports. Based on the error message, it appears that you're using akka.http.javadsl.model.HttpResponse instead of akka.http.scaladsl.model.HttpResponse; PlayJsonSupport only supports the Scala DSL:
private def parseResponse[B](response: HttpResponse)(implicit reads: Reads[B]): Future[B] = ???
// ^ this should be akka.http.scaladsl.model.HttpResponse
In other words, use
import akka.http.scaladsl.model._
instead of
import akka.http.javadsl.model._

Authentication Issue & Check Regex Issue Using Gatling

Want to Perform Load testing on Salesforce Platform. But it seems there is an error in authentication as well as regex part.
I am using Gatling testing tool & scala programming here.
If you guide me how to do load testing on salesforce that would be plus.
This is my code:
package default
import scala.concurrent.duration._
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import io.gatling.core.Predef._
class requestUser extends Simulation {
val httpProtocol = http.baseURL("http://login.salesforce.com")
val Test = exec(http("Login")
.get("/")
.basicAuth("abc#gmail.com", "Password+Token")
.formParam("sessionId","*******")
.formParam("orgId","***********")
)
.exec(http("acc")
.get("/path")
.basicAuth("abc#gmail.com", "Password+Token")
.check(status.is(200))
**.check(css("#content"))
.check(regex("""<div id ="header">Choose a Username</div>"""))
.check(regex("""<td class = "datacell">Jaipur</td>"""))**
)
.exec(http("home")
.post("/home/home.jsp")
.formParam("Post", "Test from Gatling")
.check(regex())
)
var scn = scenario("scn").exec(Test)
setUp(
scn.inject(rampUsers(1) over (10 seconds))
).protocols(httpProtocol)
}

Use case for WebDriver (https://github.com/typesafehub/webdriver) to execute js

I'm working on a web scraper using this project (based on Scala, Spray, Akka and PhantomJS)
The problem is that I can't find a more specific example of how to use it, and the documentation is missing a lot of details
1- I would like to know how to give an specific URL so I can get data from it
2- How can I excecute, or pass a javascript file or function so that phantom can run and do some stuff(return specific data or whatever, from the site in point 1- )
Here is my Main.scala file: (Is almost the same as the one in the project)
package com.typesafe.webdriver.tester
import akka.actor.{ActorRef, ActorSystem}
import akka.pattern.ask
import com.typesafe.webdriver.{Session, PhantomJs, LocalBrowser}
import akka.util.Timeout
import scala.concurrent.duration._
import scala.concurrent.ExecutionContext.Implicits.global
import spray.json._
import spray.http._
object Main {
def main(args: Array[String]) {
implicit val system = ActorSystem("webdriver-system")
implicit val timeout = Timeout(5.seconds)
system.scheduler.scheduleOnce(7.seconds) {
system.shutdown()
System.exit(1)
}
val browser = system.actorOf(PhantomJs.props(system), "localBrowser")
browser ! LocalBrowser.Startup
for (
session <- (browser ? LocalBrowser.CreateSession).mapTo[ActorRef];
result <- (session ? Session.ExecuteNativeJs("return 5+5",JsArray(JsNumber(999)))).mapTo[JsNumber]
) yield {
println(result)
try {
system.shutdown()
System.exit(0)
} catch {
case _: Throwable =>
}
}
}
}
I would suggest you to use already created web scrappers in Scala.
For example ScalaWebDcraper which has nicely writted DSL and scrapping feature.
https://github.com/Rovak/ScalaWebscraper
It can be combined with Goose, which is a web article extractor. You can use it to fetch article data from the links you visit with the previous library.
https://github.com/jiminoc/goose
Also, checkout Metascrapper, a Scala Library for Scraping Page Metadata
https://beachape.com/blog/2013/09/05/introducing-metascraper-a-scala-library-for-scraping-page-metadata/
And check this question, lot's of valuable info inside.

Passing parameter - number of users

I'm using gatling in linux terminal. When I pass parameter like described in github I get error:
value users is not a member of Integer
This is my code:
package mypackage
import io.gatling.core.Predef._
import io.gatling.http.Predef._
import io.gatling.jdbc.Predef._
import io.gatling.http.Headers.Names._
import scala.concurrent.duration._
import bootstrap._
import assertions._
import util.Random
class MySimulation extends Simulation {
val usersCount = Integer.getInteger("users", 1)
val links = csv("links.csv").random
val httpProtocol = http
.baseURL("http://mywebsite.com:8080/")
.acceptCharsetHeader("ISO-8859-1,utf-8;q=0.7,*;q=0.7")
.acceptHeader("text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8")
.acceptEncodingHeader("gzip, deflate")
.acceptLanguageHeader("fr,fr-fr;q=0.8,en-us;q=0.5,en;q=0.3")
.disableFollowRedirect
val headers_1 = Map(
"Keep-Alive" -> "115")
val headers_3 = Map(
"Keep-Alive" -> "115",
"Content-Type" -> "application/x-www-form-urlencoded")
val scn = scenario("big project benchmark")
.repeat(50) {
feed(links)
.exec(
http("request_1")
.get("${pageUri}")
.headers(headers_1)).pause(1000 millisecond)
}
setUp(scn.inject(ramp(usersCount users) over (30 seconds)))
.protocols(httpProtocol)
.assertions(global.successfulRequests.percent.is(100), details("request_1").responseTime.max.lessThan(1000))
I start this in terminal using:
JAVA_OPTS="-Dusers=300" ./gatling.sh -s mypackage.mySimulation -on testing -sd test1
Please, be patient, because I'm totally new to scala and gatling. Thanks for any help.
The problem comes from the usersCount users part of the setUp.
In Scala, this is interpreted as usersCount.users which, in our case does not exist since Integer does not have a users method.
I think (but I'm not sure since I cannot test it right now), that you should make usersCount an Int like so: val usersCount: Int = Integer.getInteger("users", 1).toInt.
Hope this helps!
PS: The reason you should convert Integer to Int is because of implicit conversions. This is a really powerful feature of Scala.
PPS: The wiki documentation was valid for Gatling 1.X, it will be updated accordingly for Gatling 2.X