mirror of https://github.com/sbt/sbt.git
Apply javafmt in sbt project
This commit is contained in:
parent
813864ec0f
commit
cf745255e8
|
|
@ -10,9 +10,13 @@ package xsbti;
|
||||||
import java.util.function.Supplier;
|
import java.util.function.Supplier;
|
||||||
|
|
||||||
public interface Logger {
|
public interface Logger {
|
||||||
void error(Supplier<String> msg);
|
void error(Supplier<String> msg);
|
||||||
void warn(Supplier<String> msg);
|
|
||||||
void info(Supplier<String> msg);
|
void warn(Supplier<String> msg);
|
||||||
void debug(Supplier<String> msg);
|
|
||||||
void trace(Supplier<Throwable> exception);
|
void info(Supplier<String> msg);
|
||||||
|
|
||||||
|
void debug(Supplier<String> msg);
|
||||||
|
|
||||||
|
void trace(Supplier<Throwable> exception);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,24 +10,44 @@ package xsbti;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface Position
|
public interface Position {
|
||||||
{
|
Optional<Integer> line();
|
||||||
Optional<Integer> line();
|
|
||||||
String lineContent();
|
|
||||||
Optional<Integer> offset();
|
|
||||||
|
|
||||||
// pointer to the column position of the error/warning
|
String lineContent();
|
||||||
Optional<Integer> pointer();
|
|
||||||
Optional<String> pointerSpace();
|
|
||||||
|
|
||||||
Optional<String> sourcePath();
|
Optional<Integer> offset();
|
||||||
Optional<File> sourceFile();
|
|
||||||
|
|
||||||
// Default values to avoid breaking binary compatibility
|
// pointer to the column position of the error/warning
|
||||||
default Optional<Integer> startOffset() { return Optional.empty(); }
|
Optional<Integer> pointer();
|
||||||
default Optional<Integer> endOffset() { return Optional.empty(); }
|
|
||||||
default Optional<Integer> startLine() { return Optional.empty(); }
|
Optional<String> pointerSpace();
|
||||||
default Optional<Integer> startColumn() { return Optional.empty(); }
|
|
||||||
default Optional<Integer> endLine() { return Optional.empty(); }
|
Optional<String> sourcePath();
|
||||||
default Optional<Integer> endColumn() { return Optional.empty(); }
|
|
||||||
|
Optional<File> sourceFile();
|
||||||
|
|
||||||
|
// Default values to avoid breaking binary compatibility
|
||||||
|
default Optional<Integer> startOffset() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Optional<Integer> endOffset() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Optional<Integer> startLine() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Optional<Integer> startColumn() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Optional<Integer> endLine() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
default Optional<Integer> endColumn() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,18 +9,21 @@ package xsbti;
|
||||||
|
|
||||||
import java.util.Optional;
|
import java.util.Optional;
|
||||||
|
|
||||||
public interface Problem
|
public interface Problem {
|
||||||
{
|
String category();
|
||||||
String category();
|
|
||||||
Severity severity();
|
Severity severity();
|
||||||
String message();
|
|
||||||
Position position();
|
String message();
|
||||||
|
|
||||||
|
Position position();
|
||||||
|
|
||||||
// Default value to avoid breaking binary compatibility
|
// Default value to avoid breaking binary compatibility
|
||||||
/**
|
/**
|
||||||
* If present, the string shown to the user when displaying this Problem.
|
* If present, the string shown to the user when displaying this Problem. Otherwise, the Problem
|
||||||
* Otherwise, the Problem will be shown in an implementation-defined way
|
* will be shown in an implementation-defined way based on the values of its other fields.
|
||||||
* based on the values of its other fields.
|
|
||||||
*/
|
*/
|
||||||
default Optional<String> rendered() { return Optional.empty(); }
|
default Optional<String> rendered() {
|
||||||
|
return Optional.empty();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,8 @@
|
||||||
|
|
||||||
package xsbti;
|
package xsbti;
|
||||||
|
|
||||||
public enum Severity
|
public enum Severity {
|
||||||
{
|
Info,
|
||||||
Info, Warn, Error
|
Warn,
|
||||||
}
|
Error
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,8 +8,8 @@
|
||||||
package xsbti;
|
package xsbti;
|
||||||
|
|
||||||
/** Used to pass a pair of values. */
|
/** Used to pass a pair of values. */
|
||||||
public interface T2<A1, A2>
|
public interface T2<A1, A2> {
|
||||||
{
|
|
||||||
public A1 get1();
|
public A1 get1();
|
||||||
|
|
||||||
public A2 get2();
|
public A2 get2();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,26 +13,25 @@ import xsbti.Logger;
|
||||||
|
|
||||||
public class ScriptConfig {
|
public class ScriptConfig {
|
||||||
|
|
||||||
private String label;
|
private String label;
|
||||||
private File testDirectory;
|
private File testDirectory;
|
||||||
private Logger logger;
|
private Logger logger;
|
||||||
|
|
||||||
public ScriptConfig(String label, File testDirectory, Logger logger) {
|
public ScriptConfig(String label, File testDirectory, Logger logger) {
|
||||||
this.label = label;
|
this.label = label;
|
||||||
this.testDirectory = testDirectory;
|
this.testDirectory = testDirectory;
|
||||||
this.logger = logger;
|
this.logger = logger;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String label() {
|
public String label() {
|
||||||
return this.label;
|
return this.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
public File testDirectory() {
|
public File testDirectory() {
|
||||||
return this.testDirectory;
|
return this.testDirectory;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Logger logger() {
|
public Logger logger() {
|
||||||
return this.logger;
|
return this.logger;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -13,6 +13,7 @@ import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
|
|
||||||
public class WrappedLoader extends URLClassLoader {
|
public class WrappedLoader extends URLClassLoader {
|
||||||
private final AtomicBoolean invalidated = new AtomicBoolean(false);
|
private final AtomicBoolean invalidated = new AtomicBoolean(false);
|
||||||
|
|
||||||
static {
|
static {
|
||||||
ClassLoader.registerAsParallelCapable();
|
ClassLoader.registerAsParallelCapable();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@ final case class Reboot(
|
||||||
app: xsbti.ApplicationID,
|
app: xsbti.ApplicationID,
|
||||||
baseDirectory: File
|
baseDirectory: File
|
||||||
) extends xsbti.Reboot {
|
) extends xsbti.Reboot {
|
||||||
|
System.err.println("AARGH " + app.classpathExtra.toSeq)
|
||||||
def arguments = argsList.toArray
|
def arguments = argsList.toArray
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -30,6 +31,7 @@ final case class ApplicationID(
|
||||||
crossVersionedValue: xsbti.CrossValue,
|
crossVersionedValue: xsbti.CrossValue,
|
||||||
extra: Seq[File]
|
extra: Seq[File]
|
||||||
) extends xsbti.ApplicationID {
|
) extends xsbti.ApplicationID {
|
||||||
|
new Exception("make app id").printStackTrace(System.err)
|
||||||
def mainComponents = components.toArray
|
def mainComponents = components.toArray
|
||||||
def classpathExtra = extra.toArray
|
def classpathExtra = extra.toArray
|
||||||
def crossVersioned = crossVersionedValue != xsbti.CrossValue.Disabled
|
def crossVersioned = crossVersionedValue != xsbti.CrossValue.Disabled
|
||||||
|
|
|
||||||
|
|
@ -16,7 +16,8 @@ final class ClassLoadingLock {
|
||||||
|
|
||||||
private final ConcurrentHashMap<String, Object> locks = new ConcurrentHashMap<>();
|
private final ConcurrentHashMap<String, Object> locks = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
<R> R withLock(final String name, final ThrowsClassNotFound<R> supplier) throws ClassNotFoundException {
|
<R> R withLock(final String name, final ThrowsClassNotFound<R> supplier)
|
||||||
|
throws ClassNotFoundException {
|
||||||
final Object newLock = new Object();
|
final Object newLock = new Object();
|
||||||
Object prevLock;
|
Object prevLock;
|
||||||
synchronized (locks) {
|
synchronized (locks) {
|
||||||
|
|
|
||||||
|
|
@ -12,8 +12,13 @@ import java.net.URL;
|
||||||
import sbt.util.Logger;
|
import sbt.util.Logger;
|
||||||
|
|
||||||
final class LayeredClassLoader extends ManagedClassLoader {
|
final class LayeredClassLoader extends ManagedClassLoader {
|
||||||
LayeredClassLoader(final URL[] classpath, final ClassLoader parent, final File tempDir, final boolean close, final
|
LayeredClassLoader(
|
||||||
boolean allowZombies, final Logger logger) {
|
final URL[] classpath,
|
||||||
|
final ClassLoader parent,
|
||||||
|
final File tempDir,
|
||||||
|
final boolean close,
|
||||||
|
final boolean allowZombies,
|
||||||
|
final Logger logger) {
|
||||||
super(classpath, parent, close, allowZombies, logger);
|
super(classpath, parent, close, allowZombies, logger);
|
||||||
setTempDir(tempDir);
|
setTempDir(tempDir);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,11 @@ abstract class ManagedClassLoader extends URLClassLoader implements NativeLoader
|
||||||
}
|
}
|
||||||
|
|
||||||
ManagedClassLoader(
|
ManagedClassLoader(
|
||||||
final URL[] urls, final ClassLoader parent, final boolean close, final boolean allowZombies, final Logger logger) {
|
final URL[] urls,
|
||||||
|
final ClassLoader parent,
|
||||||
|
final boolean close,
|
||||||
|
final boolean allowZombies,
|
||||||
|
final Logger logger) {
|
||||||
super(urls, parent);
|
super(urls, parent);
|
||||||
this.close = close;
|
this.close = close;
|
||||||
this.allowZombies = allowZombies;
|
this.allowZombies = allowZombies;
|
||||||
|
|
|
||||||
|
|
@ -20,6 +20,7 @@ public final class MetaBuildLoader extends URLClassLoader {
|
||||||
private final URLClassLoader fullScalaLoader;
|
private final URLClassLoader fullScalaLoader;
|
||||||
private final URLClassLoader libraryLoader;
|
private final URLClassLoader libraryLoader;
|
||||||
private final URLClassLoader interfaceLoader;
|
private final URLClassLoader interfaceLoader;
|
||||||
|
|
||||||
MetaBuildLoader(
|
MetaBuildLoader(
|
||||||
final URL[] urls,
|
final URL[] urls,
|
||||||
final URLClassLoader fullScalaLoader,
|
final URLClassLoader fullScalaLoader,
|
||||||
|
|
@ -49,12 +50,12 @@ public final class MetaBuildLoader extends URLClassLoader {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Rearrange the classloaders so that test-interface is above the scala library. Implemented
|
* Rearrange the classloaders so that test-interface is above the scala library. Implemented
|
||||||
* without using the scala standard library to minimize classloading.
|
* without using the scala standard library to minimize classloading.
|
||||||
*
|
*
|
||||||
* @param appProvider the appProvider that needs to be modified
|
* @param appProvider the appProvider that needs to be modified
|
||||||
* @return a ClassLoader with a URLClassLoader for the test-interface-1.0.jar above the
|
* @return a ClassLoader with a URLClassLoader for the test-interface-1.0.jar above the scala
|
||||||
* scala library.
|
* library.
|
||||||
*/
|
*/
|
||||||
public static MetaBuildLoader makeLoader(final AppProvider appProvider) throws IOException {
|
public static MetaBuildLoader makeLoader(final AppProvider appProvider) throws IOException {
|
||||||
final Pattern pattern = Pattern.compile("test-interface-[0-9.]+\\.jar");
|
final Pattern pattern = Pattern.compile("test-interface-[0-9.]+\\.jar");
|
||||||
|
|
|
||||||
|
|
@ -25,7 +25,7 @@ final class ScalaLibraryClassLoader extends URLClassLoader {
|
||||||
@Override
|
@Override
|
||||||
public String toString() {
|
public String toString() {
|
||||||
final StringBuilder builder = new StringBuilder();
|
final StringBuilder builder = new StringBuilder();
|
||||||
for (int i = 0; i < jars.length; ++ i) {
|
for (int i = 0; i < jars.length; ++i) {
|
||||||
builder.append(jars[i].toString());
|
builder.append(jars[i].toString());
|
||||||
if (i < jars.length - 2) builder.append(", ");
|
if (i < jars.length - 2) builder.append(", ");
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,19 +10,19 @@ package sbt;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
|
|
||||||
public final class ForkConfiguration implements Serializable {
|
public final class ForkConfiguration implements Serializable {
|
||||||
private final boolean ansiCodesSupported;
|
private final boolean ansiCodesSupported;
|
||||||
private final boolean parallel;
|
private final boolean parallel;
|
||||||
|
|
||||||
public ForkConfiguration(final boolean ansiCodesSupported, final boolean parallel) {
|
public ForkConfiguration(final boolean ansiCodesSupported, final boolean parallel) {
|
||||||
this.ansiCodesSupported = ansiCodesSupported;
|
this.ansiCodesSupported = ansiCodesSupported;
|
||||||
this.parallel = parallel;
|
this.parallel = parallel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isAnsiCodesSupported() {
|
public boolean isAnsiCodesSupported() {
|
||||||
return ansiCodesSupported;
|
return ansiCodesSupported;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isParallel() {
|
public boolean isParallel() {
|
||||||
return parallel;
|
return parallel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -21,334 +21,480 @@ import java.util.Collection;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.concurrent.*;
|
import java.util.concurrent.*;
|
||||||
|
|
||||||
final public class ForkMain {
|
public final class ForkMain {
|
||||||
|
|
||||||
// serializables
|
// serializables
|
||||||
// -----------------------------------------------------------------------------
|
// -----------------------------------------------------------------------------
|
||||||
|
|
||||||
final static class SubclassFingerscan implements SubclassFingerprint, Serializable {
|
static final class SubclassFingerscan implements SubclassFingerprint, Serializable {
|
||||||
private final boolean isModule;
|
private final boolean isModule;
|
||||||
private final String superclassName;
|
private final String superclassName;
|
||||||
private final boolean requireNoArgConstructor;
|
private final boolean requireNoArgConstructor;
|
||||||
SubclassFingerscan(final SubclassFingerprint print) {
|
|
||||||
isModule = print.isModule();
|
|
||||||
superclassName = print.superclassName();
|
|
||||||
requireNoArgConstructor = print.requireNoArgConstructor();
|
|
||||||
}
|
|
||||||
public boolean isModule() { return isModule; }
|
|
||||||
public String superclassName() { return superclassName; }
|
|
||||||
public boolean requireNoArgConstructor() { return requireNoArgConstructor; }
|
|
||||||
}
|
|
||||||
|
|
||||||
final static class AnnotatedFingerscan implements AnnotatedFingerprint, Serializable {
|
SubclassFingerscan(final SubclassFingerprint print) {
|
||||||
private final boolean isModule;
|
isModule = print.isModule();
|
||||||
private final String annotationName;
|
superclassName = print.superclassName();
|
||||||
AnnotatedFingerscan(final AnnotatedFingerprint print) {
|
requireNoArgConstructor = print.requireNoArgConstructor();
|
||||||
isModule = print.isModule();
|
}
|
||||||
annotationName = print.annotationName();
|
|
||||||
}
|
|
||||||
public boolean isModule() { return isModule; }
|
|
||||||
public String annotationName() { return annotationName; }
|
|
||||||
}
|
|
||||||
|
|
||||||
final static class ForkEvent implements Event, Serializable {
|
public boolean isModule() {
|
||||||
private final String fullyQualifiedName;
|
return isModule;
|
||||||
private final Fingerprint fingerprint;
|
}
|
||||||
private final Selector selector;
|
|
||||||
private final Status status;
|
|
||||||
private final OptionalThrowable throwable;
|
|
||||||
private final long duration;
|
|
||||||
|
|
||||||
ForkEvent(final Event e) {
|
public String superclassName() {
|
||||||
fullyQualifiedName = e.fullyQualifiedName();
|
return superclassName;
|
||||||
final Fingerprint rawFingerprint = e.fingerprint();
|
}
|
||||||
|
|
||||||
if (rawFingerprint instanceof SubclassFingerprint)
|
public boolean requireNoArgConstructor() {
|
||||||
fingerprint = new SubclassFingerscan((SubclassFingerprint) rawFingerprint);
|
return requireNoArgConstructor;
|
||||||
else
|
}
|
||||||
fingerprint = new AnnotatedFingerscan((AnnotatedFingerprint) rawFingerprint);
|
|
||||||
|
|
||||||
selector = e.selector();
|
|
||||||
checkSerializableSelector(selector);
|
|
||||||
status = e.status();
|
|
||||||
final OptionalThrowable originalThrowable = e.throwable();
|
|
||||||
|
|
||||||
if (originalThrowable.isDefined())
|
|
||||||
throwable = new OptionalThrowable(new ForkError(originalThrowable.get()));
|
|
||||||
else
|
|
||||||
throwable = originalThrowable;
|
|
||||||
|
|
||||||
duration = e.duration();
|
|
||||||
}
|
|
||||||
|
|
||||||
public String fullyQualifiedName() { return fullyQualifiedName; }
|
|
||||||
public Fingerprint fingerprint() { return fingerprint; }
|
|
||||||
public Selector selector() { return selector; }
|
|
||||||
public Status status() { return status; }
|
|
||||||
public OptionalThrowable throwable() { return throwable; }
|
|
||||||
public long duration() { return duration; }
|
|
||||||
|
|
||||||
private static void checkSerializableSelector(final Selector selector) {
|
|
||||||
if (! (selector instanceof Serializable)) {
|
|
||||||
throw new UnsupportedOperationException("Selector implementation must be Serializable, but " + selector.getClass().getName() + " is not.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// -----------------------------------------------------------------------------
|
|
||||||
|
|
||||||
|
|
||||||
final static class ForkError extends Exception {
|
|
||||||
private final String originalMessage;
|
|
||||||
private final String originalName;
|
|
||||||
private ForkError cause;
|
|
||||||
ForkError(final Throwable t) {
|
|
||||||
originalMessage = t.getMessage();
|
|
||||||
originalName = t.getClass().getName();
|
|
||||||
setStackTrace(t.getStackTrace());
|
|
||||||
if (t.getCause() != null) cause = new ForkError(t.getCause());
|
|
||||||
}
|
|
||||||
public String getMessage() { return originalName + ": " + originalMessage; }
|
|
||||||
public Exception getCause() { return cause; }
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// main
|
|
||||||
// ----------------------------------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
public static void main(final String[] args) throws Exception {
|
|
||||||
ClassLoader classLoader = new Run().getClass().getClassLoader();
|
|
||||||
try {
|
|
||||||
main(args, classLoader);
|
|
||||||
} finally {
|
|
||||||
System.exit(0);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public static void main(final String[] args, ClassLoader classLoader) throws Exception {
|
static final class AnnotatedFingerscan implements AnnotatedFingerprint, Serializable {
|
||||||
final Socket socket = new Socket(InetAddress.getByName(null), Integer.valueOf(args[0]));
|
private final boolean isModule;
|
||||||
final ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
|
private final String annotationName;
|
||||||
final ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
|
|
||||||
// Must flush the header that the constructor writes, otherwise the ObjectInputStream on the other end may block indefinitely
|
|
||||||
os.flush();
|
|
||||||
try {
|
|
||||||
new Run().run(is, os, classLoader);
|
|
||||||
} finally {
|
|
||||||
is.close();
|
|
||||||
os.close();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ----------------------------------------------------------------------------------------------------------------
|
AnnotatedFingerscan(final AnnotatedFingerprint print) {
|
||||||
|
isModule = print.isModule();
|
||||||
|
annotationName = print.annotationName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isModule() {
|
||||||
|
return isModule;
|
||||||
|
}
|
||||||
|
|
||||||
final private static class Run {
|
public String annotationName() {
|
||||||
|
return annotationName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void run(final ObjectInputStream is, final ObjectOutputStream os, ClassLoader classLoader) {
|
static final class ForkEvent implements Event, Serializable {
|
||||||
try {
|
private final String fullyQualifiedName;
|
||||||
runTests(is, os, classLoader);
|
private final Fingerprint fingerprint;
|
||||||
} catch (final RunAborted e) {
|
private final Selector selector;
|
||||||
internalError(e);
|
private final Status status;
|
||||||
} catch (final Throwable t) {
|
private final OptionalThrowable throwable;
|
||||||
try {
|
private final long duration;
|
||||||
logError(os, "Uncaught exception when running tests: " + t.toString());
|
|
||||||
write(os, new ForkError(t));
|
|
||||||
} catch (final Throwable t2) {
|
|
||||||
internalError(t2);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private boolean matches(final Fingerprint f1, final Fingerprint f2) {
|
ForkEvent(final Event e) {
|
||||||
if (f1 instanceof SubclassFingerprint && f2 instanceof SubclassFingerprint) {
|
fullyQualifiedName = e.fullyQualifiedName();
|
||||||
final SubclassFingerprint sf1 = (SubclassFingerprint) f1;
|
final Fingerprint rawFingerprint = e.fingerprint();
|
||||||
final SubclassFingerprint sf2 = (SubclassFingerprint) f2;
|
|
||||||
return sf1.isModule() == sf2.isModule() && sf1.superclassName().equals(sf2.superclassName());
|
|
||||||
} else if (f1 instanceof AnnotatedFingerprint && f2 instanceof AnnotatedFingerprint) {
|
|
||||||
final AnnotatedFingerprint af1 = (AnnotatedFingerprint) f1;
|
|
||||||
final AnnotatedFingerprint af2 = (AnnotatedFingerprint) f2;
|
|
||||||
return af1.isModule() == af2.isModule() && af1.annotationName().equals(af2.annotationName());
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
class RunAborted extends RuntimeException {
|
if (rawFingerprint instanceof SubclassFingerprint)
|
||||||
RunAborted(final Exception e) { super(e); }
|
fingerprint = new SubclassFingerscan((SubclassFingerprint) rawFingerprint);
|
||||||
}
|
else fingerprint = new AnnotatedFingerscan((AnnotatedFingerprint) rawFingerprint);
|
||||||
|
|
||||||
private synchronized void write(final ObjectOutputStream os, final Object obj) {
|
selector = e.selector();
|
||||||
try {
|
checkSerializableSelector(selector);
|
||||||
os.writeObject(obj);
|
status = e.status();
|
||||||
os.flush();
|
final OptionalThrowable originalThrowable = e.throwable();
|
||||||
} catch (final IOException e) {
|
|
||||||
throw new RunAborted(e);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void log(final ObjectOutputStream os, final String message, final ForkTags level) {
|
if (originalThrowable.isDefined())
|
||||||
write(os, new Object[]{level, message});
|
throwable = new OptionalThrowable(new ForkError(originalThrowable.get()));
|
||||||
}
|
else throwable = originalThrowable;
|
||||||
|
|
||||||
private void logDebug(final ObjectOutputStream os, final String message) { log(os, message, ForkTags.Debug); }
|
duration = e.duration();
|
||||||
private void logInfo(final ObjectOutputStream os, final String message) { log(os, message, ForkTags.Info); }
|
}
|
||||||
private void logWarn(final ObjectOutputStream os, final String message) { log(os, message, ForkTags.Warn); }
|
|
||||||
private void logError(final ObjectOutputStream os, final String message) { log(os, message, ForkTags.Error); }
|
|
||||||
|
|
||||||
private Logger remoteLogger(final boolean ansiCodesSupported, final ObjectOutputStream os) {
|
public String fullyQualifiedName() {
|
||||||
return new Logger() {
|
return fullyQualifiedName;
|
||||||
public boolean ansiCodesSupported() { return ansiCodesSupported; }
|
}
|
||||||
public void error(final String s) { logError(os, s); }
|
|
||||||
public void warn(final String s) { logWarn(os, s); }
|
|
||||||
public void info(final String s) { logInfo(os, s); }
|
|
||||||
public void debug(final String s) { logDebug(os, s); }
|
|
||||||
public void trace(final Throwable t) { write(os, new ForkError(t)); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void writeEvents(final ObjectOutputStream os, final TaskDef taskDef, final ForkEvent[] events) {
|
public Fingerprint fingerprint() {
|
||||||
write(os, new Object[]{taskDef.fullyQualifiedName(), events});
|
return fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
private ExecutorService executorService(final ForkConfiguration config, final ObjectOutputStream os) {
|
public Selector selector() {
|
||||||
if(config.isParallel()) {
|
return selector;
|
||||||
final int nbThreads = Runtime.getRuntime().availableProcessors();
|
}
|
||||||
logDebug(os, "Create a test executor with a thread pool of " + nbThreads + " threads.");
|
|
||||||
// more options later...
|
|
||||||
// TODO we might want to configure the blocking queue with size #proc
|
|
||||||
return Executors.newFixedThreadPool(nbThreads);
|
|
||||||
} else {
|
|
||||||
logDebug(os, "Create a single-thread test executor");
|
|
||||||
return Executors.newSingleThreadExecutor();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runTests(final ObjectInputStream is, final ObjectOutputStream os, ClassLoader classLoader) throws Exception {
|
public Status status() {
|
||||||
final ForkConfiguration config = (ForkConfiguration) is.readObject();
|
return status;
|
||||||
final ExecutorService executor = executorService(config, os);
|
}
|
||||||
final TaskDef[] tests = (TaskDef[]) is.readObject();
|
|
||||||
final int nFrameworks = is.readInt();
|
|
||||||
final Logger[] loggers = { remoteLogger(config.isAnsiCodesSupported(), os) };
|
|
||||||
|
|
||||||
for (int i = 0; i < nFrameworks; i++) {
|
public OptionalThrowable throwable() {
|
||||||
final String[] implClassNames = (String[]) is.readObject();
|
return throwable;
|
||||||
final String[] frameworkArgs = (String[]) is.readObject();
|
}
|
||||||
final String[] remoteFrameworkArgs = (String[]) is.readObject();
|
|
||||||
|
|
||||||
Framework framework = null;
|
public long duration() {
|
||||||
for (final String implClassName : implClassNames) {
|
return duration;
|
||||||
try {
|
}
|
||||||
final Object rawFramework = Class.forName(implClassName).getDeclaredConstructor().newInstance();
|
|
||||||
if (rawFramework instanceof Framework)
|
|
||||||
framework = (Framework) rawFramework;
|
|
||||||
else
|
|
||||||
framework = new FrameworkWrapper((org.scalatools.testing.Framework) rawFramework);
|
|
||||||
break;
|
|
||||||
} catch (final ClassNotFoundException e) {
|
|
||||||
logDebug(os, "Framework implementation '" + implClassName + "' not present.");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (framework == null)
|
private static void checkSerializableSelector(final Selector selector) {
|
||||||
continue;
|
if (!(selector instanceof Serializable)) {
|
||||||
|
throw new UnsupportedOperationException(
|
||||||
|
"Selector implementation must be Serializable, but "
|
||||||
|
+ selector.getClass().getName()
|
||||||
|
+ " is not.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
final ArrayList<TaskDef> filteredTests = new ArrayList<>();
|
// -----------------------------------------------------------------------------
|
||||||
for (final Fingerprint testFingerprint : framework.fingerprints()) {
|
|
||||||
for (final TaskDef test : tests) {
|
|
||||||
// TODO: To pass in correct explicitlySpecified and selectors
|
|
||||||
if (matches(testFingerprint, test.fingerprint()))
|
|
||||||
filteredTests.add(new TaskDef(test.fullyQualifiedName(), test.fingerprint(), test.explicitlySpecified(), test.selectors()));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
final Runner runner = framework.runner(frameworkArgs, remoteFrameworkArgs, classLoader);
|
|
||||||
final Task[] tasks = runner.tasks(filteredTests.toArray(new TaskDef[filteredTests.size()]));
|
|
||||||
logDebug(os, "Runner for " + framework.getClass().getName() + " produced " + tasks.length + " initial tasks for " + filteredTests.size() + " tests.");
|
|
||||||
|
|
||||||
Thread callDoneOnShutdown = new Thread(() -> runner.done());
|
static final class ForkError extends Exception {
|
||||||
Runtime.getRuntime().addShutdownHook(callDoneOnShutdown);
|
private final String originalMessage;
|
||||||
|
private final String originalName;
|
||||||
|
private ForkError cause;
|
||||||
|
|
||||||
runTestTasks(executor, tasks, loggers, os);
|
ForkError(final Throwable t) {
|
||||||
|
originalMessage = t.getMessage();
|
||||||
|
originalName = t.getClass().getName();
|
||||||
|
setStackTrace(t.getStackTrace());
|
||||||
|
if (t.getCause() != null) cause = new ForkError(t.getCause());
|
||||||
|
}
|
||||||
|
|
||||||
runner.done();
|
public String getMessage() {
|
||||||
|
return originalName + ": " + originalMessage;
|
||||||
|
}
|
||||||
|
|
||||||
Runtime.getRuntime().removeShutdownHook(callDoneOnShutdown);
|
public Exception getCause() {
|
||||||
}
|
return cause;
|
||||||
write(os, ForkTags.Done);
|
}
|
||||||
is.readObject();
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void runTestTasks(final ExecutorService executor, final Task[] tasks, final Logger[] loggers, final ObjectOutputStream os) {
|
// main
|
||||||
if( tasks.length > 0 ) {
|
// ----------------------------------------------------------------------------------------------------------------
|
||||||
final List<Future<Task[]>> futureNestedTasks = new ArrayList<>();
|
|
||||||
for( final Task task : tasks ) {
|
|
||||||
futureNestedTasks.add(runTest(executor, task, loggers, os));
|
|
||||||
}
|
|
||||||
|
|
||||||
// Note: this could be optimized further, we could have a callback once a test finishes that executes immediately the nested tasks
|
public static void main(final String[] args) throws Exception {
|
||||||
// At the moment, I'm especially interested in JUnit, which doesn't have nested tasks.
|
ClassLoader classLoader = new Run().getClass().getClassLoader();
|
||||||
final List<Task> nestedTasks = new ArrayList<>();
|
try {
|
||||||
for( final Future<Task[]> futureNestedTask : futureNestedTasks ) {
|
main(args, classLoader);
|
||||||
try {
|
} finally {
|
||||||
nestedTasks.addAll( Arrays.asList(futureNestedTask.get()));
|
System.exit(0);
|
||||||
} catch (final Exception e) {
|
}
|
||||||
logError(os, "Failed to execute task " + futureNestedTask);
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
runTestTasks(executor, nestedTasks.toArray(new Task[nestedTasks.size()]), loggers, os);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private Future<Task[]> runTest(final ExecutorService executor, final Task task, final Logger[] loggers, final ObjectOutputStream os) {
|
public static void main(final String[] args, ClassLoader classLoader) throws Exception {
|
||||||
return executor.submit(() -> {
|
final Socket socket = new Socket(InetAddress.getByName(null), Integer.valueOf(args[0]));
|
||||||
ForkEvent[] events;
|
final ObjectInputStream is = new ObjectInputStream(socket.getInputStream());
|
||||||
Task[] nestedTasks;
|
final ObjectOutputStream os = new ObjectOutputStream(socket.getOutputStream());
|
||||||
final TaskDef taskDef = task.taskDef();
|
// Must flush the header that the constructor writes, otherwise the ObjectInputStream on the
|
||||||
try {
|
// other end may block indefinitely
|
||||||
final Collection<ForkEvent> eventList = new ConcurrentLinkedDeque<>();
|
os.flush();
|
||||||
final EventHandler handler = new EventHandler() { public void handle(final Event e){ eventList.add(new ForkEvent(e)); } };
|
try {
|
||||||
logDebug(os, " Running " + taskDef);
|
new Run().run(is, os, classLoader);
|
||||||
nestedTasks = task.execute(handler, loggers);
|
} finally {
|
||||||
if(nestedTasks.length > 0 || eventList.size() > 0)
|
is.close();
|
||||||
logDebug(os, " Produced " + nestedTasks.length + " nested tasks and " + eventList.size() + " events.");
|
os.close();
|
||||||
events = eventList.toArray(new ForkEvent[eventList.size()]);
|
}
|
||||||
}
|
}
|
||||||
catch (final Throwable t) {
|
|
||||||
nestedTasks = new Task[0];
|
|
||||||
events = new ForkEvent[] { testError(os, taskDef, "Uncaught exception when running " + taskDef.fullyQualifiedName() + ": " + t.toString(), t) };
|
|
||||||
}
|
|
||||||
writeEvents(os, taskDef, events);
|
|
||||||
return nestedTasks;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private void internalError(final Throwable t) {
|
// ----------------------------------------------------------------------------------------------------------------
|
||||||
System.err.println("Internal error when running tests: " + t.toString());
|
|
||||||
}
|
|
||||||
|
|
||||||
private ForkEvent testEvent(final String fullyQualifiedName, final Fingerprint fingerprint, final Selector selector, final Status r, final ForkError err, final long duration) {
|
private static final class Run {
|
||||||
final OptionalThrowable throwable;
|
|
||||||
if (err == null)
|
|
||||||
throwable = new OptionalThrowable();
|
|
||||||
else
|
|
||||||
throwable = new OptionalThrowable(err);
|
|
||||||
return new ForkEvent(new Event() {
|
|
||||||
public String fullyQualifiedName() { return fullyQualifiedName; }
|
|
||||||
public Fingerprint fingerprint() { return fingerprint; }
|
|
||||||
public Selector selector() { return selector; }
|
|
||||||
public Status status() { return r; }
|
|
||||||
public OptionalThrowable throwable() {
|
|
||||||
return throwable;
|
|
||||||
}
|
|
||||||
public long duration() {
|
|
||||||
return duration;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
private ForkEvent testError(final ObjectOutputStream os, final TaskDef taskDef, final String message, final Throwable t) {
|
private void run(
|
||||||
logError(os, message);
|
final ObjectInputStream is, final ObjectOutputStream os, ClassLoader classLoader) {
|
||||||
final ForkError fe = new ForkError(t);
|
try {
|
||||||
write(os, fe);
|
runTests(is, os, classLoader);
|
||||||
return testEvent(taskDef.fullyQualifiedName(), taskDef.fingerprint(), new SuiteSelector(), Status.Error, fe, 0);
|
} catch (final RunAborted e) {
|
||||||
}
|
internalError(e);
|
||||||
}
|
} catch (final Throwable t) {
|
||||||
|
try {
|
||||||
|
logError(os, "Uncaught exception when running tests: " + t.toString());
|
||||||
|
write(os, new ForkError(t));
|
||||||
|
} catch (final Throwable t2) {
|
||||||
|
internalError(t2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean matches(final Fingerprint f1, final Fingerprint f2) {
|
||||||
|
if (f1 instanceof SubclassFingerprint && f2 instanceof SubclassFingerprint) {
|
||||||
|
final SubclassFingerprint sf1 = (SubclassFingerprint) f1;
|
||||||
|
final SubclassFingerprint sf2 = (SubclassFingerprint) f2;
|
||||||
|
return sf1.isModule() == sf2.isModule()
|
||||||
|
&& sf1.superclassName().equals(sf2.superclassName());
|
||||||
|
} else if (f1 instanceof AnnotatedFingerprint && f2 instanceof AnnotatedFingerprint) {
|
||||||
|
final AnnotatedFingerprint af1 = (AnnotatedFingerprint) f1;
|
||||||
|
final AnnotatedFingerprint af2 = (AnnotatedFingerprint) f2;
|
||||||
|
return af1.isModule() == af2.isModule()
|
||||||
|
&& af1.annotationName().equals(af2.annotationName());
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
class RunAborted extends RuntimeException {
|
||||||
|
RunAborted(final Exception e) {
|
||||||
|
super(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private synchronized void write(final ObjectOutputStream os, final Object obj) {
|
||||||
|
try {
|
||||||
|
os.writeObject(obj);
|
||||||
|
os.flush();
|
||||||
|
} catch (final IOException e) {
|
||||||
|
throw new RunAborted(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void log(final ObjectOutputStream os, final String message, final ForkTags level) {
|
||||||
|
write(os, new Object[] {level, message});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logDebug(final ObjectOutputStream os, final String message) {
|
||||||
|
log(os, message, ForkTags.Debug);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logInfo(final ObjectOutputStream os, final String message) {
|
||||||
|
log(os, message, ForkTags.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logWarn(final ObjectOutputStream os, final String message) {
|
||||||
|
log(os, message, ForkTags.Warn);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void logError(final ObjectOutputStream os, final String message) {
|
||||||
|
log(os, message, ForkTags.Error);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Logger remoteLogger(final boolean ansiCodesSupported, final ObjectOutputStream os) {
|
||||||
|
return new Logger() {
|
||||||
|
public boolean ansiCodesSupported() {
|
||||||
|
return ansiCodesSupported;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void error(final String s) {
|
||||||
|
logError(os, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void warn(final String s) {
|
||||||
|
logWarn(os, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void info(final String s) {
|
||||||
|
logInfo(os, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void debug(final String s) {
|
||||||
|
logDebug(os, s);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void trace(final Throwable t) {
|
||||||
|
write(os, new ForkError(t));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeEvents(
|
||||||
|
final ObjectOutputStream os, final TaskDef taskDef, final ForkEvent[] events) {
|
||||||
|
write(os, new Object[] {taskDef.fullyQualifiedName(), events});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExecutorService executorService(
|
||||||
|
final ForkConfiguration config, final ObjectOutputStream os) {
|
||||||
|
if (config.isParallel()) {
|
||||||
|
final int nbThreads = Runtime.getRuntime().availableProcessors();
|
||||||
|
logDebug(os, "Create a test executor with a thread pool of " + nbThreads + " threads.");
|
||||||
|
// more options later...
|
||||||
|
// TODO we might want to configure the blocking queue with size #proc
|
||||||
|
return Executors.newFixedThreadPool(nbThreads);
|
||||||
|
} else {
|
||||||
|
logDebug(os, "Create a single-thread test executor");
|
||||||
|
return Executors.newSingleThreadExecutor();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTests(
|
||||||
|
final ObjectInputStream is, final ObjectOutputStream os, ClassLoader classLoader)
|
||||||
|
throws Exception {
|
||||||
|
final ForkConfiguration config = (ForkConfiguration) is.readObject();
|
||||||
|
final ExecutorService executor = executorService(config, os);
|
||||||
|
final TaskDef[] tests = (TaskDef[]) is.readObject();
|
||||||
|
final int nFrameworks = is.readInt();
|
||||||
|
final Logger[] loggers = {remoteLogger(config.isAnsiCodesSupported(), os)};
|
||||||
|
|
||||||
|
for (int i = 0; i < nFrameworks; i++) {
|
||||||
|
final String[] implClassNames = (String[]) is.readObject();
|
||||||
|
final String[] frameworkArgs = (String[]) is.readObject();
|
||||||
|
final String[] remoteFrameworkArgs = (String[]) is.readObject();
|
||||||
|
|
||||||
|
Framework framework = null;
|
||||||
|
for (final String implClassName : implClassNames) {
|
||||||
|
try {
|
||||||
|
final Object rawFramework =
|
||||||
|
Class.forName(implClassName).getDeclaredConstructor().newInstance();
|
||||||
|
if (rawFramework instanceof Framework) framework = (Framework) rawFramework;
|
||||||
|
else framework = new FrameworkWrapper((org.scalatools.testing.Framework) rawFramework);
|
||||||
|
break;
|
||||||
|
} catch (final ClassNotFoundException e) {
|
||||||
|
logDebug(os, "Framework implementation '" + implClassName + "' not present.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (framework == null) continue;
|
||||||
|
|
||||||
|
final ArrayList<TaskDef> filteredTests = new ArrayList<>();
|
||||||
|
for (final Fingerprint testFingerprint : framework.fingerprints()) {
|
||||||
|
for (final TaskDef test : tests) {
|
||||||
|
// TODO: To pass in correct explicitlySpecified and selectors
|
||||||
|
if (matches(testFingerprint, test.fingerprint()))
|
||||||
|
filteredTests.add(
|
||||||
|
new TaskDef(
|
||||||
|
test.fullyQualifiedName(),
|
||||||
|
test.fingerprint(),
|
||||||
|
test.explicitlySpecified(),
|
||||||
|
test.selectors()));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
final Runner runner = framework.runner(frameworkArgs, remoteFrameworkArgs, classLoader);
|
||||||
|
final Task[] tasks = runner.tasks(filteredTests.toArray(new TaskDef[filteredTests.size()]));
|
||||||
|
logDebug(
|
||||||
|
os,
|
||||||
|
"Runner for "
|
||||||
|
+ framework.getClass().getName()
|
||||||
|
+ " produced "
|
||||||
|
+ tasks.length
|
||||||
|
+ " initial tasks for "
|
||||||
|
+ filteredTests.size()
|
||||||
|
+ " tests.");
|
||||||
|
|
||||||
|
Thread callDoneOnShutdown = new Thread(() -> runner.done());
|
||||||
|
Runtime.getRuntime().addShutdownHook(callDoneOnShutdown);
|
||||||
|
|
||||||
|
runTestTasks(executor, tasks, loggers, os);
|
||||||
|
|
||||||
|
runner.done();
|
||||||
|
|
||||||
|
Runtime.getRuntime().removeShutdownHook(callDoneOnShutdown);
|
||||||
|
}
|
||||||
|
write(os, ForkTags.Done);
|
||||||
|
is.readObject();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void runTestTasks(
|
||||||
|
final ExecutorService executor,
|
||||||
|
final Task[] tasks,
|
||||||
|
final Logger[] loggers,
|
||||||
|
final ObjectOutputStream os) {
|
||||||
|
if (tasks.length > 0) {
|
||||||
|
final List<Future<Task[]>> futureNestedTasks = new ArrayList<>();
|
||||||
|
for (final Task task : tasks) {
|
||||||
|
futureNestedTasks.add(runTest(executor, task, loggers, os));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: this could be optimized further, we could have a callback once a test finishes that
|
||||||
|
// executes immediately the nested tasks
|
||||||
|
// At the moment, I'm especially interested in JUnit, which doesn't have nested tasks.
|
||||||
|
final List<Task> nestedTasks = new ArrayList<>();
|
||||||
|
for (final Future<Task[]> futureNestedTask : futureNestedTasks) {
|
||||||
|
try {
|
||||||
|
nestedTasks.addAll(Arrays.asList(futureNestedTask.get()));
|
||||||
|
} catch (final Exception e) {
|
||||||
|
logError(os, "Failed to execute task " + futureNestedTask);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
runTestTasks(executor, nestedTasks.toArray(new Task[nestedTasks.size()]), loggers, os);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Future<Task[]> runTest(
|
||||||
|
final ExecutorService executor,
|
||||||
|
final Task task,
|
||||||
|
final Logger[] loggers,
|
||||||
|
final ObjectOutputStream os) {
|
||||||
|
return executor.submit(
|
||||||
|
() -> {
|
||||||
|
ForkEvent[] events;
|
||||||
|
Task[] nestedTasks;
|
||||||
|
final TaskDef taskDef = task.taskDef();
|
||||||
|
try {
|
||||||
|
final Collection<ForkEvent> eventList = new ConcurrentLinkedDeque<>();
|
||||||
|
final EventHandler handler =
|
||||||
|
new EventHandler() {
|
||||||
|
public void handle(final Event e) {
|
||||||
|
eventList.add(new ForkEvent(e));
|
||||||
|
}
|
||||||
|
};
|
||||||
|
logDebug(os, " Running " + taskDef);
|
||||||
|
nestedTasks = task.execute(handler, loggers);
|
||||||
|
if (nestedTasks.length > 0 || eventList.size() > 0)
|
||||||
|
logDebug(
|
||||||
|
os,
|
||||||
|
" Produced "
|
||||||
|
+ nestedTasks.length
|
||||||
|
+ " nested tasks and "
|
||||||
|
+ eventList.size()
|
||||||
|
+ " events.");
|
||||||
|
events = eventList.toArray(new ForkEvent[eventList.size()]);
|
||||||
|
} catch (final Throwable t) {
|
||||||
|
nestedTasks = new Task[0];
|
||||||
|
events =
|
||||||
|
new ForkEvent[] {
|
||||||
|
testError(
|
||||||
|
os,
|
||||||
|
taskDef,
|
||||||
|
"Uncaught exception when running "
|
||||||
|
+ taskDef.fullyQualifiedName()
|
||||||
|
+ ": "
|
||||||
|
+ t.toString(),
|
||||||
|
t)
|
||||||
|
};
|
||||||
|
}
|
||||||
|
writeEvents(os, taskDef, events);
|
||||||
|
return nestedTasks;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void internalError(final Throwable t) {
|
||||||
|
System.err.println("Internal error when running tests: " + t.toString());
|
||||||
|
}
|
||||||
|
|
||||||
|
private ForkEvent testEvent(
|
||||||
|
final String fullyQualifiedName,
|
||||||
|
final Fingerprint fingerprint,
|
||||||
|
final Selector selector,
|
||||||
|
final Status r,
|
||||||
|
final ForkError err,
|
||||||
|
final long duration) {
|
||||||
|
final OptionalThrowable throwable;
|
||||||
|
if (err == null) throwable = new OptionalThrowable();
|
||||||
|
else throwable = new OptionalThrowable(err);
|
||||||
|
return new ForkEvent(
|
||||||
|
new Event() {
|
||||||
|
public String fullyQualifiedName() {
|
||||||
|
return fullyQualifiedName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Fingerprint fingerprint() {
|
||||||
|
return fingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Selector selector() {
|
||||||
|
return selector;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Status status() {
|
||||||
|
return r;
|
||||||
|
}
|
||||||
|
|
||||||
|
public OptionalThrowable throwable() {
|
||||||
|
return throwable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public long duration() {
|
||||||
|
return duration;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ForkEvent testError(
|
||||||
|
final ObjectOutputStream os,
|
||||||
|
final TaskDef taskDef,
|
||||||
|
final String message,
|
||||||
|
final Throwable t) {
|
||||||
|
logError(os, message);
|
||||||
|
final ForkError fe = new ForkError(t);
|
||||||
|
write(os, fe);
|
||||||
|
return testEvent(
|
||||||
|
taskDef.fullyQualifiedName(),
|
||||||
|
taskDef.fingerprint(),
|
||||||
|
new SuiteSelector(),
|
||||||
|
Status.Error,
|
||||||
|
fe,
|
||||||
|
0);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -8,5 +8,9 @@
|
||||||
package sbt;
|
package sbt;
|
||||||
|
|
||||||
public enum ForkTags {
|
public enum ForkTags {
|
||||||
Error, Warn, Info, Debug, Done
|
Error,
|
||||||
|
Warn,
|
||||||
|
Info,
|
||||||
|
Debug,
|
||||||
|
Done
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -10,259 +10,318 @@ package sbt;
|
||||||
import sbt.testing.*;
|
import sbt.testing.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Adapts the old {@link org.scalatools.testing.Framework} interface into the new
|
* Adapts the old {@link org.scalatools.testing.Framework} interface into the new {@link
|
||||||
* {@link sbt.testing.Framework}
|
* sbt.testing.Framework}
|
||||||
*/
|
*/
|
||||||
final class FrameworkWrapper implements Framework {
|
final class FrameworkWrapper implements Framework {
|
||||||
|
|
||||||
private final org.scalatools.testing.Framework oldFramework;
|
private final org.scalatools.testing.Framework oldFramework;
|
||||||
|
|
||||||
FrameworkWrapper(final org.scalatools.testing.Framework oldFramework) {
|
FrameworkWrapper(final org.scalatools.testing.Framework oldFramework) {
|
||||||
this.oldFramework = oldFramework;
|
this.oldFramework = oldFramework;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String name() {
|
public String name() {
|
||||||
return oldFramework.name();
|
return oldFramework.name();
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fingerprint[] fingerprints() {
|
public Fingerprint[] fingerprints() {
|
||||||
final org.scalatools.testing.Fingerprint[] oldFingerprints = oldFramework.tests();
|
final org.scalatools.testing.Fingerprint[] oldFingerprints = oldFramework.tests();
|
||||||
final int length = oldFingerprints.length;
|
final int length = oldFingerprints.length;
|
||||||
final Fingerprint[] fingerprints = new Fingerprint[length];
|
final Fingerprint[] fingerprints = new Fingerprint[length];
|
||||||
for (int i=0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
final org.scalatools.testing.Fingerprint oldFingerprint = oldFingerprints[i];
|
final org.scalatools.testing.Fingerprint oldFingerprint = oldFingerprints[i];
|
||||||
if (oldFingerprint instanceof org.scalatools.testing.TestFingerprint)
|
if (oldFingerprint instanceof org.scalatools.testing.TestFingerprint)
|
||||||
fingerprints[i] = new SubclassFingerprintWrapper((org.scalatools.testing.TestFingerprint) oldFingerprint);
|
fingerprints[i] =
|
||||||
else if (oldFingerprint instanceof org.scalatools.testing.SubclassFingerprint)
|
new SubclassFingerprintWrapper((org.scalatools.testing.TestFingerprint) oldFingerprint);
|
||||||
fingerprints[i] = new SubclassFingerprintWrapper((org.scalatools.testing.SubclassFingerprint) oldFingerprint);
|
else if (oldFingerprint instanceof org.scalatools.testing.SubclassFingerprint)
|
||||||
else
|
fingerprints[i] =
|
||||||
fingerprints[i] = new AnnotatedFingerprintWrapper((org.scalatools.testing.AnnotatedFingerprint) oldFingerprint);
|
new SubclassFingerprintWrapper(
|
||||||
}
|
(org.scalatools.testing.SubclassFingerprint) oldFingerprint);
|
||||||
return fingerprints;
|
else
|
||||||
}
|
fingerprints[i] =
|
||||||
|
new AnnotatedFingerprintWrapper(
|
||||||
|
(org.scalatools.testing.AnnotatedFingerprint) oldFingerprint);
|
||||||
|
}
|
||||||
|
return fingerprints;
|
||||||
|
}
|
||||||
|
|
||||||
public Runner runner(final String[] args, final String[] remoteArgs, final ClassLoader testClassLoader) {
|
public Runner runner(
|
||||||
return new RunnerWrapper(oldFramework, testClassLoader, args);
|
final String[] args, final String[] remoteArgs, final ClassLoader testClassLoader) {
|
||||||
}
|
return new RunnerWrapper(oldFramework, testClassLoader, args);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class SubclassFingerprintWrapper implements SubclassFingerprint {
|
final class SubclassFingerprintWrapper implements SubclassFingerprint {
|
||||||
private final String superclassName;
|
private final String superclassName;
|
||||||
private final boolean isModule;
|
private final boolean isModule;
|
||||||
private final boolean requireNoArgConstructor;
|
private final boolean requireNoArgConstructor;
|
||||||
|
|
||||||
SubclassFingerprintWrapper(final org.scalatools.testing.SubclassFingerprint oldFingerprint) {
|
SubclassFingerprintWrapper(final org.scalatools.testing.SubclassFingerprint oldFingerprint) {
|
||||||
superclassName = oldFingerprint.superClassName();
|
superclassName = oldFingerprint.superClassName();
|
||||||
isModule = oldFingerprint.isModule();
|
isModule = oldFingerprint.isModule();
|
||||||
requireNoArgConstructor = false; // Old framework SubclassFingerprint does not require no arg constructor
|
requireNoArgConstructor =
|
||||||
}
|
false; // Old framework SubclassFingerprint does not require no arg constructor
|
||||||
|
}
|
||||||
|
|
||||||
public boolean isModule() {
|
public boolean isModule() {
|
||||||
return isModule;
|
return isModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String superclassName() {
|
public String superclassName() {
|
||||||
return superclassName;
|
return superclassName;
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean requireNoArgConstructor() {
|
public boolean requireNoArgConstructor() {
|
||||||
return requireNoArgConstructor;
|
return requireNoArgConstructor;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class AnnotatedFingerprintWrapper implements AnnotatedFingerprint {
|
final class AnnotatedFingerprintWrapper implements AnnotatedFingerprint {
|
||||||
private final String annotationName;
|
private final String annotationName;
|
||||||
private final boolean isModule;
|
private final boolean isModule;
|
||||||
|
|
||||||
AnnotatedFingerprintWrapper(final org.scalatools.testing.AnnotatedFingerprint oldFingerprint) {
|
AnnotatedFingerprintWrapper(final org.scalatools.testing.AnnotatedFingerprint oldFingerprint) {
|
||||||
annotationName = oldFingerprint.annotationName();
|
annotationName = oldFingerprint.annotationName();
|
||||||
isModule = oldFingerprint.isModule();
|
isModule = oldFingerprint.isModule();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean isModule() {
|
public boolean isModule() {
|
||||||
return isModule;
|
return isModule;
|
||||||
}
|
}
|
||||||
|
|
||||||
public String annotationName() {
|
public String annotationName() {
|
||||||
return annotationName;
|
return annotationName;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class EventHandlerWrapper implements org.scalatools.testing.EventHandler {
|
final class EventHandlerWrapper implements org.scalatools.testing.EventHandler {
|
||||||
|
|
||||||
private final EventHandler newEventHandler;
|
private final EventHandler newEventHandler;
|
||||||
private final String fullyQualifiedName;
|
private final String fullyQualifiedName;
|
||||||
private final Fingerprint fingerprint;
|
private final Fingerprint fingerprint;
|
||||||
|
|
||||||
EventHandlerWrapper(final EventHandler newEventHandler, final String fullyQualifiedName, final Fingerprint fingerprint) {
|
EventHandlerWrapper(
|
||||||
this.newEventHandler = newEventHandler;
|
final EventHandler newEventHandler,
|
||||||
this.fullyQualifiedName = fullyQualifiedName;
|
final String fullyQualifiedName,
|
||||||
this.fingerprint = fingerprint;
|
final Fingerprint fingerprint) {
|
||||||
}
|
this.newEventHandler = newEventHandler;
|
||||||
|
this.fullyQualifiedName = fullyQualifiedName;
|
||||||
|
this.fingerprint = fingerprint;
|
||||||
|
}
|
||||||
|
|
||||||
public void handle(final org.scalatools.testing.Event oldEvent) {
|
public void handle(final org.scalatools.testing.Event oldEvent) {
|
||||||
newEventHandler.handle(new EventWrapper(oldEvent, fullyQualifiedName, fingerprint));
|
newEventHandler.handle(new EventWrapper(oldEvent, fullyQualifiedName, fingerprint));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class EventWrapper implements Event {
|
final class EventWrapper implements Event {
|
||||||
|
|
||||||
private final org.scalatools.testing.Event oldEvent;
|
private final org.scalatools.testing.Event oldEvent;
|
||||||
private final String className;
|
private final String className;
|
||||||
private final Fingerprint fingerprint;
|
private final Fingerprint fingerprint;
|
||||||
private final OptionalThrowable throwable;
|
private final OptionalThrowable throwable;
|
||||||
|
|
||||||
EventWrapper(final org.scalatools.testing.Event oldEvent, final String className, final Fingerprint fingerprint) {
|
EventWrapper(
|
||||||
this.oldEvent = oldEvent;
|
final org.scalatools.testing.Event oldEvent,
|
||||||
this.className = className;
|
final String className,
|
||||||
this.fingerprint = fingerprint;
|
final Fingerprint fingerprint) {
|
||||||
final Throwable oldThrowable = oldEvent.error();
|
this.oldEvent = oldEvent;
|
||||||
if (oldThrowable == null)
|
this.className = className;
|
||||||
throwable = new OptionalThrowable();
|
this.fingerprint = fingerprint;
|
||||||
else
|
final Throwable oldThrowable = oldEvent.error();
|
||||||
throwable = new OptionalThrowable(oldThrowable);
|
if (oldThrowable == null) throwable = new OptionalThrowable();
|
||||||
}
|
else throwable = new OptionalThrowable(oldThrowable);
|
||||||
|
}
|
||||||
|
|
||||||
public String fullyQualifiedName() {
|
public String fullyQualifiedName() {
|
||||||
return className;
|
return className;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Fingerprint fingerprint() {
|
public Fingerprint fingerprint() {
|
||||||
return fingerprint;
|
return fingerprint;
|
||||||
}
|
}
|
||||||
|
|
||||||
public Selector selector() {
|
public Selector selector() {
|
||||||
return new TestSelector(oldEvent.testName());
|
return new TestSelector(oldEvent.testName());
|
||||||
}
|
}
|
||||||
|
|
||||||
public Status status() {
|
public Status status() {
|
||||||
switch (oldEvent.result()) {
|
switch (oldEvent.result()) {
|
||||||
case Success:
|
case Success:
|
||||||
return Status.Success;
|
return Status.Success;
|
||||||
case Error:
|
case Error:
|
||||||
return Status.Error;
|
return Status.Error;
|
||||||
case Failure:
|
case Failure:
|
||||||
return Status.Failure;
|
return Status.Failure;
|
||||||
case Skipped:
|
case Skipped:
|
||||||
return Status.Skipped;
|
return Status.Skipped;
|
||||||
default:
|
default:
|
||||||
throw new IllegalStateException("Invalid status.");
|
throw new IllegalStateException("Invalid status.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public OptionalThrowable throwable() {
|
public OptionalThrowable throwable() {
|
||||||
return throwable;
|
return throwable;
|
||||||
}
|
}
|
||||||
|
|
||||||
public long duration() {
|
public long duration() {
|
||||||
return -1; // Just return -1 as old event does not have duration.
|
return -1; // Just return -1 as old event does not have duration.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
final class RunnerWrapper implements Runner {
|
final class RunnerWrapper implements Runner {
|
||||||
|
|
||||||
private final org.scalatools.testing.Framework oldFramework;
|
private final org.scalatools.testing.Framework oldFramework;
|
||||||
private final ClassLoader testClassLoader;
|
private final ClassLoader testClassLoader;
|
||||||
private final String[] args;
|
private final String[] args;
|
||||||
|
|
||||||
RunnerWrapper(final org.scalatools.testing.Framework oldFramework, final ClassLoader testClassLoader, final String[] args) {
|
RunnerWrapper(
|
||||||
this.oldFramework = oldFramework;
|
final org.scalatools.testing.Framework oldFramework,
|
||||||
this.testClassLoader = testClassLoader;
|
final ClassLoader testClassLoader,
|
||||||
this.args = args;
|
final String[] args) {
|
||||||
}
|
this.oldFramework = oldFramework;
|
||||||
|
this.testClassLoader = testClassLoader;
|
||||||
|
this.args = args;
|
||||||
|
}
|
||||||
|
|
||||||
public Task[] tasks(final TaskDef[] taskDefs) {
|
public Task[] tasks(final TaskDef[] taskDefs) {
|
||||||
final int length = taskDefs.length;
|
final int length = taskDefs.length;
|
||||||
final Task[] tasks = new Task[length];
|
final Task[] tasks = new Task[length];
|
||||||
for (int i = 0; i < length; i++) {
|
for (int i = 0; i < length; i++) {
|
||||||
final TaskDef taskDef = taskDefs[i];
|
final TaskDef taskDef = taskDefs[i];
|
||||||
tasks[i] = createTask(taskDef);
|
tasks[i] = createTask(taskDef);
|
||||||
}
|
}
|
||||||
return tasks;
|
return tasks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Task createTask(final TaskDef taskDef) {
|
private Task createTask(final TaskDef taskDef) {
|
||||||
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
|
||||||
}
|
}
|
||||||
|
|
||||||
private org.scalatools.testing.Logger createOldLogger(final Logger logger) {
|
private org.scalatools.testing.Logger createOldLogger(final Logger logger) {
|
||||||
return new org.scalatools.testing.Logger() {
|
return new org.scalatools.testing.Logger() {
|
||||||
public boolean ansiCodesSupported() { return logger.ansiCodesSupported(); }
|
public boolean ansiCodesSupported() {
|
||||||
public void error(final String msg) { logger.error(msg); }
|
return logger.ansiCodesSupported();
|
||||||
public void warn(final String msg) { logger.warn(msg); }
|
}
|
||||||
public void info(final String msg) { logger.info(msg); }
|
|
||||||
public void debug(final String msg) { logger.debug(msg); }
|
|
||||||
public void trace(final Throwable t) { logger.trace(t); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runRunner(final org.scalatools.testing.Runner runner, final Fingerprint fingerprint, final EventHandler eventHandler) {
|
public void error(final String msg) {
|
||||||
// Old runner only support subclass fingerprint.
|
logger.error(msg);
|
||||||
final SubclassFingerprint subclassFingerprint = (SubclassFingerprint) fingerprint;
|
}
|
||||||
final org.scalatools.testing.TestFingerprint oldFingerprint =
|
|
||||||
new org.scalatools.testing.TestFingerprint() {
|
|
||||||
public boolean isModule() { return subclassFingerprint.isModule(); }
|
|
||||||
public String superClassName() { return subclassFingerprint.superclassName(); }
|
|
||||||
};
|
|
||||||
final String name = taskDef.fullyQualifiedName();
|
|
||||||
runner.run(name, oldFingerprint, new EventHandlerWrapper(eventHandler, name, subclassFingerprint), args);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void runRunner2(final org.scalatools.testing.Runner2 runner, final Fingerprint fingerprint, final EventHandler eventHandler) {
|
public void warn(final String msg) {
|
||||||
final org.scalatools.testing.Fingerprint oldFingerprint;
|
logger.warn(msg);
|
||||||
if (fingerprint instanceof SubclassFingerprint) {
|
}
|
||||||
final SubclassFingerprint subclassFingerprint = (SubclassFingerprint) fingerprint;
|
|
||||||
oldFingerprint = new org.scalatools.testing.SubclassFingerprint() {
|
|
||||||
public boolean isModule() { return subclassFingerprint.isModule(); }
|
|
||||||
public String superClassName() { return subclassFingerprint.superclassName(); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
final AnnotatedFingerprint annotatedFingerprint = (AnnotatedFingerprint) fingerprint;
|
|
||||||
oldFingerprint = new org.scalatools.testing.AnnotatedFingerprint() {
|
|
||||||
public boolean isModule() { return annotatedFingerprint.isModule(); }
|
|
||||||
public String annotationName() { return annotatedFingerprint.annotationName(); }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
final String name = taskDef.fullyQualifiedName();
|
|
||||||
runner.run(name, oldFingerprint, new EventHandlerWrapper(eventHandler, name, fingerprint), args);
|
|
||||||
}
|
|
||||||
|
|
||||||
public Task[] execute(final EventHandler eventHandler, final Logger[] loggers) {
|
public void info(final String msg) {
|
||||||
final int length = loggers.length;
|
logger.info(msg);
|
||||||
final org.scalatools.testing.Logger[] oldLoggers = new org.scalatools.testing.Logger[length];
|
}
|
||||||
for (int i=0; i<length; i++) {
|
|
||||||
oldLoggers[i] = createOldLogger(loggers[i]);
|
|
||||||
}
|
|
||||||
|
|
||||||
final org.scalatools.testing.Runner runner = oldFramework.testRunner(testClassLoader, oldLoggers);
|
public void debug(final String msg) {
|
||||||
final Fingerprint fingerprint = taskDef.fingerprint();
|
logger.debug(msg);
|
||||||
if (runner instanceof org.scalatools.testing.Runner2) {
|
}
|
||||||
runRunner2((org.scalatools.testing.Runner2) runner, fingerprint, eventHandler);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
runRunner(runner, fingerprint, eventHandler);
|
|
||||||
}
|
|
||||||
return new Task[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
public TaskDef taskDef() {
|
public void trace(final Throwable t) {
|
||||||
return taskDef;
|
logger.trace(t);
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public String done() {
|
private void runRunner(
|
||||||
return "";
|
final org.scalatools.testing.Runner runner,
|
||||||
}
|
final Fingerprint fingerprint,
|
||||||
|
final EventHandler eventHandler) {
|
||||||
|
// Old runner only support subclass fingerprint.
|
||||||
|
final SubclassFingerprint subclassFingerprint = (SubclassFingerprint) fingerprint;
|
||||||
|
final org.scalatools.testing.TestFingerprint oldFingerprint =
|
||||||
|
new org.scalatools.testing.TestFingerprint() {
|
||||||
|
public boolean isModule() {
|
||||||
|
return subclassFingerprint.isModule();
|
||||||
|
}
|
||||||
|
|
||||||
public String[] args() {
|
public String superClassName() {
|
||||||
return args;
|
return subclassFingerprint.superclassName();
|
||||||
}
|
}
|
||||||
|
};
|
||||||
|
final String name = taskDef.fullyQualifiedName();
|
||||||
|
runner.run(
|
||||||
|
name,
|
||||||
|
oldFingerprint,
|
||||||
|
new EventHandlerWrapper(eventHandler, name, subclassFingerprint),
|
||||||
|
args);
|
||||||
|
}
|
||||||
|
|
||||||
public String[] remoteArgs() {
|
private void runRunner2(
|
||||||
return new String[0]; // Old framework does not support remoteArgs
|
final org.scalatools.testing.Runner2 runner,
|
||||||
}
|
final Fingerprint fingerprint,
|
||||||
|
final EventHandler eventHandler) {
|
||||||
|
final org.scalatools.testing.Fingerprint oldFingerprint;
|
||||||
|
if (fingerprint instanceof SubclassFingerprint) {
|
||||||
|
final SubclassFingerprint subclassFingerprint = (SubclassFingerprint) fingerprint;
|
||||||
|
oldFingerprint =
|
||||||
|
new org.scalatools.testing.SubclassFingerprint() {
|
||||||
|
public boolean isModule() {
|
||||||
|
return subclassFingerprint.isModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String superClassName() {
|
||||||
|
return subclassFingerprint.superclassName();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
} else {
|
||||||
|
final AnnotatedFingerprint annotatedFingerprint = (AnnotatedFingerprint) fingerprint;
|
||||||
|
oldFingerprint =
|
||||||
|
new org.scalatools.testing.AnnotatedFingerprint() {
|
||||||
|
public boolean isModule() {
|
||||||
|
return annotatedFingerprint.isModule();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String annotationName() {
|
||||||
|
return annotatedFingerprint.annotationName();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
final String name = taskDef.fullyQualifiedName();
|
||||||
|
runner.run(
|
||||||
|
name, oldFingerprint, new EventHandlerWrapper(eventHandler, name, fingerprint), args);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Task[] execute(final EventHandler eventHandler, final Logger[] loggers) {
|
||||||
|
final int length = loggers.length;
|
||||||
|
final org.scalatools.testing.Logger[] oldLoggers =
|
||||||
|
new org.scalatools.testing.Logger[length];
|
||||||
|
for (int i = 0; i < length; i++) {
|
||||||
|
oldLoggers[i] = createOldLogger(loggers[i]);
|
||||||
|
}
|
||||||
|
|
||||||
|
final org.scalatools.testing.Runner runner =
|
||||||
|
oldFramework.testRunner(testClassLoader, oldLoggers);
|
||||||
|
final Fingerprint fingerprint = taskDef.fingerprint();
|
||||||
|
if (runner instanceof org.scalatools.testing.Runner2) {
|
||||||
|
runRunner2((org.scalatools.testing.Runner2) runner, fingerprint, eventHandler);
|
||||||
|
} else {
|
||||||
|
runRunner(runner, fingerprint, eventHandler);
|
||||||
|
}
|
||||||
|
return new Task[0];
|
||||||
|
}
|
||||||
|
|
||||||
|
public TaskDef taskDef() {
|
||||||
|
return taskDef;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
public String done() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] args() {
|
||||||
|
return args;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] remoteArgs() {
|
||||||
|
return new String[0]; // Old framework does not support remoteArgs
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -19,64 +19,65 @@ import xsbti.Logger;
|
||||||
import java.io.File;
|
import java.io.File;
|
||||||
|
|
||||||
public interface ZincBridgeProvider {
|
public interface ZincBridgeProvider {
|
||||||
/**
|
/**
|
||||||
* Returns an ivy resolver to resolve dependencies locally in the default `.ivy2/local`.
|
* Returns an ivy resolver to resolve dependencies locally in the default `.ivy2/local`.
|
||||||
* <p>
|
*
|
||||||
* For those users interested in using Internet resolvers like Maven Central, you can
|
* <p>For those users interested in using Internet resolvers like Maven Central, you can
|
||||||
* instantiate them via {@link Resolver#mavenCentral()} et al.
|
* instantiate them via {@link Resolver#mavenCentral()} et al.
|
||||||
*
|
*
|
||||||
* @return A local ivy resolver.
|
* @return A local ivy resolver.
|
||||||
*/
|
*/
|
||||||
public static Resolver getLocalResolver() {
|
public static Resolver getLocalResolver() {
|
||||||
return ZincComponentCompiler.LocalResolver();
|
return ZincComponentCompiler.LocalResolver();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a global lock that does nothing but calling the callable to synchronize
|
* Returns a global lock that does nothing but calling the callable to synchronize across threads.
|
||||||
* across threads. The lock file is used to resolve and download dependencies via ivy.
|
* The lock file is used to resolve and download dependencies via ivy.
|
||||||
* <p>
|
*
|
||||||
* This operation is necessary to invoke {@link ZincBridgeProvider#getProvider(File, GlobalLock, ComponentProvider, IvyConfiguration, Logger)}.
|
* <p>This operation is necessary to invoke {@link ZincBridgeProvider#getProvider(File,
|
||||||
*
|
* GlobalLock, ComponentProvider, IvyConfiguration, Logger)}.
|
||||||
* @return A default global lock.
|
*
|
||||||
*/
|
* @return A default global lock.
|
||||||
public static GlobalLock getDefaultLock() {
|
*/
|
||||||
return ZincComponentCompiler.getDefaultLock();
|
public static GlobalLock getDefaultLock() {
|
||||||
}
|
return ZincComponentCompiler.getDefaultLock();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a default component provider that retrieves and installs component managers
|
* Returns a default component provider that retrieves and installs component managers (like the
|
||||||
* (like the compiled bridge sources) under a given target directory.
|
* compiled bridge sources) under a given target directory.
|
||||||
* <p>
|
*
|
||||||
* This is the most simplistic implementation of a component provider. If you need more
|
* <p>This is the most simplistic implementation of a component provider. If you need more
|
||||||
* advanced feature, like management of component via proxies (for companies) or access to
|
* advanced feature, like management of component via proxies (for companies) or access to other
|
||||||
* other servers, you need to implement your own component provider.
|
* servers, you need to implement your own component provider.
|
||||||
*
|
*
|
||||||
* @param componentsRoot The directory in which components will be installed and retrieved.
|
* @param componentsRoot The directory in which components will be installed and retrieved.
|
||||||
* @return A default component provider.
|
* @return A default component provider.
|
||||||
*/
|
*/
|
||||||
public static ComponentProvider getDefaultComponentProvider(File componentsRoot) {
|
public static ComponentProvider getDefaultComponentProvider(File componentsRoot) {
|
||||||
return ZincComponentCompiler.getDefaultComponentProvider(componentsRoot);
|
return ZincComponentCompiler.getDefaultComponentProvider(componentsRoot);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get a compiler bridge provider that allows the user to fetch Scala and a compiled bridge.
|
* Get a compiler bridge provider that allows the user to fetch Scala and a compiled bridge.
|
||||||
*
|
*
|
||||||
* @param scalaJarsTarget The place where the downloaded Scala jars should be placed.
|
* @param scalaJarsTarget The place where the downloaded Scala jars should be placed.
|
||||||
* @param lock The lock file used internally by Ivy to synchronize the dependency resolution.
|
* @param lock The lock file used internally by Ivy to synchronize the dependency resolution.
|
||||||
* @param componentProvider A provider capable of retrieving existing components or installing
|
* @param componentProvider A provider capable of retrieving existing components or installing new
|
||||||
* new ones. The component provider manages compiled bridge sources.
|
* ones. The component provider manages compiled bridge sources.
|
||||||
* @param dependencyResolution The library management module to use to retrieve the bridge.
|
* @param dependencyResolution The library management module to use to retrieve the bridge.
|
||||||
* @param logger The logger.
|
* @param logger The logger.
|
||||||
* @return A compiler bridge provider capable of fetching scala jars and the compiler bridge.
|
* @return A compiler bridge provider capable of fetching scala jars and the compiler bridge.
|
||||||
*/
|
*/
|
||||||
public static CompilerBridgeProvider getProvider(
|
public static CompilerBridgeProvider getProvider(
|
||||||
File scalaJarsTarget,
|
File scalaJarsTarget,
|
||||||
GlobalLock lock,
|
GlobalLock lock,
|
||||||
ComponentProvider componentProvider,
|
ComponentProvider componentProvider,
|
||||||
DependencyResolution dependencyResolution,
|
DependencyResolution dependencyResolution,
|
||||||
Logger logger
|
Logger logger) {
|
||||||
) {
|
ZincComponentManager manager =
|
||||||
ZincComponentManager manager = new ZincComponentManager(lock, componentProvider, None$.empty(), logger);
|
new ZincComponentManager(lock, componentProvider, None$.empty(), logger);
|
||||||
return ZincComponentCompiler.interfaceProvider(manager, dependencyResolution, scalaJarsTarget);
|
return ZincComponentCompiler.interfaceProvider(manager, dependencyResolution, scalaJarsTarget);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue