mirror of https://github.com/sbt/sbt.git
update TestFramework
- update reset.sh for debugging - use Vector around TestFramework - unbind existing appdenders from newLog - register string codec for TestStringEvent
This commit is contained in:
parent
b013c30c30
commit
2b5637270a
|
|
@ -16,7 +16,7 @@ import sbt.protocol.testing._
|
||||||
|
|
||||||
private[sbt] object ForkTests {
|
private[sbt] object ForkTests {
|
||||||
def apply(runners: Map[TestFramework, Runner],
|
def apply(runners: Map[TestFramework, Runner],
|
||||||
tests: List[TestDefinition],
|
tests: Vector[TestDefinition],
|
||||||
config: Execution,
|
config: Execution,
|
||||||
classpath: Seq[File],
|
classpath: Seq[File],
|
||||||
fork: ForkOptions,
|
fork: ForkOptions,
|
||||||
|
|
|
||||||
|
|
@ -128,13 +128,13 @@ object Tests {
|
||||||
final case class Group(name: String, tests: Seq[TestDefinition], runPolicy: TestRunPolicy)
|
final case class Group(name: String, tests: Seq[TestDefinition], runPolicy: TestRunPolicy)
|
||||||
|
|
||||||
private[sbt] final class ProcessedOptions(
|
private[sbt] final class ProcessedOptions(
|
||||||
val tests: Seq[TestDefinition],
|
val tests: Vector[TestDefinition],
|
||||||
val setup: Seq[ClassLoader => Unit],
|
val setup: Vector[ClassLoader => Unit],
|
||||||
val cleanup: Seq[ClassLoader => Unit],
|
val cleanup: Vector[ClassLoader => Unit],
|
||||||
val testListeners: Seq[TestReportListener]
|
val testListeners: Vector[TestReportListener]
|
||||||
)
|
)
|
||||||
private[sbt] def processOptions(config: Execution,
|
private[sbt] def processOptions(config: Execution,
|
||||||
discovered: Seq[TestDefinition],
|
discovered: Vector[TestDefinition],
|
||||||
log: Logger): ProcessedOptions = {
|
log: Logger): ProcessedOptions = {
|
||||||
import collection.mutable.{ HashSet, ListBuffer }
|
import collection.mutable.{ HashSet, ListBuffer }
|
||||||
val testFilters = new ListBuffer[String => Boolean]
|
val testFilters = new ListBuffer[String => Boolean]
|
||||||
|
|
@ -172,7 +172,10 @@ object Tests {
|
||||||
if (orderedFilters.isEmpty) filtered0
|
if (orderedFilters.isEmpty) filtered0
|
||||||
else orderedFilters.flatMap(f => filtered0.filter(d => f(d.name))).toList.distinct
|
else orderedFilters.flatMap(f => filtered0.filter(d => f(d.name))).toList.distinct
|
||||||
val uniqueTests = distinctBy(tests)(_.name)
|
val uniqueTests = distinctBy(tests)(_.name)
|
||||||
new ProcessedOptions(uniqueTests, setup.toList, cleanup.toList, testListeners.toList)
|
new ProcessedOptions(uniqueTests.toVector,
|
||||||
|
setup.toVector,
|
||||||
|
cleanup.toVector,
|
||||||
|
testListeners.toVector)
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] def distinctBy[T, K](in: Seq[T])(f: T => K): Seq[T] = {
|
private[this] def distinctBy[T, K](in: Seq[T])(f: T => K): Seq[T] = {
|
||||||
|
|
@ -183,7 +186,7 @@ object Tests {
|
||||||
def apply(frameworks: Map[TestFramework, Framework],
|
def apply(frameworks: Map[TestFramework, Framework],
|
||||||
testLoader: ClassLoader,
|
testLoader: ClassLoader,
|
||||||
runners: Map[TestFramework, Runner],
|
runners: Map[TestFramework, Runner],
|
||||||
discovered: Seq[TestDefinition],
|
discovered: Vector[TestDefinition],
|
||||||
config: Execution,
|
config: Execution,
|
||||||
log: ManagedLogger): Task[Output] = {
|
log: ManagedLogger): Task[Output] = {
|
||||||
val o = processOptions(config, discovered, log)
|
val o = processOptions(config, discovered, log)
|
||||||
|
|
@ -201,11 +204,11 @@ object Tests {
|
||||||
def testTask(loader: ClassLoader,
|
def testTask(loader: ClassLoader,
|
||||||
frameworks: Map[TestFramework, Framework],
|
frameworks: Map[TestFramework, Framework],
|
||||||
runners: Map[TestFramework, Runner],
|
runners: Map[TestFramework, Runner],
|
||||||
tests: Seq[TestDefinition],
|
tests: Vector[TestDefinition],
|
||||||
userSetup: Iterable[ClassLoader => Unit],
|
userSetup: Iterable[ClassLoader => Unit],
|
||||||
userCleanup: Iterable[ClassLoader => Unit],
|
userCleanup: Iterable[ClassLoader => Unit],
|
||||||
log: ManagedLogger,
|
log: ManagedLogger,
|
||||||
testListeners: Seq[TestReportListener],
|
testListeners: Vector[TestReportListener],
|
||||||
config: Execution): Task[Output] = {
|
config: Execution): Task[Output] = {
|
||||||
def fj(actions: Iterable[() => Unit]): Task[Unit] = nop.dependsOn(actions.toSeq.fork(_()): _*)
|
def fj(actions: Iterable[() => Unit]): Task[Unit] = nop.dependsOn(actions.toSeq.fork(_()): _*)
|
||||||
def partApp(actions: Iterable[ClassLoader => Unit]) = actions.toSeq map { a => () =>
|
def partApp(actions: Iterable[ClassLoader => Unit]) = actions.toSeq map { a => () =>
|
||||||
|
|
|
||||||
|
|
@ -845,7 +845,7 @@ object Defaults extends BuildCommon {
|
||||||
val forkedConfig = config.copy(parallel = config.parallel && forkedParallelExecution)
|
val forkedConfig = config.copy(parallel = config.parallel && forkedParallelExecution)
|
||||||
s.log.debug(s"Forking tests - parallelism = ${forkedConfig.parallel}")
|
s.log.debug(s"Forking tests - parallelism = ${forkedConfig.parallel}")
|
||||||
ForkTests(runners,
|
ForkTests(runners,
|
||||||
tests.toList,
|
tests.toVector,
|
||||||
forkedConfig,
|
forkedConfig,
|
||||||
cp.files,
|
cp.files,
|
||||||
opts,
|
opts,
|
||||||
|
|
@ -855,7 +855,7 @@ object Defaults extends BuildCommon {
|
||||||
if (javaOptions.nonEmpty) {
|
if (javaOptions.nonEmpty) {
|
||||||
s.log.warn("javaOptions will be ignored, fork is set to false")
|
s.log.warn("javaOptions will be ignored, fork is set to false")
|
||||||
}
|
}
|
||||||
Tests(frameworks, loader, runners, tests, config, s.log)
|
Tests(frameworks, loader, runners, tests.toVector, config, s.log)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
val output = Tests.foldTasks(groupTasks, config.parallel)
|
val output = Tests.foldTasks(groupTasks, config.parallel)
|
||||||
|
|
|
||||||
2
reset.sh
2
reset.sh
|
|
@ -1,3 +1,3 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
rm -rf ~/.sbt/boot/scala-2.11.8/org.scala-sbt/sbt/1.0.0-SNAPSHOT/
|
rm -rf ~/.sbt/boot/scala-2.12.2/org.scala-sbt/sbt/1.0.0-SNAPSHOT/
|
||||||
|
|
|
||||||
|
|
@ -73,7 +73,7 @@ final class TestDefinition(val name: String,
|
||||||
override def hashCode: Int = (name.hashCode, TestFramework.hashCode(fingerprint)).hashCode
|
override def hashCode: Int = (name.hashCode, TestFramework.hashCode(fingerprint)).hashCode
|
||||||
}
|
}
|
||||||
|
|
||||||
final class TestRunner(delegate: Runner, listeners: Seq[TestReportListener], log: ManagedLogger) {
|
final class TestRunner(delegate: Runner, listeners: Vector[TestReportListener], log: ManagedLogger) {
|
||||||
|
|
||||||
final def tasks(testDefs: Set[TestDefinition]): Array[TestTask] =
|
final def tasks(testDefs: Set[TestDefinition]): Array[TestTask] =
|
||||||
delegate.tasks(
|
delegate.tasks(
|
||||||
|
|
@ -93,10 +93,12 @@ final class TestRunner(delegate: Runner, listeners: Seq[TestReportListener], log
|
||||||
// here we get the results! here is where we'd pass in the event listener
|
// here we get the results! here is where we'd pass in the event listener
|
||||||
val results = new scala.collection.mutable.ListBuffer[Event]
|
val results = new scala.collection.mutable.ListBuffer[Event]
|
||||||
val handler = new EventHandler { def handle(e: Event): Unit = { results += e } }
|
val handler = new EventHandler { def handle(e: Event): Unit = { results += e } }
|
||||||
val loggers = listeners.flatMap(_.contentLogger(testDefinition))
|
val loggers: Vector[ContentLogger] = listeners.flatMap(_.contentLogger(testDefinition))
|
||||||
val nestedTasks =
|
val nestedTasks =
|
||||||
try testTask.execute(handler, loggers.map(_.log).toArray)
|
try testTask.execute(handler, loggers.map(_.log).toArray)
|
||||||
finally loggers.foreach(_.flush())
|
finally {
|
||||||
|
loggers.foreach(_.flush())
|
||||||
|
}
|
||||||
val event = TestEvent(results)
|
val event = TestEvent(results)
|
||||||
safeListenersCall(_.testEvent(event))
|
safeListenersCall(_.testEvent(event))
|
||||||
(SuiteResult(results), nestedTasks.toSeq)
|
(SuiteResult(results), nestedTasks.toSeq)
|
||||||
|
|
@ -157,13 +159,13 @@ object TestFramework {
|
||||||
frameworks: Map[TestFramework, Framework],
|
frameworks: Map[TestFramework, Framework],
|
||||||
runners: Map[TestFramework, Runner],
|
runners: Map[TestFramework, Runner],
|
||||||
testLoader: ClassLoader,
|
testLoader: ClassLoader,
|
||||||
tests: Seq[TestDefinition],
|
tests: Vector[TestDefinition],
|
||||||
log: ManagedLogger,
|
log: ManagedLogger,
|
||||||
listeners: Seq[TestReportListener]
|
listeners: Vector[TestReportListener]
|
||||||
): (() => Unit, Seq[(String, TestFunction)], TestResult => () => Unit) = {
|
): (() => Unit, Vector[(String, TestFunction)], TestResult => () => Unit) = {
|
||||||
val mappedTests = testMap(frameworks.values.toSeq, tests)
|
val mappedTests = testMap(frameworks.values.toSeq, tests)
|
||||||
if (mappedTests.isEmpty)
|
if (mappedTests.isEmpty)
|
||||||
(() => (), Nil, _ => () => ())
|
(() => (), Vector(), _ => () => ())
|
||||||
else
|
else
|
||||||
createTestTasks(testLoader, runners.map {
|
createTestTasks(testLoader, runners.map {
|
||||||
case (tf, r) => (frameworks(tf), new TestRunner(r, listeners, log))
|
case (tf, r) => (frameworks(tf), new TestRunner(r, listeners, log))
|
||||||
|
|
@ -171,7 +173,7 @@ object TestFramework {
|
||||||
}
|
}
|
||||||
|
|
||||||
private[this] def order(mapped: Map[String, TestFunction],
|
private[this] def order(mapped: Map[String, TestFunction],
|
||||||
inputs: Seq[TestDefinition]): Seq[(String, TestFunction)] =
|
inputs: Vector[TestDefinition]): Vector[(String, TestFunction)] =
|
||||||
for (d <- inputs; act <- mapped.get(d.name)) yield (d.name, act)
|
for (d <- inputs; act <- mapped.get(d.name)) yield (d.name, act)
|
||||||
|
|
||||||
private[this] def testMap(frameworks: Seq[Framework],
|
private[this] def testMap(frameworks: Seq[Framework],
|
||||||
|
|
@ -193,9 +195,10 @@ object TestFramework {
|
||||||
private def createTestTasks(loader: ClassLoader,
|
private def createTestTasks(loader: ClassLoader,
|
||||||
runners: Map[Framework, TestRunner],
|
runners: Map[Framework, TestRunner],
|
||||||
tests: Map[Framework, Set[TestDefinition]],
|
tests: Map[Framework, Set[TestDefinition]],
|
||||||
ordered: Seq[TestDefinition],
|
ordered: Vector[TestDefinition],
|
||||||
log: ManagedLogger,
|
log: ManagedLogger,
|
||||||
listeners: Seq[TestReportListener]) = {
|
listeners: Vector[TestReportListener])
|
||||||
|
: (() => Unit, Vector[(String, TestFunction)], TestResult => (() => Unit)) = {
|
||||||
val testsListeners = listeners collect { case tl: TestsListener => tl }
|
val testsListeners = listeners collect { case tl: TestsListener => tl }
|
||||||
|
|
||||||
def foreachListenerSafe(f: TestsListener => Unit): () => Unit =
|
def foreachListenerSafe(f: TestsListener => Unit): () => Unit =
|
||||||
|
|
|
||||||
|
|
@ -3,7 +3,7 @@ package internal.testing
|
||||||
|
|
||||||
import testing.{ Logger => TLogger }
|
import testing.{ Logger => TLogger }
|
||||||
import sbt.internal.util.{ ManagedLogger, BufferedAppender }
|
import sbt.internal.util.{ ManagedLogger, BufferedAppender }
|
||||||
import sbt.util.{ Level, LogExchange }
|
import sbt.util.{ Level, LogExchange, ShowLines }
|
||||||
import sbt.protocol.testing._
|
import sbt.protocol.testing._
|
||||||
import java.util.concurrent.atomic.AtomicInteger
|
import java.util.concurrent.atomic.AtomicInteger
|
||||||
import scala.collection.JavaConverters._
|
import scala.collection.JavaConverters._
|
||||||
|
|
@ -11,6 +11,11 @@ import scala.collection.JavaConverters._
|
||||||
object TestLogger {
|
object TestLogger {
|
||||||
import sbt.protocol.testing.codec.JsonProtocol._
|
import sbt.protocol.testing.codec.JsonProtocol._
|
||||||
|
|
||||||
|
implicit val testStringEventShowLines: ShowLines[TestStringEvent] =
|
||||||
|
ShowLines[TestStringEvent]({
|
||||||
|
case a: TestStringEvent => List(a.value)
|
||||||
|
})
|
||||||
|
|
||||||
private def generateName: String =
|
private def generateName: String =
|
||||||
"test-" + generateId.incrementAndGet
|
"test-" + generateId.incrementAndGet
|
||||||
private val generateId: AtomicInteger = new AtomicInteger
|
private val generateId: AtomicInteger = new AtomicInteger
|
||||||
|
|
@ -38,11 +43,16 @@ object TestLogger {
|
||||||
if (per.buffered) {
|
if (per.buffered) {
|
||||||
buffs foreach { _.record() }
|
buffs foreach { _.record() }
|
||||||
}
|
}
|
||||||
new ContentLogger(wrap(newLog), () => {
|
new ContentLogger(
|
||||||
buffs foreach { _.stopQuietly() }
|
wrap(newLog),
|
||||||
per.flush()
|
() => {
|
||||||
})
|
buffs foreach { _.stopQuietly() }
|
||||||
|
per.flush()
|
||||||
|
LogExchange.unbindLoggerAppenders(newLog.name)
|
||||||
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
global.registerStringCodec[TestStringEvent]
|
||||||
val config = new TestLogging(wrap(global), global, makePerTest)
|
val config = new TestLogging(wrap(global), global, makePerTest)
|
||||||
new TestLogger(config)
|
new TestLogger(config)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue