Reputation: 34403
In a following code the test called sleep
fails gracefully, while the test freeze
causes the testing to never end.
import org.scalatest.FunSuite
import org.scalatest.concurrent.TimeLimitedTests
import org.scalatest.time.SpanSugar._
import scala.language.postfixOps
class MainTest extends FunSuite with TimeLimitedTests {
def timeLimit = 1 second
test("sleep") {
Thread.sleep(10000)
}
test("unintentional freeze") {
var i = 100
var j = 0
while (i>0) {
i += 1 // a bug: should be j += 1
i -= 1
}
}
}
I understand this because of the way how TimeLimitedTests
uses ThreadInterruptor
to abort timeouted tests. Is there some other way how can ScalaTest detect and fail such code? If not, is there some common practice how avoid or detect this type of bugs in the tested code?
When I run tests manually in the IDE, I can abort them manually and those with infinite loops will be marked as not started, but I am concerned that when this happens in a code committed, the Jenkins build process is frozen as a result, requiring a manual abort on the build server.
Upvotes: 3
Views: 1195
Reputation: 6385
First of all your example is artificial. In real life even infinite loops has invokes thread sleeping at least for millisecond: Thread.sleep(1)
. And in such case interrupt
will properly work.
But assume there are no sleeping. So you need to override defaultInterrruptor
to kill thread in more "reliable" way.
import org.scalatest.FunSuite
import org.scalatest.concurrent.{Interruptor, TimeLimitedTests, ThreadInterruptor, Timeouts}
import org.scalatest.time.SpanSugar._
import scala.language.postfixOps
class MainTest extends FunSuite with TimeLimitedTests {
override val defaultTestInterruptor: Interruptor = new Interruptor {
override def apply(testThread: Thread): Unit = {
println("Kindly die")
testThread.stop() // deprecated. unsafe. do not use
}
}
def timeLimit = 1 second
test("sleep") {
Thread.sleep(10000)
}
test("freeze") {
while (true) {}
}
}
Upvotes: 5