Created
March 19, 2013 13:54
-
-
Save nremond/5196293 to your computer and use it in GitHub Desktop.
This file contains 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
object Nico2 { | |
import scala.concurrent.duration._ | |
/// | |
implicit class UserNumberImplicit(number: Int) { | |
def users = new UserNumber(number) | |
} | |
class UserNumber(val number: Int) | |
implicit class UsersPerSecImplicit(rate: Double) { | |
def usersPerSec = new UsersPerSec(rate) | |
} | |
class UsersPerSec(val rate: Double) | |
/// | |
implicit class RampBuilder(users: UserNumber) { | |
def during(d: FiniteDuration) = new RampDefinition(users.number, d) | |
} | |
class RampDefinition(val users: Int, val duration: FiniteDuration) | |
implicit class ConstantRateBuilder(usersPerSec: UsersPerSec) { | |
def during(d: FiniteDuration) = new ConstantRateDefinition(usersPerSec.rate, d) | |
} | |
class ConstantRateDefinition(val rate: Double, val duration: FiniteDuration) | |
/// Scenarios | |
class ScenarioBuilder(injections: List[InjectionStrategy] = Nil) { | |
def ramp(rd: RampDefinition) = inject(new RampInjection(rd.users, rd.duration)) | |
def wait(d: FiniteDuration) = inject(new WaitInjection(d)) | |
def peak(users: UserNumber) = inject(new PeakInjection(users.number)) | |
def constantRate(crd: ConstantRateDefinition) = { | |
val users = (crd.duration.toSeconds * crd.rate).toInt | |
inject(new RampInjection(users, crd.duration)) | |
} | |
// For custom injection strategies | |
def inject(is: InjectionStrategy) = new ScenarioBuilder(is :: injections) | |
override def toString = injections.reverse.mkString(" AND THEN ") | |
} | |
/// injection strategies | |
trait InjectionStrategy { | |
def schedule: Stream[FiniteDuration] | |
def completedAfter: FiniteDuration | |
} | |
class RampInjection(users: Int, duration: FiniteDuration) extends InjectionStrategy { | |
override def toString = s"Ramp ${users} users for ${duration}" | |
override def schedule: Stream[FiniteDuration] = { | |
val interval = duration / users | |
for (n <- Stream.range(0, users)) yield n * interval | |
} | |
override def completedAfter: FiniteDuration = duration | |
} | |
class WaitInjection(duration: FiniteDuration) extends InjectionStrategy { | |
override def toString = s"Wait for $duration" | |
override def schedule: Stream[FiniteDuration] = Stream.empty | |
override def completedAfter: FiniteDuration = duration | |
} | |
class PeakInjection(users: Int) extends InjectionStrategy { | |
override def toString = s"Peak $users users" | |
override def schedule: Stream[FiniteDuration] = Stream.continually(0 milliseconds).take(users) | |
override def completedAfter: FiniteDuration = 0 millisecond | |
} | |
val scn = new ScenarioBuilder() //> scn : Nico2.ScenarioBuilder = | |
scn.ramp((10 users) during (10 seconds)) //> res0: Nico2.ScenarioBuilder = Ramp 10 users for 10 seconds | |
scn.wait(10 seconds) //> res1: Nico2.ScenarioBuilder = Wait for 10 seconds | |
scn.peak(100 users) //> res2: Nico2.ScenarioBuilder = Peak 100 users | |
scn.constantRate((1.2 usersPerSec) during (10 minutes)) | |
//> res3: Nico2.ScenarioBuilder = Ramp 720 users for 10 minutes | |
scn.wait(10 seconds).ramp((10 users) during (10 seconds)).constantRate((1.2 usersPerSec) during (10 minutes)).peak(100 users) | |
//> res4: Nico2.ScenarioBuilder = Wait for 10 seconds AND THEN Ramp 10 users fo | |
//| r 10 seconds AND THEN Ramp 720 users for 10 minutes AND THEN Peak 100 users | |
//| | |
//scn.rampRate((1.3 usersPerSec) to (5 usersPerSec) during (10 mins)) | |
//scn.dirac() | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment