I need to use maven surefire to launch junit test methods on a project concurrently with timeouts. Right now, I'm doing this with the code below:
Main - Makes a new fixed thread pool backed by a linked blocking queue. Then it submits runnables that make our maven cmd line call to the OS.
public class Sandbox {
public static void main(String[] args) {
ExecutorService executor = new ThreadPoolExecutor(10, 10, 5, TimeUnit.MINUTES, new LinkedBlockingQueue<Runnable>());
executor.submit(new RunCommandWithTimeout(10, TimeUnit.SECONDS, "cmd /C C:\\\\mavenTestCall1.bat"));
executor.submit(new RunCommandWithTimeout(5, TimeUnit.MINUTES, "cmd /C C:\\\\mavenTestCall2.bat"));
}
}
RunCommandWithTimeout - This class makes a call to RunTime.getRunTime().exec passing in a batch file that contains our maven call. Waits with timeout to complete
public class RunCommandWithTimeout implements Runnable{
private Process process;
private int timeout;
private TimeUnit unit;
private String command;
public RunCommandWithTimeout(int timeout, TimeUnit unit, String command) {
this.timeout = timeout;
this.unit = unit;
this.command = command;
}
@Override
public void run() {
System.out.println(LocalTime.now() + " Starting call");
try {
Runtime runtime = Runtime.getRuntime();
process = runtime.exec(command);
if (!process.waitFor(timeout, unit)) {
System.out.println(LocalTime.now() + " We timed out. Do stuff. Returning...");
process.destroyForcibly();
return;
}
} catch (InterruptedException ie) {
System.out.println(LocalTime.now() + " There is an interrupted exception. Do stuff. Returning...");
return;
} catch (IOException e) {
System.out.println(LocalTime.now() + " There is an io exception. Do stuff. Returning...");
return;
}
System.out.println(LocalTime.now() + " Call complete");
}
}
Batch File Example
pushd \\NetworkDrive\MavenProjectDirectory
mvn test -e -Dtest=TestClass#TestMethod >> C:\PathToOutputLog
It mostly works. The tests run concurrently and timeout when they're supposed to.
The issue with this approach is process.destroy isn't stopping the test from running. I can still report back that there was a timeout and that the test resulted in a failure for taking too long but that doesn't stop the process from finishing the test on the system.
Does anyone know of a better way? I know there is an embedded version of maven but I can't find any documentation on how to use it really.