mirror of https://github.com/sbt/sbt.git
Initial working version of makeParallel that support nested tasks.
This commit is contained in:
parent
a920c739d6
commit
48fb0c4ed6
|
|
@ -112,7 +112,7 @@ object Tests
|
|||
val setupTasks = fj(partApp(userSetup) :+ frameworkSetup)
|
||||
val mainTasks =
|
||||
if(config.parallel)
|
||||
makeParallel(runnables, setupTasks, config.tags).toSeq.join
|
||||
makeParallel(loader, runnables, setupTasks, config.tags)//.toSeq.join
|
||||
else
|
||||
makeSerial(loader, runnables, setupTasks, config.tags)
|
||||
val taggedMainTasks = mainTasks.tagw(config.tags : _*)
|
||||
|
|
@ -122,8 +122,30 @@ object Tests
|
|||
}
|
||||
}
|
||||
type TestRunnable = (String, TestFunction)
|
||||
def makeParallel(runnables: Iterable[TestRunnable], setupTasks: Task[Unit], tags: Seq[(Tag,Int)]) =
|
||||
runnables map { case (name, test) => task { (name, test.apply()._1) } tagw(tags : _*) tag(test.tags map (ConcurrentRestrictions.Tag(_)) : _*) dependsOn setupTasks named name }
|
||||
|
||||
private def createNestedRunnables(name: String, loader: ClassLoader, testFun: TestFunction, nestedTasks: Seq[TestTask]): Seq[(String, TestFunction)] =
|
||||
nestedTasks.view.zipWithIndex map { case (nt, idx) =>
|
||||
(name, TestFramework.createTestFunction(loader, new TestDefinition(testFun.testDefinition.name + "-" + idx, testFun.testDefinition.fingerprint), testFun.runner, nt))
|
||||
}
|
||||
|
||||
def makeParallel(loader: ClassLoader, runnables: Iterable[TestRunnable], setupTasks: Task[Unit], tags: Seq[(Tag,Int)]): Task[Map[String,SuiteResult]] =
|
||||
toTasks(loader, runnables.toSeq, tags).dependsOn(setupTasks)
|
||||
|
||||
def toTasks(loader: ClassLoader, runnables: Seq[TestRunnable], tags: Seq[(Tag,Int)]): Task[Map[String, SuiteResult]] = {
|
||||
val tasks = runnables.map { case (name, test) => toTask(loader, name, test, tags) }
|
||||
tasks.join.map( _.foldLeft(Map.empty[String, SuiteResult]) { case (sum, e) =>
|
||||
sum ++ e
|
||||
} )
|
||||
}
|
||||
|
||||
def toTask(loader: ClassLoader, name: String, fun: TestFunction, tags: Seq[(Tag,Int)]): Task[Map[String, SuiteResult]] = {
|
||||
val base = task { (name, fun.apply()) }
|
||||
val taggedBase = base.tagw(tags : _*).tag(fun.tags.map(ConcurrentRestrictions.Tag(_)) : _*)
|
||||
taggedBase flatMap { case (name, (result, nested)) =>
|
||||
val nestedRunnables = createNestedRunnables(fun.testDefinition.name, loader, fun, nested)
|
||||
toTasks(loader, nestedRunnables, tags).map( _.updated(name, result) )
|
||||
}
|
||||
}
|
||||
|
||||
def makeSerial(loader: ClassLoader, runnables: Seq[TestRunnable], setupTasks: Task[Unit], tags: Seq[(Tag,Int)]): Task[List[(String, SuiteResult)]] =
|
||||
{
|
||||
|
|
@ -133,10 +155,7 @@ object Tests
|
|||
case hd :: rst =>
|
||||
val testFun = hd._2
|
||||
val (result, nestedTasks) = testFun.apply()
|
||||
val nestedRunnables =
|
||||
nestedTasks.view.zipWithIndex map { case (nt, idx) =>
|
||||
(hd._1, TestFramework.createTestFunction(loader, new TestDefinition(testFun.testDefinition.name + "-" + idx, testFun.testDefinition.fingerprint), testFun.runner, nt))
|
||||
}
|
||||
val nestedRunnables = createNestedRunnables(testFun.testDefinition.name, loader, testFun, nestedTasks)
|
||||
processRunnable(nestedRunnables.toList ::: rst, (hd._1, result) :: acc)
|
||||
case Nil => acc
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,7 @@
|
|||
scalaVersion := "2.10.1"
|
||||
|
||||
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP15"
|
||||
|
||||
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
||||
|
||||
parallelExecution in Test := true
|
||||
|
|
@ -0,0 +1,30 @@
|
|||
package custom
|
||||
|
||||
import java.io._
|
||||
import org.scalatest._
|
||||
import events._
|
||||
|
||||
class CustomReporter extends Reporter {
|
||||
|
||||
private def writeFile(filePath: String, content: String) {
|
||||
val file = new File(filePath)
|
||||
val writer =
|
||||
if (!file.exists)
|
||||
new FileWriter(new File(filePath))
|
||||
else
|
||||
new FileWriter(new File(filePath + "-2"))
|
||||
writer.write(content)
|
||||
writer.flush()
|
||||
writer.close()
|
||||
}
|
||||
|
||||
def apply(event: Event) {
|
||||
event match {
|
||||
case SuiteStarting(_, suiteName, _, _, _, _, _, _, _, _) => writeFile("target/SuiteStarting-" + suiteName, suiteName)
|
||||
case SuiteCompleted(_, suiteName, _, _, _, _, _, _, _, _, _) => writeFile("target/SuiteCompleted-" + suiteName, suiteName)
|
||||
case TestStarting(_, _, _, _, testName, _, _, _, _, _, _, _) => writeFile("target/TestStarting-" + testName, testName)
|
||||
case TestSucceeded(_, _, _, _, testName, _, _, _, _, _, _, _, _, _) => writeFile("target/TestSucceeded-" + testName, testName)
|
||||
case _ =>
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
package com.test
|
||||
|
||||
import org.scalatest._
|
||||
|
||||
class NestedSpecs extends Suites (
|
||||
new TestSpec
|
||||
)
|
||||
|
||||
@DoNotDiscover
|
||||
class TestSpec extends Spec {
|
||||
|
||||
def `TestSpec-test-1 ` {}
|
||||
|
||||
def `TestSpec-test-2 ` {}
|
||||
|
||||
def `TestSpec-test-3 ` {}
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
#This test that the framework will execute ScalaTest nested suites as parallel nested task (InProcess) properly.
|
||||
#A CustomReporter is used to report expected ScalaTest's events by writing out to files in target/,
|
||||
#it is then used to check for their existence, and if the expected event is fired > 1 (which is unexpected),
|
||||
#a xxxx-2 file will be written, thus here we also check for 'absent' of such file.
|
||||
|
||||
> clean
|
||||
|
||||
> test
|
||||
|
||||
$ exists target/SuiteStarting-NestedSpecs
|
||||
|
||||
$ absent target/SuiteStarting-NestedSpecs-2
|
||||
|
||||
$ exists target/SuiteCompleted-NestedSpecs
|
||||
|
||||
$ absent target/SuiteCompleted-NestedSpecs-2
|
||||
|
||||
$ exists target/SuiteStarting-TestSpec
|
||||
|
||||
$ absent target/SuiteStarting-TestSpec-2
|
||||
|
||||
$ exists target/SuiteCompleted-TestSpec
|
||||
|
||||
$ absent target/SuiteCompleted-TestSpec-2
|
||||
|
||||
$ exists target/TestStarting-TestSpec-test-1
|
||||
|
||||
$ absent target/TestStarting-TestSpec-test-1-2
|
||||
|
||||
$ exists target/TestSucceeded-TestSpec-test-1
|
||||
|
||||
$ absent target/TestSucceeded-TestSpec-test-1-2
|
||||
|
||||
$ exists target/TestStarting-TestSpec-test-2
|
||||
|
||||
$ absent target/TestStarting-TestSpec-test-2-2
|
||||
|
||||
$ exists target/TestSucceeded-TestSpec-test-2
|
||||
|
||||
$ absent target/TestSucceeded-TestSpec-test-2-2
|
||||
|
||||
$ exists target/TestStarting-TestSpec-test-3
|
||||
|
||||
$ absent target/TestStarting-TestSpec-test-3-2
|
||||
|
||||
$ exists target/TestSucceeded-TestSpec-test-3
|
||||
|
||||
$ absent target/TestSucceeded-TestSpec-test-3-2
|
||||
Loading…
Reference in New Issue