Permalink
Browse files

Merge "Update to gatling 1.3.5" into develop

  • Loading branch information...
2 parents 2781ca6 + 65163ec commit c685463f1c67cbb96d285551f81c4cf5bcb48bb9 @dsyer dsyer committed with Gerrit Code Review Nov 27, 2012
View
@@ -8,29 +8,7 @@ perform load or performance testing.
## Usage
-You can run gatling, either using the supplied script, or using the Scala `sbt` build tool. The former is arguably
-simpler to set up, the latter is much faster to run. Using `sbt` is recommended if you intend to run the tests
-regularly.
-
-### Running using the script and a downloaded Gatling bundle
-
-Download and unpack the `gatling-charts-highcharts` bundle,
-[version 1.3.3](https://github.com/downloads/excilys/gatling/gatling-charts-highcharts-1.3.3-bundle.tar.gz).
-Set the `GATLING_HOME` environment variable to point to this directory.
-
-Change to the `uaa/gatling` directory and run the `gatling` script there. It should give you a menu of the available
-simulations:
-
- /Users/luke/Work/uaa/gatling
- GATLING_HOME is set to /Users/luke/Work/tools/gatling-charts-highcharts-1.3.3
- Collecting simulations...
- Choose a simulation number:
- [0] AccountLockoutSimulation
- [1] ScimWorkoutSimulation
- [2] UaaBaseDataCreationSimulation
- [3] UaaSmokeSimulation
- [4] VarzSimulation
-
+The project is designed to run gatling using the Scala `sbt` build tool.
### Targeting a UAA
@@ -66,7 +44,9 @@ Run sbt, and then type the `gatling` command from within the `sbt` console:
The environment variables for the UAA instance can be set as described in the previous section.
To test a UAA instance, first run the `UaaBaseDataCreationSimulation` to populate the system. This only needs to be done
-once. Then try running the `UaaSmokeSimulation` which works out the system using the created data.
+once. Then try running the `UaaSmokeSimulation` which works out the system using the created data. This simulation
+runs for a fixed duration (600 seconds, by default). This can be overridden by setting the `GATLING_DURATION`
+environment variable to the desired number of seconds.
## Customization
@@ -11,7 +11,7 @@ object GatlingPlugin {
val gatlingConfigFile = SettingKey[String]("gatling-config-file")
lazy val gatlingSettings = Seq(
- gatlingVersion := "1.3.3",
+ gatlingVersion := "1.3.5",
fullClasspath in gatling <<= fullClasspath or (fullClasspath in Runtime),
gatlingResultsDirectory <<= target(_.getAbsolutePath + "/gatling-results"),
gatlingDataDirectory <<= (resourceDirectory in Compile).apply(_.getAbsolutePath),
@@ -50,7 +50,7 @@ object UaaGatlingBuild extends Build {
val buildSettings = Defaults.defaultSettings ++ gatlingSettings ++ Seq (
scalaVersion := "2.9.2",
- gatlingVersion := "1.3.3",
+ gatlingVersion := "1.3.5",
version := "0.1-SNAPSHOT",
resolvers ++= Seq(mavenLocalRepo, excilysReleaseRepo, excilys3rdPartyRepo, jenkinsRepo, typesafeRepo, twitterRepo))
@@ -81,6 +81,7 @@ class UaaSmokeSimulation extends Simulation {
.post("/password/score")
.param("password", "sdfghhju")
.check(status is 200, jsonPath("//score") is "1"))
+ .pause(1,5)
}
@@ -22,16 +22,18 @@ import com.excilys.ebi.gatling.http.check.HttpCheck
import com.excilys.ebi.gatling.http.check.HttpExtractorCheckBuilder
import com.excilys.ebi.gatling.http.request.HttpPhase
-import AccessTokenCheckBuilder._
+import OAuthCheckBuilder._
import com.excilys.ebi.gatling.core.action.builder.ActionBuilder
import com.excilys.ebi.gatling.http.response.ExtendedResponse
/**
- * Checks for the presence of an access token in the fragment of the Location header or JSON body
+ * Checks for the presence of an access token or authorization code in the fragment/parameters of the Location header
+ * or in the JSON body
*/
-object AccessTokenCheckBuilder {
- val fragmentTokenPattern = Pattern.compile(".*#.*access_token=([^&]+).*")
- val jsonBodyTokenPattern = Pattern.compile(""""access_token":"(.*?)"""")
+object OAuthCheckBuilder {
+ private val fragmentTokenPattern = Pattern.compile(".*#.*access_token=([^&]+).*")
+ private val jsonBodyTokenPattern = Pattern.compile(""""access_token":"(.*?)"""")
+ private val authorizationCodePattern = Pattern.compile(".*code=([^&]+).*")
def fragmentToken = new FragmentTokenCheckBuilder
@@ -40,6 +42,9 @@ object AccessTokenCheckBuilder {
// Get round Gatling bug #609
def locationHeader = new LocationHeaderCheckBuilder
+ // Allows saving of the auth code. Should only fail if response is a redirect with no auth code in the location
+ def authCode = new AuthCodeCheckBuilder
+
private[uaa] def fragmentExtractorFactory: ExtractorFactory[ExtendedResponse, String, String] = { (response: ExtendedResponse) =>
(expression: String) =>
val location = response.getHeader("Location")
@@ -50,6 +55,16 @@ object AccessTokenCheckBuilder {
} else None
}
+ private[uaa] def authCodeExtractorFactory: ExtractorFactory[ExtendedResponse, String, String] = { (response: ExtendedResponse) =>
+ (expression: String) =>
+ val location = response.getHeader("Location")
+ if (location != null) {
+ val matcher = authorizationCodePattern.matcher(location)
+ if (matcher.find()) Some(matcher.group(1)) else None
+ } else Some("NoLocationNoCode")
+
+ }
+
private[uaa] def jsonExtractorFactory: ExtractorFactory[ExtendedResponse, String, String] = { (response: ExtendedResponse) =>
(expression: String) =>
val matcher = jsonBodyTokenPattern.matcher(response.getResponseBody())
@@ -73,6 +88,10 @@ private[uaa] class JsonTokenCheckBuilder extends HttpExtractorCheckBuilder[Strin
def find = new MatcherCheckBuilder[HttpCheck[String], ExtendedResponse, String, String](httpCheckBuilderFactory, jsonExtractorFactory)
}
+private[uaa] class AuthCodeCheckBuilder extends HttpExtractorCheckBuilder[String,String](s => "", HttpPhase.HeadersReceived) {
+ def find = new MatcherCheckBuilder[HttpCheck[String], ExtendedResponse, String, String](httpCheckBuilderFactory, authCodeExtractorFactory)
+}
+
private[uaa] class LocationHeaderCheckBuilder extends HttpExtractorCheckBuilder[String, String](s => "", HttpPhase.HeadersReceived) {
def find = new MatcherCheckBuilder[HttpCheck[String], ExtendedResponse, String, String](httpCheckBuilderFactory, locationHeaderExtractorFactory)
}
@@ -88,7 +107,7 @@ object OAuthComponents {
"Accept" -> "application/json",
"Content-Type" -> "application/x-www-form-urlencoded")
- private val AuthorizationCode = ".*code=([^&]+).*".r
+ def haveAuthCode: (Session => Boolean) = _.isAttributeDefined("code")
def haveAccessToken : (Session => Boolean) = _.isAttributeDefined("access_token")
@@ -98,16 +117,6 @@ object OAuthComponents {
def statusIs(status:Int) : (Session => Boolean) = _.getAttribute("status").toString.toInt == status
- def extractAuthzCode(s: Session): Session =
- s.getTypedAttribute[String]("location") match {
- case AuthorizationCode(code) =>
-// println("Auth code: " + code)
- s.setAttribute("code", code)
- case l =>
- println("\nLocation '%s' didn't contain an authorization code".format(l))
- s
- }
-
/**
* Performs an oauth token request as the specific client and saves the returned token
* in the client session under the key "access_token".
@@ -185,7 +194,6 @@ object OAuthComponents {
// .queryParam("scope", client.scopes.mkString(" "))
.queryParam("redirect_uri", redirectUri)
.queryParam("response_type", "code")
-// .headers(plainHeaders)
.check(status.is(302)))
.exec(login(username, password))
// .exec((s: Session) => {
@@ -194,18 +202,16 @@ object OAuthComponents {
// s
// })
.exec(
- http("Reload")
+ http("Reload after login")
.get("${location}")
- .check(status.saveAs("status"), saveLocation()))
+ .check(status.saveAs("status"), authCode.saveAs("code")))
.doIf(statusIs(200))(chain.exec( // Not auto-approved, so we do the approval page
http("Authorization Approval")
.post("/oauth/authorize")
.param("user_oauth_approval", "true")
-// .headers(plainHeaders)
- .check(status.is(302), saveLocation())))
- .exec((s: Session) => { extractAuthzCode(s) })
- .exec((s: Session) => { clearCookies(s) })
- .exec(
+ .check(status.is(302), authCode.saveAs("code"))))
+ .exec(clearCookies(_))
+ .doIf(haveAuthCode) { chain.exec(
http("Access Token Request")
.post("/oauth/token")
.basicAuth(client.id, client.secret)
@@ -215,6 +221,7 @@ object OAuthComponents {
.param("grant_type", "authorization_code")
.headers(jsonHeaders)
.check(status.is(200)))
+ }
}

0 comments on commit c685463

Please sign in to comment.