scalameta / munit

Scala testing library with actionable errors and extensible APIs
https://scalameta.org/munit
Apache License 2.0
429 stars 90 forks source link

`ExceptionInInitializerError` causes test to hang for entire timeout #772

Open armanbilge opened 5 months ago

armanbilge commented 5 months ago
//> using dep org.scalameta::munit::1.0.0-M12

import munit.FunSuite
import scala.concurrent.Future
import scala.concurrent.ExecutionContext

object Dep {
  def attr: Boolean = true

  throw new IllegalArgumentException("boom")
}

final class InitSuite extends FunSuite {
  test("hanging") {
    Future(assert(Dep.attr))(ExecutionContext.global)
  }
}
java.lang.ExceptionInInitializerError
        at InitSuite.$init$$$anonfun$1$$anonfun$1$$anonfun$1(foo.test.scala:15)
        at munit.Assertions.munitCaptureClues(Assertions.scala:299)
        at munit.Assertions.munitCaptureClues$(Assertions.scala:15)
        at munit.FunSuite.munitCaptureClues(FunSuite.scala:11)
        at munit.Assertions.assert$$anonfun$1(Assertions.scala:30)
        at munit.Assertions.assert$$anonfun$adapted$1(Assertions.scala:34)
        at munit.internal.console.StackTraces$.dropInside(StackTraces.scala:10)
        at munit.Assertions.assert(Assertions.scala:34)
        at munit.Assertions.assert$(Assertions.scala:15)
        at munit.FunSuite.assert(FunSuite.scala:11)
        at InitSuite.$init$$$anonfun$1$$anonfun$1(foo.test.scala:15)
        at InitSuite.$init$$$anonfun$1$$anonfun$adapted$1(foo.test.scala:15)
        at scala.concurrent.Future$.$anonfun$apply$1(Future.scala:687)
        at scala.concurrent.impl.Promise$Transformation.run(Promise.scala:467)
        at java.base/java.util.concurrent.ForkJoinTask$RunnableExecuteAction.exec(ForkJoinTask.java:1395)
        at java.base/java.util.concurrent.ForkJoinTask.doExec(ForkJoinTask.java:373)
        at java.base/java.util.concurrent.ForkJoinPool$WorkQueue.topLevelExec(ForkJoinPool.java:1182)
        at java.base/java.util.concurrent.ForkJoinPool.scan(ForkJoinPool.java:1655)
        at java.base/java.util.concurrent.ForkJoinPool.runWorker(ForkJoinPool.java:1622)
        at java.base/java.util.concurrent.ForkJoinWorkerThread.run(ForkJoinWorkerThread.java:165)
Caused by: java.lang.IllegalArgumentException: boom
        at Dep$.<clinit>(foo.test.scala:10)
        ... 20 more
InitSuite:
==> X InitSuite.hanging  30.01s java.util.concurrent.TimeoutException: test timed out after 30 seconds

h/t @milessabin

armanbilge commented 5 months ago

Might be related to this.

https://github.com/scalameta/munit/blob/83cb747ff13b4f9bad00b0dff94ef1ef12096f2b/munit/shared/src/main/scala/munit/Exceptions.scala#L11-L20

milessabin commented 5 months ago

I think the issue is here, https://github.com/scalameta/munit/blob/83cb747ff13b4f9bad00b0dff94ef1ef12096f2b/munit/jvm/src/main/scala/munit/internal/PlatformCompat.scala#L73-L80 The ExceptionInInitializerError will escape the Try and so the timeout won't be cancelled.