These are chat archives for etorreborre/specs2

27th
Jan 2017
Eric Torreborre
@etorreborre
Jan 27 2017 07:36
@panchul I couldn't find a way around that compiler bug. You will have to take another approach like this one
import akka.actor.ActorSystem
import akka.testkit.{ImplicitSender, TestKitBase}
import com.typesafe.config.ConfigFactory
import org.scalacheck._
import org.specs2.ScalaCheck
import org.specs2.matcher.ThrownExpectations
import org.specs2.Specification
import scala.concurrent.duration._

class ThingieProcessorSpecification extends Specification with ThrownExpectations with ScalaCheck { def is = s2"""

  Test thingie $testThingieWorks

"""

    def genInt = Gen.const(1)

    val testThingieWorks = prop { (i: Int, akka: Akka) =>
      import akka._; akka {
        within(5.seconds)(ok)
      }
    }.setGen1(genInt)

  implicit def arbitraryAkka: Arbitrary[Akka] =
    Arbitrary(Gen.const(Akka()))
}

case class Akka() extends org.specs2.specification.After with TestKitBase with ImplicitSender {
  lazy val system = ActorSystem(
    "XiIntegrateSpecs",
    ConfigFactory.parseString("""
      akka.loggers = ["akka.testkit.TestEventListener"]
    """)
     )

  def after: Unit = system.terminate()
}
Eric Torreborre
@etorreborre
Jan 27 2017 07:44
@rossabaker I suggest you steal the code and tweak it to your needs. Here is a version which should fail
import org.specs2.concurrent.ExecutionEnv
import org.specs2.execute.AsResult
import org.specs2.matcher.{Expectable, TerminationMatchers}
import org.specs2.specification.{Around, Context, EachContext}
import org.specs2.specification.core.Env
import org.specs2._
import TerminationMatchers._
import scala.concurrent.duration._
import org.specs2.matcher.MustMatchers._

/**
 * This trait can be used to add a global time out to each example or for a specific one:
 *
 *  - for each example mix-in the trait
 *  - for a single example import the object and use the upTo context:
 *
 *   my example must terminate in a reasonable amount of time \${upTo(3.seconds)(e1)}
 */
trait ExamplesTimeout extends EachContext with AroundTimeout {

  def context: Env => Context = { env: Env =>
    val timeout = env.arguments.commandLine.intOr("timeout", 1000 * 60).millis
    aroundTimeout(timeout)(env.executionEnv)
  }
}

object ExamplesTimeout extends ExamplesTimeout

trait AroundTimeout {

  def upTo[T](to: Duration)(t: => T)(implicit asResult: AsResult[T], ee: ExecutionEnv) =
    aroundTimeout(to)(ee).apply(t)

  def aroundTimeout(to: Duration)(implicit ee: ExecutionEnv): Around =
    new Around {
      def around[T : AsResult](t: =>T) = {
        lazy val result = t
        val termination = result must terminate(retries = 10, sleep = (to.toMillis / 10).millis)

        if (!termination.isSuccess) termination.toResult
        else AsResult(result)
      }
    }
}

object AroundTimeout extends AroundTimeout
Aleksandr Panchul
@panchul
Jan 27 2017 14:57
@etorreborre , thanks for the work-around, that resolves the blocker I had.
Ross A. Baker
@rossabaker
Jan 27 2017 16:54
@etorreborre Thanks! @bfritz, that’s probably useful for the issue you’re chasing.
Brad Fritz
@bfritz
Jan 27 2017 20:29
@etorreborre @rossabaker Thank you!
I used the ExamplesTimeout pattern to arrive at:
bfritz/http4s@9896907
so I could do a thread dump and see what's blocking.
It's probably full of subtle bugs, but seems to be doing what I want it to.
Aleksandr Panchul
@panchul
Jan 27 2017 20:34
@etorreborre , in that code above in testThingieWorks, inside within's body when I try to send messages to the actor that I am trying to test, something does not work - the actor under test seems to be able to receive a message, but I don't see the messages coming back. I am trying to receive using expectMsg("hi"), and I see that there is send(), but I am not sure how to invoke it (send(demo, "hi") does not compile, but I presume it is what I need to use for the ImplicitSender to receive the message back). Could you please take a look? It is around line 89 in here: https://github.com/panchul/scala_akka_test/blob/master/src/test/scala/ThingieProcessor2Specification.scala
Eric Torreborre
@etorreborre
Jan 27 2017 22:15

If you want to use send you need to add it to the Akka class

case class Akka() extends org.specs2.specification.After with TestKitBase with ImplicitSender {
  def send(actor: ActorRef, msg: Any): Unit = actor.!(msg)(testActor)
}

I can not unfortunately help you more with Akka