http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/scenarios/GeoScenarios.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/scenarios/GeoScenarios.scala b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/GeoScenarios.scala new file mode 100755 index 0000000..5487cd4 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/GeoScenarios.scala @@ -0,0 +1,49 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.apache.usergrid.scenarios + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ +import org.apache.usergrid.helpers.{Headers, Utils} +import org.apache.usergrid.settings.Settings + +object GeoScenarios { + + val getGeolocation = exec( + http("GET geolocated user") + .get("/users?ql=location%20within%20" + Settings.geoSearchRadius + "%20of%20${latitude},${longitude}") + .headers(Headers.authToken) + + .check(status.is(200)) + ) + + val getGeolocationWithQuery = exec( + http("GET geolocated user with query") + .get("/users?ql=${queryParams}%20AND%20location%20within%20" + Settings.geoSearchRadius + "%20of%20${latitude},${longitude}") + .headers(Headers.authToken) + .check(status.is(200)) + ) + + val updateGeolocation = exec( + http("PUT user location") + .put(_ => "/users/user" + Utils.generateRandomInt(1, Settings.totalUsers)) + .body(StringBody("""{ "location": { "latitude": "${latitude}", "longitude": "${longitude}"} }""")) + .headers(Headers.authToken) + .check(status.is(200)) + ) + +}
http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/scenarios/NotificationScenarios.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/scenarios/NotificationScenarios.scala b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/NotificationScenarios.scala new file mode 100755 index 0000000..1bd2a27 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/NotificationScenarios.scala @@ -0,0 +1,80 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.scenarios + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ +import org.apache.usergrid.helpers.Headers + +import org.apache.usergrid.settings.Settings + + +/** + * + * Creates a new device + * + * Expects: + * + * authToken The auth token to use when creating the application + * orgName The name of the org + * appName The name of the app + * notifierName The name of the created notifier + * deviceName the name of the device created to send the notification to + * + * Produces: + * + * N/A + * + * + */ +object NotificationScenarios { + + val notifier = Settings.pushNotifier + + /** + * send the notification now + */ + val sendNotification = exec(http("Send Single Notification") + .post("/devices/${entityName}/notifications") + .body(StringBody(_ => """{ "payloads": { """" + notifier + """": "testmessage"} }""")) + .headers(Headers.authToken) + .check(status.is(200)) + ) + + val sendNotificationToUser= exec(http("Send Notification to All Devices") + .post("/users/${userId}/notifications") + .body(StringBody(_ => """{ "payloads": {"""" + notifier + """": "testmessage"} }""")) + .headers(Headers.authToken) + .check(status.is(200)) + ) + + + val userFeeder = Settings.getInfiniteUserFeeder + val createScenario = scenario("Create Push Notification") + .feed(userFeeder) + .exec(TokenScenarios.getUserToken) + .exec(UserScenarios.getUserByUsername) + .exec( sendNotificationToUser) + + /** + * TODO: Add posting to users, which would expect a user in the session + */ + + + + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/scenarios/NotifierScenarios.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/scenarios/NotifierScenarios.scala b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/NotifierScenarios.scala new file mode 100755 index 0000000..a16b800 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/NotifierScenarios.scala @@ -0,0 +1,70 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.scenarios + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ +import org.apache.usergrid.helpers.Headers +import org.apache.usergrid.settings.Settings + +/** + * + * Creates a new no-op notifier + * + * + * Expects: + * + * authToken The auth token to use when creating the application + * orgName The name of the org + * appName The name of the app + * + * Produces: + * + * notifierName The name of the created notifier + * + */ +object NotifierScenarios { + + val notifier = Settings.pushNotifier + val provider = Settings.pushProvider + val org = Settings.org + val app = Settings.app + + /** + * Create a notifier + */ + val createNotifier = exec( + session => { + session.set("notifier", notifier) + session.set("provider", provider) + } + ) + + .exec(http("Create Notifier") + .post("/notifiers") + .headers(Headers.authToken) + .body(StringBody(_ => """{ "name": """" + notifier + """", "provider": """" + provider + """"}""")) + .check(status.in(Range(200,400)))) + + val checkNotifier = exec(http("Get Notifier") + .get("/notifiers/"+notifier) + .headers(Headers.authToken) + .check(status.is(200),status.saveAs("notifierStatus")) + ) + + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/scenarios/OrganizationScenarios.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/scenarios/OrganizationScenarios.scala b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/OrganizationScenarios.scala new file mode 100755 index 0000000..d835cf1 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/OrganizationScenarios.scala @@ -0,0 +1,60 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.scenarios + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ +import org.apache.usergrid.datagenerators.FeederGenerator +import org.apache.usergrid.helpers.Headers +import org.apache.usergrid.settings.Settings + +/** + * Performs organization registration + * + * + * Produces: + * + * orgName The name of the created organization + * userName The user name of the admin to log in with + * password The password of the admin to use + */ +object OrganizationScenarios { + + //register the org with the randomly generated org + val createOrgAndAdmin = + exec(http("Create Organization") + .post(_ => Settings.baseUrl + "/management/organizations") + .headers(Headers.authAnonymous) + .body(StringBody(session => """{ "organization": """" + Settings.org + """", "username": """" + Settings.adminUser + """", "name": "${entityName}", "email": "${entityName}@apigee.com", "password":"""" + Settings.adminPassword + """" }""")) + .check(status.in(Range(200,400))) + ) + val createOrgBatch = + feed(FeederGenerator.generateRandomEntityNameFeeder("org", 1)) + .exec(createOrgAndAdmin) + .exec(TokenScenarios.getManagementToken) + .exec(ApplicationScenarios.createApplication) + .exec(NotifierScenarios.createNotifier) + .exec(session => { + // print the Session for debugging, don't do that on real Simulations + // println(session) + session + }) + + val createOrgScenario = scenario("Create org").exec(createOrgBatch) + + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/scenarios/TokenScenarios.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/scenarios/TokenScenarios.scala b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/TokenScenarios.scala new file mode 100755 index 0000000..bfe3064 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/TokenScenarios.scala @@ -0,0 +1,56 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.scenarios + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ +import io.gatling.http.request.StringBody +import org.apache.usergrid.helpers.Headers +import org.apache.usergrid.settings.Settings + + +/** + * Class that will get the token and insert it into the test session. + * Assumes that the following values are present in the session. + * + * Expects: + * + * userName The user name to log in with + * password The password to use + * + * Produces: + * + * authToken A valid access token if the login attempt is successful + */ + +object TokenScenarios { + val getManagementToken = exec(http("POST Org Token") + .post(_ => Settings.baseUrl + "/management/token") + .headers(Headers.authAnonymous) + //pass in the the username and password, store the "access_token" json response element as the var "authToken" in the session + .body(StringBody(_ => """{ "username": """" + Settings.adminUser + """", "password": """" + Settings.adminPassword + """", "grant_type": "password" }""")) + .check(jsonPath("$.access_token").find(0).saveAs("authToken")) + ) + + val getUserToken = + exec( + http("POST user token") + .post("/token") + .body(StringBody("""{ "grant_type": "password", "username": "${username}", "password": "password" }""")) + .check(status.is(200),jsonPath("$..access_token").exists,jsonPath("$..access_token").saveAs("authToken")) + ) +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/scenarios/UserScenarios.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/scenarios/UserScenarios.scala b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/UserScenarios.scala new file mode 100755 index 0000000..39540c6 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/scenarios/UserScenarios.scala @@ -0,0 +1,210 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.usergrid.scenarios + +import io.gatling.core.Predef._ +import io.gatling.http.Predef._ +import io.gatling.http.request.StringBody +import org.apache.usergrid.datagenerators.FeederGenerator +import org.apache.usergrid.settings.Settings +import org.apache.usergrid.helpers.Extractors._ +import org.apache.usergrid.helpers.{Headers, Utils} + + +object UserScenarios { + + /** + * Naming constants used in the scenarios for saving values into the sessions + */ + + //The value for the cursor + val SessionVarCursor: String = "cursor" + + //the value for the json array of users + val SessionVarUsers: String = "users" + + //the value for the users uuid + val SessionVarUserId: String = "userId" + + //the value for HTTP response code after requests + val SessionVarUserStatus: String = "userStatus" + + val getRandomUser = exec( + http("GET user") + .get("/users/user" + Utils.generateRandomInt(1, Settings.numEntities)) + .headers(Headers.authToken) + .check(status.is(200)) + ) + + + val getUserByUsername = exec( + http("GET user") + .get("/users/${username}") + .headers(Headers.authToken) + .check(status.saveAs(SessionVarUserStatus), jsonPath("$..entities[0]").exists, jsonPath("$..entities[0].uuid").exists, jsonPath("$..entities[0].uuid").saveAs(SessionVarUserId)) + ) + + + /** + * Post a user + */ + val postUser = + + exec( + http("POST geolocated Users") + .post("/users") + .body(StringBody( """{"location":{"latitude":"${latitude}","longitude":"${longitude}"},"username":"${username}", + "displayName":"${displayName}","age":"${age}","seen":"${seen}","weight":"${weight}", + "height":"${height}","aboutMe":"${aboutMe}","profileId":"${profileId}","headline":"${headline}", + "showAge":"${showAge}","relationshipStatus":"${relationshipStatus}","ethnicity":"${ethnicity}","password":"password"}""")) + .check(status.saveAs(SessionVarUserStatus)) + .check(status.is(200), jsonPath("$..entities[0].uuid").saveAs(SessionVarUserId)) + ) + + + /** + * Try to get a user, if it returns a 404, create the user + */ + val postUserIfNotExists = + exec(getUserByUsername) + .doIf("${userStatus}", "404") { + exec(postUser) + } + + + val putUser = exec( + http("PUT geolocated Users") + .put("/users/${username}") + .headers(Headers.authToken) + .body(StringBody( """{"location":{"latitude":"${latitude}","longitude":"${longitude}"},"username":"${username}", + "displayName":"${displayName}","age":"${age}","seen":"${seen}","weight":"${weight}", + "height":"${height}","aboutMe":"${aboutMe}","profileId":"${profileId}","headline":"${headline}", + "showAge":"${showAge}","relationshipStatus":"${relationshipStatus}","ethnicity":"${ethnicity}","password":"password"}""")) + .check(status.is(200), jsonPath("$..entities[0].uuid").saveAs(SessionVarUserId)) + + ) + + + val deleteUser = exec( + http("DELETE geolocated Users") + .delete("/users/${username}") + .headers(Headers.authToken) + .check(status.in(Seq(200,404))) + ) + + val deleteUserIfExists = + exec(getUserByUsername) + .doIf("${userStatus}", "200") { + deleteUser + } + + /** + * Get a collection of users without a cursor. Sets the cursor and entities array as "users" + */ + val getUsersWithoutCursor = exec( + http("GET user") + .get("/users") + .headers(Headers.authToken) + .check(status.is(200), maybeExtractEntities(SessionVarUsers), maybeExtractCursor(SessionVarCursor)) + ) + + /** + * Get the next page of users with the cursor, expects the value "cursor" to be present in teh session + */ + //maybe doif for detecting empty session? + val getUsersWithCursor = exec( + http("GET user") + .get("/users?cursor=${" + SessionVarCursor + "}") + .headers(Headers.authToken) + .check(status.is(200), maybeExtractEntities(SessionVarUsers), maybeExtractCursor(SessionVarCursor)) + ) /** + * Debugging block + + .exec(session => { + + val cursor = session.get(SessionVarCursor) + val users = session.get(SessionVarUsers) + + session + }) */ + + + val deleteUserByUsername = exec( + http("DELETE user") + .delete("/users/${username}") + .headers(Headers.authToken) + .check(status.is(200), jsonPath("$..entities[0].uuid").saveAs(SessionVarUserId)) + ) + + /** + * Logs in as the admin user. Checks if a user exists, if not, creates the user + * Logs in as the user, then creates 2 devices if they do not exist + */ + val createUsersWithDevicesScenario = scenario("Create Users") + .feed(Settings.getInfiniteUserFeeder) + .exec(TokenScenarios.getManagementToken) + .exec(UserScenarios.postUserIfNotExists) + .exec(TokenScenarios.getUserToken) + .exec(UserScenarios.getUserByUsername) + .repeat(2) { + feed(FeederGenerator.generateEntityNameFeeder("device", Settings.numDevices)) + .exec(DeviceScenarios.maybeCreateDevices) + } + + /** + * Posts a new user every time + */ + val postUsersInfinitely = scenario("Post Users") + .feed(Settings.getInfiniteUserFeeder) + .exec(postUser) + + + /** + * Puts a new user every time + */ + val putUsersInfinitely = scenario("Put Users").exec(injectManagementTokenIntoSession) + .feed(Settings.getInfiniteUserFeeder) + .exec(putUser) + + /** + * Deletes user every time + */ + val deleteUsersInfinitely = scenario("Delete Users").exec(injectManagementTokenIntoSession) + .feed(Settings.getInfiniteUserFeeder) + .exec(deleteUser) + + /** + * Get the users a page at a time until exhausted + */ + val getUserPagesToEnd = scenario("Get User Pages").exec(injectManagementTokenIntoSession) + //get users without a cursor + .exec(getUsersWithoutCursor) + //as long as we have a cursor, keep getting results + .asLongAs(stringParamExists(SessionVarCursor)) { + exec(getUsersWithCursor) + }.exec(sessionFunction => { + sessionFunction + }) + + val getUsersByUsername = scenario("Get User By Username").exec(injectManagementTokenIntoSession) + .feed(Settings.getInfiniteUserFeeder) + //get users without a cursor + .exec(getUserByUsername) + + + } http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/settings/Settings.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/settings/Settings.scala b/tests/performance/src/main/scala/org/apache/usergrid/settings/Settings.scala new file mode 100755 index 0000000..e27903a --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/settings/Settings.scala @@ -0,0 +1,612 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.settings + +import java.io.{PrintWriter, FileOutputStream} +import java.net.URLDecoder +import java.util +import java.util.concurrent.TimeUnit +import java.util.concurrent.atomic.AtomicInteger +import javax.xml.bind.DatatypeConverter +import io.gatling.http.Predef._ +import io.gatling.core.Predef._ +import io.gatling.http.config.HttpProtocolBuilder +import org.apache.usergrid.datagenerators.FeederGenerator +import org.apache.usergrid.enums._ +import org.apache.usergrid.helpers.Utils +import scala.collection.mutable + +object Settings { + + def initStrSetting(cfg: String): String = { + val setting = System.getProperty(cfg) + + if (setting != null) setting else ConfigProperties.getDefault(cfg).toString + } + + def initBoolSetting(cfg: String): Boolean = { + val strSetting = System.getProperty(cfg) + val default:Boolean = ConfigProperties.getDefault(cfg).asInstanceOf[Boolean] + + if (strSetting != null) { + if (default) // default is true + strSetting.toLowerCase != "false" + else // default is false + strSetting.toLowerCase == "true" + } else { + default + } + } + + def initIntSetting(cfg: String): Int = { + val integerSetting:Integer = Integer.getInteger(cfg) + + if (integerSetting != null) + integerSetting.toInt + else + ConfigProperties.getDefault(cfg).asInstanceOf[Int] + } + + def initLongSetting(cfg: String): Long = { + val longSetting:java.lang.Long = java.lang.Long.getLong(cfg) + + if (longSetting != null) + longSetting.toLong + else + ConfigProperties.getDefault(cfg).asInstanceOf[Long] + } + + // load configuration settings via property or default + val org = initStrSetting(ConfigProperties.Org) + val app = initStrSetting(ConfigProperties.App) + val allApps: Boolean = app == "*" + val adminUser = initStrSetting(ConfigProperties.AdminUser) + val adminPassword = initStrSetting(ConfigProperties.AdminPassword) + + private val cfgBaseUrl = initStrSetting(ConfigProperties.BaseUrl) + val baseUrl = if (cfgBaseUrl.takeRight(1) == "/") cfgBaseUrl.dropRight(1) else cfgBaseUrl + def orgUrl(org: String): String = { + baseUrl + "/" + org + } + def appUrl(app: String): String = { + orgUrl(org) + "/" + app + } + val managementUrl = baseUrl + "/management/organizations" + org + val baseOrgUrl = orgUrl(org) + val baseAppUrl = appUrl(app) + + private def httpConf(baseUrl: String): HttpProtocolBuilder = { + http + .baseURL(baseUrl) + .connection("keep-alive") + .extraInfoExtractor { + i => + if (Settings.printFailedRequests && i.status == io.gatling.core.result.message.KO) { + println(s"==============") + println(s"Request: ${i.request.getMethod} ${i.request.getUrl}") + println(s"body:") + println(s" ${i.request.getStringData}") + println(s"==============") + println(s"Response: ${i.response.statusCode.getOrElse(-1)}") + println(s"body:") + println(s" ${i.response.body.string}") + println(s"==============") + } + Nil + } + } + val httpOrgConf: HttpProtocolBuilder = httpConf(baseOrgUrl) + val httpAppConf: HttpProtocolBuilder = httpConf(baseAppUrl) + val authType = initStrSetting(ConfigProperties.AuthType) + val tokenType = initStrSetting(ConfigProperties.TokenType) + + val skipSetup:Boolean = initBoolSetting(ConfigProperties.SkipSetup) + val createOrg:Boolean = !skipSetup && initBoolSetting(ConfigProperties.CreateOrg) + val createApp:Boolean = !skipSetup && initBoolSetting(ConfigProperties.CreateApp) + val loadEntities:Boolean = !skipSetup && initBoolSetting(ConfigProperties.LoadEntities) + val sandboxCollection:Boolean = initBoolSetting(ConfigProperties.SandboxCollection) + val scenarioType = initStrSetting(ConfigProperties.ScenarioType) + + val rampUsers:Int = initIntSetting(ConfigProperties.RampUsers) + val constantUsersPerSec:Int = initIntSetting(ConfigProperties.ConstantUsersPerSec) // users to add per second during constant injection + val constantUsersDuration:Int = initIntSetting(ConfigProperties.ConstantUsersDuration) // number of seconds + val totalUsers:Int = rampUsers + (constantUsersPerSec * constantUsersDuration) + val userSeed:Int = initIntSetting(ConfigProperties.UserSeed) + val appUser = initStrSetting(ConfigProperties.AppUser) + val appUserPassword = initStrSetting(ConfigProperties.AppUserPassword) + + // val appUserBase64 = Base64.getEncoder.encodeToString((appUser + ":" + appUserPassword).getBytes(StandardCharsets.UTF_8)) + val appUserBase64: String = DatatypeConverter.printBase64Binary((appUser + ":" + appUserPassword).getBytes("UTF-8")) + + val totalNumEntities:Int = initIntSetting(ConfigProperties.NumEntities) + val numDevices:Int = initIntSetting(ConfigProperties.NumDevices) + + val collection = initStrSetting(ConfigProperties.Collection) + val baseCollectionUrl = baseAppUrl + "/" + collection + + val rampTime:Int = initIntSetting(ConfigProperties.RampTime) // in seconds + val throttle:Int = initIntSetting(ConfigProperties.Throttle) // in seconds + val holdDuration:Int = initIntSetting(ConfigProperties.HoldDuration) // in seconds + + // Geolocation settings + val centerLatitude:Double = 37.442348 // latitude of center point + val centerLongitude:Double = -122.138268 // longitude of center point + val userLocationRadius:Double = 32000 // location of requesting user in meters + val geoSearchRadius:Int = 8000 // search area in meters + + // Push Notification settings + val pushNotifier = initStrSetting(ConfigProperties.PushNotifier) + val pushProvider = initStrSetting(ConfigProperties.PushProvider) + + // Large Entity Collection settings + val entityPrefix = initStrSetting(ConfigProperties.EntityPrefix) + val entityType = initStrSetting(ConfigProperties.EntityType) // basic/trivial/? + val overallEntitySeed = initIntSetting(ConfigProperties.EntitySeed) + val searchLimit:Int = initIntSetting(ConfigProperties.SearchLimit) + val searchQuery = initStrSetting(ConfigProperties.SearchQuery) + val endConditionType = initStrSetting(ConfigProperties.EndConditionType) + val endMinutes:Int = initIntSetting(ConfigProperties.EndMinutes) + val endRequestCount:Int = initIntSetting(ConfigProperties.EndRequestCount) + + // Org creation fields + private val cfgOrgCreationUsername = initStrSetting(ConfigProperties.OrgCreationUsername) + private val cfgOrgCreationEmail = initStrSetting(ConfigProperties.OrgCreationEmail) + private val cfgOrgCreationName = initStrSetting(ConfigProperties.OrgCreationName) + val orgCreationUsername = if (cfgOrgCreationUsername == "") org.concat("_admin") else cfgOrgCreationUsername + val orgCreationEmail = if (cfgOrgCreationEmail == "") orgCreationUsername.concat("@usergrid.com") else cfgOrgCreationEmail + val orgCreationName = if (cfgOrgCreationName == "") orgCreationUsername else cfgOrgCreationName + val orgCreationPassword = initStrSetting(ConfigProperties.OrgCreationPassword) + + val retryCount:Int = initIntSetting(ConfigProperties.RetryCount) + val laterThanTimestamp:Long = initLongSetting(ConfigProperties.LaterThanTimestamp) + val entityProgressCount:Long = initLongSetting(ConfigProperties.EntityProgressCount) + private val logEntityProgress: Boolean = entityProgressCount > 0L + val injectionList = initStrSetting(ConfigProperties.InjectionList) + val printFailedRequests:Boolean = initBoolSetting(ConfigProperties.PrintFailedRequests) + val getViaQuery:Boolean = initBoolSetting(ConfigProperties.GetViaQuery) + private val queryParamConfig = initStrSetting(ConfigProperties.QueryParams) + val queryParamMap: Map[String,String] = mapFromQueryParamConfigString(queryParamConfig) + val csvFeedPattern = initStrSetting(ConfigProperties.CsvFeedPattern) + val flushCsv:Long = initLongSetting(ConfigProperties.FlushCsv) + val unlimitedFeed:Boolean = initBoolSetting(ConfigProperties.UnlimitedFeed) + // unlimited feed forces interleaved worker feed + val interleavedWorkerFeed:Boolean = if (unlimitedFeed) true else initBoolSetting(ConfigProperties.InterleavedWorkerFeed) + val newCsvOnFlush:Boolean = initBoolSetting(ConfigProperties.NewCsvOnFlush) + val deleteAfterSuccessfulAudit:Boolean = initBoolSetting(ConfigProperties.DeleteAfterSuccessfulAudit) + val usergridRegion = initStrSetting(ConfigProperties.UsergridRegion) + val saveInvalidResponse = initBoolSetting(ConfigProperties.SaveInvalidResponse) + + val multiPropertyPrefix = initStrSetting(ConfigProperties.MultiPropertyPrefix) + val multiPropertyCount:Int = initIntSetting(ConfigProperties.MultiPropertyCount) + val multiPropertySizeInK:Int = initIntSetting(ConfigProperties.MultiPropertySizeInK) + val entityNumberProperty = initStrSetting(ConfigProperties.EntityNumberProperty) + + // Entity update + val updateProperty = initStrSetting(ConfigProperties.UpdateProperty) + val updateValue = initStrSetting(ConfigProperties.UpdateValue) + val updateBody = Utils.toJSONStr(Map(updateProperty -> updateValue)) + + // Entity workers + private val cfgEntityWorkerCount:Int = initIntSetting(ConfigProperties.EntityWorkerCount) + private val cfgEntityWorkerNum:Int = initIntSetting(ConfigProperties.EntityWorkerNum) + val useWorkers:Boolean = cfgEntityWorkerCount > 1 && cfgEntityWorkerNum >= 1 && cfgEntityWorkerNum <= cfgEntityWorkerCount + val entityWorkerCount:Int = if (useWorkers) cfgEntityWorkerCount else 1 + val entityWorkerNum:Int = if (useWorkers) cfgEntityWorkerNum else 1 + + // if only one worker system, these numbers will still be fine + private val entitiesPerWorkerFloor:Int = totalNumEntities / entityWorkerCount + private val leftOver:Int = totalNumEntities % entityWorkerCount // will be 0 if only one worker + private val extraEntity:Int = if (entityWorkerNum <= leftOver) 1 else 0 + private val zeroBasedWorkerNum:Int = entityWorkerNum - 1 + val entitySeed:Int = if (unlimitedFeed) overallEntitySeed else overallEntitySeed + zeroBasedWorkerNum * entitiesPerWorkerFloor + (if (extraEntity == 1) zeroBasedWorkerNum else leftOver) + // numEntities is used for random name generation, must be >= 0 even if not used for entity counting (as in unlimitedFeed=true) + val numEntities:Int = if (unlimitedFeed) 1000000000 else entitiesPerWorkerFloor + extraEntity + + // UUID log file, have to go through this because creating a csv feeder with an invalid csv file fails at maven compile time + private val dummyTestCsv = ConfigProperties.getDefault(ConfigProperties.UuidFilename).toString + private val dummyAuditCsv = ConfigProperties.getDefault(ConfigProperties.AuditUuidFilename).toString + private val dummyAuditFailedCsv = ConfigProperties.getDefault(ConfigProperties.FailedUuidFilename).toString + private val dummyCaptureCsv = "/tmp/notused.csv" + + private val uuidFilename = initStrSetting(ConfigProperties.UuidFilename) + private val auditUuidFilename = initStrSetting(ConfigProperties.AuditUuidFilename) + private val failedUuidFilename = initStrSetting(ConfigProperties.FailedUuidFilename) + + // feeds require valid files, even if test won't be run + val feedUuids = scenarioType match { + case ScenarioType.UuidRandomInfinite => true + case _ => false + } + val feedUuidFilename = scenarioType match { + case ScenarioType.UuidRandomInfinite => uuidFilename + case _ => dummyTestCsv + } + if (feedUuids && feedUuidFilename == dummyTestCsv) { + println("Scenario requires CSV file containing UUIDs") + System.exit(1) + } + + val feedAuditUuids = scenarioType match { + case ScenarioType.AuditVerifyCollectionEntities => true + case _ => false + } + val feedAuditUuidFilename = scenarioType match { + case ScenarioType.AuditVerifyCollectionEntities => auditUuidFilename + case _ => dummyAuditCsv + } + if (feedAuditUuids && feedAuditUuidFilename == dummyAuditCsv) { + println("Scenario requires CSV file containing audit UUIDs") + System.exit(1) + } + + val captureUuidFilename = scenarioType match { + case ScenarioType.LoadEntities => uuidFilename + case ScenarioType.GetByNameSequential => uuidFilename + case _ => dummyCaptureCsv // won't write to this file + } + val captureUuids = if (captureUuidFilename == dummyCaptureCsv) false + else scenarioType match { + case ScenarioType.LoadEntities => true + case ScenarioType.GetByNameSequential => true + case _ => false + } + + val captureAuditUuidFilename = scenarioType match { + case ScenarioType.AuditGetCollectionEntities => auditUuidFilename + case ScenarioType.AuditVerifyCollectionEntities => failedUuidFilename + case _ => dummyCaptureCsv // won't write to this file + } + if (scenarioType == ScenarioType.AuditGetCollectionEntities && captureAuditUuidFilename == dummyCaptureCsv) { + println("Scenario requires CSV file location to capture audit UUIDs") + System.exit(1) + } + val captureAuditUuids = (scenarioType == ScenarioType.AuditGetCollectionEntities) || + (scenarioType == ScenarioType.AuditVerifyCollectionEntities && captureAuditUuidFilename != dummyAuditFailedCsv) + + /* + println(s"feedUuids=$feedUuids") + println(s"feedUuidFilename=$feedUuidFilename") + println(s"feedAuditUuids=$feedAuditUuids") + println(s"feedAuditUuidFilename=$feedAuditUuidFilename") + println(s"captureUuids=$captureUuids") + println(s"captureUuidFilename=$captureUuidFilename") + println(s"captureAuditUuids=$captureAuditUuids") + println(s"captureAuditUuidFilename=$captureAuditUuidFilename") + */ + + val purgeUsers:Int = initIntSetting(ConfigProperties.PurgeUsers) + + val uuidsHeader = "collection,name,uuid,modified,status" + val uuidsFailHeader = "collection,name,uuid,modified,status,error,lastStatus" + case class AuditList(var collection: String, var entityName: String, var uuid: String, var modified: Long, var status: Int) + case class AuditFailList(var collection: String, var entityName: String, var uuid: String, var modified: Long, + var status: Int, var error: String, var lastStatus: String) + + //private var uuidMap: Map[Int, String] = Map() + private var uuidList: mutable.MutableList[AuditList] = mutable.MutableList[AuditList]() + private val statusCounts: mutable.Map[Int,Long] = mutable.Map[Int,Long]().withDefaultValue(0L) + private var entityCounter: Long = 0L + private var lastEntityCountPrinted: Long = 0L + private var flushCounter: Long = 0L + private var firstFlush: Boolean = true + private var numberFlushes: Long = 0L + private var uuidWriter: PrintWriter = null + + def addStatus(status: Int): Unit = { + statusCounts.synchronized { + statusCounts(status) += 1L + } + } + + def addUuid(uuid: String, collection: String, entityName: String, modified: Long, status: Int): Unit = { + if (captureUuids) { + uuidList.synchronized { + uuidList += AuditList(collection, entityName, uuid, modified, status) + entityCounter += 1L + flushCounter += 1L + if (logEntityProgress && (entityCounter >= lastEntityCountPrinted + entityProgressCount)) { + println(s"Entity: $entityCounter") + lastEntityCountPrinted = entityCounter + } + if (flushCsv > 0 && flushCounter >= flushCsv) { + if (uuidWriter == null) { + uuidWriter = { + val fileWithSuffix = f"$captureUuidFilename.$numberFlushes%04d" + val fos = new FileOutputStream(if (newCsvOnFlush) fileWithSuffix else captureUuidFilename) + new PrintWriter(fos, false) + } + } + if (newCsvOnFlush || firstFlush) { + uuidWriter.println(uuidsHeader) + } + val sortedUuidList: List[AuditList] = uuidList.toList.sortBy(e => (e.collection, e.entityName, e.modified)) + sortedUuidList.foreach { e => + uuidWriter.println(s"${e.collection},${e.entityName},${e.uuid},${e.modified},${e.status}") + } + uuidWriter.flush() + if (newCsvOnFlush) { + uuidWriter.close() + uuidWriter = null + } + flushCounter = 0L + numberFlushes += 1L + uuidList.clear() + firstFlush = false + } + } + } + // println(s"UUID: ${name},${uuid}") + } + + def writeUuidsToFile(): Unit = { + if (captureUuids) { + if (uuidWriter == null) { + uuidWriter = { + val fileWithSuffix = f"$captureUuidFilename.$numberFlushes%04d" + val fos = new FileOutputStream(if (newCsvOnFlush) fileWithSuffix else captureUuidFilename) + new PrintWriter(fos, false) + } + } + if (newCsvOnFlush || firstFlush) { + uuidWriter.println(uuidsHeader) + } + val sortedUuidList: List[AuditList] = uuidList.toList.sortBy(e => (e.collection, e.entityName, e.modified)) + sortedUuidList.foreach { e => + uuidWriter.println(s"${e.collection},${e.entityName},${e.uuid},${e.modified},${e.status}") + } + uuidWriter.flush() + uuidWriter.close() + numberFlushes += 1L + uuidList.clear() + firstFlush = false + } + } + + + + // key: uuid, value: collection + private var auditEntityCounter: Long = 0L + private var lastAuditEntityCountPrinted: Long = 0L + private var auditUuidList: mutable.MutableList[AuditFailList] = mutable.MutableList[AuditFailList]() + def addAuditUuid(uuid: String, collection: String, entityName: String, modified: Long, status: Int, error: String, + lastStatus: String): Unit = { + if (captureAuditUuids) { + auditUuidList.synchronized { + auditUuidList += AuditFailList(collection, entityName, uuid, modified, status, error, lastStatus) + auditEntityCounter += 1L + if (logEntityProgress && (auditEntityCounter >= lastAuditEntityCountPrinted + entityProgressCount)) { + println(s"Entity: $auditEntityCounter") + lastAuditEntityCountPrinted = auditEntityCounter + } + } + } + } + + def writeAuditUuidsToFile(uuidDesc: String): Unit = { + if (captureAuditUuids) { + println(s"Sorting and writing ${auditUuidList.size} $uuidDesc UUIDs in CSV file $captureAuditUuidFilename") + val writer = { + val fos = new FileOutputStream(captureAuditUuidFilename) + new PrintWriter(fos, false) + } + writer.println(uuidsFailHeader) + val uuidList: List[AuditFailList] = auditUuidList.toList.sortBy(e => (e.collection, e.entityName, e.modified, e.status)) + uuidList.foreach { e => + writer.println(s"${e.collection},${e.entityName},${e.uuid},${e.modified},${e.status},${e.error},${e.lastStatus}") + } + writer.flush() + writer.close() + } + } + + def getUserFeeder:Array[Map[String, String]]= { + FeederGenerator.generateUserWithGeolocationFeeder(totalUsers, userLocationRadius, centerLatitude, centerLongitude) + } + + def getInfiniteUserFeeder:Iterator[Map[String, String]]= { + FeederGenerator.generateUserWithGeolocationFeederInfinite(userSeed, userLocationRadius, centerLatitude, centerLongitude) + } + + private var testStartTime: Long = System.currentTimeMillis() + private var testEndTime: Long = 0 + + def getTestStartTime: Long = { + testStartTime + } + + def setTestStartTime(): Unit = { + testStartTime = System.currentTimeMillis() + } + + def setTestEndTime(): Unit = { + testEndTime = System.currentTimeMillis() + } + + def continueMinutesTest: Boolean = { + (System.currentTimeMillis() - testStartTime) < (endMinutes.toLong*60L*1000L) + } + + private val countAuditSuccess = new AtomicInteger(0) + private val countAuditNotFoundViaQuery = new AtomicInteger(0) + private val countAuditNotFoundAtAll = new AtomicInteger(0) + private val countAuditBadResponse = new AtomicInteger(0) + private val countAuditPayloadUuidError = new AtomicInteger(0) + private val countAuditPayloadNameError = new AtomicInteger(0) + private val countAuditEntryDeleteSuccess = new AtomicInteger(0) + private val countAuditEntryDeleteFailure = new AtomicInteger(0) + + def incAuditSuccess(): Unit = { + countAuditSuccess.incrementAndGet() + } + + def incAuditNotFoundViaQuery(): Unit = { + countAuditNotFoundViaQuery.incrementAndGet() + } + + def incAuditNotFoundAtAll(): Unit = { + countAuditNotFoundAtAll.incrementAndGet() + } + + def incAuditBadResponse(): Unit = { + countAuditBadResponse.incrementAndGet() + } + + def incAuditPayloadUuidError(): Unit = { + countAuditPayloadUuidError.incrementAndGet() + } + + def incAuditPayloadNameError(): Unit = { + countAuditPayloadNameError.incrementAndGet() + } + + def incAuditEntryDeleteSuccess(): Unit = { + countAuditEntryDeleteSuccess.incrementAndGet() + } + + def incAuditEntryDeleteFailure(): Unit = { + countAuditEntryDeleteFailure.incrementAndGet() + } + + def printAuditResults(): Unit = { + if (scenarioType == ScenarioType.AuditVerifyCollectionEntities) { + val countSuccess = countAuditSuccess.get + val countNotFoundViaQuery = countAuditNotFoundViaQuery.get + val countNotFoundAtAll = countAuditNotFoundAtAll.get + val countBadResponse = countAuditBadResponse.get + val countPayloadUuidErrors = countAuditPayloadUuidError.get + val countPayloadNameErrors = countAuditPayloadNameError.get + val countDeleteSuccess = countAuditEntryDeleteSuccess.get + val countDeleteFailure = countAuditEntryDeleteFailure.get + val countTotal = countSuccess + countNotFoundViaQuery + countBadResponse + + val seconds = ((testEndTime - testStartTime) / 1000).toInt + val s:Int = seconds % 60 + val m:Int = (seconds/60) % 60 + val h:Int = seconds/(60*60) + val elapsedStr = f"$h%d:$m%02d:$s%02d" + + println() + println("-----------------------------------------------------------------------------") + println("AUDIT RESULTS") + println("-----------------------------------------------------------------------------") + println() + println(s"Successful: $countSuccess") + println(s"Not Found via query: $countNotFoundViaQuery (found via direct access)") + println(s"Not Found at all: $countNotFoundAtAll") + println(s"Bad Response: $countBadResponse") + if (deleteAfterSuccessfulAudit) { + println() + println(s"Delete Successes: $countDeleteSuccess") + println(s"Delete Failures: $countDeleteFailure") + } + if (countPayloadUuidErrors > 0 || countPayloadNameErrors > 0) { + println() + println(s"Payload Mismatches/Errors") + println(s" UUID: $countPayloadUuidErrors") + println(s" Name: $countPayloadNameErrors") + } + println(s"Total: $countTotal") + println() + println(s"Start Timestamp(ms): $testStartTime") + println(s"End Timestamp(ms): $testEndTime") + println(s"Elapsed Time: $elapsedStr") + println() + println("-----------------------------------------------------------------------------") + println() + } + } + + def printSettingsSummary(afterTest: Boolean): Unit = { + val authTypeStr = authType + (if (authType == AuthType.Token) s"($tokenType)" else "") + val endConditionStr = if (endConditionType == EndConditionType.MinutesElapsed) s"$endMinutes minutes elapsed" else s"$endRequestCount requests" + val seconds = ((testEndTime - testStartTime) / 1000).toInt + val s:Int = seconds % 60 + val m:Int = (seconds/60) % 60 + val h:Int = seconds/(60*60) + val elapsedStr = f"$h%d:$m%02d:$s%02d" + println() + println("-----------------------------------------------------------------------------") + println("SIMULATION SETTINGS") + println("-----------------------------------------------------------------------------") + println() + println(s"ScenarioType:$scenarioType AuthType:$authTypeStr") + println() + println(s"BaseURL:$baseUrl") + println(s"Org:$org App:$app Collection:$collection") + println(s"CreateOrg:$createOrg CreateApp:$createApp LoadEntities:$loadEntities") + println(s"SandboxCollection:$sandboxCollection SkipSetup:$skipSetup") + println(s"AuthType:$authType TokenType:$tokenType AdminUser:$adminUser") + println() + println(s"EntityType:$entityType Prefix:$entityPrefix RetryCount:$retryCount") + if (scenarioType == ScenarioType.AuditGetCollectionEntities && laterThanTimestamp > 0) { + if (laterThanTimestamp > 0) println(s"SearchLimit:$searchLimit OnlyForEntriesAtOrLater:$laterThanTimestamp") + } else { + println(s"SearchLimit:$searchLimit SearchQuery:$searchQuery") + } + if (queryParamConfig != "") println(s"Extra query params: $queryParamConfig") + println() + println(s"Overall: NumEntities:$totalNumEntities Seed:$overallEntitySeed Workers:$entityWorkerCount") + println(s"Worker: NumEntities:$numEntities Seed:$entitySeed WorkerNum:$entityWorkerNum") + println() + println(s"Ramp: Users:$rampUsers Time:$rampTime") + println(s"Constant: UsersPerSec:$constantUsersPerSec Time:$constantUsersDuration") + println(s"EndCondition:$endConditionStr") + println() + if (feedUuids) { + println(s"Feed CSV: $feedUuidFilename") + println(s"Feed pattern: $csvFeedPattern") + } + if (feedAuditUuids) println(s"Audit Feed CSV: $feedAuditUuidFilename") + if (captureUuids) println(s"Capture CSV:$captureUuidFilename") + if (captureAuditUuids) { + if (scenarioType == ScenarioType.AuditVerifyCollectionEntities) + println(s"Audit Capture CSV (failed entities):$captureAuditUuidFilename") + else + println(s"Audit Capture CSV:$captureAuditUuidFilename") + } + println() + println() + if (afterTest) { + println(s"TestStarted:$testStartTime TestEnded:$testEndTime Elapsed: $elapsedStr") + } else { + println(s"TestStarted:$testStartTime") + } + println() + println("-----------------------------------------------------------------------------") + println() + } + + def mapFromQueryParamConfigString(queryParamConfigString: String): Map[String,String] = { + val params = mutable.Map[String,String]() + val paramStrings:Array[String] = queryParamConfigString split "&" + for (i <- paramStrings.indices) { + val param = paramStrings(i) + val pair = param split "=" + val key = URLDecoder.decode(pair(0), "UTF-8") + val value = pair.length match { + case l if l > 1 => URLDecoder.decode(pair(1), "UTF-8") + case _ => "" + } + params(key) = value + println(s"QueryParam $key = $value") + } + params.toMap + } + + printSettingsSummary(false) + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/AuditSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/AuditSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/AuditSimulation.scala new file mode 100755 index 0000000..ac900fd --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/AuditSimulation.scala @@ -0,0 +1,86 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.simulations + +import io.gatling.core.Predef._ +import io.gatling.core.structure.ScenarioBuilder +import io.gatling.http.config.HttpProtocolBuilder +import org.apache.usergrid.enums.ScenarioType +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.{AuditScenarios, EntityCollectionScenarios} +import org.apache.usergrid.settings.Settings + +/** + * Audit simulations. + * + */ +class AuditSimulation extends Simulation { + + def getScenario(scenarioType: String): ScenarioBuilder = { + scenarioType match { + case ScenarioType.AuditGetCollectionEntities => AuditScenarios.getAllCollections + case ScenarioType.AuditVerifyCollectionEntities => AuditScenarios.verifyAuditedEntities + case ScenarioType.AuditDeleteEntities => AuditScenarios.deleteAuditedEntities + } + } + + before{ + Settings.setTestStartTime() + } + + if (ScenarioType.isValid(Settings.scenarioType)) { + val scenario: ScenarioBuilder = getScenario(Settings.scenarioType) + val httpConf: HttpProtocolBuilder = Settings.httpOrgConf + .acceptHeader("application/json") + + setUp( + scenario + .inject( + rampUsers(Settings.rampUsers) over Settings.rampTime + ).protocols(httpConf) + ) + } else { + println(s"Audit scenario type ${Settings.scenarioType} not found.") + } + + after { + endHandler + } + + def endHandler: Unit = { + Settings.setTestEndTime() + if (Settings.captureAuditUuids) { + val uuidDesc = Settings.scenarioType match { + case ScenarioType.AuditGetCollectionEntities => "found" + case ScenarioType.AuditVerifyCollectionEntities => "failed" + case ScenarioType.AuditDeleteEntities => "failed" + } + Settings.writeAuditUuidsToFile(uuidDesc) + } + Settings.printSettingsSummary(true) + Settings.printAuditResults() + } + + def abortedEarly: Unit = { + println(">>>>>>>>>>>>AUDIT ABORTED") + endHandler + } + + sys addShutdownHook abortedEarly + +} + http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/ConfigurableSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/ConfigurableSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/ConfigurableSimulation.scala new file mode 100755 index 0000000..a3eb595 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/ConfigurableSimulation.scala @@ -0,0 +1,105 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.simulations + +import io.gatling.core.Predef._ +import io.gatling.core.controller.inject.InjectionStep +import io.gatling.core.structure.ScenarioBuilder +import org.apache.usergrid.enums.ScenarioType +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.EntityCollectionScenarios +import org.apache.usergrid.settings.Settings + +import scala.collection.mutable + +/** + * Configurable simulations. + * + * Configuration items: + * skipSetup, createOrg, org, createApp, app, adminUser, adminPassword, baseUrl, + * numEntities, entityType, entityPrefix, entitySeed, rampUsers, rampTime, + * constantUsersPerSec, constantUsersDuration, collection, scenarioType + * + * getAllByCursor scenario: searchQuery, searchLimit + */ +class ConfigurableSimulation extends Simulation { + + def getScenario(scenarioType: String): ScenarioBuilder = { + scenarioType match { + case ScenarioType.LoadEntities => EntityCollectionScenarios.loadEntities + case ScenarioType.DeleteEntities => EntityCollectionScenarios.deleteEntities + case ScenarioType.UpdateEntities => EntityCollectionScenarios.updateEntities + case ScenarioType.GetAllByCursor => EntityCollectionScenarios.getEntityPagesToEnd + case ScenarioType.NameRandomInfinite => EntityCollectionScenarios.getRandomEntitiesByName + case ScenarioType.UuidRandomInfinite => EntityCollectionScenarios.getRandomEntitiesByUuid + case ScenarioType.GetByNameSequential => EntityCollectionScenarios.getEntitiesByNameSequential + case ScenarioType.DoNothing => EntityCollectionScenarios.doNothing + case _ => null + } + } + + before{ + if (!Settings.skipSetup) { + println("Begin setup") + if (Settings.createOrg) Setup.setupOrg() + if (Settings.createApp) Setup.setupApplication() + if (Settings.loadEntities) Setup.setupEntitiesCollection(Settings.numEntities, Settings.entityType, Settings.entityPrefix, Settings.entitySeed) + } else { + println("Skipping setup") + } + if (Settings.sandboxCollection) Setup.sandboxCollection() + Settings.setTestStartTime() + } + + if (ScenarioType.isValid(Settings.scenarioType)) { + val scenario: ScenarioBuilder = getScenario(Settings.scenarioType) + var stepCount:Int = 0 + if (Settings.rampUsers > 0) stepCount += 1 + if (Settings.constantUsersPerSec > 0) stepCount += 1 + val injectStepList = new mutable.ArraySeq[InjectionStep](stepCount) + var currentStep = 0 + if (Settings.rampUsers > 0) { + injectStepList(currentStep) = rampUsers(Settings.rampUsers) over Settings.rampTime + currentStep += 1 + } + if (Settings.constantUsersPerSec > 0) { + injectStepList(currentStep) = constantUsersPerSec(Settings.constantUsersPerSec) during Settings.constantUsersDuration + currentStep += 1 + } + setUp( + scenario + .inject(injectStepList) + .protocols(Settings.httpAppConf.connection("keep-alive").acceptHeader("application/json")) + ) + } else { + println(s"scenarioType ${Settings.scenarioType} not found.") + } + + after { + endHandler + } + + def endHandler: Unit = { + Settings.setTestEndTime() + if (Settings.captureUuids) Settings.writeUuidsToFile() + Settings.printSettingsSummary(true) + } + + sys addShutdownHook endHandler + +} + http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/CustomInjectionSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/CustomInjectionSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/CustomInjectionSimulation.scala new file mode 100755 index 0000000..fe0fc43 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/CustomInjectionSimulation.scala @@ -0,0 +1,107 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.simulations + +import io.gatling.core.Predef._ +import io.gatling.core.controller.inject.InjectionStep +import io.gatling.core.structure.ScenarioBuilder +import org.apache.usergrid.enums.ScenarioType +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.EntityCollectionScenarios +import org.apache.usergrid.settings.Settings + +import scala.collection.mutable + +/** + * Simulations with custom injection. + */ +class CustomInjectionSimulation extends Simulation { + + def getScenario(scenarioType: String): ScenarioBuilder = { + scenarioType match { + case ScenarioType.LoadEntities => EntityCollectionScenarios.loadEntities + case ScenarioType.DeleteEntities => EntityCollectionScenarios.deleteEntities + case ScenarioType.UpdateEntities => EntityCollectionScenarios.updateEntities + case ScenarioType.GetAllByCursor => EntityCollectionScenarios.getEntityPagesToEnd + case ScenarioType.NameRandomInfinite => EntityCollectionScenarios.getRandomEntitiesByName + case ScenarioType.UuidRandomInfinite => EntityCollectionScenarios.getRandomEntitiesByUuid + case ScenarioType.GetByNameSequential => EntityCollectionScenarios.getEntitiesByNameSequential + case _ => null + } + } + + before{ + if (!Settings.skipSetup) { + println("Begin setup") + if (Settings.createOrg) Setup.setupOrg() + if (Settings.createApp) Setup.setupApplication() + if (Settings.loadEntities) Setup.setupEntitiesCollection(Settings.numEntities, Settings.entityType, Settings.entityPrefix, Settings.entitySeed) + } else { + println("Skipping setup") + } + if (Settings.sandboxCollection) Setup.sandboxCollection() + Settings.setTestStartTime() + } + + if (ScenarioType.isValid(Settings.scenarioType)) { + val scenario: ScenarioBuilder = getScenario(Settings.scenarioType) + + val injectionList:String = Settings.injectionList + val injectStepsArray:Array[String] = injectionList.split("\\s*;\\s*") + val injectStepList:mutable.ArraySeq[InjectionStep] = new mutable.ArraySeq[InjectionStep](injectStepsArray.length) + for (i <- injectStepsArray.indices) { + val injectionStep = injectStepsArray(i).trim + println(injectionStep) + val stepRegex = """(.+)\((.*)\)""".r + val stepRegex(stepType,stepArgsStr) = injectionStep + println(s"stepType:$stepType stepArgs:$stepArgsStr") + val stepArgs = stepArgsStr.split("\\s*,\\s*") + injectStepList(i) = stepType match { + case "rampUsers" => rampUsers(stepArgs(0).toInt) over stepArgs(1).toInt + case "constantUsersPerSec" => constantUsersPerSec(stepArgs(0).toDouble) during stepArgs(1).toInt + case "constantUsersPerSecRandomized" => constantUsersPerSec(stepArgs(0).toDouble) during stepArgs(1).toInt randomized + case "atOnceUsers" => atOnceUsers(stepArgs(0).toInt) + case "rampUsersPerSec" => rampUsersPerSec(stepArgs(0).toDouble) to stepArgs(1).toInt during stepArgs(2).toInt + case "rampUsersPerSecRandomized" => rampUsersPerSec(stepArgs(0).toDouble) to stepArgs(1).toInt during stepArgs(2).toInt randomized + case "heavisideUsers" => heavisideUsers(stepArgs(0).toInt) over stepArgs(1).toInt + case "nothingFor" => nothingFor(stepArgs(0).toInt) + } + } + + setUp( + scenario + .inject(injectStepList) + .protocols(Settings.httpAppConf.connection("keep-alive").acceptHeader("application/json")) + ) + } else { + println(s"scenarioType ${Settings.scenarioType} not found.") + } + + after { + endHandler + } + + def endHandler: Unit = { + Settings.setTestEndTime() + if (Settings.captureUuids) Settings.writeUuidsToFile() + Settings.printSettingsSummary(true) + } + + sys addShutdownHook(endHandler) + +} + http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/AppSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/AppSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/AppSimulation.scala new file mode 100644 index 0000000..d113c87 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/AppSimulation.scala @@ -0,0 +1,41 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ + +package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import io.gatling.core.scenario.Simulation +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.NotificationScenarios +import org.apache.usergrid.settings.Settings + +import scala.concurrent.duration._ + +class AppSimulation extends Simulation { + println("Begin setup") + Setup.setupNotifier() + println("End Setup") + + setUp( + NotificationScenarios.createScenario + .inject(constantUsersPerSec(Settings.constantUsersPerSec) during (Settings.constantUsersDuration)) + .protocols(Settings.httpAppConf.acceptHeader("application/json")) + ).throttle(reachRps(Settings.throttle) in (Settings.rampTime seconds), holdFor(Settings.holdDuration)) +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/ConnectionsSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/ConnectionsSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/ConnectionsSimulation.scala new file mode 100644 index 0000000..86a5c11 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/ConnectionsSimulation.scala @@ -0,0 +1,51 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ + +package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import io.gatling.core.scenario.Simulation +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.ConnectionScenarios +import org.apache.usergrid.settings.Settings + +import scala.concurrent.duration._ + +class ConnectionsSimulation extends Simulation{ + + if(!Settings.skipSetup) { + println("Begin setup") + Setup.setupOrg() + Setup.setupApplication() + Setup.setupNotifier() + Setup.setupUsers() + println("End Setup") + }else{ + println("Skipping Setup") + } + + setUp( + ConnectionScenarios.createScenario + .inject(constantUsersPerSec(Settings.constantUsersPerSec) during Settings.constantUsersDuration) // wait for 15 seconds so create org can finish, need to figure out coordination + .throttle(reachRps(Settings.throttle) in Settings.rampTime.seconds) + .protocols( Settings.httpAppConf.acceptHeader("application/json")) + ) + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/DeleteUsersSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/DeleteUsersSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/DeleteUsersSimulation.scala new file mode 100644 index 0000000..cc89dcc --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/DeleteUsersSimulation.scala @@ -0,0 +1,56 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ + +package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import io.gatling.core.scenario.Simulation +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.UserScenarios +import org.apache.usergrid.settings.Settings + +/** + * Deletes application users continually to an application. Expects the following parameters + * + * -DmaxPossibleUsers : The maximum number of users to be making requests as fast as possible. Think of this as conccurrent users in the system + * -DrampTime: The amount of time (in seconds) to allow for maxPossibleUsers to be reached. This will add new users linearlly + * -Dduration: The amount of time (in seconds) to continue to perform requests up with the maxPossibleUsers + */ +class DeleteUsersSimulation extends Simulation { + + println("Begin setup") + Setup.setupOrg() + Setup.setupApplication() + println("End Setup") + + + setUp( + UserScenarios.deleteUsersInfinitely + .inject( + /** + * injection steps take from this forum post + * https://groups.google.com/forum/#!topic/gatling/JfYHaWCbA-w + */ + rampUsers(Settings.rampUsers) over Settings.rampTime, + constantUsersPerSec(Settings.constantUsersPerSec) during Settings.constantUsersDuration + + )).protocols(Settings.httpAppConf.acceptHeader("application/json")) + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetEntitySimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetEntitySimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetEntitySimulation.scala new file mode 100644 index 0000000..7b896e9 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetEntitySimulation.scala @@ -0,0 +1,44 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import org.apache.usergrid.datagenerators.FeederGenerator +import org.apache.usergrid.scenarios.UserScenarios +import org.apache.usergrid.settings.Settings + +import scala.concurrent.duration._ + +class GetEntitySimulation extends Simulation { + + // Target settings + val httpConf = Settings.httpAppConf + + // Simulation settings + val numUsers:Int = Settings.rampUsers + val numEntities:Int = Settings.numEntities + val rampTime:Int = Settings.rampTime + val throttle:Int = Settings.throttle + + val feeder = FeederGenerator.generateEntityNameFeeder("user", numEntities) + + val scnToRun = scenario("GET entity") + .exec(UserScenarios.getRandomUser) + + setUp(scnToRun.inject(atOnceUsers(numUsers)).throttle(reachRps(throttle) in (rampTime.seconds)).protocols(httpConf)).maxDuration(Settings.holdDuration) + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetUserPagesSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetUserPagesSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetUserPagesSimulation.scala new file mode 100755 index 0000000..353c5db --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetUserPagesSimulation.scala @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.UserScenarios +import org.apache.usergrid.settings.Settings + +/** + * Posts application users continually to an application. Expects the following parameters + * + * -DmaxPossibleUsers : The maximum number of users to be making requests as fast as possible. Think of this as conccurrent users in the system + * -DrampTime: The amount of time (in seconds) to allow for maxPossibleUsers to be reached. This will add new users linearlly + * -Dduration: The amount of time (in seconds) to continue to perform requests up with the maxPossibleUsers + */ +class GetUserPagesSimulation extends Simulation { + + println("Begin setup") + Setup.setupOrg() + Setup.setupApplication() + println("End Setup") + + + setUp( + UserScenarios.getUserPagesToEnd + .inject( + /** + * injection steps take from this forum post + * https://groups.google.com/forum/#!topic/gatling/JfYHaWCbA-w + */ + rampUsers(Settings.rampUsers) over Settings.rampTime, + constantUsersPerSec(Settings.constantUsersPerSec) during Settings.constantUsersDuration + + )).protocols(Settings.httpAppConf.acceptHeader("application/json")) + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetUsersSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetUsersSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetUsersSimulation.scala new file mode 100755 index 0000000..bc3e899 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/GetUsersSimulation.scala @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.UserScenarios +import org.apache.usergrid.settings.Settings + +/** + * Posts application users continually to an application. Expects the following parameters + * + * -DmaxPossibleUsers : The maximum number of users to be making requests as fast as possible. Think of this as conccurrent users in the system + * -DrampTime: The amount of time (in seconds) to allow for maxPossibleUsers to be reached. This will add new users linearlly + * -Dduration: The amount of time (in seconds) to continue to perform requests up with the maxPossibleUsers + */ +class GetUsersSimulation extends Simulation { + + println("Begin setup") + Setup.setupOrg() + Setup.setupApplication() + println("End Setup") + + + setUp( + UserScenarios.getUsersByUsername + .inject( + /** + * injection steps take from this forum post + * https://groups.google.com/forum/#!topic/gatling/JfYHaWCbA-w + */ + rampUsers(Settings.rampUsers) over Settings.rampTime, + constantUsersPerSec(Settings.constantUsersPerSec) during Settings.constantUsersDuration + + )).protocols(Settings.httpAppConf.acceptHeader("application/json")) + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PostCustomEntitySimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PostCustomEntitySimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PostCustomEntitySimulation.scala new file mode 100644 index 0000000..d05a49c --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PostCustomEntitySimulation.scala @@ -0,0 +1,76 @@ +/* + * + * * Licensed to the Apache Software Foundation (ASF) under one or more + * * contributor license agreements. The ASF licenses this file to You + * * under the Apache License, Version 2.0 (the "License"); you may not + * * use this file except in compliance with the License. + * * You may obtain a copy of the License at + * * + * * http://www.apache.org/licenses/LICENSE-2.0 + * * + * * Unless required by applicable law or agreed to in writing, software + * * distributed under the License is distributed on an "AS IS" BASIS, + * * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * * See the License for the specific language governing permissions and + * * limitations under the License. For additional information regarding + * * copyright in this work, please see the NOTICE file in the top level + * * directory of this distribution. + * + */ + +package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import io.gatling.core.scenario.Simulation +import org.apache.usergrid.datagenerators.FeederGenerator +import org.apache.usergrid.scenarios.EntityScenarios +import org.apache.usergrid.settings.Settings + +/** + * PostCustomEntitySimulation - creates lots of custom entities + * + * Run this way: + * mvn gatling:execute -DrampTime=10 -DmaxPossibleUsers=10 -Dduration=120 -Dorg=yourorgname -Dapp=sandbox -Dbaseurl=https://api.usergrid.com -DadminUser=yourusername -DadminPassword='yourpassword' -Dgatling.simulationClass=org.apache.usergrid.simulations.deprecated.PostCustomEntitySimulation -Dcollection=yourcollection + * + * + */ +class PostCustomEntitySimulation extends Simulation { + + if(!Settings.skipSetup) { + println("Begin setup") + println("These aren't the droids you are looking for...") + //exec(TokenScenarios.getManagementToken) + println("End Setup") + }else{ + println("Skipping Setup") + } + + val numEntities:Int = Settings.numEntities + val collection = Settings.collection + println("collection type = " + collection) + val rampTime:Int = Settings.rampTime + val throttle:Int = Settings.throttle + val feeder = FeederGenerator.generateCustomEntityInfinite(0) + val httpConf = Settings.httpAppConf + + val scnToRun = scenario("POST custom entities") + .feed(feeder) + .exec(EntityScenarios.postEntity) + + /* + val scnToRun = scenario("POST custom entities") + .feed(feeder) + .doIfOrElse(session => session("token").as[String].nonEmpty(session)) { + exec(EntityScenarios.postEntityWithToken) + } { + exec(EntityScenarios.postEntity) + } +*/ + + + setUp(scnToRun.inject( + rampUsers(Settings.rampUsers) over Settings.rampTime, + constantUsersPerSec(Settings.constantUsersPerSec) during Settings.constantUsersDuration + ).protocols(httpConf)).maxDuration(Settings.holdDuration) + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PostUsersSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PostUsersSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PostUsersSimulation.scala new file mode 100755 index 0000000..04a7a3e --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PostUsersSimulation.scala @@ -0,0 +1,51 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios.UserScenarios +import org.apache.usergrid.settings.Settings + +/** + * Posts application users continually to an application. Expects the following parameters + * + * -DmaxPossibleUsers : The maximum number of users to be making requests as fast as possible. Think of this as conccurrent users in the system + * -DrampTime: The amount of time (in seconds) to allow for maxPossibleUsers to be reached. This will add new users linearlly + * -Dduration: The amount of time (in seconds) to continue to perform requests up with the maxPossibleUsers + */ +class PostUsersSimulation extends Simulation { + + println("Begin setup") + Setup.setupOrg() + Setup.setupApplication() + println("End Setup") + + + setUp( + UserScenarios.postUsersInfinitely + .inject( + /** + * injection steps take from this forum post + * https://groups.google.com/forum/#!topic/gatling/JfYHaWCbA-w + */ + rampUsers(Settings.rampUsers) over Settings.rampTime, + constantUsersPerSec(Settings.constantUsersPerSec) during Settings.constantUsersDuration + + )).protocols(Settings.httpAppConf.acceptHeader("application/json")) + +} http://git-wip-us.apache.org/repos/asf/usergrid/blob/29bf682e/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PushNotificationTargetUserSimulation.scala ---------------------------------------------------------------------- diff --git a/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PushNotificationTargetUserSimulation.scala b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PushNotificationTargetUserSimulation.scala new file mode 100644 index 0000000..3e11845 --- /dev/null +++ b/tests/performance/src/main/scala/org/apache/usergrid/simulations/deprecated/PushNotificationTargetUserSimulation.scala @@ -0,0 +1,45 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.apache.usergrid.simulations.deprecated + +import io.gatling.core.Predef._ +import org.apache.usergrid.helpers.Setup +import org.apache.usergrid.scenarios._ +import org.apache.usergrid.settings.Settings + +class PushNotificationTargetUserSimulation extends Simulation { + + + before{ + if (!Settings.skipSetup) { + Setup.setupOrg() + Setup.setupApplication() + Setup.setupNotifier() + Setup.setupUsers() + } else { + println("Skipping setup") + } + } + setUp( + NotificationScenarios.createScenario + .inject( + rampUsers(Settings.rampUsers) over Settings.rampTime, + constantUsersPerSec(Settings.constantUsersPerSec) during Settings.constantUsersDuration) + .protocols( Settings.httpAppConf.acceptHeader("application/json")) + ) + +}