Skip to content

Commit

Permalink
added the progress bar monitor to the parallel test runners. this bre…
Browse files Browse the repository at this point in the history
…aks the monitor because it is not thread safe yet.
  • Loading branch information
jurgenvinju committed Apr 2, 2024
1 parent 300f8ad commit 40d71da
Show file tree
Hide file tree
Showing 3 changed files with 41 additions and 38 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,8 @@
import java.util.concurrent.TimeUnit;
import java.util.function.Consumer;

import jline.TerminalFactory;

import org.junit.runner.Description;
import org.junit.runner.Result;
import org.junit.runner.Runner;
Expand All @@ -38,6 +40,7 @@
import org.rascalmpl.interpreter.load.StandardLibraryContributor;
import org.rascalmpl.interpreter.result.AbstractFunction;
import org.rascalmpl.interpreter.utils.RascalManifest;
import org.rascalmpl.repl.TerminalProgressBarMonitor;
import org.rascalmpl.uri.URIUtil;
import org.rascalmpl.values.ValueFactoryFactory;

Expand All @@ -53,6 +56,7 @@
*
*/
public class RascalJUnitParallelRecursiveTestRunner extends Runner {
private final static TerminalProgressBarMonitor monitor = new TerminalProgressBarMonitor(System.out, TerminalFactory.get());
private final int numberOfWorkers;
private final Semaphore importsCompleted = new Semaphore(0);
private final Semaphore waitForRunning = new Semaphore(0);
Expand All @@ -67,7 +71,6 @@ public class RascalJUnitParallelRecursiveTestRunner extends Runner {

private final ISourceLocation projectRoot;


public RascalJUnitParallelRecursiveTestRunner(Class<?> clazz) {
System.err.println("Rascal JUnit uses Rascal version " + RascalManifest.getRascalVersionNumber());

Expand Down Expand Up @@ -96,17 +99,12 @@ public RascalJUnitParallelRecursiveTestRunner(Class<?> clazz) {
@Override
public Description getDescription() {
if (rootDesc == null) {
long start = System.nanoTime();
fillModuleWorkList();
long stop = System.nanoTime();
reportTime("Iterating modules", start, stop);
startModuleTesters();

start = System.nanoTime();
rootDesc = Description.createSuiteDescription(projectRoot.toString());
processIncomingModuleDescriptions(rootDesc);
stop = System.nanoTime();
reportTime("Importing modules, looking for tests", start, stop);

assert descriptions.isEmpty();
}
return rootDesc;
Expand All @@ -116,18 +114,10 @@ public Description getDescription() {
public void run(RunNotifier notifier) {
assert rootDesc != null;
notifier.fireTestRunStarted(rootDesc);
long start = System.nanoTime();
runTests(notifier);
long stop = System.nanoTime();
reportTime("Testing modules", start, stop);
notifier.fireTestRunFinished(new Result());
}

private void reportTime(String job, long start, long stop) {
System.out.println(job + ": " + ((stop-start)/1000_000) + "ms");
System.out.flush();
}

private void processIncomingModuleDescriptions(Description rootDesc) {
int completed = 0;
while (completed < numberOfWorkers) {
Expand All @@ -146,7 +136,6 @@ private void processIncomingModuleDescriptions(Description rootDesc) {
}
}


private void startModuleTesters() {
for (int i = 0; i < numberOfWorkers; i++) {
new ModuleTester("JUnit Rascal Evaluator " + (i + 1)).start();
Expand Down Expand Up @@ -189,9 +178,9 @@ private void runTests(RunNotifier notifier) {


public class ModuleTester extends Thread {

private GlobalEnvironment heap;
private ModuleEnvironment root;

private PrintWriter stderr = new PrintWriter(System.err);
private PrintWriter stdout = new PrintWriter(System.out);
private Evaluator evaluator;
Expand Down Expand Up @@ -224,7 +213,6 @@ private void runTests() {
continue;
}


TestEvaluator runner = new TestEvaluator(evaluator, trl);
runner.test(mod.getDisplayName());

Expand Down Expand Up @@ -260,10 +248,10 @@ private void processModules() {
evaluator.doImport(new NullRascalMonitor(), module);
}
catch (Throwable e) {
synchronized(stderr) {
stderr.println("Could not import " + module + " for testing...");
stderr.println(e.getMessage());
e.printStackTrace(stderr);
synchronized(stdout) {
evaluator.warning("Could not import " + module + " for testing...", null);
evaluator.warning(e.getMessage(), null);
e.printStackTrace(evaluator.getOutPrinter());
}

// register a failing module to make sure we report failure later on.
Expand Down Expand Up @@ -303,7 +291,8 @@ private void initializeEvaluator() {
heap = new GlobalEnvironment();
root = heap.addModule(new ModuleEnvironment("___junit_test___", heap));

evaluator = new Evaluator(ValueFactoryFactory.getValueFactory(), System.in, System.err, System.out, root, heap);
evaluator = new Evaluator(ValueFactoryFactory.getValueFactory(), System.in, System.err, monitor, root, heap);
evaluator.setMonitor(monitor);
evaluator.addRascalSearchPathContributor(StandardLibraryContributor.getInstance());
evaluator.getConfiguration().setErrors(true);

Expand All @@ -315,8 +304,8 @@ private void initializeEvaluator() {
public class Listener implements ITestResultListener {
private final PrintWriter stderr;
private final Description module;
private final IRascalMonitor monitor;
private String context = "";
private final IRascalMonitor monitor;

public Listener(Description module, PrintWriter stderr, IRascalMonitor monitor) {
this.module = module;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ public static List<String> getRecursiveModuleList(ISourceLocation root, List<Str
ISourceLocation currentDir = todo.poll();

if (!URIResolverRegistry.getInstance().exists(currentDir)) {
evaluator.warning("Skipping " + currentDir + ", does not exist.", currentDir);
// this happens due to searching in the entire classpath
continue;
}

Expand Down
40 changes: 27 additions & 13 deletions test/org/rascalmpl/test/functionality/ParallelEvaluatorsTests.java
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,15 @@
import org.rascalmpl.interpreter.env.GlobalEnvironment;
import org.rascalmpl.interpreter.env.ModuleEnvironment;
import org.rascalmpl.interpreter.load.StandardLibraryContributor;
import org.rascalmpl.repl.TerminalProgressBarMonitor;
import org.rascalmpl.values.ValueFactoryFactory;

import io.usethesource.vallang.ISourceLocation;
import jline.TerminalFactory;

public class ParallelEvaluatorsTests {

private static final TerminalProgressBarMonitor monitor = new TerminalProgressBarMonitor(System.out, TerminalFactory.get());

private static final String[] testModules = new String[] {
"lang::rascal::tests::library::ValueIO",
"lang::rascal::tests::library::Map",
Expand All @@ -32,27 +35,38 @@ private static Evaluator freshEvaluator() {
var heap = new GlobalEnvironment();
var root = heap.addModule(new ModuleEnvironment("___test___", heap));

var evaluator = new Evaluator(ValueFactoryFactory.getValueFactory(), System.in, System.err, System.out, root, heap);
var evaluator = new Evaluator(ValueFactoryFactory.getValueFactory(), System.in, System.err, monitor, root, heap);
evaluator.setMonitor(monitor);
evaluator.addRascalSearchPathContributor(StandardLibraryContributor.getInstance());
evaluator.setTestResultListener(new ITestResultListener() {
private String context;

@Override
public void start(String context, int count) { }
public void start(String context, int count) {
this.context = context;
monitor.jobStart(context, count);
}

@Override
public void report(boolean successful, String test, ISourceLocation loc, String message,
Throwable exception) {
if (exception != null) {
System.err.println("Got exception: " + exception);
exception.printStackTrace(System.err);
throw new RuntimeException(exception);
}
monitor.jobStep(context, "Run " + test, 1);
if (exception != null) {
evaluator.warning("Got exception: " + exception, loc);
exception.printStackTrace(evaluator.getOutPrinter());
throw new RuntimeException(exception);
}
}

@Override
public void ignored(String test, ISourceLocation loc) { }
public void ignored(String test, ISourceLocation loc) {
monitor.jobStep(context,"Ignored " + test, 1);
}

@Override
public void done() {}
public void done() {
monitor.jobEnd(context, true);
}
});
return evaluator;
}
Expand All @@ -76,9 +90,9 @@ public void testMultipleEvaluators() {
return;
}
var currentTarget = currentModule.get();
System.out.println("Testing module: " + currentTarget + " started");
evaluator.doImport(null, currentTarget);
if (!evaluator.runTests(null)) {

evaluator.doImport(monitor, currentTarget);
if (!evaluator.runTests(monitor)) {
result.set(false);
}
allDone.await();
Expand Down

0 comments on commit 40d71da

Please sign in to comment.