Skip to content

Instantly share code, notes, and snippets.

@nremond
Created March 19, 2013 13:54
Show Gist options
  • Save nremond/5196293 to your computer and use it in GitHub Desktop.
Save nremond/5196293 to your computer and use it in GitHub Desktop.
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