Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Cleanup after tests to avoid OOME: Metaspace in fast-run testOnly sequence #254

Open
wants to merge 2 commits into
base: develop
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
31 changes: 31 additions & 0 deletions build.sbt
Original file line number Diff line number Diff line change
Expand Up @@ -102,6 +102,10 @@ lazy val lmCore = (project in file("core"))
managedSourceDirectories in Compile +=
baseDirectory.value / "src" / "main" / "contraband-scala",
sourceManaged in (Compile, generateContrabands) := baseDirectory.value / "src" / "main" / "contraband-scala",
testOptions in Test += {
val log = streams.value.log
Tests.Cleanup { loader => cleanupTests(loader, log) }
},
contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats,
// WORKAROUND sbt/sbt#2205 include managed sources in packageSrc
mappings in (Compile, packageSrc) ++= {
Expand Down Expand Up @@ -227,6 +231,10 @@ lazy val lmIvy = (project in file("ivy"))
contrabandFormatsForType in generateContrabands in Compile := DatatypeConfig.getFormats,
scalacOptions in (Compile, console) --=
Vector("-Ywarn-unused-import", "-Ywarn-unused", "-Xlint"),
testOptions in Test += {
val log = streams.value.log
Tests.Cleanup { loader => cleanupTests(loader, log) }
},
mimaSettings,
mimaBinaryIssueFilters ++= Seq(
exclude[DirectMissingMethodProblem]("sbt.internal.librarymanagement.ivyint.GigahorseUrlHandler#SbtUrlInfo.this"),
Expand Down Expand Up @@ -275,3 +283,26 @@ inThisBuild(Seq(

def inCompileAndTest(ss: SettingsDefinition*): Seq[Setting[_]] =
Seq(Compile, Test) flatMap (inConfig(_)(Def.settings(ss: _*)))


// TODO move into sbt-house-rules?
def cleanupTests(loader: ClassLoader, log: sbt.internal.util.ManagedLogger): Unit = {
// shutdown Log4J to avoid classloader leaks
try {
val logManager = Class.forName("org.apache.logging.log4j.LogManager", false, loader)
logManager.getMethod("shutdown").invoke(null)
log.debug("Log4J2 Shutdown successful!")
} catch {
case _: ClassNotFoundException =>
// not in this classloader
case t: Throwable =>
log.debug("Could not shut down Log4J")
log.trace(t)
}
// Scala Test loads property bundles, let's eagerly clear then from the internal cache
// TODO move into SBT itself?
java.util.ResourceBundle.clearCache(loader)
// Scala Test also starts TimerThreads that it doesn't eagerly cancel. This can weakly retain
// metaspace until a full GC.
System.gc()
}