0

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.

Dylan Cruz
  • 25
  • 4
  • Perhaps something variation of [this](https://stackoverflow.com/questions/16608934/can-i-apply-a-time-limit-for-all-the-tests-in-the-suite)? – Andrew S Aug 10 '17 at 19:27
  • Unfortunately that won't work in this instance as the timeout is being defined outside of the test code. – Dylan Cruz Aug 10 '17 at 19:58

0 Answers0