When to use def and val on Gatling scenarios and chains - scala

I come from a Java background and am taking over a Gatling project where I noticed what seems to me a bit of inconsistency when using what is a val or a def method. The picture below exemplifies that and I was wondering if there's any guidance on what is the best usage for these within the Gatling context please.
These are other examples where I'm not sure what should be used. I'm assuming a Switch makes sense being inside a method but not sure about the others?
private def teacherViewResources: ChainBuilder =
exec(viewResourcesFlow)
.randomSwitch(
70.0 -> pause(1,2).exec(teacherLaunchResource),
10.0 -> pause(1,2).exec(teacherAssignResource),
20.0 -> pause(1,2).exec(teacherResourcesNext)
)
private def teacherLaunchResource: ChainBuilder =
exec(launchResourcesFlow)
val rootTeacherScenario = scenario("Root Teacher Scenario " + currentScenario.toString)
.doIfOrElse(currentScenario == PossibleScenarios.BRANCH)(
feed(userFeederTeacher).during(EXECUTION_TIME_SEC) {
exec(teacherBranching)
}
//For use with atOnceUsers for debugging
//feed(userFeederTeacher).exec(simulationTeacherBranching)
)(
exec {
session =>
logger.debug("Invalid teacher scenario chosen")
session
}
)
val loginFlowWithExit = exec(loginFlow).exitHereIfFailed
val teacherBranching = group("teacherBranching") {
exec(loginFlow)
.exec(session => sessionSetSessionVariable(session))
.exec(execFlaggedScenario(teacherDashboard)) // First method to run for a teacher
.exec(logout())
}
Many thanks.

val is evaluated once while def is evaluated on every call.
Remember that Gatling DSL components are just builders, not what is executed when your test is running.
Everything that doesn't take a parameter could be a val, you just have to make sure you don't end up with using forward references, eg:
broken:
val foo = exec(???).exec(bar) // here, bar is still null because it's populated later in the code
val bar = exec(???)
correct:
val bar = exec(???)
val foo = exec(???).exec(bar) // fine because bar is already populated

Related

Is it possible to reference count call location?

This question isn't programming language specific (the more general the better), but I'm working in Scala (not necessarily on the JVM). Is there a means to reference count by call location, not the number of total calls? In particular, it would be great to be able to detect if a given method is called from more than one call location.
I think I can fake it to some extent by doing a reference equality check with a function, but this could be abused easily by having a global-ish token, or even calling the function multiple times in the same scope:
sealed case class Token();
class MyClass[A] {
var tokenOpt: Option[Token] = None
def callMeFromOnePlace(x: A)(implicit tk: Token) = {
tokenOpt match {
case Some(priorTk) => if (priorTk ne tk) throw new IllegalStateException("")
case None => tokenOpt = Some(tk)
}
// Do some work ...
}
}
Then this should work fine:
val myObj = new MyClass[Int]
val myIntList = List(1,2,3)
implicit val token = Token()
myIntList.map(ii => myObj.callMeFromOnePlace(ii))
But unfortunately, so would this:
val myObj = new MyClass[Int]
implicit val token = Token()
myObj.callMeFromOnePlace(1)
myObj.callMeFromOnePlace(1) //oops, want this to fail
When you are talking about call location, it can be represented by a call stack trace. Here is a simple example:
// keep track of calls here (you can use immutable style if you want)
var callCounts = Map.empty[Int, Int]
def f(): Unit = {
// calculate call stack trace hashCode for more efficient storage
// .toSeq makes WrappedArray, that knows how to properly calculate .hashCode()
val hashCode = new RuntimeException().getStackTrace.toSeq.hashCode()
val callLocation = hashCode
callCounts += (callLocation -> (callCounts.getOrElse(callLocation, 0) + 1))
}
List(1,2,3).foreach(_ =>
f()
)
f()
f()
println(callCounts) // Map(75070239 -> 3, 900408638 -> 1, -1658734417 -> 1)
I am not completely clear what you want to do but for your //oops.. example to fail you need just check the PriorTk is not None. (do note that it is not a thread safe solution )
For completeness, enforcing these kind of constraints from a type system perspective requires linear types.

Test valid state transitions with scalacheck

Suppose I have this class:
case class Receipt(id: Long, state: String) {
def transitionTo(newState: String) = {
if (!canTransitionTo(newState)) {
throw new IllegalStateExcetion(s"cant transition from $state to $newState")
}
this.copy(state = newState)
}
}
I'd like to test the logic in canTransitionTo (not included here for the sake of simplicity) with scalachecks Commands but I'm having a bit of trouble on how to begin. Any ideas?
There are some tutorials how to test state machines with this framework but they test another property. Usually they create a Command for each valid transition and fire scalacheck to do any random combinations of them. The goal of such property is to verify that state machine behaves normally for any number of valid transitions.
This approach will not test canTransitionTo because it assumes all transitions are valid. Testing transitions between any pair of states will require to reimplement a notion of valid and invalid transitions in terms of scalacheck. This could be even more complex then original canTransitionTo function.
If one of transition sets is much smaller than other scalacheck can help to generate another one. For example if there are only handful of valid transitions and tenth of invalid then generators can help.
private val allStates: Gen[String] = Gen.oneOf("State1", "State2", "State3")
private val validTransitions: Set[(String, String)] = Set("State1" -> "State2", "State2" -> "State3", "State3" -> "State1")
private val validTransitionsGen: Gen[(String, String)] = Gen.oneOf(validTransitions.toSeq)
private val invalidTransition: Gen[(String, String)] = for {
from <- allStates
to <- allStates
if !validTransitions.contains(from -> to) //this is reimplementaion of canTransitionTo
} yield from -> to
property("valid transitions") = forAll(validTransitionsGen) { transition =>
Receipt(0, transition._1).canTransitionTo(transition._2)
}
property("invalid transitions") = forAll(invalidTransition) { transition =>
!Receipt(0, transition._1).canTransitionTo(transition._2)
}

Scala TypeTags and performance

There are some answers around for equivalent questions about Java, but is scala reflection (2.11, TypeTags) really slow? there's a long narrative write-up about it at http://docs.scala-lang.org/overviews/reflection/overview.html, where the answer to this question is hard to extract.
I see a lot of advice floating around about avoiding reflection, maybe some of it predating the improvements of 2.11, but if this works well it looks like it can solve the debilitating aspect of the JVM's type erasure, for scala code.
Thanks!
Let's measure it.
I've created simple class C that has one method. All what this method do is sleep for 10ms.
Let's invoke this method
within reflection
directly
And see which is faster and how fast it is.
I've created three tests.
Test 1. Invoke via reflection. Execution time include all work that necessary to be done for setup reflection.
Create runtimeMirror, reflect class, create declaration for method, and at last step - execute method.
Test 2. Do not take into account this preparation stage, as it can be re-used.
We are calculate time of method invoking via reflection only.
Test 3. Invoke method directly.
Results:
Reflection from start : job done in 2561ms got 101 (1,5seconds for setup each execution)
Invoke method reflection: job done in 1093ms got 101 ( < 1ms for setup each execution)
No reflection: job done in 1087ms got 101 ( < 1ms for setup each execution)
Conclusion:
Setup phase increase execution time dramatically. But there are no need to perform setup on each execution (this is like class initialization - can be done once). So if you use reflection in right way(with separated init stage) it shows relevant performance and can be used for production.
Source code:
class C {
def x = {
Thread.sleep(10)
1
}
}
class XYZTest extends FunSpec {
def withTime[T](procName: String, f: => T): T = {
val start = System.currentTimeMillis()
val r = f
val end = System.currentTimeMillis()
print(s"$procName job done in ${end-start}ms")
r
}
describe("SomeTest") {
it("rebuild each time") {
val s = withTime("Reflection from start : ", (0 to 100). map {x =>
val ru = scala.reflect.runtime.universe
val m = ru.runtimeMirror(getClass.getClassLoader)
val im = m.reflect(new C)
val methodX = ru.typeOf[C].declaration(ru.TermName("x")).asMethod
val mm = im.reflectMethod(methodX)
mm().asInstanceOf[Int]
}).sum
println(s" got $s")
}
it("invoke each time") {
val ru = scala.reflect.runtime.universe
val m = ru.runtimeMirror(getClass.getClassLoader)
val im = m.reflect(new C)
val s = withTime("Invoke method reflection: ", (0 to 100). map {x =>
val methodX = ru.typeOf[C].declaration(ru.TermName("x")).asMethod
val mm = im.reflectMethod(methodX)
mm().asInstanceOf[Int]
}).sum
println(s" got $s")
}
it("invoke directly") {
val c = new C()
val s = withTime("No reflection: ", (0 to 100). map {x =>
c.x
}).sum
println(s" got $s")
}
}
}

Does scala have a lazy evaluating wrapper?

I want to return a wrapper/holder for a result that I want to compute only once and only if the result is actually used. Something like:
def getAnswer(question: Question): Lazy[Answer] = ???
println(getAnswer(q).value)
This should be pretty easy to implement using lazy val:
class Lazy[T](f: () => T) {
private lazy val _result = Try(f())
def value: T = _result.get
}
But I'm wondering if there's already something like this baked into the standard API.
A quick search pointed at Streams and DelayedLazyVal but neither is quite what I'm looking for.
Streams do memoize the stream elements, but it seems like the first element is computed at construction:
def compute(): Int = { println("computing"); 1 }
val s1 = compute() #:: Stream.empty
// computing is printed here, before doing s1.take(1)
In a similar vein, DelayedLazyVal starts computing upon construction, even requires an execution context:
val dlv = new DelayedLazyVal(() => 1, { println("started") })
// immediately prints out "started"
There's scalaz.Need which I think you'd be able to use for this.

How to create a play.api.libs.iteratee.Enumerator which inserts some data between the items of a given Enumerator?

I use Play framework with ReactiveMongo. Most of ReactiveMongo APIs are based on the Play Enumerator. As long as I fetch some data from MongoDB and return it "as-is" asynchronously, everything is fine. Also the transformation of the data, like converting BSON to String, using Enumerator.map is obvious.
But today I faced a problem which at the bottom line narrowed to the following code. I wasted half of the day trying to create an Enumerator which would consume items from the given Enumerator and insert some items between them. It is important not to load all the items at once, as there could be many of them (the code example has only two items "1" and "2"). But semantically it is similar to mkString of the collections. I am sure it can be done very easily, but the best I could come with - was this code. Very similar code creating an Enumerator using Concurrent.broadcast serves me well for WebSockets. But here even that does not work. The HTTP response never comes back. When I look at Enumeratee, it looks that it is supposed to provide such functionality, but I could not find the way to do the trick.
P.S. Tried to call chan.eofAndEnd in Iteratee.mapDone, and chunked(enums >>> Enumerator.eof instead of chunked(enums) - did not help. Sometimes the response comes back, but does not contain the correct data. What do I miss?
def trans(in:Enumerator[String]):Enumerator[String] = {
val (res, chan) = Concurrent.broadcast[String]
val iter = Iteratee.fold(true) { (isFirst, curr:String) =>
if (!isFirst)
chan.push("<-------->")
chan.push(curr)
false
}
in.apply(iter)
res
}
def enums:Enumerator[String] = {
val en12 = Enumerator[String]("1", "2")
trans(en12)
//en12 //if I comment the previous line and uncomment this, it prints "12" as expected
}
def enum = Action {
Ok.chunked(enums)
}
Here is my solution which I believe to be correct for this type of problem. Comments are welcome:
def fill[From](
prefix: From => Enumerator[From],
infix: (From, From) => Enumerator[From],
suffix: From => Enumerator[From]
)(implicit ec:ExecutionContext) = new Enumeratee[From, From] {
override def applyOn[A](inner: Iteratee[From, A]): Iteratee[From, Iteratee[From, A]] = {
//type of the state we will use for fold
case class State(prev:Option[From], it:Iteratee[From, A])
Iteratee.foldM(State(None, inner)) { (prevState, newItem:From) =>
val toInsert = prevState.prev match {
case None => prefix(newItem)
case Some(prevItem) => infix (prevItem, newItem)
}
for(newIt <- toInsert >>> Enumerator(newItem) |>> prevState.it)
yield State(Some(newItem), newIt)
} mapM {
case State(None, it) => //this is possible when our input was empty
Future.successful(it)
case State(Some(lastItem), it) =>
suffix(lastItem) |>> it
}
}
}
// if there are missing integers between from and to, fill that gap with 0
def fillGap(from:Int, to:Int)(implicit ec:ExecutionContext) = Enumerator enumerate List.fill(to-from-1)(0)
def fillFrom(x:Int)(input:Int)(implicit ec:ExecutionContext) = fillGap(x, input)
def fillTo(x:Int)(input:Int)(implicit ec:ExecutionContext) = fillGap(input, x)
val ints = Enumerator(10, 12, 15)
val toStr = Enumeratee.map[Int] (_.toString)
val infill = fill(
fillFrom(5),
fillGap,
fillTo(20)
)
val res = ints &> infill &> toStr // res will have 0,0,0,0,10,0,12,0,0,15,0,0,0,0
You wrote that you are working with WebSockets, so why don't you use dedicated solution for that? What you wrote is better for Server-Sent-Events rather than WS. As I understood you, you want to filter your results before sending them back to client? If its correct then you Enumeratee instead of Enumerator. Enumeratee is transformation from-to. This is very good piece of code how to use Enumeratee. May be is not directly about what you need but I found there inspiration for my project. Maybe when you analyze given code you would find best solution.