package org.pitest.mutationtest.execute; import java.util.ArrayList; import java.util.List; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; import java.util.concurrent.Future; import java.util.concurrent.LinkedBlockingQueue; import java.util.concurrent.ThreadPoolExecutor; import java.util.concurrent.TimeUnit; import java.util.logging.Logger; import org.pitest.functional.FCollection; import org.pitest.functional.SideEffect1; import org.pitest.mutationtest.ClassMutationResults; import org.pitest.mutationtest.MutationMetaData; import org.pitest.mutationtest.MutationResultListener; import org.pitest.mutationtest.build.MutationAnalysisUnit; import org.pitest.util.Log; import org.pitest.util.Unchecked; public class MutationAnalysisExecutor { private static final Logger LOG = Log.getLogger(); private final List<MutationResultListener> listeners; private final ThreadPoolExecutor executor; public MutationAnalysisExecutor(int numberOfThreads, List<MutationResultListener> listeners) { this.listeners = listeners; this.executor = new ThreadPoolExecutor(numberOfThreads, numberOfThreads, 10, TimeUnit.SECONDS, new LinkedBlockingQueue<Runnable>(), Executors.defaultThreadFactory()); } // entry point for mutation testing public void run(final List<MutationAnalysisUnit> testUnits) { LOG.fine("Running " + testUnits.size() + " units"); signalRunStartToAllListeners(); List<Future<MutationMetaData>> results = new ArrayList<Future<MutationMetaData>>( testUnits.size()); for (final MutationAnalysisUnit unit : testUnits) { results.add(this.executor.submit(unit)); } this.executor.shutdown(); try { processResult(results); } catch (InterruptedException e) { throw Unchecked.translateCheckedException(e); } catch (ExecutionException e) { throw Unchecked.translateCheckedException(e); } signalRunEndToAllListeners(); } private void processResult(List<Future<MutationMetaData>> results) throws InterruptedException, ExecutionException { for (Future<MutationMetaData> f : results) { MutationMetaData r = f.get(); for (MutationResultListener l : this.listeners) { for (final ClassMutationResults cr : r.toClassResults()) { l.handleMutationResult(cr); } } } } private void signalRunStartToAllListeners() { FCollection.forEach(this.listeners, new SideEffect1<MutationResultListener>() { @Override public void apply(final MutationResultListener a) { a.runStart(); } }); } private void signalRunEndToAllListeners() { FCollection.forEach(this.listeners, new SideEffect1<MutationResultListener>() { @Override public void apply(final MutationResultListener a) { a.runEnd(); } }); } }