Search code examples
scalaakkaspecs2akka-testkit

Modifying ask timeout in akka testkit


I have tried half a dozen different approaches, but I cannot seem to modify the default timeout value for an actor ask. This means it almost always fails on the CI server.

Here's my current iteration. There are several attempts bundled together. None of them do anything to modify the timeout value from 1 second.

base test class

import akka.actor.ActorSystem
import akka.testkit.TestKit
import com.typesafe.config.ConfigFactory
import org.specs2.mutable.SpecificationLike
import org.specs2.specification.AfterEach
import org.specs2.specification.core.Fragments

abstract class TestActors
    extends TestKit(ActorSystem("testsystem", ConfigFactory.load("test-application.conf")))
    with SpecificationLike
    with AfterEach {
  override def map(fs: => Fragments) = super.map(fs) ^ step(system.terminate, global = true)
  def after = system.terminate()
}

Spec

class RepoSpec(implicit ee: ExecutionEnv) extends TestActors {
  isolated

  implicit val timeout = Timeout(5 seconds)

  val repo = system.actorOf(Props(classOf[Repo], data))

  "return None when there's no such record" >> {
    implicit val timeout = Timeout(30 seconds)
    val record = repo ? GetRecord(1, RecordKey(1, 1, 1))
    record must beEqualTo(Option.empty[Record]).await
  }
}

src/test/resources/test-application.conf

akka.test {
  timefactor=10
  single-expect-default=5000
}

The specs complete on my laptop, but fail on Travis with:

[error] x return None when there's no such record
[error]  Timeout after 1 second (retries = 0, timeout = 1 second), timeFactor = 1 (TestActors.scala:10)

Edit: It's odd that the line referenced in the error message is TestActors.scala:10 - that is the class definition of the base test class.

If I can just get the system to understand that 1 second is too quick, I'd be very happy.


Solution

  • You can override the timeout setting to something greater than one second:

    record must beEqualTo(Option.empty[Record]).await(timeout = 5.seconds)
    

    However, the recommended practice is to set a higher timeFactor execution environment argument in specs2 when running your tests on a CI server. Await timeout settings are multiplied by timeFactor, whose default value is one. In your test, timeout has a value of one second, and timeFactor is one, leading to the total timeout of one second: 1 second * 1. Change timeFactor as appropriate for your CI server.