Skip to content

Instantly share code, notes, and snippets.

@sadikovi
Created February 25, 2015 09:26
Show Gist options
  • Save sadikovi/a428c6a75d585086db1a to your computer and use it in GitHub Desktop.
Save sadikovi/a428c6a75d585086db1a to your computer and use it in GitHub Desktop.
Another example of Gatling scenario with complex authentication/response processing and number of simple requests that have been used as a test.
package mobilepackage
import io.gatling.core.Predef._
import io.gatling.core.session._
import io.gatling.http.Predef._
import scala.concurrent.duration._
import scala.util.parsing.json._
import general._
class LoginSimulation extends Simulation {
// configure proxy
var httpProxy = Proxy(DomainProxy.host, DomainProxy.port)
// set headers
val sentHeaders = Map(
"User-Agent" -> "Mozilla/5.0 (Windows NT 6.1; WOW64; rv:35.0) Gecko/20100101 Firefox/35.0",
"Accept" -> "application/json, text/javascript, */*; q=0.01",
"Accept-Language" -> "en-US,en;q=0.5",
"DNT" -> "1",
"Connection" -> "keep-alive",
"Pragma" -> "no-cache",
"Cache-Control" -> "no-cache",
"Referer" -> "http://localhost/mobile/controlpanel/"
)
// configure basic http
val httpConf = http
.proxy(httpProxy)
.baseURL("http://localhost")
.headers(sentHeaders)
object Actions {
// fetch token key and number of iterations and store them back in session
def retrieveAuthData(session: Session, datakey: String) : AuthData = {
// get response as a string
var t:String = session.get(datakey).as[String];
// weird bug of the framework on a server that generates json with some strange symbol in the beginning
// remove everything from the beginning of the string to reach first symbol "{"
var altered:String = t.slice(t.indexOfSlice("{"), t.length);
var a:Map[String, Any] = Util.mapFromJsonString(altered);
// retrieve parameters from json
var token:String = a("Token").asInstanceOf[String];
var iterations:Int = a("KeyStrengtheningIterations").asInstanceOf[Double].toInt;
var mobileEncryption:Boolean = a("MobileEncryption").asInstanceOf[Boolean];
return new AuthData(token, iterations, mobileEncryption);
}
// action to prepare data to create a user
def prepare(usertoken: UserToken, authdata: AuthData) : String = {
var a:String = Util.randomName(10);
var b:String = Util.randomName(10);
var json:String = Util.jsonFromMap(Map(
"DocumentType" -> "UserCreateData",
"Username" -> a,
"FirstName" -> a,
"LastName" -> a,
"CompanyName" -> "Cookies",
"Password" -> b,
"Image" -> Util.defaultImageBinaryData(),
"Email" -> "[email protected]",
"Active" -> "true"
));
return MobileEncryption.encryptString(json, usertoken, authdata);
}
}
// create feeder with credentials
val feeder = jsonFile("credentials.json").queue;
// create scenario
object Auth {
var device = new DeviceData();
// pick user from feeder
// and set username, password, and deviceId
var pickUser = feed(feeder)
// init request with feeder
val checkSessionIsOn = exec(
http("check_session_is_on")
.get("http://localhost/mobile/webservices/mobile")
.check(status.is(200))
)
val checkSessionIsOff = exec(
http("check_session_is_off")
.get("http://localhost/mobile/webservices/mobile")
.check(status.is(401))
)
// login chain of requests
val login = tryMax(2) {
exec(
http("requesting_onetime_token")
.post("http://localhost/mobile/webservices/Mobile/core/oneTimeLoginToken")
.headers(Map(
"Accept" -> "application/json, text/javascript, */*; q=0.01",
"Content-Type" -> "application/x-www-form-urlencoded; charset=UTF-8"
)
)
.body(StringBody(
Util.jsonFromMap(Map(
"DocumentType" -> "OneTimeLoginTokenRequestDocument",
"Username" -> "${username}",
"DeviceId" -> "${deviceId}",
"DeviceType" -> device.getType()
))
))
.check(status.is(200))
.check(bodyString.saveAs("mobile_response"))
)
.exec{ session =>
var userToken = new UserToken(
session("username").asOption[String],
session("password").asOption[String]
);
//println(session("username").as[String] + "->" + session("password").as[String])
val authdata = Actions.retrieveAuthData(session, "mobile_response");
val encToken = MobileEncryption.encryptUserToken(userToken, authdata);
session.set("mobile_encryptedUserToken", encToken);
}
.exec(
http("sending_login_token")
.post("http://localhost/mobile/webservices/Mobile/core/sessions")
.body(StringBody(
Util.jsonFromMap(Map(
"DocumentType" -> "SessionCreationDocument",
"Username" -> "${username}",
"UserToken" -> "${mobile_encryptedUserToken}",
"DeviceInformation" -> Map(
"AdditionalInformation" -> device.getAddInfo(),
"DeviceModel" -> device.getVersion().toString,
"DeviceType" -> device.getType(),
"DeviceId" -> "${deviceId}"
)
))
))
.check(status.is(200))
)
.exec(
http("checking_login_success")
.get("http://localhost/mobile/webservices/mobile")
.check(status.is(200))
)
}.exitHereIfFailed
// logout - server side logging out + clearing all the cookies
var logout = exec{ session =>
var usertoken = new UserToken(
session("username").asOption[String],
session("password").asOption[String]
);
val authdata = new AuthData("");
val encToken = MobileEncryption.encryptUserToken(usertoken, authdata);
session.set("mobile_logoutToken", encToken);
}
.exec(
http("logging_out")
.post("http://localhost/mobile/webservices/mobile/core/sessions/current")
.body(StringBody("${mobile_logoutToken}"))
.check(status.is(200))
)
.exec(flushSessionCookies)
}
object Browse {
val serverPage = exec(
http("server_page")
.get("http://localhost/mobile/webservices/controlpanel/Server")
.headers(Map(
"Accept" -> "text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8"
)
)
.check(status.is(200))
)
.pause(5, 15)
val deviceManagement = exec(
http("device_management")
.get("http://localhost/mobile/webservices/controlpanel/DeviceManagement")
.check(status.is(200))
)
.pause(5, 15)
val analytics = exec(
http("analytics")
.get("http://localhost/mobile/webservices/controlpanel/Analytics")
.check(status.is(200))
)
.pause(5, 15)
val accessControl = exec(
http("access_control")
.get("http://localhost/mobile/webservices/controlpanel/AccessControl")
.check(status.is(200))
)
.pause(5, 15)
val userAdministration = exec(
http("user_administration")
.get("http://localhost/mobile/webservices/defaultuserplugin/users")
.check(status.is(200))
)
.pause(5, 15)
val createUser = exec { session =>
var usertoken = new UserToken(session("username").asOption[String], session("password").asOption[String]);
val authdata = Actions.retrieveAuthData(session, "mobile_response");
session.set("mobile_createuser_msg", Actions.prepare(usertoken, authdata))
}
.exec(
http("createUser")
.post("http://localhost/mobile/webservices/defaultuserplugin/users")
.body(StringBody("${mobile_createuser_msg}"))
.check(status.is(200))
)
.pause(5, 15)
}
val analyticsUsers = scenario("Analytics Users")
.exec(Auth.pickUser)
.repeat(8) {
exec(
Auth.checkSessionIsOff,
Auth.login,
Browse.analytics,
Browse.accessControl,
Browse.analytics,
Browse.deviceManagement,
Browse.analytics,
Auth.logout
)
}
val deviceManagementUsers = scenario("Device Management Users")
.exec(Auth.pickUser)
.repeat(8) {
exec(
Auth.checkSessionIsOff,
Auth.login,
Browse.accessControl,
Browse.deviceManagement,
Browse.serverPage,
Browse.deviceManagement,
Browse.userAdministration,
Browse.deviceManagement,
Auth.logout
)
}
val adminUsers = scenario("Admin Users")
.exec(Auth.pickUser)
.repeat(8) {
exec(
Auth.checkSessionIsOff,
Auth.login,
Browse.serverPage,
Browse.accessControl,
Browse.userAdministration,
Browse.deviceManagement,
Browse.serverPage,
Auth.logout
)
}
.repeat(2) {
exec(
Auth.checkSessionIsOff,
Auth.login,
Browse.userAdministration,
Browse.createUser,
Auth.logout
)
}
// set it all up
setUp(
analyticsUsers.inject(
rampUsers(10) over (4 seconds)
),
deviceManagementUsers.inject(
rampUsers(8) over (3 seconds)
),
adminUsers.inject(
nothingFor(3 seconds),
rampUsers(2) over (1 seconds)
)
).protocols(httpConf)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment