/*
* Copyright 2014 EMC Corporation. All Rights Reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License").
* You may not use this file except in compliance with the License.
* A copy of the License is located at
*
* http://www.apache.org/licenses/LICENSE-2.0.txt
*
* or in the "license" file accompanying this file. This file is distributed
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either
* express or implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.emc.test.util;
import org.junit.runners.BlockJUnit4ClassRunner;
import org.junit.runners.model.InitializationError;
import org.junit.runners.model.RunnerScheduler;
import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* NOTE: when threading a test class, remember that remote state must also be synchronized! That means don't
* use the same object keys in different tests! And if you can help it, try not to use the same bucket either!
*/
public class ConcurrentJunitRunner extends BlockJUnit4ClassRunner {
public ConcurrentJunitRunner(final Class<?> klass) throws InitializationError {
super(klass);
setScheduler(new RunnerScheduler() {
ExecutorService executorService = Executors.newFixedThreadPool(
klass.isAnnotationPresent(Concurrent.class) ?
klass.getAnnotation(Concurrent.class).threads() :
(int) (Runtime.getRuntime().availableProcessors() * 1.5));
Queue<Future<?>> tasks = new LinkedList<Future<?>>();
@Override
public void schedule(Runnable childStatement) {
tasks.add(executorService.submit(childStatement));
}
@Override
public void finished() {
try {
for (Future<?> task : tasks) task.get();
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
} catch (ExecutionException e) {
e.printStackTrace(); // (JUnit *should* fail the test)
} finally {
executorService.shutdownNow();
}
}
});
}
}