mirror of https://github.com/sbt/sbt.git
Change to use test-interface-1.0-SNAP7, and use ScalaTest 2.0.M6-SNAP26 which implemented test-interface-1.0-SNAP7.
This commit is contained in:
parent
220886be80
commit
5bb46359b5
|
|
@ -11,7 +11,7 @@ import Tests.{Output => TestOutput, _}
|
||||||
import ForkMain._
|
import ForkMain._
|
||||||
|
|
||||||
private[sbt] object ForkTests {
|
private[sbt] object ForkTests {
|
||||||
def apply(runners: Map[TestFramework, Runner], tests: List[TestDefinition], config: Execution, classpath: Seq[File], fork: ForkOptions, log: Logger): Task[TestOutput] = {
|
def apply(runners: Map[TestFramework, Runner], tests: List[TestDefinition], config: Execution, loader: ClassLoader, classpath: Seq[File], fork: ForkOptions, log: Logger): Task[TestOutput] = {
|
||||||
val opts = config.options.toList
|
val opts = config.options.toList
|
||||||
val listeners = opts flatMap {
|
val listeners = opts flatMap {
|
||||||
case Listeners(ls) => ls
|
case Listeners(ls) => ls
|
||||||
|
|
@ -40,7 +40,22 @@ private[sbt] object ForkTests {
|
||||||
case _: java.net.SocketException => return
|
case _: java.net.SocketException => return
|
||||||
}
|
}
|
||||||
val os = new ObjectOutputStream(socket.getOutputStream)
|
val os = new ObjectOutputStream(socket.getOutputStream)
|
||||||
val is = new ObjectInputStream(socket.getInputStream)
|
// Make sure that ObjectInputStream use the passed in class loader
|
||||||
|
// ObjectInputStream class loading seems to be confusing, some old but useful links for reference:
|
||||||
|
// https://forums.oracle.com/thread/1151865
|
||||||
|
// http://sourceforge.net/p/jpype/bugs/52/
|
||||||
|
// http://tech-tauk.blogspot.com/2010/05/thread-context-classlaoder-in.html
|
||||||
|
val is = new ObjectInputStream(socket.getInputStream) {
|
||||||
|
override protected def resolveClass(desc: ObjectStreamClass): Class[_] = {
|
||||||
|
try {
|
||||||
|
val name = desc.getName
|
||||||
|
Class.forName(name, false, loader)
|
||||||
|
}
|
||||||
|
catch {
|
||||||
|
case e: ClassNotFoundException => super.resolveClass(desc)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
os.writeBoolean(log.ansiCodesSupported)
|
os.writeBoolean(log.ansiCodesSupported)
|
||||||
|
|
|
||||||
|
|
@ -11,7 +11,7 @@ package sbt
|
||||||
import xsbti.api.Definition
|
import xsbti.api.Definition
|
||||||
import ConcurrentRestrictions.Tag
|
import ConcurrentRestrictions.Tag
|
||||||
|
|
||||||
import testing.{AnnotatedFingerprint, Fingerprint, Framework, SubclassFingerprint, Runner, Task => TestTask}
|
import testing.{AnnotatedFingerprint, Fingerprint, Framework, SubclassFingerprint, Runner, TaskDef, SuiteSelector, Task => TestTask}
|
||||||
import scala.annotation.tailrec
|
import scala.annotation.tailrec
|
||||||
|
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
|
@ -123,9 +123,10 @@ object Tests
|
||||||
}
|
}
|
||||||
type TestRunnable = (String, TestFunction)
|
type TestRunnable = (String, TestFunction)
|
||||||
|
|
||||||
private def createNestedRunnables(name: String, loader: ClassLoader, testFun: TestFunction, nestedTasks: Seq[TestTask]): Seq[(String, TestFunction)] =
|
private def createNestedRunnables(loader: ClassLoader, testFun: TestFunction, nestedTasks: Seq[TestTask]): Seq[(String, TestFunction)] =
|
||||||
nestedTasks.view.zipWithIndex map { case (nt, idx) =>
|
nestedTasks.view.zipWithIndex map { case (nt, idx) =>
|
||||||
(name, TestFramework.createTestFunction(loader, new TestDefinition(testFun.testDefinition.name + "-" + idx, testFun.testDefinition.fingerprint), testFun.runner, nt))
|
val testFunDef = testFun.taskDef
|
||||||
|
(testFunDef.fullyQualifiedName, TestFramework.createTestFunction(loader, new TaskDef(testFunDef.fullyQualifiedName + "-" + idx, testFunDef.fingerprint, testFunDef.explicitlySpecified, testFunDef.selectors), testFun.runner, nt))
|
||||||
}
|
}
|
||||||
|
|
||||||
def makeParallel(loader: ClassLoader, runnables: Iterable[TestRunnable], setupTasks: Task[Unit], tags: Seq[(Tag,Int)]): Task[Map[String,SuiteResult]] =
|
def makeParallel(loader: ClassLoader, runnables: Iterable[TestRunnable], setupTasks: Task[Unit], tags: Seq[(Tag,Int)]): Task[Map[String,SuiteResult]] =
|
||||||
|
|
@ -142,7 +143,7 @@ object Tests
|
||||||
val base = task { (name, fun.apply()) }
|
val base = task { (name, fun.apply()) }
|
||||||
val taggedBase = base.tagw(tags : _*).tag(fun.tags.map(ConcurrentRestrictions.Tag(_)) : _*)
|
val taggedBase = base.tagw(tags : _*).tag(fun.tags.map(ConcurrentRestrictions.Tag(_)) : _*)
|
||||||
taggedBase flatMap { case (name, (result, nested)) =>
|
taggedBase flatMap { case (name, (result, nested)) =>
|
||||||
val nestedRunnables = createNestedRunnables(fun.testDefinition.name, loader, fun, nested)
|
val nestedRunnables = createNestedRunnables(loader, fun, nested)
|
||||||
toTasks(loader, nestedRunnables, tags).map( _.updated(name, result) )
|
toTasks(loader, nestedRunnables, tags).map( _.updated(name, result) )
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -155,7 +156,7 @@ object Tests
|
||||||
case hd :: rst =>
|
case hd :: rst =>
|
||||||
val testFun = hd._2
|
val testFun = hd._2
|
||||||
val (result, nestedTasks) = testFun.apply()
|
val (result, nestedTasks) = testFun.apply()
|
||||||
val nestedRunnables = createNestedRunnables(testFun.testDefinition.name, loader, testFun, nestedTasks)
|
val nestedRunnables = createNestedRunnables(loader, testFun, nestedTasks)
|
||||||
processRunnable(nestedRunnables.toList ::: rst, (hd._1, result) :: acc)
|
processRunnable(nestedRunnables.toList ::: rst, (hd._1, result) :: acc)
|
||||||
case Nil => acc
|
case Nil => acc
|
||||||
}
|
}
|
||||||
|
|
@ -202,7 +203,8 @@ object Tests
|
||||||
defined(annotations, d.annotations, d.isModule)
|
defined(annotations, d.annotations, d.isModule)
|
||||||
|
|
||||||
val discovered = Discovery(firsts(subclasses), firsts(annotations))(definitions)
|
val discovered = Discovery(firsts(subclasses), firsts(annotations))(definitions)
|
||||||
val tests = for( (df, di) <- discovered; fingerprint <- toFingerprints(di) ) yield new TestDefinition(df.name, fingerprint)
|
// TODO: To pass in correct explicitlySpecified and selectors
|
||||||
|
val tests = for( (df, di) <- discovered; fingerprint <- toFingerprints(di) ) yield new TestDefinition(df.name, fingerprint, false, Array(new SuiteSelector))
|
||||||
val mains = discovered collect { case (df, di) if di.hasMain => df.name }
|
val mains = discovered collect { case (df, di) if di.hasMain => df.name }
|
||||||
(tests, mains.toSet)
|
(tests, mains.toSet)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -484,7 +484,7 @@ object Defaults extends BuildCommon
|
||||||
case Tests.Group(name, tests, runPolicy) =>
|
case Tests.Group(name, tests, runPolicy) =>
|
||||||
runPolicy match {
|
runPolicy match {
|
||||||
case Tests.SubProcess(opts) =>
|
case Tests.SubProcess(opts) =>
|
||||||
ForkTests(runners, tests.toList, config, cp.files, opts, s.log) tag Tags.ForkedTestGroup
|
ForkTests(runners, tests.toList, config, loader, cp.files, opts, s.log) tag Tags.ForkedTestGroup
|
||||||
case Tests.InProcess =>
|
case Tests.InProcess =>
|
||||||
Tests(frameworks, loader, runners, tests, config, s.log)
|
Tests(frameworks, loader, runners, tests, config, s.log)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -79,10 +79,10 @@ object Sbt extends Build
|
||||||
// Apache Ivy integration
|
// Apache Ivy integration
|
||||||
lazy val ivySub = baseProject(file("ivy"), "Ivy") dependsOn(interfaceSub, launchInterfaceSub, crossSub, logSub % "compile;test->test", ioSub % "compile;test->test", launchSub % "test->test") settings(ivy, jsch, testExclusive)
|
lazy val ivySub = baseProject(file("ivy"), "Ivy") dependsOn(interfaceSub, launchInterfaceSub, crossSub, logSub % "compile;test->test", ioSub % "compile;test->test", launchSub % "test->test") settings(ivy, jsch, testExclusive)
|
||||||
// Runner for uniform test interface
|
// Runner for uniform test interface
|
||||||
lazy val testingSub = baseProject(file("testing"), "Testing") dependsOn(ioSub, classpathSub, logSub, launchInterfaceSub, testAgentSub) settings(libraryDependencies += "org.scalatest" % "test-interface" % "1.0-SNAP3")
|
lazy val testingSub = baseProject(file("testing"), "Testing") dependsOn(ioSub, classpathSub, logSub, launchInterfaceSub, testAgentSub) settings(libraryDependencies += "org.scalatest" % "test-interface" % "1.0-SNAP7")
|
||||||
// Testing agent for running tests in a separate process.
|
// Testing agent for running tests in a separate process.
|
||||||
lazy val testAgentSub = project(file("testing/agent"), "Test Agent") settings(
|
lazy val testAgentSub = project(file("testing/agent"), "Test Agent") settings(
|
||||||
libraryDependencies += "org.scalatest" % "test-interface" % "1.0-SNAP3"
|
libraryDependencies += "org.scalatest" % "test-interface" % "1.0-SNAP7"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Basic task engine
|
// Basic task engine
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
scalaVersion := "2.10.1"
|
scalaVersion := "2.10.1"
|
||||||
|
|
||||||
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP15"
|
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP26"
|
||||||
|
|
||||||
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
scalaVersion := "2.10.1"
|
scalaVersion := "2.10.1"
|
||||||
|
|
||||||
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP15"
|
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP26"
|
||||||
|
|
||||||
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
scalaVersion := "2.10.1"
|
scalaVersion := "2.10.1"
|
||||||
|
|
||||||
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP15"
|
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP26"
|
||||||
|
|
||||||
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
scalaVersion := "2.10.1"
|
scalaVersion := "2.10.1"
|
||||||
|
|
||||||
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP15"
|
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP26"
|
||||||
|
|
||||||
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
scalaVersion := "2.10.1"
|
scalaVersion := "2.10.1"
|
||||||
|
|
||||||
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP15"
|
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP26"
|
||||||
|
|
||||||
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
scalaVersion := "2.10.1"
|
scalaVersion := "2.10.1"
|
||||||
|
|
||||||
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP15"
|
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP26"
|
||||||
|
|
||||||
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
||||||
|
|
@ -15,9 +15,9 @@ object Ticket543Test extends Build {
|
||||||
testListeners += new TestReportListener {
|
testListeners += new TestReportListener {
|
||||||
def testEvent(event: TestEvent) {
|
def testEvent(event: TestEvent) {
|
||||||
for (e <- event.detail.filter(_.status == sbt.testing.Status.Failure)) {
|
for (e <- event.detail.filter(_.status == sbt.testing.Status.Failure)) {
|
||||||
if (e.throwable ne null) {
|
if (e.throwable != null && e.throwable.isDefined) {
|
||||||
val caw = new CharArrayWriter
|
val caw = new CharArrayWriter
|
||||||
e.throwable.printStackTrace(new PrintWriter(caw))
|
e.throwable.get.printStackTrace(new PrintWriter(caw))
|
||||||
if (caw.toString.contains("Test.scala:"))
|
if (caw.toString.contains("Test.scala:"))
|
||||||
marker.createNewFile()
|
marker.createNewFile()
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
scalaVersion := "2.10.1"
|
scalaVersion := "2.10.1"
|
||||||
|
|
||||||
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP15"
|
libraryDependencies += "org.scalatest" %% "scalatest" % "2.0.M6-SNAP26"
|
||||||
|
|
||||||
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
testOptions in Test += Tests.Argument("-r", "custom.CustomReporter")
|
||||||
|
|
@ -63,68 +63,41 @@ public class ForkMain {
|
||||||
public String getMessage() { return originalMessage; }
|
public String getMessage() { return originalMessage; }
|
||||||
public Exception getCause() { return cause; }
|
public Exception getCause() { return cause; }
|
||||||
}
|
}
|
||||||
static class ForkSelector extends Selector implements Serializable {}
|
|
||||||
static class ForkSuiteSelector extends ForkSelector {}
|
|
||||||
static class ForkTestSelector extends ForkSelector {
|
|
||||||
private String testName;
|
|
||||||
ForkTestSelector(TestSelector testSelector) {
|
|
||||||
this.testName = testSelector.getTestName();
|
|
||||||
}
|
|
||||||
public String getTestName() {
|
|
||||||
return testName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static class ForkNestedSuiteSelector extends ForkSelector {
|
|
||||||
private String suiteId;
|
|
||||||
ForkNestedSuiteSelector(NestedSuiteSelector nestedSuiteSelector) {
|
|
||||||
this.suiteId = nestedSuiteSelector.getSuiteId();
|
|
||||||
}
|
|
||||||
public String getSuiteId() {
|
|
||||||
return suiteId;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
static class ForkNestedTestSelector extends ForkSelector {
|
|
||||||
private String suiteId;
|
|
||||||
private String testName;
|
|
||||||
ForkNestedTestSelector(NestedTestSelector nestedTestSelector) {
|
|
||||||
this.suiteId = nestedTestSelector.getSuiteId();
|
|
||||||
this.testName = nestedTestSelector.getTestName();
|
|
||||||
}
|
|
||||||
public String getSuiteId() {
|
|
||||||
return suiteId;
|
|
||||||
}
|
|
||||||
public String getTestName() {
|
|
||||||
return testName;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static class ForkEvent implements Event, Serializable {
|
static class ForkEvent implements Event, Serializable {
|
||||||
private String fullyQualifiedName;
|
private String fullyQualifiedName;
|
||||||
private boolean isModule;
|
private Fingerprint fingerprint;
|
||||||
private ForkSelector selector;
|
private Selector selector;
|
||||||
private Status status;
|
private Status status;
|
||||||
private Throwable throwable;
|
private OptionalThrowable throwable;
|
||||||
|
private long duration;
|
||||||
ForkEvent(Event e) {
|
ForkEvent(Event e) {
|
||||||
fullyQualifiedName = e.fullyQualifiedName();
|
fullyQualifiedName = e.fullyQualifiedName();
|
||||||
isModule = e.isModule();
|
Fingerprint rawFingerprint = e.fingerprint();
|
||||||
|
if (rawFingerprint instanceof SubclassFingerprint)
|
||||||
|
this.fingerprint = new SubclassFingerscan((SubclassFingerprint) rawFingerprint);
|
||||||
|
else
|
||||||
|
this.fingerprint = new AnnotatedFingerscan((AnnotatedFingerprint) rawFingerprint);
|
||||||
selector = forkSelector(e.selector());
|
selector = forkSelector(e.selector());
|
||||||
status = e.status();
|
status = e.status();
|
||||||
if (e.throwable() != null) throwable = new ForkError(e.throwable());
|
OptionalThrowable originalThrowable = e.throwable();
|
||||||
|
if (originalThrowable.isDefined())
|
||||||
|
this.throwable = new OptionalThrowable(new ForkError(originalThrowable.get()));
|
||||||
|
else
|
||||||
|
this.throwable = originalThrowable;
|
||||||
|
this.duration = e.duration();
|
||||||
}
|
}
|
||||||
public String fullyQualifiedName() { return fullyQualifiedName; }
|
public String fullyQualifiedName() { return fullyQualifiedName; }
|
||||||
public boolean isModule() { return isModule; }
|
public Fingerprint fingerprint() { return fingerprint; }
|
||||||
public Selector selector() { return selector; }
|
public Selector selector() { return selector; }
|
||||||
public Status status() { return status; }
|
public Status status() { return status; }
|
||||||
public Throwable throwable() { return throwable; }
|
public OptionalThrowable throwable() { return throwable; }
|
||||||
protected ForkSelector forkSelector(Selector selector) {
|
public long duration() { return duration; }
|
||||||
if (selector instanceof SuiteSelector)
|
protected Selector forkSelector(Selector selector) {
|
||||||
return new ForkSuiteSelector();
|
if (selector instanceof Serializable)
|
||||||
else if (selector instanceof TestSelector)
|
return selector;
|
||||||
return new ForkTestSelector((TestSelector) selector);
|
|
||||||
else if (selector instanceof NestedSuiteSelector)
|
|
||||||
return new ForkNestedSuiteSelector((NestedSuiteSelector) selector);
|
|
||||||
else
|
else
|
||||||
return new ForkNestedTestSelector((NestedTestSelector) selector);
|
throw new UnsupportedOperationException("Selector implementation must be Serializable.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
public static void main(String[] args) throws Exception {
|
public static void main(String[] args) throws Exception {
|
||||||
|
|
@ -172,8 +145,8 @@ public class ForkMain {
|
||||||
void logDebug(ObjectOutputStream os, String message) {
|
void logDebug(ObjectOutputStream os, String message) {
|
||||||
write(os, new Object[]{ForkTags.Debug, message});
|
write(os, new Object[]{ForkTags.Debug, message});
|
||||||
}
|
}
|
||||||
void writeEvents(ObjectOutputStream os, ForkTestDefinition test, ForkEvent[] events) {
|
void writeEvents(ObjectOutputStream os, TaskDef taskDef, ForkEvent[] events) {
|
||||||
write(os, new Object[]{test.name, events});
|
write(os, new Object[]{taskDef.fullyQualifiedName(), events});
|
||||||
}
|
}
|
||||||
void runTests(ObjectInputStream is, final ObjectOutputStream os) throws Exception {
|
void runTests(ObjectInputStream is, final ObjectOutputStream os) throws Exception {
|
||||||
final boolean ansiCodesSupported = is.readBoolean();
|
final boolean ansiCodesSupported = is.readBoolean();
|
||||||
|
|
@ -212,15 +185,18 @@ public class ForkMain {
|
||||||
if (framework == null)
|
if (framework == null)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
ArrayList<ForkTestDefinition> filteredTests = new ArrayList<ForkTestDefinition>();
|
ArrayList<TaskDef> filteredTests = new ArrayList<TaskDef>();
|
||||||
for (Fingerprint testFingerprint : framework.fingerprints()) {
|
for (Fingerprint testFingerprint : framework.fingerprints()) {
|
||||||
for (ForkTestDefinition test : tests) {
|
for (ForkTestDefinition test : tests) {
|
||||||
if (matches(testFingerprint, test.fingerprint)) filteredTests.add(test);
|
// TODO: To pass in correct explicitlySpecified and selectors
|
||||||
|
if (matches(testFingerprint, test.fingerprint))
|
||||||
|
filteredTests.add(new TaskDef(test.name, test.fingerprint, false, new Selector[] { new SuiteSelector() }));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
final Runner runner = framework.runner(frameworkArgs, remoteFrameworkArgs, getClass().getClassLoader());
|
final Runner runner = framework.runner(frameworkArgs, remoteFrameworkArgs, getClass().getClassLoader());
|
||||||
for (ForkTestDefinition test : filteredTests)
|
Task[] tasks = runner.tasks(filteredTests.toArray(new TaskDef[filteredTests.size()]));
|
||||||
runTestSafe(test, runner, loggers, os);
|
for (Task task : tasks)
|
||||||
|
runTestSafe(task, runner, loggers, os);
|
||||||
runner.done();
|
runner.done();
|
||||||
}
|
}
|
||||||
write(os, ForkTags.Done);
|
write(os, ForkTags.Done);
|
||||||
|
|
@ -240,21 +216,19 @@ public class ForkMain {
|
||||||
return task;
|
return task;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
void runTestSafe(ForkTestDefinition test, Runner runner, Logger[] loggers, ObjectOutputStream os) {
|
void runTestSafe(Task task, Runner runner, Logger[] loggers, ObjectOutputStream os) {
|
||||||
|
TaskDef taskDef = task.taskDef();
|
||||||
try {
|
try {
|
||||||
// TODO: To pass in correct explicitlySpecified and selectors
|
|
||||||
Task task = runner.task(test.name, test.fingerprint, false, new Selector[] { new SuiteSelector() });
|
|
||||||
|
|
||||||
List<NestedTask> nestedTasks = new ArrayList<NestedTask>();
|
List<NestedTask> nestedTasks = new ArrayList<NestedTask>();
|
||||||
for (Task nt : runTest(test, task, loggers, os))
|
for (Task nt : runTest(taskDef, task, loggers, os))
|
||||||
nestedTasks.add(new NestedTask(test.name, nt));
|
nestedTasks.add(new NestedTask(taskDef.fullyQualifiedName(), nt));
|
||||||
while (true) {
|
while (true) {
|
||||||
List<NestedTask> newNestedTasks = new ArrayList<NestedTask>();
|
List<NestedTask> newNestedTasks = new ArrayList<NestedTask>();
|
||||||
int nestedTasksLength = nestedTasks.size();
|
int nestedTasksLength = nestedTasks.size();
|
||||||
for (int i = 0; i < nestedTasksLength; i++) {
|
for (int i = 0; i < nestedTasksLength; i++) {
|
||||||
NestedTask nestedTask = nestedTasks.get(i);
|
NestedTask nestedTask = nestedTasks.get(i);
|
||||||
String nestedParentName = nestedTask.getParentName() + "-" + i;
|
String nestedParentName = nestedTask.getParentName() + "-" + i;
|
||||||
for (Task nt : runTest(new ForkTestDefinition(nestedParentName, test.fingerprint), nestedTask.getTask(), loggers, os)) {
|
for (Task nt : runTest(nestedTask.getTask().taskDef(), nestedTask.getTask(), loggers, os)) {
|
||||||
newNestedTasks.add(new NestedTask(nestedParentName, nt));
|
newNestedTasks.add(new NestedTask(nestedParentName, nt));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -265,10 +239,10 @@ public class ForkMain {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} catch (Throwable t) {
|
} catch (Throwable t) {
|
||||||
writeEvents(os, test, new ForkEvent[] { testError(os, test, "Uncaught exception when running " + test.name + ": " + t.toString(), t) });
|
writeEvents(os, taskDef, new ForkEvent[] { testError(os, taskDef, "Uncaught exception when running " + taskDef.fullyQualifiedName() + ": " + t.toString(), t) });
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Task[] runTest(ForkTestDefinition test, Task task, Logger[] loggers, ObjectOutputStream os) {
|
Task[] runTest(TaskDef taskDef, Task task, Logger[] loggers, ObjectOutputStream os) {
|
||||||
ForkEvent[] events;
|
ForkEvent[] events;
|
||||||
Task[] nestedTasks;
|
Task[] nestedTasks;
|
||||||
try {
|
try {
|
||||||
|
|
@ -279,9 +253,9 @@ public class ForkMain {
|
||||||
}
|
}
|
||||||
catch (Throwable t) {
|
catch (Throwable t) {
|
||||||
nestedTasks = new Task[0];
|
nestedTasks = new Task[0];
|
||||||
events = new ForkEvent[] { testError(os, test, "Uncaught exception when running " + test.name + ": " + t.toString(), t) };
|
events = new ForkEvent[] { testError(os, taskDef, "Uncaught exception when running " + taskDef.fullyQualifiedName() + ": " + t.toString(), t) };
|
||||||
}
|
}
|
||||||
writeEvents(os, test, events);
|
writeEvents(os, taskDef, events);
|
||||||
return nestedTasks;
|
return nestedTasks;
|
||||||
}
|
}
|
||||||
void run(ObjectInputStream is, ObjectOutputStream os) throws Exception {
|
void run(ObjectInputStream is, ObjectOutputStream os) throws Exception {
|
||||||
|
|
@ -301,23 +275,33 @@ public class ForkMain {
|
||||||
void internalError(Throwable t) {
|
void internalError(Throwable t) {
|
||||||
System.err.println("Internal error when running tests: " + t.toString());
|
System.err.println("Internal error when running tests: " + t.toString());
|
||||||
}
|
}
|
||||||
ForkEvent testEvent(final String fullyQualifiedName, final Fingerprint fingerprint, final Selector selector, final Status r, final Throwable err) {
|
ForkEvent testEvent(final String fullyQualifiedName, final Fingerprint fingerprint, final Selector selector, final Status r, final Throwable err, final long duration) {
|
||||||
|
final OptionalThrowable throwable;
|
||||||
|
if (err == null)
|
||||||
|
throwable = new OptionalThrowable();
|
||||||
|
else
|
||||||
|
throwable = new OptionalThrowable(err);
|
||||||
return new ForkEvent(new Event() {
|
return new ForkEvent(new Event() {
|
||||||
public String fullyQualifiedName() { return fullyQualifiedName; }
|
public String fullyQualifiedName() { return fullyQualifiedName; }
|
||||||
public boolean isModule() { return fingerprint instanceof SubclassFingerprint ? ((SubclassFingerprint) fingerprint).isModule() : ((AnnotatedFingerprint) fingerprint).isModule(); }
|
public Fingerprint fingerprint() { return fingerprint; }
|
||||||
public Selector selector() { return selector; }
|
public Selector selector() { return selector; }
|
||||||
public Status status() { return r; }
|
public Status status() { return r; }
|
||||||
public Throwable throwable() { return err; }
|
public OptionalThrowable throwable() {
|
||||||
|
return throwable;
|
||||||
|
}
|
||||||
|
public long duration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
ForkEvent testError(ObjectOutputStream os, ForkTestDefinition test, String message) {
|
ForkEvent testError(ObjectOutputStream os, TaskDef taskDef, String message) {
|
||||||
logError(os, message);
|
logError(os, message);
|
||||||
return testEvent(test.name, test.fingerprint, new SuiteSelector(), Status.Error, null);
|
return testEvent(taskDef.fullyQualifiedName(), taskDef.fingerprint(), new SuiteSelector(), Status.Error, null, 0);
|
||||||
}
|
}
|
||||||
ForkEvent testError(ObjectOutputStream os, ForkTestDefinition test, String message, Throwable t) {
|
ForkEvent testError(ObjectOutputStream os, TaskDef taskDef, String message, Throwable t) {
|
||||||
logError(os, message);
|
logError(os, message);
|
||||||
write(os, t);
|
write(os, t);
|
||||||
return testEvent(test.name, test.fingerprint, new SuiteSelector(), Status.Error, t);
|
return testEvent(taskDef.fullyQualifiedName(), taskDef.fingerprint(), new SuiteSelector(), Status.Error, t, 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -88,16 +88,16 @@ class EventHandlerWrapper implements org.scalatools.testing.EventHandler {
|
||||||
|
|
||||||
private EventHandler newEventHandler;
|
private EventHandler newEventHandler;
|
||||||
private String fullyQualifiedName;
|
private String fullyQualifiedName;
|
||||||
private boolean isModule;
|
private Fingerprint fingerprint;
|
||||||
|
|
||||||
public EventHandlerWrapper(EventHandler newEventHandler, String fullyQualifiedName, boolean isModule) {
|
public EventHandlerWrapper(EventHandler newEventHandler, String fullyQualifiedName, Fingerprint fingerprint) {
|
||||||
this.newEventHandler = newEventHandler;
|
this.newEventHandler = newEventHandler;
|
||||||
this.fullyQualifiedName = fullyQualifiedName;
|
this.fullyQualifiedName = fullyQualifiedName;
|
||||||
this.isModule = isModule;
|
this.fingerprint = fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handle(org.scalatools.testing.Event oldEvent) {
|
public void handle(org.scalatools.testing.Event oldEvent) {
|
||||||
newEventHandler.handle(new EventWrapper(oldEvent, fullyQualifiedName, isModule));
|
newEventHandler.handle(new EventWrapper(oldEvent, fullyQualifiedName, fingerprint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -105,20 +105,26 @@ class EventWrapper implements Event {
|
||||||
|
|
||||||
private org.scalatools.testing.Event oldEvent;
|
private org.scalatools.testing.Event oldEvent;
|
||||||
private String className;
|
private String className;
|
||||||
private boolean classIsModule;
|
private Fingerprint fingerprint;
|
||||||
|
private OptionalThrowable throwable;
|
||||||
|
|
||||||
public EventWrapper(org.scalatools.testing.Event oldEvent, String className, boolean classIsModule) {
|
public EventWrapper(org.scalatools.testing.Event oldEvent, String className, Fingerprint fingerprint) {
|
||||||
this.oldEvent = oldEvent;
|
this.oldEvent = oldEvent;
|
||||||
this.className = className;
|
this.className = className;
|
||||||
this.classIsModule = classIsModule;
|
this.fingerprint = fingerprint;
|
||||||
|
Throwable oldThrowable = oldEvent.error();
|
||||||
|
if (oldThrowable == null)
|
||||||
|
throwable = new OptionalThrowable();
|
||||||
|
else
|
||||||
|
throwable = new OptionalThrowable(oldThrowable);
|
||||||
}
|
}
|
||||||
|
|
||||||
public String fullyQualifiedName() {
|
public String fullyQualifiedName() {
|
||||||
return className;
|
return className;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isModule() {
|
public Fingerprint fingerprint() {
|
||||||
return classIsModule;
|
return fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Selector selector() {
|
public Selector selector() {
|
||||||
|
|
@ -140,10 +146,13 @@ class EventWrapper implements Event {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Throwable throwable() {
|
public OptionalThrowable throwable() {
|
||||||
return oldEvent.error();
|
return throwable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public long duration() {
|
||||||
|
return 0; // Just return 0 as old event does not have duration.
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class RunnerWrapper implements Runner {
|
class RunnerWrapper implements Runner {
|
||||||
|
|
@ -158,7 +167,18 @@ class RunnerWrapper implements Runner {
|
||||||
this.args = args;
|
this.args = args;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task task(final String fullyQualifiedName, final Fingerprint fingerprint, boolean explicitlySpecified, Selector[] selectors) {
|
public Task[] tasks(TaskDef[] taskDefs) {
|
||||||
|
int length = taskDefs.length;
|
||||||
|
Task[] tasks = new Task[length];
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
TaskDef taskDef = taskDefs[i];
|
||||||
|
tasks[i] = createTask(taskDef.fullyQualifiedName(), taskDef.fingerprint(), taskDef.explicitlySpecified(), taskDef.selectors());
|
||||||
|
}
|
||||||
|
return tasks;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task createTask(final String fullyQualifiedName, final Fingerprint fingerprint, boolean explicitlySpecified, Selector[] selectors) {
|
||||||
|
final TaskDef taskDef = new TaskDef(fullyQualifiedName, fingerprint, explicitlySpecified, selectors);
|
||||||
return new Task() {
|
return new Task() {
|
||||||
public String[] tags() {
|
public String[] tags() {
|
||||||
return new String[0]; // Old framework does not support tags
|
return new String[0]; // Old framework does not support tags
|
||||||
|
|
@ -183,19 +203,17 @@ class RunnerWrapper implements Runner {
|
||||||
public boolean isModule() { return subclassFingerprint.isModule(); }
|
public boolean isModule() { return subclassFingerprint.isModule(); }
|
||||||
public String superClassName() { return subclassFingerprint.superclassName(); }
|
public String superClassName() { return subclassFingerprint.superclassName(); }
|
||||||
};
|
};
|
||||||
runner.run(fullyQualifiedName, oldFingerprint, new EventHandlerWrapper(eventHandler, fullyQualifiedName, subclassFingerprint.isModule()), args);
|
runner.run(fullyQualifiedName, oldFingerprint, new EventHandlerWrapper(eventHandler, fullyQualifiedName, subclassFingerprint), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void runRunner2(org.scalatools.testing.Runner2 runner, Fingerprint fingerprint, EventHandler eventHandler) {
|
private void runRunner2(org.scalatools.testing.Runner2 runner, Fingerprint fingerprint, EventHandler eventHandler) {
|
||||||
org.scalatools.testing.Fingerprint oldFingerprint = null;
|
org.scalatools.testing.Fingerprint oldFingerprint = null;
|
||||||
boolean isModule = false;
|
|
||||||
if (fingerprint instanceof SubclassFingerprint) {
|
if (fingerprint instanceof SubclassFingerprint) {
|
||||||
final SubclassFingerprint subclassFingerprint = (SubclassFingerprint) fingerprint;
|
final SubclassFingerprint subclassFingerprint = (SubclassFingerprint) fingerprint;
|
||||||
oldFingerprint = new org.scalatools.testing.SubclassFingerprint() {
|
oldFingerprint = new org.scalatools.testing.SubclassFingerprint() {
|
||||||
public boolean isModule() { return subclassFingerprint.isModule(); }
|
public boolean isModule() { return subclassFingerprint.isModule(); }
|
||||||
public String superClassName() { return subclassFingerprint.superclassName(); }
|
public String superClassName() { return subclassFingerprint.superclassName(); }
|
||||||
};
|
};
|
||||||
isModule = subclassFingerprint.isModule();
|
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
final AnnotatedFingerprint annotatedFingerprint = (AnnotatedFingerprint) fingerprint;
|
final AnnotatedFingerprint annotatedFingerprint = (AnnotatedFingerprint) fingerprint;
|
||||||
|
|
@ -203,9 +221,8 @@ class RunnerWrapper implements Runner {
|
||||||
public boolean isModule() { return annotatedFingerprint.isModule(); }
|
public boolean isModule() { return annotatedFingerprint.isModule(); }
|
||||||
public String annotationName() { return annotatedFingerprint.annotationName(); }
|
public String annotationName() { return annotatedFingerprint.annotationName(); }
|
||||||
};
|
};
|
||||||
isModule = annotatedFingerprint.isModule();
|
|
||||||
}
|
}
|
||||||
runner.run(fullyQualifiedName, oldFingerprint, new EventHandlerWrapper(eventHandler, fullyQualifiedName, isModule), args);
|
runner.run(fullyQualifiedName, oldFingerprint, new EventHandlerWrapper(eventHandler, fullyQualifiedName, fingerprint), args);
|
||||||
}
|
}
|
||||||
|
|
||||||
public Task[] execute(EventHandler eventHandler, Logger[] loggers) {
|
public Task[] execute(EventHandler eventHandler, Logger[] loggers) {
|
||||||
|
|
@ -224,6 +241,10 @@ class RunnerWrapper implements Runner {
|
||||||
}
|
}
|
||||||
return new Task[0];
|
return new Task[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public TaskDef taskDef() {
|
||||||
|
return taskDef;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -51,7 +51,7 @@ case class TestFramework(val implClassNames: String*)
|
||||||
def create(loader: ClassLoader, log: Logger): Option[Framework] =
|
def create(loader: ClassLoader, log: Logger): Option[Framework] =
|
||||||
createFramework(loader, log, implClassNames.toList)
|
createFramework(loader, log, implClassNames.toList)
|
||||||
}
|
}
|
||||||
final class TestDefinition(val name: String, val fingerprint: Fingerprint)
|
final class TestDefinition(val name: String, val fingerprint: Fingerprint, val explicitlySpecified: Boolean, val selectors: Array[Selector])
|
||||||
{
|
{
|
||||||
override def toString = "Test " + name + " : " + TestFramework.toString(fingerprint)
|
override def toString = "Test " + name + " : " + TestFramework.toString(fingerprint)
|
||||||
override def equals(t: Any) =
|
override def equals(t: Any) =
|
||||||
|
|
@ -65,13 +65,15 @@ final class TestDefinition(val name: String, val fingerprint: Fingerprint)
|
||||||
|
|
||||||
final class TestRunner(delegate: Runner, listeners: Seq[TestReportListener], log: Logger) {
|
final class TestRunner(delegate: Runner, listeners: Seq[TestReportListener], log: Logger) {
|
||||||
|
|
||||||
final def task(testDefinition: TestDefinition): TestTask =
|
final def tasks(testDefs: Set[TestDefinition]): Array[TestTask] =
|
||||||
delegate.task(testDefinition.name, testDefinition.fingerprint, false, Array(new SuiteSelector)) // TODO: To pass in correct explicitlySpecified and selectors
|
delegate.tasks(testDefs.map(df => new TaskDef(df.name, df.fingerprint, df.explicitlySpecified, df.selectors)).toArray)
|
||||||
|
|
||||||
final def run(testDefinition: TestDefinition, testTask: TestTask): (SuiteResult, Seq[TestTask]) =
|
final def run(taskDef: TaskDef, testTask: TestTask): (SuiteResult, Seq[TestTask]) =
|
||||||
{
|
{
|
||||||
log.debug("Running " + testDefinition)
|
val testDefinition = new TestDefinition(taskDef.fullyQualifiedName, taskDef.fingerprint, taskDef.explicitlySpecified, taskDef.selectors)
|
||||||
|
log.debug("Running " + taskDef)
|
||||||
val name = testDefinition.name
|
val name = testDefinition.name
|
||||||
|
|
||||||
def runTest() =
|
def runTest() =
|
||||||
{
|
{
|
||||||
// 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
|
||||||
|
|
@ -186,8 +188,8 @@ object TestFramework
|
||||||
def pickOne(prints: Seq[Fingerprint]): Fingerprint =
|
def pickOne(prints: Seq[Fingerprint]): Fingerprint =
|
||||||
frameworkPrints.find(prints.toSet) getOrElse prints.head
|
frameworkPrints.find(prints.toSet) getOrElse prints.head
|
||||||
val uniqueDefs =
|
val uniqueDefs =
|
||||||
for( (name, defs) <- tests.groupBy(_.name) ) yield
|
for( ((name, explicitlySpecified, selectors), defs) <- tests.groupBy(t => (t.name, t.explicitlySpecified, t.selectors)) ) yield
|
||||||
new TestDefinition(name, pickOne(defs.map(_.fingerprint)))
|
new TestDefinition(name, pickOne(defs.map(_.fingerprint)), explicitlySpecified, selectors)
|
||||||
uniqueDefs.toSet
|
uniqueDefs.toSet
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -203,11 +205,10 @@ object TestFramework
|
||||||
val testTasks =
|
val testTasks =
|
||||||
tests flatMap { case (framework, (testDefinitions, testArgs)) =>
|
tests flatMap { case (framework, (testDefinitions, testArgs)) =>
|
||||||
val runner = runners(framework)
|
val runner = runners(framework)
|
||||||
for(testDefinition <- testDefinitions) yield
|
val testTasks = withContextLoader(loader) { runner.tasks(testDefinitions) }
|
||||||
{
|
for (testTask <- testTasks) yield {
|
||||||
val testTask = withContextLoader(loader) { runner.task(testDefinition) }
|
val taskDef = testTask.taskDef
|
||||||
val testFunction = createTestFunction(loader, testDefinition, runner, testTask)
|
(taskDef.fullyQualifiedName, createTestFunction(loader, taskDef, runner, testTask))
|
||||||
(testDefinition.name, testFunction)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -229,11 +230,11 @@ object TestFramework
|
||||||
val main = ClasspathUtilities.makeLoader(classpath, dual, scalaInstance, tempDir)
|
val main = ClasspathUtilities.makeLoader(classpath, dual, scalaInstance, tempDir)
|
||||||
ClasspathUtilities.filterByClasspath(interfaceJar +: classpath, main)
|
ClasspathUtilities.filterByClasspath(interfaceJar +: classpath, main)
|
||||||
}
|
}
|
||||||
def createTestFunction(loader: ClassLoader, testDefinition: TestDefinition, runner:TestRunner, testTask: TestTask): TestFunction =
|
def createTestFunction(loader: ClassLoader, taskDef: TaskDef, runner:TestRunner, testTask: TestTask): TestFunction =
|
||||||
new TestFunction(testDefinition, runner, (r: TestRunner) => withContextLoader(loader) { r.run(testDefinition, testTask) }) { def tags = testTask.tags }
|
new TestFunction(taskDef, runner, (r: TestRunner) => withContextLoader(loader) { r.run(taskDef, testTask) }) { def tags = testTask.tags }
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class TestFunction(val testDefinition: TestDefinition, val runner: TestRunner, fun: (TestRunner) => (SuiteResult, Seq[TestTask])) {
|
abstract class TestFunction(val taskDef: TaskDef, val runner: TestRunner, fun: (TestRunner) => (SuiteResult, Seq[TestTask])) {
|
||||||
|
|
||||||
def apply(): (SuiteResult, Seq[TestTask]) = fun(runner)
|
def apply(): (SuiteResult, Seq[TestTask]) = fun(runner)
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue