package org.jboss.test.faces; import java.util.concurrent.CountDownLatch; import org.junit.rules.MethodRule; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.Statement; public final class ThreadsRule implements MethodRule { public Statement apply(final Statement statement, final FrameworkMethod frameworkMethod, final Object o) { final Threads concurrent = frameworkMethod.getAnnotation(Threads.class); if (concurrent == null) return statement; else { return new Statement() { @Override public void evaluate() throws Throwable { final String name = frameworkMethod.getName(); final Thread[] threads = new Thread[concurrent.value()]; final CountDownLatch go = new CountDownLatch(1); final CountDownLatch finished = new CountDownLatch( threads.length); for (int i = 0; i < threads.length; i++) { threads[i] = new Thread(new Runnable() { public void run() { try { go.await(); } catch (InterruptedException e) { Thread.currentThread().interrupt(); } try { statement.evaluate(); // frameworkMethod.invokeExplosively(o); } catch (Error e) { throw e; } catch (RuntimeException r) { throw r; } catch (Throwable throwable) { RuntimeException r = new RuntimeException( throwable.getMessage(), throwable); r.setStackTrace(throwable.getStackTrace()); throw r; } finally { finished.countDown(); } } }, name + "-Thread-" + i); threads[i].start(); } go.countDown(); finished.await(); } }; } } }