I have a problem when trying to use the basicAuth method with parameter retrived from a csv files.
Here is my code:
class spiSimulation extends Simulation {
val httpProtocol = http
.baseURL("http://spi.test.com")
.inferHtmlResources()
val headers_0 = Map(
"Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8",
"Cache-Control" -> "no-cache",
"Pragma" -> "no-cache",
"Proxy-Connection" -> "keep-alive")
val users = csv("users.csv")
val scn = scenario("LosspiSimulation_request")
.feed(users)
.exec(
http("request")
.get("/SPI/Basic").headers(headers_0)
.basicAuth("${login}", "${password}")
.headers(headers_0).check(
header("Set-Cookie").saveAs("Cookie")))
.exec(
http("validate")
.get("/SPI-back/Validation?cookie=${Cookie}")
.headers(headers_0))
setUp(scn.inject(rampUsers(10) over (2 seconds))).protocols(httpProtocol)
}
When I use only one user and hard code my login and password it works. But with param login and password, I have two errors when running the Gatling script, one is "No attribute named Cookie" is defined and "No attribute named login is defined".
Here is a sample of my csv file:
login, password
test01, password01
test02, password02
I would be pleased if you can find a solution.
Thank you very much for your help!
Please try without whitespaces in the CSV file :)
The Feeders documentation of Gatling explicitly states that they honor only The RFC. They do not automatically trim whitespaces.
Should be:
login,password
test01,password01
test02,password02
Last line
setUp(scn.inject(rampUsers(10) over (2 seconds))).protocols(httpProtocol)
You declare 10 user and program must have 10 user in csv file.
Related
I am using Gatling for performance testing, so I want know that how we extract token id from the login request here is code
val scn = scenario("Navigation")
.exec(http("request_6")
.post("/WEBAUTO03/aurora/login/security_check")
.headers(headers_6)
.formParam("j_username", "TONY")
.formParam("j_password", "1234")
.formParam("doLogin", "")
Above request provide token and I need apply the token in following request
val headers_9 = Map(
"Content-type" -> "text/plain",
"Origin" -> "https://resource.com",
"X-XSRF-TOKEN" -> ""4c81ed9c-e509-4830-b724-62e489c918e2"") -----here i need to replace token
.exec(http("request_9")
.post("/WEBAUTO03/aurora/JSON-RPC")
.headers(headers_9)
.body(RawFileBody("webview/navigation/0009_request.txt")))
anyone have any idea
Without seeing the response from the "above request" we cannot suggest the exact steps, approximate would be something like:
http("request_6")
.post("/WEBAUTO03/aurora/login/security_check")
.check(css("input[name='csrf_token']", "value").saveAs("Correlation1"))
val headers_9 = Map(
"Content-type" -> "text/plain",
"Origin" -> "https://resource.com",
"X-CSRF-Token" -> "${Correlation1}")
More information:
Gatling HTTP Checks
How to Run a Simple Load Test with Gatling
im new to Gatling and have been trying to setup a test where my users login, get an access token, then perform some simple get requests using that token. Having 1-2 users works fine, however once i start ramping up the users i start getting spammed with this error:
[ERROR] i.g.h.a.HttpRequestAction - 'httpRequest-2' failed to execute: No attribute named 'access_token' is defined
Im thinking it could have something to do with the way I am saving and using the access token ?
class GatlingTest extends Simulation {
val httpProtocol = http
.baseUrl("https://myurl.com/api/v1")
.inferHtmlResources(BlackList(""".*\.js""", """.*\.css""", """.*\.gif""", """.*\.jpeg""", """.*\.jpg""", """.*\.ico""", """.*\.woff""", """.*\.woff2""", """.*\.(t|o)tf""", """.*\.png""", """.*detectportal\.firefox\.com.*"""), WhiteList())
.acceptLanguageHeader("en-GB,en;q=0.5")
.upgradeInsecureRequestsHeader("1")
object GetUserData {
val userData = exec(http("Get_User_Data")
.get("/user")
.header("Authorization", "Bearer ${access_token}"))
.pause(1)
}
object GetUserInfo {
val userInfo = exec(http("Get_User_Info")
.get("/userInfo")
.header("Authorization", "Bearer ${access_token}")
.header("Accept", "application/json"))
.pause(1)
}
object Login {
val sentHeaders = Map("api_key" -> "nnxzv336wt2374h6zw5x24qd", "Content-Type" -> "application/x-www-form-urlencoded", "Accept" -> "application/json")
val login = exec(http("Login_User")
.post("/login")
.basicAuth("username", "password")
.headers(sentHeaders)
.body(StringBody("grant_type=password&username=username#username.local&password=12345"))
.check(jsonPath("$.access_token").saveAs("access_token"))
)
}
val user = scenario("User").exec(Login.login).exec(GetUserData.userData, GetUserInfo.userInfo)
setUp(
user.inject(
rampUsers(5).during(2.seconds),
).protocols(httpProtocol)
)
}
I have added Authorization Bearer to the get requests, like i mentioned it does work, but as soon as 3+ users are involved i get the error.
It means the login request failed and hence, the user wasn't able to capture the access_token there.
I am working on performance test, for that I have below Gatling script -
val getUserById: ChainBuilder = feed(userEmailFeeder).exec(http("User By Id")
.get("url")
.headers(getHeaders)
.check(status is 200)
)
private val getHeaders = Map.apply(
"Content-Type" -> "application/json",
"Accept" -> "application/json",
"token" -> {tokenValue}
)
object BearerToken {
//Generating token here
}
In userEmailFeeder I have user emails and passwords. I have to generate a token for every email present in feeder and add to header in getHeader.
Can someone guide me how I can pass same email & associated password to BearerToken for which getUserById is referring from feeder so it will genearte token and add into header?
You can create method which will get your email and password from session, generate token and then write this values to session.
val generateTokenByEmailAndPassword: Expression[Session] = (session: Session) => {
val email = session("email").as[String]
val password = session("password").as[String]
// your logic for generate token
val token = email + password
session.set("tokenValue", token)
}
And then add to scenarion
...
.feed(userEmailFeeder)
.exec(generateTokenByEmailAndPassword)
.exec(http("User By Id")
...
A little remark - for get session value need add $
Wrong: {tokenValue}
Right way: ${tokenValue}
i'm trying to build a scenario where the user log in first, then do something before logging out.
The problem is that i want to save the header response from the log in request to use it in my next request.
When a user log in, he gets an header response containing the Authorization header, with the token.
Here is my code, but it's not working :
val LoggingTest = scenario("Basic Scenario")
.exec(http("Logging")
.post("/login")
.body(
StringBody("""{"name" : "test",
"password" : "test"}""")
)
.check(header("Authorization").saveAs("token"),status.is(200))
).pause(15)
.exec(http("check")
.get("/sayhi")
.header("Authorization",s"${token}")
.check(status.is(200))
).pause(15)
How can i fix it please ?
This is how you can do it:
import io.gatling.core.Predef._
import io.gatling.http.Predef._
val LoggingTest: ScenarioBuilder = scenario("Basic Scenario")
.exec(http("Logging")
.post("/login")
.body(
StringBody("""{"name" : "test",
"password" : "test"}""")
)
.check(header("Authorization").saveAs("token"),status.is(200))
).pause(15)
.exec(
http("check")
.get("/sayhi")
.header("Authorization", session => session("token").validate[String])
.check(status.is(200))
).pause(15)
It's not s"${token}" but "${token}" without the s.
Sadly, IntelliJ automatically adds this s because it thinks you want to use Scala's String interpolation while you want to use Gatling Expression Language.
I have a web app which uses a form to login, this returns a session cookie to the user which is used to authorize requests to the rest of the app. I'm having trouble sending this cookie value with my requests. My test harness is below:
val loginResponse = await(WS.url(s"http://localhost:$port/authenticate")
.withHeaders("Content-Type" -> "application/x-www-form-urlencoded")
.post(Map("email" -> Seq("admin#example.com"), "password" -> Seq("genivirocks!"))))
loginResponse.status mustBe (OK)
val cookies = loginResponse.cookies(0).toString
val vehiclesResponse = await(WS.url(s"http://localhost:$port/api/v1/vehicles/" + testVin)
.withHeaders("Cookie" -> cookies)
.put(""))
vehiclesResponse.status mustBe (OK)
val vehiclesFilterResponse = await(WS.url(s"http://localhost:$port/api/v1/vehicles?regex=" + testVin)
.withHeaders("Cookie" -> cookies)
.get())
vehiclesFilterResponse.status mustBe (OK)
The request fails, as the second request gets a 204 instead of a 200, as it gets redirected to the login page because the cookie is interpreted as invalid. The web server gives the following error, when the second request is made:
2015-10-06 14:56:15,991
[sota-core-service-akka.actor.default-dispatcher-42] WARN
akka.actor.ActorSystemImpl - Illegal request header: Illegal 'cookie'
header: Invalid input 'EOI', expected tchar, '\r', WSP or '=' (line 1,
column 178):
PLAY2AUTH_SESS_ID=ee84a2d5a0a422a3e5446f82f9f3c6f8eda9db1cr~jz7ei0asg0hk.ebd8j.h4cpjj~~9c0(yxt8p*jqvgf)_t1.5b(7i~tly21(*id;
path=/; expires=1444139775000; maxAge=3600s; HTTPOnly
I've tried building the cookie string myself and making sure there are no extra '\r' characters at the end and so on, with no luck. Google also doesn't seem to have any hints. Is there a better way of sending cookie values using WS?
EDIT
Got it working with the following code:
import play.api.mvc.Cookies
val loginResponse = ...
loginResponse.status mustBe (OK)
val cookies = loginResponse.cookies
val cookie = Cookies.decodeCookieHeader(loginResponse.cookies(0).toString)
val vehiclesResponse = await(WS.url(s"http://localhost:$port/api/v1/vehicles/" + testVin)
.withHeaders("Cookie" -> Cookies.encodeCookieHeader(cookie))
.put(""))
vehiclesResponse.status mustBe (OK)
...
Why don't you use the existing Cookies.encode function to do the cookie encoding for you?
import play.api.mvc.Cookies
val loginResponse = ...
loginResponse.status mustBe (OK)
val cookies = loginResponse.cookies
val vehiclesResponse = await(WS.url(s"http://localhost:$port/api/v1/vehicles/" + testVin)
.withHeaders("Cookie" -> Cookies.encode(cookies))
.put(""))
vehiclesResponse.status mustBe (OK)
...