I want to reuse some integration tests for load testing purposes. I implemented a rule which is parameterized by an annotation:
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface Parallel {
int invocations() default 1;
int rampUpTime() default 0;
}
In my rule implementation the annotation is evaluated and a statement is set up, which has a evaluate method like that:
@Override
public void evaluate() throws Throwable {
ScheduledExecutorService exe = Executors.newScheduledThreadPool(invocations);
for (int i = 0; i < invocations; i++) {
ScheduledFuture<?> scheduledFuture = exe.schedule(new Runnable() {
@Override
public void run() {
try {
invocated++;
// Request test = Request.method(description.getTestClass(), description.getMethodName());
// new JUnitCore().run(test);
statement.evaluate();
} catch (Throwable e) {
e.printStackTrace();
}
}
}, i * rampUpTime, this.timeUnit);
futures.add(scheduledFuture);
}
}
So, the evaluate
call gets wrapped in a Runnable()
and scheduled as described in the annotation. The thing is: In my rule, only the scheduling takes place, the runner doesn´t know (or care) about all the runables which only run as long as it takes to set up the whole test suite. So I´m trying to add the calls to evalute()
to the test runner. First try was to use JUnitCore.run(...)
which of course ends in a recursion.
Next try was to collect all the futures and wait for them to finish. This works fine on a per test basis, but I want to execute a whole test suite in parallel. And also, in my test report, I only see the test being executed once.
So then I thought I use a parameterized suite with a context (an object which collects all the futures from all tests) as parameter, but I didn´t found a way to promote this context object to the tests, each test has to have its own parameters.
I´m now asking for a way to add multiple executions from my rule to the test runner which is executing it.
LoadTest
from clarkware.com/software/JUnitPerf.html might help – Icky