org.kaizen4j.common.util.TestUtils Maven / Gradle / Ivy
package org.kaizen4j.common.util;
import com.google.common.base.Preconditions;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.TimeUnit;
/**
* Created by liuguowen on 2019/6/18.
*/
public class TestUtils {
public static void assertConcurrent(final String message, final List extends Runnable> runnables,
final int maxTimeoutSeconds) throws InterruptedException {
final int numThreads = runnables.size();
final List exceptions = Collections.synchronizedList(new ArrayList<>());
final ExecutorService threadPool = Executors.newFixedThreadPool(numThreads);
try {
final CountDownLatch allExecutorThreadsReady = new CountDownLatch(numThreads);
final CountDownLatch afterInitBlocker = new CountDownLatch(1);
final CountDownLatch allDone = new CountDownLatch(numThreads);
for (final Runnable submittedTestRunnable : runnables) {
threadPool.submit(() -> {
allExecutorThreadsReady.countDown();
try {
afterInitBlocker.await();
submittedTestRunnable.run();
} catch (final Throwable e) {
exceptions.add(e);
} finally {
allDone.countDown();
}
});
}
// wait until all threads are ready
Preconditions.checkArgument(allExecutorThreadsReady.await(runnables.size() * 10, TimeUnit.MILLISECONDS),
"Timeout initializing threads! Perform long lasting initializations before passing runnables to assertConcurrent");
// start all test runners
afterInitBlocker.countDown();
Preconditions.checkArgument(allDone.await(maxTimeoutSeconds, TimeUnit.SECONDS),
message + " timeout! More than " + maxTimeoutSeconds + " seconds");
} finally {
threadPool.shutdownNow();
}
Preconditions.checkArgument(exceptions.isEmpty(), message + " failed with exception(s) " + exceptions);
}
@SuppressWarnings("unchecked")
public static T invokePrivateMethod(Class> clazz, String name, Class>[] parameterTypes, Object[] args)
throws Exception {
Object object = clazz.newInstance();
Method method = clazz.getDeclaredMethod(name, parameterTypes);
method.setAccessible(true);
return (T) method.invoke(object, args);
}
}