Created
February 19, 2012 14:29
-
-
Save piotrga/1864064 to your computer and use it in GitHub Desktop.
Performance test
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
package com.XXX.connector | |
import testdsl.connector.ConnectorAccountDsl | |
import testdsl.facebook.FacebookAccountDsl | |
import util.Random | |
import akka.actor.{Scheduler, Actor} | |
import java.util.concurrent.TimeUnit | |
import org.junit.Test | |
import testdsl.AcceptanceTestingDsl | |
import org.junit.runner.RunWith | |
import com.tbone.ext.junit.{RequireRemoteHostRunner, RemoteHost} | |
import akka.util.duration._ | |
import com.tbone.scalatest.MuteLogging | |
import org.scalatest.WordSpec | |
import akka.dispatch.{MessageDispatcher, Dispatchers, Futures, Future} | |
import akka.util.Duration | |
class Performance5000Test extends AcceptanceTestingDsl with WordSpec with MuteLogging { | |
case class PerformanceTest( | |
USERS : Int = 50, | |
LOGGING_GAP : Duration = 5 seconds, | |
POLLING : Int = 0, | |
USER_GAP : Duration = 100 millis, | |
THREAD_LIMIT : Int = 100 | |
) { | |
def safe(block: => Unit){ | |
try{block} catch {case _=>} | |
} | |
class Brain extends Actor{ | |
var errorCount = 0 | |
var successCount = 0 | |
var successRatio = 100d | |
implicit val dispatcher : MessageDispatcher = Dispatchers.newExecutorBasedEventDrivenWorkStealingDispatcher("fast", THREAD_LIMIT*2) | |
.setCorePoolSize(THREAD_LIMIT) | |
.setMaxPoolSize(THREAD_LIMIT) | |
.build | |
override def preStart() { | |
Scheduler.scheduleOnce(self, ('recalculateStats, errorCount, successCount), 10, TimeUnit.SECONDS ) | |
} | |
protected def receive = { | |
case ('createUser, id:String) => Actor.spawn{ | |
val user = facebook createUser id | |
self ! ('userCreated, id, user) | |
} | |
case ('userCreated, userId:String, user:FacebookAccountDsl) => { | |
println("User created [%s]" format userId) | |
if (math.random<(POLLING.toDouble/USERS)) self ! ('poll, user) | |
println("Scheduling login every [%s]" format LOGGING_GAP) | |
Scheduler.schedule(self, ('login, userId, user), 0, LOGGING_GAP.toNanos, TimeUnit.NANOSECONDS ) | |
} | |
case ('poll, user:ConnectorAccountDsl) => safe{ | |
println("Starting long poll for user [%s]" format user.id) | |
user startLongPolling | |
} | |
case ('login, userId: String, user:FacebookAccountDsl) => Actor.spawn{ | |
try{ | |
println("Logging in [%s]" format userId) | |
connector facebookLoginViaCIA user | |
self ! 'success | |
}catch{ | |
case e => self ! ('error, e.getMessage) | |
} | |
} | |
case 'success => successCount+=1 | |
case ('error, msg) => { | |
errorCount += 1 | |
System.err.println("[%d, %3.0f%% errors] Error [%s]" format(errorCount, 100-successRatio, msg)) | |
} | |
case ('recalculateStats, prevErrors:Int, prevSuccesses:Int) =>{ | |
val successDelta = successCount - prevSuccesses | |
val errorDelta = errorCount - prevErrors | |
successRatio = if (errorDelta+successDelta == 0) 0 else (100 * successDelta) / (errorDelta+successDelta) | |
Scheduler.scheduleOnce(self, ('recalculateStats, errorCount, successCount), 10, TimeUnit.SECONDS ) | |
} | |
} | |
} | |
def run { | |
val brain = Actor.actorOf(new Brain).start() | |
for(i<-1 to USERS){ | |
brain ! ('createUser, "jim-"+i) | |
Thread.sleep(Random.nextInt(USER_GAP.toMillis.toInt)) | |
} | |
Thread.sleep(10000000L); | |
} | |
} | |
"200 users trying to relogin every 20 seconds" in { | |
PerformanceTest(USERS = 200, LOGGING_GAP = 20 seconds, USER_GAP = 1000 millis, THREAD_LIMIT = 500, POLLING = 0).run | |
} | |
"One user constantly logging in" in { | |
PerformanceTest(USERS = 1, LOGGING_GAP = 10 millis, USER_GAP = 1000 millis, THREAD_LIMIT = 500, POLLING = 0).run | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment