Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

sbt assembly with integration test

Hi i have an SBT build file that handles Integration test within our organization, the test themselves work and i can run separately unit and it test. However when packaging the app with sbt-assembly i am not able to run both test sequentially (unit ++ it) because it goes out of memory when compiling, here is the sbt.Project with its settings:

  import BuildSettings._
  import Dependencies._
  import Resolvers._

  val name = "api"
  lazy val api = Project(
    name, file("."),
    settings = buildSettings
      ++ Seq(resolvers := repositories, libraryDependencies ++= dependencies)
      ++ SbtStartScript.startScriptForClassesSettings
      ++ Revolver.settings
      ++ assemblySettings
      ++ Seq(jarName := name + "-" + currentGitBranch + ".jar")
  ).configs(IntegrationTest)
    .settings(Defaults.itSettings: _*)
    .settings(parallelExecution in IntegrationTest := false)
    .settings(parallelExecution in Test := true)
    .settings(scalaSource in IntegrationTest := baseDirectory.value / "src/test/scala")
    .settings(resourceDirectory in IntegrationTest := baseDirectory.value / "src/test/resources")
    .settings(
  testOptions in IntegrationTest := Seq(Tests.Filter(itFilter)),
  testOptions in Test := Seq(Tests.Filter(unitFilter))
    )
    .settings(parallelExecution in Compile := true)
    .settings(fork in Compile := true)
    .settings(sources in (Compile, doc) := Seq.empty)
    .settings(test in assembly := Seq(
      (test in Test).value ,
      (test in IntegrationTest).value
    ))

  def currentGitBranch = {
    "git rev-parse --abbrev-ref HEAD".lines_!.mkString.replaceAll("/", "-").replaceAll("heads-", "")
  }

  def itFilter(name: String): Boolean = name endsWith "IT"

  def unitFilter(name: String): Boolean = !itFilter(name)

as you can see i used (test in assembly := { ... }) to specify what test to run during the task assembly::test, however if i run sbt assembly it fails with

java.util.concurrent.ExecutionException: java.lang.OutOfMemoryError:GC overhead limit exceeded

I tried using only one of the two (unit/it) test and it manages to compile but i do need to have them both, any suggestion? Thanks in advance.

Edit: i tried running sbt with SBT_OPTS="-Xmx1536M -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled" and i had a different message in the error, java.lang.OutOfMemoryError: Java heap space

like image 479
user145634 Avatar asked Mar 10 '23 08:03

user145634


1 Answers

What you're doing now is running test and integration test in parallel during the assembly. SBT tries to parallelize all the things by running independent operations in parallel, and definition like this:

test in assembly := Seq(
  (test in Test).value ,
  (test in IntegrationTest).value
)

allows it to do so, because those 2 tasks (test in Test and test in IntegrationTest) are independent from each other.

It might work if you give it more memory with sbt -mem 4096 or even more, but you can also run them sequentially using Def.sequential approach, as described here. Your code would look like this:

test in assembly := Def.sequential(
  test in Test,
  test in IntegrationTest
).value
like image 197
Haspemulator Avatar answered Mar 23 '23 17:03

Haspemulator