mirror of https://github.com/sbt/sbt.git
[2.x] feat: Expose `scripted / excludeFilter` and `scripted / includeFilter` keys for scripted test filtering. (#9131)
* [2.x] feat: Add scripted / includeFilter and scripted / excludeFilter * [2.x] Add scripted-exclude-filter scripted test. Remove stale item from Scripted.sbtWindowsExcludeFilter
This commit is contained in:
parent
d132926197
commit
9275bda052
|
|
@ -1011,7 +1011,9 @@ def scriptedTask(launch: Boolean): Def.Initialize[InputTask[Unit]] = Def.inputTa
|
||||||
.filterNot(_.getName.contains("scala-compiler")),
|
.filterNot(_.getName.contains("scala-compiler")),
|
||||||
(bundledLauncherProj / Compile / packageBin).value,
|
(bundledLauncherProj / Compile / packageBin).value,
|
||||||
streams.value.log,
|
streams.value.log,
|
||||||
scriptedKeepTempDirectory.value
|
scriptedKeepTempDirectory.value,
|
||||||
|
(scripted / includeFilter).value,
|
||||||
|
(scripted / excludeFilter).value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1090,6 +1092,8 @@ def otherRootSettings =
|
||||||
scriptedSource := (sbtProj / sourceDirectory).value / "sbt-test",
|
scriptedSource := (sbtProj / sourceDirectory).value / "sbt-test",
|
||||||
scripted / watchTriggers += scriptedSource.value.toGlob / **,
|
scripted / watchTriggers += scriptedSource.value.toGlob / **,
|
||||||
scriptedUnpublished / watchTriggers := (scripted / watchTriggers).value,
|
scriptedUnpublished / watchTriggers := (scripted / watchTriggers).value,
|
||||||
|
scripted / includeFilter := AllPassFilter,
|
||||||
|
scripted / excludeFilter := Scripted.sbtWindowsExcludeFilter,
|
||||||
scriptedLaunchOpts := List("-Xmx1500M", "-Xms512M", "-server") :::
|
scriptedLaunchOpts := List("-Xmx1500M", "-Xms512M", "-server") :::
|
||||||
(sys.props.get("sbt.ivy.home") match {
|
(sys.props.get("sbt.ivy.home") match {
|
||||||
case Some(home) => List(s"-Dsbt.ivy.home=$home")
|
case Some(home) => List(s"-Dsbt.ivy.home=$home")
|
||||||
|
|
|
||||||
|
|
@ -63,6 +63,8 @@ object ScriptedPlugin extends AutoPlugin {
|
||||||
|
|
||||||
override lazy val projectSettings: Seq[Setting[?]] = Seq(
|
override lazy val projectSettings: Seq[Setting[?]] = Seq(
|
||||||
ivyConfigurations ++= Seq(ScriptedConf, ScriptedLaunchConf),
|
ivyConfigurations ++= Seq(ScriptedConf, ScriptedLaunchConf),
|
||||||
|
scripted / includeFilter := AllPassFilter,
|
||||||
|
scripted / excludeFilter := NothingFilter,
|
||||||
scriptedSbt := (pluginCrossBuild / sbtVersion).value,
|
scriptedSbt := (pluginCrossBuild / sbtVersion).value,
|
||||||
sbtLauncher := Def.uncached(
|
sbtLauncher := Def.uncached(
|
||||||
getJars(ScriptedLaunchConf)
|
getJars(ScriptedLaunchConf)
|
||||||
|
|
@ -183,7 +185,9 @@ object ScriptedPlugin extends AutoPlugin {
|
||||||
scriptedLaunchOpts.value,
|
scriptedLaunchOpts.value,
|
||||||
new java.util.ArrayList[File](),
|
new java.util.ArrayList[File](),
|
||||||
scriptedParallelInstances.value,
|
scriptedParallelInstances.value,
|
||||||
scriptedKeepTempDirectory.value
|
scriptedKeepTempDirectory.value,
|
||||||
|
(scripted / includeFilter).value,
|
||||||
|
(scripted / excludeFilter).value,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,11 @@
|
||||||
|
|
||||||
package sbt
|
package sbt
|
||||||
|
|
||||||
import java.io.File
|
import java.io.{ File, FileFilter as JFileFilter }
|
||||||
import java.lang.reflect.Method
|
import java.lang.reflect.Method
|
||||||
|
|
||||||
|
import sbt.io.{ AllPassFilter, NothingFilter }
|
||||||
|
|
||||||
sealed trait ScriptedRun {
|
sealed trait ScriptedRun {
|
||||||
final def run(
|
final def run(
|
||||||
resourceBaseDirectory: File,
|
resourceBaseDirectory: File,
|
||||||
|
|
@ -62,6 +64,37 @@ sealed trait ScriptedRun {
|
||||||
} catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause }
|
} catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final def run(
|
||||||
|
resourceBaseDirectory: File,
|
||||||
|
bufferLog: Boolean,
|
||||||
|
tests: Seq[String],
|
||||||
|
launcherJar: File,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Seq[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
instances: Int,
|
||||||
|
keepTempDirectory: Boolean,
|
||||||
|
includeFilter: JFileFilter,
|
||||||
|
excludeFilter: JFileFilter,
|
||||||
|
): Unit = {
|
||||||
|
try {
|
||||||
|
invoke(
|
||||||
|
resourceBaseDirectory,
|
||||||
|
bufferLog,
|
||||||
|
tests.toArray,
|
||||||
|
launcherJar,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts.toArray,
|
||||||
|
prescripted,
|
||||||
|
instances,
|
||||||
|
keepTempDirectory,
|
||||||
|
includeFilter,
|
||||||
|
excludeFilter,
|
||||||
|
)
|
||||||
|
()
|
||||||
|
} catch { case e: java.lang.reflect.InvocationTargetException => throw e.getCause }
|
||||||
|
}
|
||||||
|
|
||||||
protected def invoke(
|
protected def invoke(
|
||||||
resourceBaseDirectory: File,
|
resourceBaseDirectory: File,
|
||||||
bufferLog: java.lang.Boolean,
|
bufferLog: java.lang.Boolean,
|
||||||
|
|
@ -97,6 +130,33 @@ sealed trait ScriptedRun {
|
||||||
keepTempDirectory: java.lang.Boolean,
|
keepTempDirectory: java.lang.Boolean,
|
||||||
): AnyRef
|
): AnyRef
|
||||||
|
|
||||||
|
// Default drops filters and calls V3 invoke so V1/V2/V3 subclasses need not override.
|
||||||
|
protected def invoke(
|
||||||
|
resourceBaseDirectory: File,
|
||||||
|
bufferLog: java.lang.Boolean,
|
||||||
|
tests: Array[String],
|
||||||
|
launcherJar: File,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Array[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
instances: java.lang.Integer,
|
||||||
|
keepTempDirectory: java.lang.Boolean,
|
||||||
|
includeFilter: JFileFilter,
|
||||||
|
excludeFilter: JFileFilter,
|
||||||
|
): AnyRef = {
|
||||||
|
invoke(
|
||||||
|
resourceBaseDirectory,
|
||||||
|
bufferLog,
|
||||||
|
tests,
|
||||||
|
launcherJar,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts,
|
||||||
|
prescripted,
|
||||||
|
instances,
|
||||||
|
keepTempDirectory,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
object ScriptedRun {
|
object ScriptedRun {
|
||||||
|
|
@ -108,48 +168,92 @@ object ScriptedRun {
|
||||||
val sCls = classOf[String]
|
val sCls = classOf[String]
|
||||||
val lfCls = classOf[java.util.List[File]]
|
val lfCls = classOf[java.util.List[File]]
|
||||||
val iCls = classOf[Int]
|
val iCls = classOf[Int]
|
||||||
|
val ffCls = classOf[JFileFilter]
|
||||||
|
|
||||||
val clazz = scriptedTests.getClass
|
val clazz = scriptedTests.getClass
|
||||||
if (batchExecution)
|
if (batchExecution)
|
||||||
try
|
try
|
||||||
new RunInParallelV3(
|
new RunInParallelV4(
|
||||||
scriptedTests,
|
scriptedTests,
|
||||||
clazz.getMethod("runInParallel", fCls, bCls, asCls, fCls, sCls, asCls, lfCls, iCls, bCls)
|
clazz.getMethod(
|
||||||
|
"runInParallel",
|
||||||
|
fCls,
|
||||||
|
bCls,
|
||||||
|
asCls,
|
||||||
|
fCls,
|
||||||
|
sCls,
|
||||||
|
asCls,
|
||||||
|
lfCls,
|
||||||
|
iCls,
|
||||||
|
bCls,
|
||||||
|
ffCls,
|
||||||
|
ffCls,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
catch {
|
catch {
|
||||||
case _: NoSuchMethodException =>
|
case _: NoSuchMethodException =>
|
||||||
try
|
try
|
||||||
new RunInParallelV2(
|
new RunInParallelV3(
|
||||||
scriptedTests,
|
scriptedTests,
|
||||||
clazz.getMethod("runInParallel", fCls, bCls, asCls, fCls, sCls, asCls, lfCls, iCls)
|
clazz
|
||||||
|
.getMethod("runInParallel", fCls, bCls, asCls, fCls, sCls, asCls, lfCls, iCls, bCls)
|
||||||
)
|
)
|
||||||
catch {
|
catch {
|
||||||
case _: NoSuchMethodException =>
|
case _: NoSuchMethodException =>
|
||||||
new RunInParallelV1(
|
try
|
||||||
scriptedTests,
|
new RunInParallelV2(
|
||||||
clazz.getMethod("runInParallel", fCls, bCls, asCls, fCls, asCls, lfCls, iCls)
|
scriptedTests,
|
||||||
)
|
clazz
|
||||||
|
.getMethod("runInParallel", fCls, bCls, asCls, fCls, sCls, asCls, lfCls, iCls)
|
||||||
|
)
|
||||||
|
catch {
|
||||||
|
case _: NoSuchMethodException =>
|
||||||
|
new RunInParallelV1(
|
||||||
|
scriptedTests,
|
||||||
|
clazz.getMethod("runInParallel", fCls, bCls, asCls, fCls, asCls, lfCls, iCls)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
try
|
try
|
||||||
new RunV3(
|
new RunV4(
|
||||||
scriptedTests,
|
scriptedTests,
|
||||||
clazz.getMethod("run", fCls, bCls, asCls, fCls, sCls, asCls, lfCls, bCls)
|
clazz.getMethod(
|
||||||
|
"run",
|
||||||
|
fCls,
|
||||||
|
bCls,
|
||||||
|
asCls,
|
||||||
|
fCls,
|
||||||
|
sCls,
|
||||||
|
asCls,
|
||||||
|
lfCls,
|
||||||
|
bCls,
|
||||||
|
ffCls,
|
||||||
|
ffCls,
|
||||||
|
)
|
||||||
)
|
)
|
||||||
catch {
|
catch {
|
||||||
case _: NoSuchMethodException =>
|
case _: NoSuchMethodException =>
|
||||||
try
|
try
|
||||||
new RunV2(
|
new RunV3(
|
||||||
scriptedTests,
|
scriptedTests,
|
||||||
clazz.getMethod("run", fCls, bCls, asCls, fCls, sCls, asCls, lfCls)
|
clazz.getMethod("run", fCls, bCls, asCls, fCls, sCls, asCls, lfCls, bCls)
|
||||||
)
|
)
|
||||||
catch {
|
catch {
|
||||||
case _: NoSuchMethodException =>
|
case _: NoSuchMethodException =>
|
||||||
new RunV1(
|
try
|
||||||
scriptedTests,
|
new RunV2(
|
||||||
clazz.getMethod("run", fCls, bCls, asCls, fCls, asCls, lfCls)
|
scriptedTests,
|
||||||
)
|
clazz.getMethod("run", fCls, bCls, asCls, fCls, sCls, asCls, lfCls)
|
||||||
|
)
|
||||||
|
catch {
|
||||||
|
case _: NoSuchMethodException =>
|
||||||
|
new RunV1(
|
||||||
|
scriptedTests,
|
||||||
|
clazz.getMethod("run", fCls, bCls, asCls, fCls, asCls, lfCls)
|
||||||
|
)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -301,4 +405,113 @@ object ScriptedRun {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private class RunV4(scriptedTests: AnyRef, run: Method) extends ScriptedRun {
|
||||||
|
override protected def invoke(
|
||||||
|
resourceBaseDirectory: File,
|
||||||
|
bufferLog: java.lang.Boolean,
|
||||||
|
tests: Array[String],
|
||||||
|
launcherJar: File,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Array[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
instances: java.lang.Integer,
|
||||||
|
keepTempDirectory: java.lang.Boolean,
|
||||||
|
): AnyRef =
|
||||||
|
invoke(
|
||||||
|
resourceBaseDirectory,
|
||||||
|
bufferLog,
|
||||||
|
tests,
|
||||||
|
launcherJar,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts,
|
||||||
|
prescripted,
|
||||||
|
instances,
|
||||||
|
keepTempDirectory,
|
||||||
|
AllPassFilter,
|
||||||
|
NothingFilter,
|
||||||
|
)
|
||||||
|
|
||||||
|
override protected def invoke(
|
||||||
|
resourceBaseDirectory: File,
|
||||||
|
bufferLog: java.lang.Boolean,
|
||||||
|
tests: Array[String],
|
||||||
|
launcherJar: File,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Array[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
instances: java.lang.Integer,
|
||||||
|
keepTempDirectory: java.lang.Boolean,
|
||||||
|
includeFilter: JFileFilter,
|
||||||
|
excludeFilter: JFileFilter,
|
||||||
|
): AnyRef =
|
||||||
|
run.invoke(
|
||||||
|
scriptedTests,
|
||||||
|
resourceBaseDirectory,
|
||||||
|
bufferLog,
|
||||||
|
tests,
|
||||||
|
launcherJar,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts,
|
||||||
|
prescripted,
|
||||||
|
keepTempDirectory,
|
||||||
|
includeFilter,
|
||||||
|
excludeFilter,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RunInParallelV4(scriptedTests: AnyRef, runInParallel: Method) extends ScriptedRun {
|
||||||
|
override protected def invoke(
|
||||||
|
resourceBaseDirectory: File,
|
||||||
|
bufferLog: java.lang.Boolean,
|
||||||
|
tests: Array[String],
|
||||||
|
launcherJar: File,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Array[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
instances: Integer,
|
||||||
|
keepTempDirectory: java.lang.Boolean,
|
||||||
|
): AnyRef =
|
||||||
|
invoke(
|
||||||
|
resourceBaseDirectory,
|
||||||
|
bufferLog,
|
||||||
|
tests,
|
||||||
|
launcherJar,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts,
|
||||||
|
prescripted,
|
||||||
|
instances,
|
||||||
|
keepTempDirectory,
|
||||||
|
AllPassFilter,
|
||||||
|
NothingFilter,
|
||||||
|
)
|
||||||
|
|
||||||
|
override protected def invoke(
|
||||||
|
resourceBaseDirectory: File,
|
||||||
|
bufferLog: java.lang.Boolean,
|
||||||
|
tests: Array[String],
|
||||||
|
launcherJar: File,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Array[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
instances: Integer,
|
||||||
|
keepTempDirectory: java.lang.Boolean,
|
||||||
|
includeFilter: JFileFilter,
|
||||||
|
excludeFilter: JFileFilter,
|
||||||
|
): AnyRef =
|
||||||
|
runInParallel.invoke(
|
||||||
|
scriptedTests,
|
||||||
|
resourceBaseDirectory,
|
||||||
|
bufferLog,
|
||||||
|
tests,
|
||||||
|
launcherJar,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts,
|
||||||
|
prescripted,
|
||||||
|
instances,
|
||||||
|
keepTempDirectory,
|
||||||
|
includeFilter,
|
||||||
|
excludeFilter,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,20 @@ object Scripted {
|
||||||
|
|
||||||
val RepoOverrideTest = config("repoOverrideTest") extend Compile
|
val RepoOverrideTest = config("repoOverrideTest") extend Compile
|
||||||
|
|
||||||
|
val sbtWindowsExcludeFilter: FileFilter =
|
||||||
|
if (scala.util.Properties.isWin)
|
||||||
|
new SimpleFileFilter(f =>
|
||||||
|
(f.getParentFile.getName, f.getName) match {
|
||||||
|
case ("classloader-cache", "jni") => true // no native lib is built for windows
|
||||||
|
case ("classloader-cache", "spark") =>
|
||||||
|
true // the test spark server is unable to bind to a local socket on Visual Studio 2019
|
||||||
|
case ("nio", "make-clone") => true // uses gcc which isn't set up on all systems
|
||||||
|
case ("watch", "symlinks") => true // symlinks don't work the same on windows
|
||||||
|
case _ => false
|
||||||
|
}
|
||||||
|
)
|
||||||
|
else NothingFilter
|
||||||
|
|
||||||
import sbt.complete.*
|
import sbt.complete.*
|
||||||
|
|
||||||
// Paging, 1-index based.
|
// Paging, 1-index based.
|
||||||
|
|
@ -106,7 +120,9 @@ object Scripted {
|
||||||
classpath: Seq[File],
|
classpath: Seq[File],
|
||||||
launcherJar: File,
|
launcherJar: File,
|
||||||
logger: Logger,
|
logger: Logger,
|
||||||
keepTempDirectory: Boolean
|
keepTempDirectory: Boolean,
|
||||||
|
includeFilter: java.io.FileFilter,
|
||||||
|
excludeFilter: java.io.FileFilter,
|
||||||
): Unit = {
|
): Unit = {
|
||||||
logger.info(s"Tests selected: ${args.mkString("\n * ", "\n * ", "\n")}")
|
logger.info(s"Tests selected: ${args.mkString("\n * ", "\n * ", "\n")}")
|
||||||
logger.info("")
|
logger.info("")
|
||||||
|
|
@ -120,18 +136,6 @@ object Scripted {
|
||||||
|
|
||||||
// Interface to cross class loader
|
// Interface to cross class loader
|
||||||
type SbtScriptedRunner = {
|
type SbtScriptedRunner = {
|
||||||
// def runInParallel(
|
|
||||||
// resourceBaseDirectory: File,
|
|
||||||
// bufferLog: Boolean,
|
|
||||||
// tests: Array[String],
|
|
||||||
// launchOpts: Array[String],
|
|
||||||
// prescripted: java.util.List[File],
|
|
||||||
// scalaVersion: String,
|
|
||||||
// sbtVersion: String,
|
|
||||||
// classpath: Array[File],
|
|
||||||
// instances: Int
|
|
||||||
// ): Unit
|
|
||||||
|
|
||||||
def runInParallel(
|
def runInParallel(
|
||||||
resourceBaseDirectory: File,
|
resourceBaseDirectory: File,
|
||||||
bufferLog: Boolean,
|
bufferLog: Boolean,
|
||||||
|
|
@ -141,7 +145,9 @@ object Scripted {
|
||||||
launchOpts: Array[String],
|
launchOpts: Array[String],
|
||||||
prescripted: java.util.List[File],
|
prescripted: java.util.List[File],
|
||||||
instance: Int,
|
instance: Int,
|
||||||
keepTempDirectory: Boolean
|
keepTempDirectory: Boolean,
|
||||||
|
includeFilter: java.io.FileFilter,
|
||||||
|
excludeFilter: java.io.FileFilter,
|
||||||
): Unit
|
): Unit
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -166,17 +172,6 @@ object Scripted {
|
||||||
}
|
}
|
||||||
import scala.language.reflectiveCalls
|
import scala.language.reflectiveCalls
|
||||||
|
|
||||||
// bridge.runInParallel(
|
|
||||||
// sourcePath,
|
|
||||||
// bufferLog,
|
|
||||||
// args.toArray,
|
|
||||||
// launchOpts.toArray,
|
|
||||||
// callback,
|
|
||||||
// scalaVersion,
|
|
||||||
// sbtVersion,
|
|
||||||
// classpath.toArray,
|
|
||||||
// instances
|
|
||||||
// )
|
|
||||||
bridge.runInParallel(
|
bridge.runInParallel(
|
||||||
sourcePath,
|
sourcePath,
|
||||||
bufferLog,
|
bufferLog,
|
||||||
|
|
@ -186,7 +181,9 @@ object Scripted {
|
||||||
launchOpts.toArray,
|
launchOpts.toArray,
|
||||||
callback,
|
callback,
|
||||||
instances,
|
instances,
|
||||||
keepTempDirectory
|
keepTempDirectory,
|
||||||
|
includeFilter,
|
||||||
|
excludeFilter,
|
||||||
)
|
)
|
||||||
} catch { case ite: InvocationTargetException => throw ite.getCause }
|
} catch { case ite: InvocationTargetException => throw ite.getCause }
|
||||||
} finally {
|
} finally {
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,5 @@
|
||||||
|
lazy val root = (project in file("."))
|
||||||
|
.enablePlugins(SbtPlugin)
|
||||||
|
.settings(
|
||||||
|
scripted / excludeFilter := new SimpleFileFilter(_.getName == "skipped")
|
||||||
|
)
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
addSbtPlugin("nonexistent.example" % "sbt-nonexistent" % "0.0.0")
|
||||||
|
|
@ -0,0 +1 @@
|
||||||
|
> compile
|
||||||
|
|
@ -0,0 +1,23 @@
|
||||||
|
# `passing` is a project that compiles; `skipped` has a project/plugins.sbt referencing a
|
||||||
|
# fictitious plugin so its sbt session fails to load if actually run.
|
||||||
|
$ copy-file changes/ok-test src/sbt-test/group/passing/test
|
||||||
|
$ copy-file changes/ok-test src/sbt-test/group/skipped/test
|
||||||
|
$ copy-file changes/broken-plugins.sbt src/sbt-test/group/skipped/project/plugins.sbt
|
||||||
|
|
||||||
|
> scripted
|
||||||
|
|
||||||
|
# Explicit selection of the un-filtered test. Succeeds.
|
||||||
|
> scripted group/passing
|
||||||
|
|
||||||
|
# Explicit selection of a filtered test yields "No tests found matching" error.
|
||||||
|
-> scripted group/skipped
|
||||||
|
|
||||||
|
# Replace the excludeFilter to let both run. `skipped` now fails.
|
||||||
|
> set scripted / excludeFilter := NothingFilter
|
||||||
|
-> scripted
|
||||||
|
-> scripted group/skipped
|
||||||
|
|
||||||
|
# Flip to includeFilter: only accept tests whose name is "passing".
|
||||||
|
> set scripted / includeFilter := new SimpleFileFilter(_.getName == "passing")
|
||||||
|
> scripted
|
||||||
|
-> scripted group/skipped
|
||||||
|
|
@ -102,7 +102,6 @@ final class ScriptedTests(
|
||||||
Map('$' -> fileHandler, '>' -> sbtHandler, '#' -> CommentHandler)
|
Map('$' -> fileHandler, '>' -> sbtHandler, '#' -> CommentHandler)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Returns a sequence of test runners that have to be applied in the call site. */
|
|
||||||
def batchScriptedRunner(
|
def batchScriptedRunner(
|
||||||
testGroupAndNames: Seq[(String, String)],
|
testGroupAndNames: Seq[(String, String)],
|
||||||
prescripted: File => Unit,
|
prescripted: File => Unit,
|
||||||
|
|
@ -110,6 +109,28 @@ final class ScriptedTests(
|
||||||
prop: RemoteSbtCreatorProp,
|
prop: RemoteSbtCreatorProp,
|
||||||
log: Logger,
|
log: Logger,
|
||||||
keepTempDirectory: Boolean = false,
|
keepTempDirectory: Boolean = false,
|
||||||
|
): Seq[TestRunner] =
|
||||||
|
batchScriptedRunner(
|
||||||
|
testGroupAndNames,
|
||||||
|
prescripted,
|
||||||
|
sbtInstances,
|
||||||
|
prop,
|
||||||
|
log,
|
||||||
|
keepTempDirectory,
|
||||||
|
AllPassFilter,
|
||||||
|
NothingFilter,
|
||||||
|
)
|
||||||
|
|
||||||
|
/** Returns a sequence of test runners that have to be applied in the call site. */
|
||||||
|
def batchScriptedRunner(
|
||||||
|
testGroupAndNames: Seq[(String, String)],
|
||||||
|
prescripted: File => Unit,
|
||||||
|
sbtInstances: Int,
|
||||||
|
prop: RemoteSbtCreatorProp,
|
||||||
|
log: Logger,
|
||||||
|
keepTempDirectory: Boolean,
|
||||||
|
includeFilter: java.io.FileFilter,
|
||||||
|
excludeFilter: java.io.FileFilter,
|
||||||
): Seq[TestRunner] = {
|
): Seq[TestRunner] = {
|
||||||
// Test group and names may be file filters (like '*')
|
// Test group and names may be file filters (like '*')
|
||||||
val groupAndNameDirs = {
|
val groupAndNameDirs = {
|
||||||
|
|
@ -117,12 +138,14 @@ final class ScriptedTests(
|
||||||
(group, name) <- testGroupAndNames
|
(group, name) <- testGroupAndNames
|
||||||
groupDir <- (resourceBaseDirectory * group).get()
|
groupDir <- (resourceBaseDirectory * group).get()
|
||||||
testDir <- (groupDir * name).get()
|
testDir <- (groupDir * name).get()
|
||||||
|
if !testDir.isFile
|
||||||
|
if includeFilter.accept(testDir) && !excludeFilter.accept(testDir)
|
||||||
} yield (groupDir, testDir)
|
} yield (groupDir, testDir)
|
||||||
}
|
}
|
||||||
|
|
||||||
type TestInfo = ((String, String), File)
|
type TestInfo = ((String, String), File)
|
||||||
|
|
||||||
val labelsAndDirs = groupAndNameDirs.filterNot(_._2.isFile).map { (groupDir, nameDir) =>
|
val labelsAndDirs = groupAndNameDirs.map { (groupDir, nameDir) =>
|
||||||
val groupName = groupDir.getName
|
val groupName = groupDir.getName
|
||||||
val testName = nameDir.getName
|
val testName = nameDir.getName
|
||||||
val testDirectory = testResources.readOnlyResourceDirectory(groupName, testName)
|
val testDirectory = testResources.readOnlyResourceDirectory(groupName, testName)
|
||||||
|
|
@ -137,18 +160,15 @@ final class ScriptedTests(
|
||||||
case s => s
|
case s => s
|
||||||
}
|
}
|
||||||
|
|
||||||
val runFromSourceBasedTestsUnfiltered = labelsAndDirs
|
|
||||||
val runFromSourceBasedTests = runFromSourceBasedTestsUnfiltered.filterNot(windowsExclude)
|
|
||||||
|
|
||||||
def logTests(size: Int, how: String) =
|
def logTests(size: Int, how: String) =
|
||||||
log.info(
|
log.info(
|
||||||
f"Running $size / $totalSize (${size * 100d / totalSize}%3.2f%%) scripted tests with $how"
|
f"Running $size / $totalSize (${size * 100d / totalSize}%3.2f%%) scripted tests with $how"
|
||||||
)
|
)
|
||||||
logTests(runFromSourceBasedTests.size, prop.toString)
|
logTests(labelsAndDirs.size, prop.toString)
|
||||||
|
|
||||||
if (keepTempDirectory && runFromSourceBasedTests.size > 1) {
|
if (keepTempDirectory && labelsAndDirs.size > 1) {
|
||||||
sys.error(
|
sys.error(
|
||||||
s"scriptedKeepTempDirectory requires exactly one test, but ${runFromSourceBasedTests.size} tests were requested"
|
s"scriptedKeepTempDirectory requires exactly one test, but ${labelsAndDirs.size} tests were requested"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -170,27 +190,10 @@ final class ScriptedTests(
|
||||||
.toList
|
.toList
|
||||||
}
|
}
|
||||||
|
|
||||||
createTestRunners(runFromSourceBasedTests)
|
createTestRunners(labelsAndDirs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val windowsExclude: (((String, String), File)) => Boolean =
|
|
||||||
if (scala.util.Properties.isWin) { case (testName, _) =>
|
|
||||||
testName match {
|
|
||||||
case ("classloader-cache", "jni") => true // no native lib is built for windows
|
|
||||||
case ("classloader-cache", "snapshot") =>
|
|
||||||
true // the test overwrites a jar that is being used which is verboten in windows
|
|
||||||
// The test spark server is unable to bind to a local socket on Visual Studio 2019
|
|
||||||
case ("classloader-cache", "spark") => true
|
|
||||||
case ("nio", "make-clone") => true // uses gcc which isn't set up on all systems
|
|
||||||
// symlinks don't work the same on windows. Symlink monitoring does work in many cases
|
|
||||||
// on windows but not to the same level as it does on osx and linux
|
|
||||||
case ("watch", "symlinks") => true
|
|
||||||
case _ => false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else _ => false
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines the batch execution of scripted tests.
|
* Defines the batch execution of scripted tests.
|
||||||
*
|
*
|
||||||
|
|
@ -512,6 +515,37 @@ class ScriptedRunner {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Entry point with configurable include/exclude filters. */
|
||||||
|
def run(
|
||||||
|
resourceBaseDirectory: File,
|
||||||
|
bufferLog: Boolean,
|
||||||
|
tests: Array[String],
|
||||||
|
launcherJar: File,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Array[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
keepTempDirectory: Boolean,
|
||||||
|
includeFilter: java.io.FileFilter,
|
||||||
|
excludeFilter: java.io.FileFilter,
|
||||||
|
): Unit = {
|
||||||
|
val logger = TestConsoleLogger()
|
||||||
|
run(
|
||||||
|
resourceBaseDirectory,
|
||||||
|
bufferLog,
|
||||||
|
tests,
|
||||||
|
logger,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts,
|
||||||
|
prescripted,
|
||||||
|
LauncherBased(launcherJar),
|
||||||
|
Int.MaxValue,
|
||||||
|
parallelExecution = false,
|
||||||
|
keepTempDirectory,
|
||||||
|
includeFilter,
|
||||||
|
excludeFilter,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the entry point used by SbtPlugin in sbt 1.2.x, 1.3.x, 1.4.x etc.
|
* This is the entry point used by SbtPlugin in sbt 1.2.x, 1.3.x, 1.4.x etc.
|
||||||
* Removing this method will break scripted and sbt plugin cross building.
|
* Removing this method will break scripted and sbt plugin cross building.
|
||||||
|
|
@ -596,6 +630,37 @@ class ScriptedRunner {
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** Entry point with configurable include/exclude filters. */
|
||||||
|
def runInParallel(
|
||||||
|
resourceBaseDirectory: File,
|
||||||
|
bufferLog: Boolean,
|
||||||
|
tests: Array[String],
|
||||||
|
launcherJar: File,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Array[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
instance: Int,
|
||||||
|
keepTempDirectory: Boolean,
|
||||||
|
includeFilter: java.io.FileFilter,
|
||||||
|
excludeFilter: java.io.FileFilter,
|
||||||
|
): Unit = {
|
||||||
|
val logger = TestConsoleLogger()
|
||||||
|
runInParallel(
|
||||||
|
resourceBaseDirectory,
|
||||||
|
bufferLog,
|
||||||
|
tests,
|
||||||
|
logger,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts,
|
||||||
|
prescripted,
|
||||||
|
LauncherBased(launcherJar),
|
||||||
|
instance,
|
||||||
|
keepTempDirectory,
|
||||||
|
includeFilter,
|
||||||
|
excludeFilter,
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
// This is called by project/Scripted.scala
|
// This is called by project/Scripted.scala
|
||||||
// Using java.util.List[File] to encode File => Unit
|
// Using java.util.List[File] to encode File => Unit
|
||||||
def runInParallel(
|
def runInParallel(
|
||||||
|
|
@ -633,6 +698,35 @@ class ScriptedRunner {
|
||||||
prop: RemoteSbtCreatorProp,
|
prop: RemoteSbtCreatorProp,
|
||||||
instances: Int,
|
instances: Int,
|
||||||
keepTempDirectory: Boolean = false,
|
keepTempDirectory: Boolean = false,
|
||||||
|
): Unit =
|
||||||
|
runInParallel(
|
||||||
|
baseDir,
|
||||||
|
bufferLog,
|
||||||
|
tests,
|
||||||
|
logger,
|
||||||
|
javaCommand,
|
||||||
|
launchOpts,
|
||||||
|
prescripted,
|
||||||
|
prop,
|
||||||
|
instances,
|
||||||
|
keepTempDirectory,
|
||||||
|
AllPassFilter,
|
||||||
|
NothingFilter,
|
||||||
|
)
|
||||||
|
|
||||||
|
private[sbt] def runInParallel(
|
||||||
|
baseDir: File,
|
||||||
|
bufferLog: Boolean,
|
||||||
|
tests: Array[String],
|
||||||
|
logger: Logger,
|
||||||
|
javaCommand: String,
|
||||||
|
launchOpts: Array[String],
|
||||||
|
prescripted: java.util.List[File],
|
||||||
|
prop: RemoteSbtCreatorProp,
|
||||||
|
instances: Int,
|
||||||
|
keepTempDirectory: Boolean,
|
||||||
|
includeFilter: java.io.FileFilter,
|
||||||
|
excludeFilter: java.io.FileFilter,
|
||||||
): Unit =
|
): Unit =
|
||||||
run(
|
run(
|
||||||
baseDir,
|
baseDir,
|
||||||
|
|
@ -646,6 +740,8 @@ class ScriptedRunner {
|
||||||
instances,
|
instances,
|
||||||
parallelExecution = true,
|
parallelExecution = true,
|
||||||
keepTempDirectory,
|
keepTempDirectory,
|
||||||
|
includeFilter,
|
||||||
|
excludeFilter,
|
||||||
)
|
)
|
||||||
|
|
||||||
private def run(
|
private def run(
|
||||||
|
|
@ -660,6 +756,8 @@ class ScriptedRunner {
|
||||||
instances: Int,
|
instances: Int,
|
||||||
parallelExecution: Boolean,
|
parallelExecution: Boolean,
|
||||||
keepTempDirectory: Boolean = false,
|
keepTempDirectory: Boolean = false,
|
||||||
|
includeFilter: java.io.FileFilter = AllPassFilter,
|
||||||
|
excludeFilter: java.io.FileFilter = NothingFilter,
|
||||||
): Unit = {
|
): Unit = {
|
||||||
val addTestFile = (f: File) => { prescripted.add(f); () }
|
val addTestFile = (f: File) => { prescripted.add(f); () }
|
||||||
val runner = new ScriptedTests(baseDir, bufferLog, javaCommand, launchOpts.toIndexedSeq)
|
val runner = new ScriptedTests(baseDir, bufferLog, javaCommand, launchOpts.toIndexedSeq)
|
||||||
|
|
@ -682,7 +780,9 @@ class ScriptedRunner {
|
||||||
groupCount,
|
groupCount,
|
||||||
prop,
|
prop,
|
||||||
logger,
|
logger,
|
||||||
keepTempDirectory
|
keepTempDirectory,
|
||||||
|
includeFilter,
|
||||||
|
excludeFilter,
|
||||||
)
|
)
|
||||||
// Fail if user provided test patterns but none matched any existing test directories
|
// Fail if user provided test patterns but none matched any existing test directories
|
||||||
if (tests.nonEmpty && scriptedRunners.isEmpty) {
|
if (tests.nonEmpty && scriptedRunners.isEmpty) {
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue