You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@maven.apache.org by ag...@apache.org on 2014/03/09 20:42:05 UTC

[01/11] git commit: SUREFIRE [1048] Surefire does not use the total amount of threads specified by threadCount

Repository: maven-surefire
Updated Branches:
  refs/heads/master 55b8d9117 -> 569724167


SUREFIRE [1048] Surefire does not use the total amount of threads specified by threadCount


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/eaeaa28d
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/eaeaa28d
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/eaeaa28d

Branch: refs/heads/master
Commit: eaeaa28dc22ec8098c05fe3eb895e325d12a2676
Parents: 55b8d91
Author: Tibor Digana <ti...@lycos.com>
Authored: Sun Feb 23 16:18:05 2014 +0100
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 19:46:39 2014 +0100

----------------------------------------------------------------------
 .../plugin/surefire/AbstractSurefireMojo.java   |  30 ++-
 .../surefire/booter/ProviderParameterNames.java |   2 +
 .../surefire/junitcore/JUnitCoreParameters.java |  23 +-
 .../surefire/junitcore/JUnitCoreProvider.java   |   2 +-
 .../surefire/junitcore/JUnitCoreWrapper.java    |   6 +-
 .../junitcore/ParallelComputerFactory.java      | 126 ++++++-----
 .../junitcore/pc/ParallelComputerBuilder.java   |  75 +++++--
 .../surefire/junitcore/pc/RunnerCounter.java    |  43 ++++
 .../surefire/junitcore/pc/WrappedRunners.java   |  46 ++++
 .../junitcore/JUnitCoreParametersTest.java      |   8 +-
 .../junitcore/ParallelComputerFactoryTest.java  | 208 +++++++++----------
 .../surefire/junitcore/Surefire746Test.java     |   2 +-
 12 files changed, 381 insertions(+), 190 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index 3a12f1c..f4da5a3 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
@@ -495,6 +495,17 @@ public abstract class AbstractSurefireMojo
     protected String parallel;
 
     /**
+     * (JUnit 4.7 / provider only) The thread counts do not exceed the number of parallel suite, class runners and
+     * average number of methods per class if set to <strong>true</strong>.
+     * <p/>
+     * True by default.
+     *
+     * @since 2.17
+     */
+    @Parameter( property = "parallelOptimized", defaultValue = "true" )
+    protected boolean parallelOptimized;
+
+    /**
      * (JUnit 4.7 provider) The attribute thread-count-suites allows you to specify the concurrency in test suites, i.e.:
      * <ul>
      *  <li>number of threads executing JUnit test suites if <code>threadCount</code> is 0 or unspecified</li>
@@ -1147,12 +1158,14 @@ public abstract class AbstractSurefireMojo
                 Double.toString( getParallelTestsTimeoutInSeconds() ) );
         getProperties().setProperty( ProviderParameterNames.PARALLEL_TIMEOUTFORCED_PROP,
                 Double.toString( getParallelTestsTimeoutForcedInSeconds() ) );
+        getProperties().setProperty( ProviderParameterNames.PARALLEL_OPTIMIZE_PROP,
+                                     Boolean.toString( isParallelOptimized() ) );
 
         String message =
             "parallel='" + usedParallel + '\'' + ", perCoreThreadCount=" + getPerCoreThreadCount() + ", threadCount="
                 + usedThreadCount + ", useUnlimitedThreads=" + getUseUnlimitedThreads() +
                     ", threadCountSuites=" + getThreadCountSuites() + ", threadCountClasses=" + getThreadCountClasses() +
-                    ", threadCountMethods=" + getThreadCountMethods();
+                    ", threadCountMethods=" + getThreadCountMethods() + ", parallelOptimized=" + isParallelOptimized();
 
         getLog().info( message );
     }
@@ -1926,6 +1939,7 @@ public abstract class AbstractSurefireMojo
         checksum.add( getPerCoreThreadCount() );
         checksum.add( getUseUnlimitedThreads() );
         checksum.add( getParallel() );
+        checksum.add( isParallelOptimized() );
         checksum.add( isTrimStackTrace() );
         checksum.add( getRemoteRepositories() );
         checksum.add( isDisableXmlReport() );
@@ -2740,12 +2754,22 @@ public abstract class AbstractSurefireMojo
         this.parallel = parallel;
     }
 
+    public boolean isParallelOptimized()
+    {
+        return parallelOptimized;
+    }
+
+    @SuppressWarnings( "UnusedDeclaration" )
+    public void setParallelOptimized( boolean parallelOptimized )
+    {
+        this.parallelOptimized = parallelOptimized;
+    }
+
     public int getThreadCountSuites()
     {
         return threadCountSuites;
     }
 
-    @SuppressWarnings( "UnusedDeclaration" )
     public void setThreadCountSuites( int threadCountSuites )
     {
         this.threadCountSuites = threadCountSuites;
@@ -2756,7 +2780,6 @@ public abstract class AbstractSurefireMojo
         return threadCountClasses;
     }
 
-    @SuppressWarnings( "UnusedDeclaration" )
     public void setThreadCountClasses( int threadCountClasses )
     {
         this.threadCountClasses = threadCountClasses;
@@ -2767,7 +2790,6 @@ public abstract class AbstractSurefireMojo
         return threadCountMethods;
     }
 
-    @SuppressWarnings( "UnusedDeclaration" )
     public void setThreadCountMethods( int threadCountMethods )
     {
         this.threadCountMethods = threadCountMethods;

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-api/src/main/java/org/apache/maven/surefire/booter/ProviderParameterNames.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ProviderParameterNames.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ProviderParameterNames.java
index 72c16ac..d9e1377 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ProviderParameterNames.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ProviderParameterNames.java
@@ -41,4 +41,6 @@ public class ProviderParameterNames
 
     public static final String PARALLEL_TIMEOUTFORCED_PROP = "paralleltimeoutforced";
 
+    public static final String PARALLEL_OPTIMIZE_PROP = "paralleloptimization";
+
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java
index 8421751..4c042a0 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java
@@ -28,7 +28,7 @@ import org.apache.maven.surefire.booter.ProviderParameterNames;
 /**
  * @author Kristian Rosenvold
  */
-class JUnitCoreParameters
+public final class JUnitCoreParameters
 {
     public static final String PARALLEL_KEY = ProviderParameterNames.PARALLEL_PROP;
 
@@ -48,6 +48,8 @@ class JUnitCoreParameters
 
     public static final String PARALLEL_TIMEOUTFORCED_KEY = ProviderParameterNames.PARALLEL_TIMEOUTFORCED_PROP;
 
+    public static final String PARALLEL_OPTIMIZE = ProviderParameterNames.PARALLEL_OPTIMIZE_PROP;
+
     private final String parallel;
 
     private final Boolean perCoreThreadCount;
@@ -66,6 +68,8 @@ class JUnitCoreParameters
 
     private final Boolean useUnlimitedThreads;
 
+    private final boolean parallelOptimization;
+
     public JUnitCoreParameters( Properties properties )
     {
         parallel = properties.getProperty( PARALLEL_KEY, "none" ).toLowerCase();
@@ -79,6 +83,7 @@ class JUnitCoreParameters
             Math.max( Double.valueOf( properties.getProperty( PARALLEL_TIMEOUT_KEY, "0" ) ), 0 );
         parallelTestsTimeoutForcedInSeconds =
             Math.max( Double.valueOf( properties.getProperty( PARALLEL_TIMEOUTFORCED_KEY, "0" ) ), 0 );
+        parallelOptimization = Boolean.valueOf( properties.getProperty( PARALLEL_OPTIMIZE, "true" ) );
     }
 
     private static Collection<String> lowerCase( String... elements )
@@ -96,7 +101,7 @@ class JUnitCoreParameters
         return "all".equals( parallel );
     }
 
-    public boolean isParallelMethod()
+    public boolean isParallelMethods()
     {
         return isAllParallel() || lowerCase( "both", "methods", "suitesAndMethods", "classesAndMethods" ).contains(
             parallel );
@@ -114,12 +119,12 @@ class JUnitCoreParameters
     }
 
     /**
-     * @deprecated Instead use the expression ( {@link #isParallelMethod()} && {@link #isParallelClasses()} ).
+     * @deprecated Instead use the expression ( {@link #isParallelMethods()} && {@link #isParallelClasses()} ).
      */
     @Deprecated
     public boolean isParallelBoth()
     {
-        return isParallelMethod() && isParallelClasses();
+        return isParallelMethods() && isParallelClasses();
     }
 
     public Boolean isPerCoreThreadCount()
@@ -169,7 +174,12 @@ class JUnitCoreParameters
 
     public boolean isAnyParallelitySelected()
     {
-        return isParallelSuites() || isParallelClasses() || isParallelMethod();
+        return isParallelSuites() || isParallelClasses() || isParallelMethods();
+    }
+
+    public boolean isParallelOptimization()
+    {
+        return parallelOptimization;
     }
 
     @Override
@@ -177,6 +187,7 @@ class JUnitCoreParameters
     {
         return "parallel='" + parallel + '\'' + ", perCoreThreadCount=" + perCoreThreadCount + ", threadCount="
             + threadCount + ", useUnlimitedThreads=" + useUnlimitedThreads + ", threadCountSuites=" + threadCountSuites
-            + ", threadCountClasses=" + threadCountClasses + ", threadCountMethods=" + threadCountMethods;
+            + ", threadCountClasses=" + threadCountClasses + ", threadCountMethods=" + threadCountMethods
+            + ", parallelOptimization=" + parallelOptimization;
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
index de0673c..04f1673 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreProvider.java
@@ -163,7 +163,7 @@ public class JUnitCoreProvider
 
     private boolean isParallelMethodsAndTypes()
     {
-        return jUnitCoreParameters.isParallelMethod() && isParallelTypes();
+        return jUnitCoreParameters.isParallelMethods() && isParallelTypes();
     }
 
     private boolean isParallelTypes()

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
index e124f6e..7bf7a89 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
@@ -55,7 +55,7 @@ class JUnitCoreWrapper
         }
         else
         {
-            exeuteLazy( testsToRun, filter, computer, junitCore );
+            executeLazy( testsToRun, filter, computer, junitCore );
         }
 
         if ( computer instanceof ParallelComputer )
@@ -85,7 +85,7 @@ class JUnitCoreWrapper
         createRequestAndRun( filter, computer, junitCore, tests );
     }
 
-    private static void exeuteLazy( TestsToRun testsToRun, Filter filter, Computer computer, JUnitCore junitCore )
+    private static void executeLazy( TestsToRun testsToRun, Filter filter, Computer computer, JUnitCore junitCore )
         throws TestSetFailedException
     {
         // in order to support LazyTestsToRun, the iterator must be used
@@ -119,7 +119,7 @@ class JUnitCoreWrapper
     {
         return parameters.isNoThreading()
             ? Computer.serial()
-            : ParallelComputerFactory.createParallelComputer( parameters );
+            : ParallelComputerFactory.createParallelComputer( parameters, parameters.isParallelOptimization() ? null : null );//todo resolve
     }
 
     private static class FilteringRequest

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
index d7fe2d1..91ef5bc 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
@@ -21,6 +21,7 @@ package org.apache.maven.surefire.junitcore;
 
 import org.apache.maven.surefire.junitcore.pc.ParallelComputer;
 import org.apache.maven.surefire.junitcore.pc.ParallelComputerBuilder;
+import org.apache.maven.surefire.junitcore.pc.RunnerCounter;
 import org.apache.maven.surefire.testset.TestSetFailedException;
 
 import java.util.concurrent.TimeUnit;
@@ -59,10 +60,10 @@ final class ParallelComputerFactory
         ParallelComputerFactory.availableProcessors = Runtime.getRuntime().availableProcessors();
     }
 
-    static ParallelComputer createParallelComputer( JUnitCoreParameters params )
+    static ParallelComputer createParallelComputer( JUnitCoreParameters params, RunnerCounter counts )
         throws TestSetFailedException
     {
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, counts );
         ParallelComputerBuilder builder = new ParallelComputerBuilder();
 
         if ( params.isParallelSuites() )
@@ -75,7 +76,7 @@ final class ParallelComputerFactory
             resolveClassesConcurrency( builder, concurrency.classes );
         }
 
-        if ( params.isParallelMethod() )
+        if ( params.isParallelMethods() )
         {
             resolveMethodsConcurrency( builder, concurrency.methods );
         }
@@ -86,7 +87,7 @@ final class ParallelComputerFactory
         return builder.buildComputer( timeout, timeoutForced, TimeUnit.NANOSECONDS );
     }
 
-    static Concurrency resolveConcurrency( JUnitCoreParameters params )
+    static Concurrency resolveConcurrency( JUnitCoreParameters params, RunnerCounter counts )
         throws TestSetFailedException
     {
         if ( !params.isAnyParallelitySelected() )
@@ -108,26 +109,23 @@ final class ParallelComputerFactory
         {
             return concurrencyForUnlimitedThreads( params );
         }
-        else
+        else if ( hasThreadCount( params ) )
         {
-            if ( hasThreadCount( params ) )
+            if ( hasThreadCounts( params ) )
             {
-                if ( hasThreadCounts( params ) )
-                {
-                    return isLeafUnspecified( params )
-                        ? concurrencyFromAllThreadCountsButUnspecifiedLeafCount( params )
-                        : concurrencyFromAllThreadCounts( params );
-                }
-                else
-                {
-                    return estimateConcurrency( params );
-                }
+                return isLeafUnspecified( params )
+                    ? concurrencyFromAllThreadCountsButUnspecifiedLeafCount( params, counts )
+                    : concurrencyFromAllThreadCounts( params );
             }
             else
             {
-                return concurrencyFromThreadCounts( params );
+                return estimateConcurrency( params, counts );
             }
         }
+        else
+        {
+            return concurrencyFromThreadCounts( params );
+        }
     }
 
     private static long secondsToNanos( double seconds )
@@ -194,50 +192,74 @@ final class ParallelComputerFactory
         Concurrency concurrency = new Concurrency();
         concurrency.suites = params.isParallelSuites() ? threadCountSuites( params ) : 0;
         concurrency.classes = params.isParallelClasses() ? threadCountClasses( params ) : 0;
-        concurrency.methods = params.isParallelMethod() ? threadCountMethods( params ) : 0;
+        concurrency.methods = params.isParallelMethods() ? threadCountMethods( params ) : 0;
         concurrency.capacity = Integer.MAX_VALUE;
         return concurrency;
     }
 
-    private static Concurrency estimateConcurrency( JUnitCoreParameters params )
+    private static Concurrency estimateConcurrency( JUnitCoreParameters params, RunnerCounter counts )
     {
-        Concurrency concurrency = new Concurrency();
-        concurrency.suites = params.isParallelSuites() ? params.getThreadCountSuites() : 0;
-        concurrency.classes = params.isParallelClasses() ? params.getThreadCountClasses() : 0;
-        concurrency.methods = params.isParallelMethod() ? params.getThreadCountMethods() : 0;
-        concurrency.capacity = params.getThreadCount();
-
-        // estimate parallel thread counts
-        double ratio = 1d / countParallelEntities( params );
-        int threads = multiplyByCoreCount( params, ratio * concurrency.capacity );
-        concurrency.suites = params.isParallelSuites() ? threads : 0;
-        concurrency.classes = params.isParallelClasses() ? threads : 0;
-        concurrency.methods = params.isParallelMethod() ? threads : 0;
-        if ( countParallelEntities( params ) == 1 )
+        final Concurrency concurrency = new Concurrency();
+        final int parallelEntities = countParallelEntities( params );
+        concurrency.capacity = multiplyByCoreCount( params, params.getThreadCount() );
+        if ( parallelEntities == 1 || counts == null || counts.classes == 0 )
         {
-            concurrency.capacity = 0;
+            // Estimate parallel thread counts.
+            double ratio = 1d / parallelEntities;
+            int threads = multiplyByCoreCount( params, ratio * params.getThreadCount() );
+            concurrency.suites = params.isParallelSuites() ? threads : 0;
+            concurrency.classes = params.isParallelClasses() ? threads : 0;
+            concurrency.methods = params.isParallelMethods() ? threads : 0;
+            if ( parallelEntities == 1 )
+            {
+                concurrency.capacity = 0;
+            }
+            else
+            {
+                adjustLeaf( params, concurrency );
+            }
         }
         else
         {
-            concurrency.capacity = multiplyByCoreCount( params, concurrency.capacity );
+            // Try to allocate suites+classes+methods within threadCount,
+            concurrency.suites = params.isParallelSuites() ? multiplyByCoreCount( params, counts.suites ) : 0;
+            concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, counts.classes ) : 0;
+            concurrency.methods =
+                params.isParallelMethods() ? multiplyByCoreCount( params, counts.methods / counts.classes ) : 0;
+            double sum = (double) concurrency.suites + concurrency.classes + concurrency.methods;
+            if ( concurrency.capacity < sum && sum != 0 )
+            {
+                // otherwise allocate them using the weighting factor < 1.
+                double weight = concurrency.capacity / sum;
+                concurrency.suites *= weight;
+                concurrency.classes *= weight;
+                concurrency.methods *= weight;
+                adjustPrecisionInLeaf( params, concurrency );
+            }
             adjustLeaf( params, concurrency );
         }
         return concurrency;
     }
 
-    private static Concurrency concurrencyFromAllThreadCountsButUnspecifiedLeafCount( JUnitCoreParameters params )
+    private static Concurrency concurrencyFromAllThreadCountsButUnspecifiedLeafCount( JUnitCoreParameters params,
+                                                                                      RunnerCounter counts )
     {
         Concurrency concurrency = new Concurrency();
         concurrency.suites = params.isParallelSuites() ? params.getThreadCountSuites() : 0;
+        concurrency.suites = params.isParallelSuites() ? multiplyByCoreCount( params, concurrency.suites ) : 0;
         concurrency.classes = params.isParallelClasses() ? params.getThreadCountClasses() : 0;
-        concurrency.methods = params.isParallelMethod() ? params.getThreadCountMethods() : 0;
-        concurrency.capacity = params.getThreadCount();
+        concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, concurrency.classes ) : 0;
+        concurrency.methods = params.isParallelMethods() ? params.getThreadCountMethods() : 0;
+        concurrency.methods = params.isParallelMethods() ? multiplyByCoreCount( params, concurrency.methods ) : 0;
+        concurrency.capacity = multiplyByCoreCount( params, params.getThreadCount() );
+
+        if ( counts != null )
+        {
+            concurrency.suites = (int) Math.min( Math.min( concurrency.suites, counts.suites ), Integer.MAX_VALUE );
+            concurrency.classes = (int) Math.min( Math.min( concurrency.classes, counts.classes ), Integer.MAX_VALUE );
+        }
 
         setLeafInfinite( params, concurrency );
-        concurrency.suites = params.isParallelSuites() ? multiplyByCoreCount( params, concurrency.suites ) : 0;
-        concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, concurrency.classes ) : 0;
-        concurrency.methods = params.isParallelMethod() ? multiplyByCoreCount( params, concurrency.methods ) : 0;
-        concurrency.capacity = multiplyByCoreCount( params, concurrency.capacity );
 
         return concurrency;
     }
@@ -247,7 +269,7 @@ final class ParallelComputerFactory
         Concurrency concurrency = new Concurrency();
         concurrency.suites = params.isParallelSuites() ? params.getThreadCountSuites() : 0;
         concurrency.classes = params.isParallelClasses() ? params.getThreadCountClasses() : 0;
-        concurrency.methods = params.isParallelMethod() ? params.getThreadCountMethods() : 0;
+        concurrency.methods = params.isParallelMethods() ? params.getThreadCountMethods() : 0;
         concurrency.capacity = params.getThreadCount();
         double all = sumThreadCounts( concurrency );
 
@@ -257,7 +279,7 @@ final class ParallelComputerFactory
         concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, concurrency.capacity * (
             concurrency.classes / all ) ) : 0;
 
-        concurrency.methods = params.isParallelMethod() ? multiplyByCoreCount( params, concurrency.capacity * (
+        concurrency.methods = params.isParallelMethods() ? multiplyByCoreCount( params, concurrency.capacity * (
             concurrency.methods / all ) ) : 0;
 
         concurrency.capacity = multiplyByCoreCount( params, concurrency.capacity );
@@ -270,7 +292,7 @@ final class ParallelComputerFactory
         Concurrency concurrency = new Concurrency();
         concurrency.suites = params.isParallelSuites() ? threadCountSuites( params ) : 0;
         concurrency.classes = params.isParallelClasses() ? threadCountClasses( params ) : 0;
-        concurrency.methods = params.isParallelMethod() ? threadCountMethods( params ) : 0;
+        concurrency.methods = params.isParallelMethods() ? threadCountMethods( params ) : 0;
         concurrency.capacity = (int) Math.min( sumThreadCounts( concurrency ), Integer.MAX_VALUE );
         return concurrency;
     }
@@ -288,7 +310,7 @@ final class ParallelComputerFactory
             count++;
         }
 
-        if ( params.isParallelMethod() )
+        if ( params.isParallelMethods() )
         {
             count++;
         }
@@ -297,7 +319,7 @@ final class ParallelComputerFactory
 
     private static void adjustPrecisionInLeaf( JUnitCoreParameters params, Concurrency concurrency )
     {
-        if ( params.isParallelMethod() )
+        if ( params.isParallelMethods() )
         {
             concurrency.methods = concurrency.capacity - concurrency.suites - concurrency.classes;
         }
@@ -309,7 +331,7 @@ final class ParallelComputerFactory
 
     private static void adjustLeaf( JUnitCoreParameters params, Concurrency concurrency )
     {
-        if ( params.isParallelMethod() )
+        if ( params.isParallelMethods() )
         {
             concurrency.methods = Integer.MAX_VALUE;
         }
@@ -321,7 +343,7 @@ final class ParallelComputerFactory
 
     private static void setLeafInfinite( JUnitCoreParameters params, Concurrency concurrency )
     {
-        if ( params.isParallelMethod() )
+        if ( params.isParallelMethods() )
         {
             concurrency.methods = Integer.MAX_VALUE;
         }
@@ -339,7 +361,7 @@ final class ParallelComputerFactory
     {
         int maskOfParallel = params.isParallelSuites() ? 4 : 0;
         maskOfParallel |= params.isParallelClasses() ? 2 : 0;
-        maskOfParallel |= params.isParallelMethod() ? 1 : 0;
+        maskOfParallel |= params.isParallelMethods() ? 1 : 0;
 
         int maskOfConcurrency = params.getThreadCountSuites() > 0 ? 4 : 0;
         maskOfConcurrency |= params.getThreadCountClasses() > 0 ? 2 : 0;
@@ -361,9 +383,9 @@ final class ParallelComputerFactory
 
     private static boolean hasThreadCounts( JUnitCoreParameters jUnitCoreParameters )
     {
-        return jUnitCoreParameters.getThreadCountSuites() > 0 ||
-            jUnitCoreParameters.getThreadCountClasses() > 0 ||
-            jUnitCoreParameters.getThreadCountMethods() > 0;
+        return jUnitCoreParameters.isParallelSuites() && jUnitCoreParameters.getThreadCountSuites() > 0 ||
+            jUnitCoreParameters.isParallelClasses() && jUnitCoreParameters.getThreadCountClasses() > 0 ||
+            jUnitCoreParameters.isParallelMethods() && jUnitCoreParameters.getThreadCountMethods() > 0;
     }
 
     private static boolean hasThreadCount( JUnitCoreParameters jUnitCoreParameters )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java
index 8e7f5b0..ca49561 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java
@@ -19,6 +19,7 @@ package org.apache.maven.surefire.junitcore.pc;
  * under the License.
  */
 
+import org.apache.maven.surefire.junitcore.JUnitCoreParameters;
 import org.junit.internal.runners.ErrorReportingRunner;
 import org.junit.runner.Description;
 import org.junit.runner.Runner;
@@ -33,7 +34,7 @@ import org.junit.runners.model.RunnerBuilder;
 import java.util.ArrayList;
 import java.util.Collection;
 import java.util.Collections;
-import java.util.HashMap;
+import java.util.EnumMap;
 import java.util.Iterator;
 import java.util.LinkedHashSet;
 import java.util.Map;
@@ -64,16 +65,20 @@ import java.util.concurrent.TimeUnit;
  * @author Tibor Digana (tibor17)
  * @since 2.16
  */
-public class ParallelComputerBuilder
+public final class ParallelComputerBuilder
 {
     static final int TOTAL_POOL_SIZE_UNDEFINED = 0;
 
-    private final Map<Type, Integer> parallelGroups = new HashMap<Type, Integer>( 3 );
+    private final Map<Type, Integer> parallelGroups = new EnumMap<Type, Integer>( Type.class );
 
     private boolean useSeparatePools;
 
     private int totalPoolSize;
 
+    private JUnitCoreParameters parameters;
+
+    private boolean optimize;
+
     /**
      * Calling {@link #useSeparatePools()}.
      */
@@ -85,6 +90,12 @@ public class ParallelComputerBuilder
         parallelGroups.put( Type.METHODS, 0 );
     }
 
+    public ParallelComputerBuilder( JUnitCoreParameters parameters )
+    {
+        this();
+        this.parameters = parameters;
+    }
+
     public ParallelComputerBuilder useSeparatePools()
     {
         totalPoolSize = TOTAL_POOL_SIZE_UNDEFINED;
@@ -116,6 +127,12 @@ public class ParallelComputerBuilder
         return this;
     }
 
+    public ParallelComputerBuilder optimize( boolean optimize )
+    {
+        this.optimize = optimize;
+        return this;
+    }
+
     public ParallelComputerBuilder parallelSuites()
     {
         return parallel( Type.SUITES );
@@ -203,12 +220,14 @@ public class ParallelComputerBuilder
 
         private final Map<Type, Integer> allGroups;
 
+        private long nestedClassesChildren;
+
         private volatile Scheduler master;
 
         private PC( long timeout, long timeoutForced, TimeUnit timeoutUnit )
         {
             super( timeout, timeoutForced, timeoutUnit );
-            allGroups = new HashMap<Type, Integer>( ParallelComputerBuilder.this.parallelGroups );
+            allGroups = new EnumMap<Type, Integer>( ParallelComputerBuilder.this.parallelGroups );
             poolCapacity = ParallelComputerBuilder.this.totalPoolSize;
             splitPool = ParallelComputerBuilder.this.useSeparatePools;
         }
@@ -226,7 +245,16 @@ public class ParallelComputerBuilder
         {
             super.getSuite( builder, cls );
             populateChildrenFromSuites();
-            return setSchedulers();
+
+            WrappedRunners suiteSuites = wrapRunners( suites );
+            WrappedRunners suiteClasses = wrapRunners( classes );
+
+            long suitesCount = suites.size();
+            long classesCount = classes.size() + nestedClasses.size();
+            long methodsCount = suiteClasses.embeddedChildrenCount + nestedClassesChildren;
+            tryOptimize( suitesCount, classesCount, methodsCount );
+
+            return setSchedulers( suiteSuites.wrappingSuite, suiteClasses.wrappingSuite );
         }
 
         @Override
@@ -252,28 +280,45 @@ public class ParallelComputerBuilder
             return runner;
         }
 
-        private <T extends Runner> ParentRunner wrapRunners( Collection<T> runners )
+        private void tryOptimize( long suites, long classes, long methods )
+        {
+            //todo remove statement, we will rely on single non-default constructor. Final class.
+            final JUnitCoreParameters parameters = ParallelComputerBuilder.this.parameters;
+            if ( ParallelComputerBuilder.this.optimize && parameters != null )
+            {
+                ;//todo
+            }
+        }
+
+        private <T extends Runner> WrappedRunners wrapRunners( Collection<T> runners )
             throws InitializationError
         {
+            long childrenCounter = 0;
             ArrayList<Runner> runs = new ArrayList<Runner>();
             for ( T runner : runners )
             {
-                if ( runner != null && hasChildren( runner ) )
+                if ( runner != null )
                 {
-                    runs.add( runner );
+                    int children = countChildren( runner );
+                    childrenCounter += children;
+                    if ( children != 0 )
+                    {
+                        runs.add( runner );
+                    }
                 }
             }
 
-            return runs.isEmpty() ? null : new Suite( null, runs )
+            Suite wrapper = runs.isEmpty() ? null : new Suite( null, runs )
             {
             };
+            return new WrappedRunners( wrapper, childrenCounter );
         }
 
-        private boolean hasChildren( Runner runner )
+        private int countChildren( Runner runner )
         {
             Description description = runner.getDescription();
             Collection children = description == null ? null : description.getChildren();
-            return children != null && !children.isEmpty();
+            return children == null ? 0 : children.size();
         }
 
         private ExecutorService createPool( int poolSize )
@@ -344,7 +389,7 @@ public class ParallelComputerBuilder
             }
         }
 
-        private Runner setSchedulers()
+        private Runner setSchedulers( ParentRunner suiteSuites, ParentRunner suiteClasses )
             throws InitializationError
         {
             int parallelSuites = allGroups.get( Type.SUITES );
@@ -354,7 +399,6 @@ public class ParallelComputerBuilder
             ExecutorService commonPool = splitPool || poolSize == 0 ? null : createPool( poolSize );
             master = createMaster( commonPool, poolSize );
 
-            ParentRunner suiteSuites = wrapRunners( suites );
             if ( suiteSuites != null )
             {
                 // a scheduler for parallel suites
@@ -370,7 +414,6 @@ public class ParallelComputerBuilder
             }
 
             // schedulers for parallel classes
-            ParentRunner suiteClasses = wrapRunners( classes );
             ArrayList<ParentRunner> allSuites = new ArrayList<ParentRunner>( suites );
             allSuites.addAll( nestedSuites );
             if ( suiteClasses != null )
@@ -507,7 +550,9 @@ public class ParallelComputerBuilder
                 }
                 else if ( child instanceof ParentRunner )
                 {
-                    nestedClasses.add( (ParentRunner) child );
+                    ParentRunner parentRunner = (ParentRunner) child;
+                    nestedClasses.add( parentRunner );
+                    nestedClassesChildren += parentRunner.getDescription().getChildren().size();
                 }
             }
 

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
new file mode 100644
index 0000000..48ef73a
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
@@ -0,0 +1,43 @@
+package org.apache.maven.surefire.junitcore.pc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+/**
+ * Counts number of JUnit suites, classes and methods.
+ *
+ * @author tibor17 (Tibor Digana)
+ * @see ParallelComputerBuilder
+ * @since 2.17
+ */
+final public class RunnerCounter//todo needs refactoring, remove public
+{
+    public final long suites;
+
+    public final long classes;
+
+    public final long methods;
+
+    RunnerCounter( long suites, long classes, long methods )
+    {
+        this.suites = suites;
+        this.classes = classes;
+        this.methods = methods;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/WrappedRunners.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/WrappedRunners.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/WrappedRunners.java
new file mode 100644
index 0000000..4550b5e
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/WrappedRunners.java
@@ -0,0 +1,46 @@
+package org.apache.maven.surefire.junitcore.pc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.junit.runners.ParentRunner;
+
+/**
+ * We need to wrap runners in a suite and count children of these runners.
+ * <p/>
+ * Old JUnit versions do not cache children after the first call of
+ * {@link org.junit.runners.ParentRunner#getChildren()}.
+ * Due to performance reasons, the children have to be observed just once.
+ *
+ * @author tibor17 (Tibor Digana)
+ * @see ParallelComputerBuilder
+ * @since 2.17
+ */
+final class WrappedRunners
+{
+    final ParentRunner wrappingSuite;
+
+    final long embeddedChildrenCount;
+
+    WrappedRunners( ParentRunner wrappingSuite, long embeddedChildrenCount )
+    {
+        this.wrappingSuite = wrappingSuite;
+        this.embeddedChildrenCount = embeddedChildrenCount;
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java
index e100357..c73fa01 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java
@@ -32,9 +32,9 @@ public class JUnitCoreParametersTest
     public void testIsParallelMethod()
         throws Exception
     {
-        assertFalse( getTestSetClasses().isParallelMethod() );
-        assertTrue( getTestSetMethods().isParallelMethod() );
-        assertTrue( getTestSetBoth().isParallelMethod() );
+        assertFalse( getTestSetClasses().isParallelMethods() );
+        assertTrue( getTestSetMethods().isParallelMethods() );
+        assertTrue( getTestSetBoth().isParallelMethods() );
     }
 
     public void testIsParallelClasses()
@@ -148,6 +148,6 @@ public class JUnitCoreParametersTest
 
     private boolean isParallelMethodsAndClasses( JUnitCoreParameters jUnitCoreParameters )
     {
-        return jUnitCoreParameters.isParallelMethod() && jUnitCoreParameters.isParallelClasses();
+        return jUnitCoreParameters.isParallelMethods() && jUnitCoreParameters.isParallelClasses();
     }
 }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java
index c3682ae..6803265 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java
@@ -89,7 +89,7 @@ public final class ParallelComputerFactoryTest
     {
         Properties properties = new Properties();
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( new JUnitCoreParameters( properties ) );
+        resolveConcurrency( new JUnitCoreParameters( properties ), null );
     }
 
     @Test
@@ -99,9 +99,9 @@ public final class ParallelComputerFactoryTest
         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suites" ) );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params );
+        resolveConcurrency( params, null );
     }
 
     @Test
@@ -111,9 +111,9 @@ public final class ParallelComputerFactoryTest
         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classes" ) );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params );
+        resolveConcurrency( params, null );
     }
 
     @Test
@@ -123,9 +123,9 @@ public final class ParallelComputerFactoryTest
         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "methods" ) );
         assertFalse( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params );
+        resolveConcurrency( params, null );
     }
 
     @Test
@@ -135,9 +135,9 @@ public final class ParallelComputerFactoryTest
         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "both" ) );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params );
+        resolveConcurrency( params, null );
     }
 
     @Test
@@ -147,9 +147,9 @@ public final class ParallelComputerFactoryTest
         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "all" ) );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params );
+        resolveConcurrency( params, null );
     }
 
     @Test
@@ -159,9 +159,9 @@ public final class ParallelComputerFactoryTest
         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndClasses" ) );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params );
+        resolveConcurrency( params, null );
     }
 
     @Test
@@ -171,9 +171,9 @@ public final class ParallelComputerFactoryTest
         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndMethods" ) );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params );
+        resolveConcurrency( params, null );
     }
 
     @Test
@@ -183,9 +183,9 @@ public final class ParallelComputerFactoryTest
         JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classesAndMethods" ) );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params );
+        resolveConcurrency( params, null );
     }
 
     @Theory
@@ -197,10 +197,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suites" );
         properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -208,10 +208,10 @@ public final class ParallelComputerFactoryTest
 
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -227,10 +227,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "classes" );
         properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
@@ -238,10 +238,10 @@ public final class ParallelComputerFactoryTest
 
         properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 5 * cpu ) );
@@ -257,10 +257,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "methods" );
         properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -268,10 +268,10 @@ public final class ParallelComputerFactoryTest
 
         properties.setProperty( THREADCOUNTMETHODS_KEY, "5" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -287,10 +287,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
         properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
@@ -299,10 +299,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 15 * cpu ) );
@@ -318,10 +318,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
         properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -330,10 +330,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -349,10 +349,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
         properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
@@ -361,10 +361,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 5 * cpu ) );
@@ -380,10 +380,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "all" );
         properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
@@ -393,10 +393,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "30" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 15 * cpu ) );
@@ -412,10 +412,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suites" );
         properties.setProperty( THREADCOUNT_KEY, "3" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 0 ) );
         assertThat( concurrency.suites, is( 3 * cpu ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -431,10 +431,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "classes" );
         properties.setProperty( THREADCOUNT_KEY, "3" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 0 ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 3 * cpu ) );
@@ -450,10 +450,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "methods" );
         properties.setProperty( THREADCOUNT_KEY, "3" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 0 ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -469,10 +469,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "both" );
         properties.setProperty( THREADCOUNT_KEY, "3" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
@@ -488,10 +488,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
         properties.setProperty( THREADCOUNT_KEY, "3" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
@@ -507,10 +507,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
         properties.setProperty( THREADCOUNT_KEY, "3" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -526,10 +526,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
         properties.setProperty( THREADCOUNT_KEY, "3" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
@@ -545,10 +545,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "all" );
         properties.setProperty( THREADCOUNT_KEY, "3" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         assertThat( concurrency.suites, is( cpu ) );
         assertThat( concurrency.classes, is( cpu ) );
@@ -567,10 +567,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTSUITES_KEY, "34" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "66" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
         assertThat( concurrency.suites, is( concurrentSuites ) );
@@ -590,10 +590,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTSUITES_KEY, "34" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "66" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
         assertThat( concurrency.suites, is( concurrentSuites ) );
@@ -613,10 +613,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTCLASSES_KEY, "34" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "66" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         assertThat( concurrency.suites, is( 0 ) );
         int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
@@ -637,10 +637,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTCLASSES_KEY, "34" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "49" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 3 * cpu ) );
         int concurrentSuites = (int) ( 0.17d * concurrency.capacity );
         int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
@@ -660,10 +660,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNT_KEY, "6" );
         properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 6 * cpu ) );
         assertThat( concurrency.suites, is( 2 * cpu ) );
         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
@@ -681,10 +681,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNT_KEY, "6" );
         properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 6 * cpu ) );
         assertThat( concurrency.suites, is( 2 * cpu ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -702,10 +702,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNT_KEY, "6" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "2" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 6 * cpu ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 2 * cpu ) );
@@ -724,10 +724,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "4" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 14 * cpu ) );
         assertThat( concurrency.suites, is( 2 * cpu ) );
         assertThat( concurrency.classes, is( 4 * cpu ) );
@@ -743,10 +743,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suites" );
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 5 * cpu ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -762,10 +762,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "classes" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 5 * cpu ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 5 * cpu ) );
@@ -781,10 +781,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "methods" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "5" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 5 * cpu ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -802,10 +802,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 20 * cpu ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 15 * cpu ) );
@@ -817,10 +817,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethod() );
+        assertFalse( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
@@ -838,10 +838,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 20 * cpu ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -853,10 +853,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 0 ) );
@@ -874,10 +874,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 20 * cpu ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 5 * cpu ) );
@@ -889,10 +889,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertFalse( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 0 ) );
         assertThat( concurrency.classes, is( 5 * cpu ) );
@@ -911,10 +911,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "30" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params );
+        Concurrency concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( 50 * cpu ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 15 * cpu ) );
@@ -927,10 +927,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( 5 * cpu ) );
         assertThat( concurrency.classes, is( 15 * cpu ) );
@@ -940,10 +940,10 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "all" );
         properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
         params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params );
+        concurrency = resolveConcurrency( params, null );
         assertTrue( params.isParallelSuites() );
         assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethod() );
+        assertTrue( params.isParallelMethods() );
         assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
         assertThat( concurrency.classes, is( 15 * cpu ) );
@@ -958,7 +958,7 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( PARALLEL_KEY, "methods" );
         properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        ParallelComputer pc = createParallelComputer( params );
+        ParallelComputer pc = createParallelComputer( params, null );
 
         Result result = new JUnitCore().run( pc, TestClass.class );
         long timeSpent = runtime.stop();
@@ -982,7 +982,7 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
         properties.setProperty( PARALLEL_TIMEOUT_KEY, Double.toString( 2.5d ) );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        ParallelComputer pc = createParallelComputer( params );
+        ParallelComputer pc = createParallelComputer( params, null );
 
         new JUnitCore().run( pc, TestClass.class );
         long timeSpent = runtime.stop();
@@ -1004,7 +1004,7 @@ public final class ParallelComputerFactoryTest
         properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
         properties.setProperty( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 2.5d ) );
         JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        ParallelComputer pc = createParallelComputer( params );
+        ParallelComputer pc = createParallelComputer( params, null );
 
         new JUnitCore().run( pc, TestClass.class );
         long timeSpent = runtime.stop();

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/eaeaa28d/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
index ab312af..3fee3df 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Surefire746Test.java
@@ -162,7 +162,7 @@ public class Surefire746Test
             throws Exception
         {
             throw new RuntimeException(
-                "This Exception will cause Surefire to receive a internal JUnit Description and fail" );
+                "This Exception will cause Surefire to receive an internal JUnit Description and fail." );
         }
     }
 }
\ No newline at end of file


[11/11] git commit: [SUREFIRE-1041] Created integration test based on sample project provided by Dan Fabulich

Posted by ag...@apache.org.
[SUREFIRE-1041] Created integration test based on sample project provided by Dan Fabulich


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/56972416
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/56972416
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/56972416

Branch: refs/heads/master
Commit: 569724167048c945c9b316547536ec96bae97806
Parents: ec46baf
Author: Andreas Gudian <ag...@apache.org>
Authored: Sat Mar 8 20:54:36 2014 +0100
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 20:18:58 2014 +0100

----------------------------------------------------------------------
 .../jiras/Surefire1041FailingJUnitRunnerIT.java | 38 +++++++++++++
 .../pom.xml                                     | 60 ++++++++++++++++++++
 .../src/test/java/test/AppTest.java             | 38 +++++++++++++
 .../src/test/java/test/BadRunner.java           | 43 ++++++++++++++
 4 files changed, 179 insertions(+)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/56972416/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1041FailingJUnitRunnerIT.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1041FailingJUnitRunnerIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1041FailingJUnitRunnerIT.java
new file mode 100644
index 0000000..bb65682
--- /dev/null
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/jiras/Surefire1041FailingJUnitRunnerIT.java
@@ -0,0 +1,38 @@
+package org.apache.maven.surefire.its.jiras;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.apache.maven.surefire.its.fixture.SurefireJUnit4IntegrationTestCase;
+import org.junit.Test;
+
+/**
+ * SUREFIRE-1041: An error in a JUnit runner should not lead to an error in Surefire
+ *
+ * @author Andreas Gudian
+ */
+public class Surefire1041FailingJUnitRunnerIT
+    extends SurefireJUnit4IntegrationTestCase
+{
+    @Test
+    public void reportErrorInJUnitRunnerAsTestError()
+    {
+        unpack( "surefire-1041-exception-in-junit-runner" ).mavenTestFailureIgnore( true ).executeTest().assertTestSuiteResults( 1, 1, 0, 0 );
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/56972416/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/pom.xml b/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/pom.xml
new file mode 100644
index 0000000..e1331cb
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/pom.xml
@@ -0,0 +1,60 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!--
+  ~ Licensed to the Apache Software Foundation (ASF) under one
+  ~ or more contributor license agreements.  See the NOTICE file
+  ~ distributed with this work for additional information
+  ~ regarding copyright ownership.  The ASF licenses this file
+  ~ to you under the Apache License, Version 2.0 (the
+  ~ "License"); you may not use this file except in compliance
+  ~ with the License.  You may obtain a copy of the License at
+  ~
+  ~     http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing,
+  ~ software distributed under the License 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.
+  -->
+
+<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
+  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
+  <modelVersion>4.0.0</modelVersion>
+  <parent>
+    <groupId>org.apache.maven.surefire</groupId>
+    <artifactId>it-parent</artifactId>
+    <version>1.0</version>
+  </parent>
+
+  <artifactId>surefire-1041</artifactId>
+  <name>Tests that test reporter does not fail with NPE when a JUnit-Runner has an error.</name>
+
+  <build>
+    <plugins>
+      <plugin>
+        <artifactId>maven-surefire-plugin</artifactId>
+        <configuration>
+          <forkMode>once</forkMode>
+          <forkCount>1</forkCount>
+        </configuration>
+        <dependencies>
+          <dependency>
+            <groupId>org.apache.maven.surefire</groupId>
+            <artifactId>surefire-junit47</artifactId>
+            <version>${surefire.version}</version>
+          </dependency>
+        </dependencies>
+      </plugin>
+    </plugins>
+  </build>
+
+  <dependencies>
+    <dependency>
+      <groupId>junit</groupId>
+      <artifactId>junit</artifactId>
+      <version>4.11</version>
+      <scope>test</scope>
+    </dependency>
+  </dependencies>
+</project>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/56972416/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/src/test/java/test/AppTest.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/src/test/java/test/AppTest.java b/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/src/test/java/test/AppTest.java
new file mode 100644
index 0000000..978da1a
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/src/test/java/test/AppTest.java
@@ -0,0 +1,38 @@
+package test;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+/**
+ *
+ * @author Dan Fabulich
+ *
+ */
+@RunWith(BadRunner.class)
+public class AppTest
+{
+
+    @Test
+    public void testApp()
+    {
+    }
+}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/56972416/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/src/test/java/test/BadRunner.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/src/test/java/test/BadRunner.java b/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/src/test/java/test/BadRunner.java
new file mode 100644
index 0000000..759c0f4
--- /dev/null
+++ b/surefire-integration-tests/src/test/resources/surefire-1041-exception-in-junit-runner/src/test/java/test/BadRunner.java
@@ -0,0 +1,43 @@
+package test;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.junit.runner.notification.RunNotifier;
+import org.junit.runners.BlockJUnit4ClassRunner;
+import org.junit.runners.model.InitializationError;
+
+/**
+ *
+ * @author Dan Fabulich
+ *
+ */
+public class BadRunner extends BlockJUnit4ClassRunner{
+
+	public BadRunner(Class<?> testClass) throws InitializationError {
+		super(testClass);
+	}
+
+	@Override
+	public void run(RunNotifier notifier) {
+		String x = null;
+		if (false) x = "";
+		x.toString();
+	}
+}


[10/11] git commit: [SUREFIRE-1041] Do not crash with NPE in case a JUnit runner fails Submitted by: Dan Fabulich

Posted by ag...@apache.org.
[SUREFIRE-1041] Do not crash with NPE in case a JUnit runner fails
Submitted by: Dan Fabulich

o Applied without changes


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/ec46bafc
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/ec46bafc
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/ec46bafc

Branch: refs/heads/master
Commit: ec46bafca72b1b8b243a48d47023d1e750da08f5
Parents: a1d86c7
Author: Andreas Gudian <ag...@apache.org>
Authored: Sat Mar 8 20:53:35 2014 +0100
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 20:18:58 2014 +0100

----------------------------------------------------------------------
 .../java/org/apache/maven/surefire/report/SimpleReportEntry.java | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/ec46bafc/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java b/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java
index ca33a5f..2229815 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/report/SimpleReportEntry.java
@@ -55,11 +55,11 @@ public class SimpleReportEntry
     {
         if ( source == null )
         {
-            throw new NullPointerException( "source is null" );
+            source = "null";
         }
         if ( name == null )
         {
-            throw new NullPointerException( "name is null" );
+            name = "null";
         }
 
         this.source = source;


[08/11] git commit: [SUREFIRE-1063] Fix typos and grammatical errors

Posted by ag...@apache.org.
[SUREFIRE-1063] Fix typos and grammatical errors


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/4f97226d
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/4f97226d
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/4f97226d

Branch: refs/heads/master
Commit: 4f97226d279c67d480bf52eb326011060bddf0a0
Parents: aff2622
Author: Eric Dahl <er...@gmail.com>
Authored: Fri Feb 21 18:25:01 2014 -0600
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 20:16:02 2014 +0100

----------------------------------------------------------------------
 .../maven/plugin/surefire/booterclient/ForkConfiguration.java    | 2 +-
 .../apache/maven/plugin/surefire/booterclient/ForkStarter.java   | 4 ++--
 maven-surefire-plugin/src/site/fml/faq.fml                       | 2 +-
 .../org/apache/maven/surefire/booter/ForkingRunListener.java     | 2 +-
 .../apache/maven/surefire/providerapi/ProviderParameters.java    | 2 +-
 .../org/apache/maven/surefire/report/ConsoleOutputCapture.java   | 2 +-
 .../java/org/apache/maven/surefire/booter/ProviderFactory.java   | 2 +-
 .../src/test/resources/fork-mode-testng/pom.xml                  | 2 +-
 .../resources/testng-junit-together/src/test/java/JunitTest.java | 2 +-
 .../src/test/java/Junit4NoRunWithTest.java                       | 2 +-
 .../src/test/java/Junit4SimpleRunWithTest.java                   | 2 +-
 surefire-shadefire/pom.xml                                       | 2 +-
 12 files changed, 13 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
index 079ee32..ca9bff1 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkConfiguration.java
@@ -210,7 +210,7 @@ public class ForkConfiguration
 
     /**
      * Replaces expressions <pre>@{property-name}</pre> with the corresponding properties
-     * from the model. This allows late evaluation of property values when the plugin is exexcuted (as compared
+     * from the model. This allows late evaluation of property values when the plugin is executed (as compared
      * to evaluation when the pom is parsed as is done with <pre>${property-name}</pre> expressions).
      *
      * This allows other plugins to modify or set properties with the changes getting picked up by surefire.

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
index 95bc007..8861e51 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/booterclient/ForkStarter.java
@@ -483,8 +483,8 @@ public class ForkStarter
                 {
                     // noinspection ThrowFromFinallyBlock
                     throw new RuntimeException(
-                        "The forked VM terminated without saying properly goodbye. VM crash or System.exit called ?"
-                            + "\nCommand was" + cli.toString() );
+                        "The forked VM terminated without properly saying goodbye. VM crash or System.exit called?"
+                            + "\nCommand was " + cli.toString() );
                 }
 
             }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/maven-surefire-plugin/src/site/fml/faq.fml
----------------------------------------------------------------------
diff --git a/maven-surefire-plugin/src/site/fml/faq.fml b/maven-surefire-plugin/src/site/fml/faq.fml
index a518c57..8308a9a 100644
--- a/maven-surefire-plugin/src/site/fml/faq.fml
+++ b/maven-surefire-plugin/src/site/fml/faq.fml
@@ -51,7 +51,7 @@ under the License.
       </answer>
     </faq>
     <faq id="vm-termination">
-      <question>Surefire fails with the message "The forked VM terminated without saying properly goodbye"</question>
+      <question>Surefire fails with the message "The forked VM terminated without properly saying  goodbye"</question>
       <answer>
         <p>
         Surefire does not support tests or any referenced libraries calling System.exit() at any time. If

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
index 6bb2491..0af1e29 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/booter/ForkingRunListener.java
@@ -173,7 +173,7 @@ public class ForkingRunListener
         int i = StringUtils.escapeBytesToPrintable( content, 0, buf, off, len );
         content[i++] = (byte) '\n';
 
-        synchronized ( target ) // See notes about synhronization/thread safety in class javadoc
+        synchronized ( target ) // See notes about synchronization/thread safety in class javadoc
         {
             target.write( header, 0, header.length );
             target.write( content, 0, i );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
index 94f0261..06048e9 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/providerapi/ProviderParameters.java
@@ -76,7 +76,7 @@ public interface ProviderParameters
     /**
      * Gets a logger intended for console output.
      * <p/>
-     * This output is inteded for provider-oriented messages that are not attached to a single test-set
+     * This output is intended for provider-oriented messages that are not attached to a single test-set
      * and will normally be written to something console-like immediately.
      *
      * @return A console logger

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-api/src/main/java/org/apache/maven/surefire/report/ConsoleOutputCapture.java
----------------------------------------------------------------------
diff --git a/surefire-api/src/main/java/org/apache/maven/surefire/report/ConsoleOutputCapture.java b/surefire-api/src/main/java/org/apache/maven/surefire/report/ConsoleOutputCapture.java
index c7c6069..dd1d665 100644
--- a/surefire-api/src/main/java/org/apache/maven/surefire/report/ConsoleOutputCapture.java
+++ b/surefire-api/src/main/java/org/apache/maven/surefire/report/ConsoleOutputCapture.java
@@ -84,7 +84,7 @@ public class ConsoleOutputCapture
         {
             if ( s == null )
             {
-                s = "null"; // Shamelessy taken from super.print
+                s = "null"; // Shamelessly taken from super.print
             }
             final byte[] bytes = s.getBytes();
             final byte[] join = ByteBuffer.join( bytes, 0, bytes.length, newline, 0, 1 );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
----------------------------------------------------------------------
diff --git a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
index e0c88bc..02454aa 100644
--- a/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
+++ b/surefire-booter/src/main/java/org/apache/maven/surefire/booter/ProviderFactory.java
@@ -69,7 +69,7 @@ public class ProviderFactory
     {
         final PrintStream orgSystemOut = System.out;
         final PrintStream orgSystemErr = System.err;
-        // Note that System.out/System.err are also read in the "ReporterConfiguration" instatiation
+        // Note that System.out/System.err are also read in the "ReporterConfiguration" instantiation
         // in createProvider below. These are the same values as here.
 
         ProviderFactory providerFactory =

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-integration-tests/src/test/resources/fork-mode-testng/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/fork-mode-testng/pom.xml b/surefire-integration-tests/src/test/resources/fork-mode-testng/pom.xml
index 25b66f0..ec5d3c6 100644
--- a/surefire-integration-tests/src/test/resources/fork-mode-testng/pom.xml
+++ b/surefire-integration-tests/src/test/resources/fork-mode-testng/pom.xml
@@ -41,7 +41,7 @@
       <scope>test</scope>
       <exclusions>
         <exclusion>
-          <!-- NOTE: Deliberaty excluding junit to enforce TestNG only tests, cf. SUREFIRE-642 -->
+          <!-- NOTE: Deliberately excluding junit to enforce TestNG only tests, cf. SUREFIRE-642 -->
           <groupId>junit</groupId>
           <artifactId>junit</artifactId>
         </exclusion>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-integration-tests/src/test/resources/testng-junit-together/src/test/java/JunitTest.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/testng-junit-together/src/test/java/JunitTest.java b/surefire-integration-tests/src/test/resources/testng-junit-together/src/test/java/JunitTest.java
index 84287c0..58931a9 100644
--- a/surefire-integration-tests/src/test/resources/testng-junit-together/src/test/java/JunitTest.java
+++ b/surefire-integration-tests/src/test/resources/testng-junit-together/src/test/java/JunitTest.java
@@ -29,7 +29,7 @@ public class JunitTest extends TestCase {
 	Object testObject;
 	
 	/**
-	 * Creats an object instance
+	 * Creates an object instance
 	 */
 	public void setUp()
 	{

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4NoRunWithTest.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4NoRunWithTest.java b/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4NoRunWithTest.java
index 8641825..a7b6934 100644
--- a/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4NoRunWithTest.java
+++ b/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4NoRunWithTest.java
@@ -33,7 +33,7 @@ public class Junit4NoRunWithTest {
 	Object testObject;
 
 	/**
-	 * Creats an object instance
+	 * Creates an object instance
 	 */
 	@Before
 	public void setUp()

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4SimpleRunWithTest.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4SimpleRunWithTest.java b/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4SimpleRunWithTest.java
index 38f9215..d9a6420 100644
--- a/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4SimpleRunWithTest.java
+++ b/surefire-integration-tests/src/test/resources/testng-junit4-together/src/test/java/Junit4SimpleRunWithTest.java
@@ -36,7 +36,7 @@ public class Junit4SimpleRunWithTest {
 	Object testObject;
 
 	/**
-	 * Creats an object instance
+	 * Creates an object instance
 	 */
 	@Before
 	public void setUp()

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/4f97226d/surefire-shadefire/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-shadefire/pom.xml b/surefire-shadefire/pom.xml
index d20208d..280da55 100644
--- a/surefire-shadefire/pom.xml
+++ b/surefire-shadefire/pom.xml
@@ -31,7 +31,7 @@
 
   <name>ShadeFire JUnit3 Provider</name>
   <description>A super-shaded junit3 provider that is used by surefire to build itself,
-    that basically has ALL classes relocated to facilitate no API-conflict whatsover with ourself.
+    that basically has ALL classes relocated to facilitate no API-conflict whatsoever with ourself.
     The only remaining point of conflict is around the booter properties file format
   </description>
   <licenses>


[02/11] PC optimization refactoring (Only unit tests. Missing IT tests refactoring.)

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtilTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtilTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtilTest.java
new file mode 100644
index 0000000..68e16e1
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtilTest.java
@@ -0,0 +1,1063 @@
+package org.apache.maven.surefire.junitcore.pc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.apache.maven.surefire.junitcore.JUnitCoreParameters;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.JUnitCore;
+import org.junit.runner.Result;
+import org.junit.runner.RunWith;
+
+import java.util.Properties;
+import java.util.concurrent.ExecutionException;
+
+import static org.apache.maven.surefire.junitcore.pc.ParallelComputerUtil.*;
+import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.*;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.*;
+
+/**
+ * Testing an algorithm in {@link ParallelComputerUtil} which configures
+ * allocated thread resources in ParallelComputer by given {@link org.apache.maven.surefire.junitcore.JUnitCoreParameters}.
+ *
+ * @author Tibor Digana (tibor17)
+ * @see ParallelComputerUtil
+ * @since 2.16
+ */
+@RunWith( Theories.class )
+public final class ParallelComputerUtilTest
+{
+    @DataPoint
+    public static final int CPU_1 = 1;
+
+    @DataPoint
+    public static final int CPU_4 = 4;
+
+    @Rule
+    public final ExpectedException exception = ExpectedException.none();
+
+    @Rule
+    public final Stopwatch runtime = new Stopwatch();
+
+    @BeforeClass
+    public static void beforeClass()
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( 1 );
+    }
+
+    @AfterClass
+    public static void afterClass()
+    {
+        ParallelComputerUtil.setDefaultAvailableProcessors();
+    }
+
+    private static Properties parallel( String parallel )
+    {
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, parallel );
+        return properties;
+    }
+
+    @Test
+    public void unknownParallel()
+        throws TestSetFailedException
+    {
+        Properties properties = new Properties();
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( new JUnitCoreParameters( properties ), null );
+    }
+
+    @Test
+    public void unknownThreadCountSuites()
+        throws TestSetFailedException
+    {
+        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suites" ) );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( params, null );
+    }
+
+    @Test
+    public void unknownThreadCountClasses()
+        throws TestSetFailedException
+    {
+        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classes" ) );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( params, null );
+    }
+
+    @Test
+    public void unknownThreadCountMethods()
+        throws TestSetFailedException
+    {
+        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "methods" ) );
+        assertFalse( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( params, null );
+    }
+
+    @Test
+    public void unknownThreadCountBoth()
+        throws TestSetFailedException
+    {
+        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "both" ) );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( params, null );
+    }
+
+    @Test
+    public void unknownThreadCountAll()
+        throws TestSetFailedException
+    {
+        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "all" ) );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( params, null );
+    }
+
+    @Test
+    public void unknownThreadCountSuitesAndClasses()
+        throws TestSetFailedException
+    {
+        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndClasses" ) );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( params, null );
+    }
+
+    @Test
+    public void unknownThreadCountSuitesAndMethods()
+        throws TestSetFailedException
+    {
+        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndMethods" ) );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( params, null );
+    }
+
+    @Test
+    public void unknownThreadCountClassesAndMethods()
+        throws TestSetFailedException
+    {
+        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classesAndMethods" ) );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        exception.expect( TestSetFailedException.class );
+        resolveConcurrency( params, null );
+    }
+
+    @Theory
+    public void useUnlimitedThreadsSuites( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suites" );
+        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 0 ) );
+
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void useUnlimitedThreadsClasses( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classes" );
+        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 5 * cpu ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void unlimitedThreadsMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "methods" );
+        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "5" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 5 * cpu ) );
+    }
+
+    @Theory
+    public void unlimitedThreadsSuitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 15 * cpu ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void unlimitedThreadsSuitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 15 * cpu ) );
+    }
+
+    @Theory
+    public void unlimitedThreadsClassesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 5 * cpu ) );
+        assertThat( concurrency.methods, is( 15 * cpu ) );
+    }
+
+    @Theory
+    public void unlimitedThreadsAll( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "30" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 15 * cpu ) );
+        assertThat( concurrency.methods, is( 30 * cpu ) );
+    }
+
+    @Theory
+    public void threadCountSuites( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suites" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( 3 * cpu ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountClasses( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classes" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 3 * cpu ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "methods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 3 * cpu ) );
+    }
+
+    @Theory
+    public void threadCountBoth( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "both" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountClassesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountSuitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountSuitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountAll( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( cpu ) );
+        assertThat( concurrency.classes, is( cpu ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void everyThreadCountSuitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        // % percentage ratio
+        properties.setProperty( THREADCOUNTSUITES_KEY, "34" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "66" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
+        assertThat( concurrency.suites, is( concurrentSuites ) );
+        assertThat( concurrency.classes, is( concurrency.capacity - concurrentSuites ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void everyThreadCountSuitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        // % percentage ratio
+        properties.setProperty( THREADCOUNTSUITES_KEY, "34" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "66" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
+        assertThat( concurrency.suites, is( concurrentSuites ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( concurrency.capacity - concurrentSuites ) );
+    }
+
+    @Theory
+    public void everyThreadCountClassesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        // % percentage ratio
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "34" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "66" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
+        assertThat( concurrency.classes, is( concurrentClasses ) );
+        assertThat( concurrency.methods, is( concurrency.capacity - concurrentClasses ) );
+    }
+
+    @Theory
+    public void everyThreadCountAll( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        // % percentage ratio
+        properties.setProperty( THREADCOUNTSUITES_KEY, "17" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "34" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "49" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        int concurrentSuites = (int) ( 0.17d * concurrency.capacity );
+        int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
+        assertThat( concurrency.suites, is( concurrentSuites ) );
+        assertThat( concurrency.classes, is( concurrentClasses ) );
+        assertThat( concurrency.methods, is( concurrency.capacity - concurrentSuites - concurrentClasses ) );
+    }
+
+    @Theory
+    public void reusableThreadCountSuitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test classes
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( 2 * cpu ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void reusableThreadCountSuitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test methods
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( 2 * cpu ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void reusableThreadCountClassesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test methods
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 2 * cpu ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void reusableThreadCountAll( int cpu )
+        throws TestSetFailedException
+    {
+        // 8 * cpu to 13 * cpu threads to run test methods
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNT_KEY, "14" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "4" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 14 * cpu ) );
+        assertThat( concurrency.suites, is( 2 * cpu ) );
+        assertThat( concurrency.classes, is( 4 * cpu ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void suites( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suites" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 5 * cpu ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void classes( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classes" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 5 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 5 * cpu ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void methods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "methods" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "5" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 5 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 5 * cpu ) );
+    }
+
+    @Theory
+    public void suitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 20 * cpu ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 15 * cpu ) );
+        assertThat( concurrency.methods, is( 0 ) );
+
+        // Warning: this case works but is not enabled in AbstractSurefireMojo
+        // Instead use the 'useUnlimitedThreads' parameter.
+        properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void suitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 20 * cpu ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 15 * cpu ) );
+
+        // Warning: this case works but is not enabled in AbstractSurefireMojo
+        // Instead use the 'useUnlimitedThreads' parameter.
+        properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void classesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 20 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 5 * cpu ) );
+        assertThat( concurrency.methods, is( 15 * cpu ) );
+
+        // Warning: this case works but is not enabled in AbstractSurefireMojo
+        // Instead use the 'useUnlimitedThreads' parameter.
+        properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 5 * cpu ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void all( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerUtil.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "30" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        Concurrency concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 50 * cpu ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 15 * cpu ) );
+        assertThat( concurrency.methods, is( 30 * cpu ) );
+
+        // Warning: these cases work but they are not enabled in AbstractSurefireMojo
+        // Instead use the 'useUnlimitedThreads' parameter.
+        properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( 5 * cpu ) );
+        assertThat( concurrency.classes, is( 15 * cpu ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+
+        properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
+        params = new JUnitCoreParameters( properties );
+        concurrency = resolveConcurrency( params, null );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.classes, is( 15 * cpu ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Test
+    public void withoutShutdown()
+        throws TestSetFailedException, ExecutionException, InterruptedException
+    {
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "methods" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( params );
+        ParallelComputer pc = pcBuilder.buildComputer();
+        Result result = new JUnitCore().run( pc, TestClass.class );
+        long timeSpent = runtime.stop();
+        long deltaTime = 500L;
+
+        assertTrue( result.wasSuccessful() );
+        assertThat( result.getRunCount(), is( 3 ) );
+        assertThat( result.getFailureCount(), is( 0 ) );
+        assertThat( result.getIgnoreCount(), is( 0 ) );
+        assertEquals( 10000L, timeSpent, deltaTime );
+    }
+
+    @Test
+    public void shutdown()
+        throws TestSetFailedException, ExecutionException, InterruptedException
+    {
+        // The JUnitCore returns after 2.5s.
+        // The test-methods in TestClass are NOT interrupted, and return normally after 5s.
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "methods" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
+        properties.setProperty( PARALLEL_TIMEOUT_KEY, Double.toString( 2.5d ) );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( params );
+        ParallelComputer pc = pcBuilder.buildComputer();
+        new JUnitCore().run( pc, TestClass.class );
+        long timeSpent = runtime.stop();
+        long deltaTime = 500L;
+
+        assertEquals( 2500L, timeSpent, deltaTime );
+        assertTrue( pc.describeElapsedTimeout().contains(
+            "The test run has finished abruptly after timeout of 2.5 seconds." ) );
+        assertTrue( pc.describeElapsedTimeout().contains( TestClass.class.getName() ) );
+    }
+
+    @Test
+    public void forcedShutdown()
+        throws TestSetFailedException, ExecutionException, InterruptedException
+    {
+        // The JUnitCore returns after 2.5s, and the test-methods in TestClass are interrupted.
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "methods" );
+        properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
+        properties.setProperty( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 2.5d ) );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        ParallelComputerBuilder pcBuilder = new ParallelComputerBuilder( params );
+        ParallelComputer pc = pcBuilder.buildComputer();
+        new JUnitCore().run( pc, TestClass.class );
+        long timeSpent = runtime.stop();
+        long deltaTime = 500L;
+
+        assertEquals( 2500L, timeSpent, deltaTime );
+        assertTrue( pc.describeElapsedTimeout().contains(
+            "The test run has finished abruptly after timeout of 2.5 seconds." ) );
+        assertTrue( pc.describeElapsedTimeout().contains( TestClass.class.getName() ) );
+    }
+
+    public static class TestClass
+    {
+        @Test
+        public void a()
+            throws InterruptedException
+        {
+            long t1 = System.currentTimeMillis();
+            try{
+                Thread.sleep( 5000L );
+            }
+            finally
+            {
+                System.out.println( getClass().getSimpleName() + "#a() spent " + ( System.currentTimeMillis() - t1 ) );
+            }
+        }
+
+        @Test
+        public void b()
+            throws InterruptedException
+        {
+            long t1 = System.currentTimeMillis();
+            try{
+                Thread.sleep( 5000L );
+            }
+            finally
+            {
+                System.out.println( getClass().getSimpleName() + "#b() spent " + ( System.currentTimeMillis() - t1 ) );
+            }
+        }
+
+        @Test
+        public void c()
+            throws InterruptedException
+        {
+            long t1 = System.currentTimeMillis();
+            try{
+                Thread.sleep( 5000L );
+            }
+            finally
+            {
+                System.out.println( getClass().getSimpleName() + "#c() spent " + ( System.currentTimeMillis() - t1 ) );
+            }
+        }
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/Stopwatch.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/Stopwatch.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/Stopwatch.java
new file mode 100644
index 0000000..739f5ba
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/Stopwatch.java
@@ -0,0 +1,46 @@
+package org.apache.maven.surefire.junitcore.pc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.junit.rules.TestWatchman;
+import org.junit.runners.model.FrameworkMethod;
+
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author Tibor Digana (tibor17)
+ * @since 2.16
+ */
+public final class Stopwatch
+    extends TestWatchman
+{
+    private long startNanos;
+
+    public long stop()
+    {
+        return TimeUnit.MILLISECONDS.convert( System.nanoTime() - startNanos, TimeUnit.NANOSECONDS );
+    }
+
+    @Override
+    public void starting( FrameworkMethod method )
+    {
+        startNanos = System.nanoTime();
+    }
+}


[04/11] git commit: PC optimization refactoring (Only unit tests. Missing IT tests refactoring.)

Posted by ag...@apache.org.
PC optimization refactoring (Only unit tests. Missing IT tests refactoring.)


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/01c39b01
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/01c39b01
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/01c39b01

Branch: refs/heads/master
Commit: 01c39b013e4d2fcc53e39a422890a3b78bce0f54
Parents: c85e6e8
Author: Tibor Digana <ti...@lycos.com>
Authored: Mon Mar 3 23:29:50 2014 +0100
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 19:46:40 2014 +0100

----------------------------------------------------------------------
 .../surefire/junitcore/JUnitCoreParameters.java |    8 +-
 .../surefire/junitcore/JUnitCoreWrapper.java    |    8 +-
 .../junitcore/ParallelComputerFactory.java      |  450 --------
 .../surefire/junitcore/pc/Concurrency.java      |   29 +
 .../surefire/junitcore/pc/ParallelComputer.java |   19 +-
 .../junitcore/pc/ParallelComputerBuilder.java   |  145 ++-
 .../junitcore/pc/ParallelComputerUtil.java      |  355 ++++++
 .../surefire/junitcore/pc/RunnerCounter.java    |   10 +-
 .../maven/surefire/junitcore/pc/Type.java       |   31 +
 .../surefire/junitcore/JUnit4SuiteTest.java     |    8 +-
 .../junitcore/JUnitCoreParametersTest.java      |  167 ++-
 .../OptimizedParallelComputerTest.java          |  323 ------
 .../junitcore/ParallelComputerFactoryTest.java  | 1063 ------------------
 .../maven/surefire/junitcore/Stopwatch.java     |   46 -
 .../pc/OptimizedParallelComputerTest.java       |  323 ++++++
 .../pc/ParallelComputerBuilderTest.java         |   43 +-
 .../junitcore/pc/ParallelComputerUtilTest.java  | 1063 ++++++++++++++++++
 .../maven/surefire/junitcore/pc/Stopwatch.java  |   46 +
 18 files changed, 2115 insertions(+), 2022 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java
index 4c042a0..04031c6 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreParameters.java
@@ -48,7 +48,7 @@ public final class JUnitCoreParameters
 
     public static final String PARALLEL_TIMEOUTFORCED_KEY = ProviderParameterNames.PARALLEL_TIMEOUTFORCED_PROP;
 
-    public static final String PARALLEL_OPTIMIZE = ProviderParameterNames.PARALLEL_OPTIMIZE_PROP;
+    public static final String PARALLEL_OPTIMIZE_KEY = ProviderParameterNames.PARALLEL_OPTIMIZE_PROP;
 
     private final String parallel;
 
@@ -83,7 +83,7 @@ public final class JUnitCoreParameters
             Math.max( Double.valueOf( properties.getProperty( PARALLEL_TIMEOUT_KEY, "0" ) ), 0 );
         parallelTestsTimeoutForcedInSeconds =
             Math.max( Double.valueOf( properties.getProperty( PARALLEL_TIMEOUTFORCED_KEY, "0" ) ), 0 );
-        parallelOptimization = Boolean.valueOf( properties.getProperty( PARALLEL_OPTIMIZE, "true" ) );
+        parallelOptimization = Boolean.valueOf( properties.getProperty( PARALLEL_OPTIMIZE_KEY, "true" ) );
     }
 
     private static Collection<String> lowerCase( String... elements )
@@ -169,10 +169,10 @@ public final class JUnitCoreParameters
 
     public boolean isNoThreading()
     {
-        return !isAnyParallelitySelected();
+        return !isParallelismSelected();
     }
 
-    public boolean isAnyParallelitySelected()
+    public boolean isParallelismSelected()
     {
         return isParallelSuites() || isParallelClasses() || isParallelMethods();
     }

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
index 7bf7a89..14fd77c 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/JUnitCoreWrapper.java
@@ -19,13 +19,11 @@ package org.apache.maven.surefire.junitcore;
  * under the License.
  */
 
-import java.util.List;
-
 import org.apache.maven.surefire.common.junit4.JUnit4RunListener;
 import org.apache.maven.surefire.junitcore.pc.ParallelComputer;
+import org.apache.maven.surefire.junitcore.pc.ParallelComputerBuilder;
 import org.apache.maven.surefire.testset.TestSetFailedException;
 import org.apache.maven.surefire.util.TestsToRun;
-
 import org.junit.runner.Computer;
 import org.junit.runner.JUnitCore;
 import org.junit.runner.Request;
@@ -35,6 +33,8 @@ import org.junit.runner.manipulation.Filter;
 import org.junit.runner.manipulation.NoTestsRemainException;
 import org.junit.runner.notification.RunListener;
 
+import java.util.List;
+
 /**
  * Encapsulates access to JUnitCore
  *
@@ -119,7 +119,7 @@ class JUnitCoreWrapper
     {
         return parameters.isNoThreading()
             ? Computer.serial()
-            : ParallelComputerFactory.createParallelComputer( parameters, parameters.isParallelOptimization() ? null : null );//todo resolve
+            : new ParallelComputerBuilder( parameters ).buildComputer();
     }
 
     private static class FilteringRequest

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
deleted file mode 100644
index 70d4a64..0000000
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
+++ /dev/null
@@ -1,450 +0,0 @@
-package org.apache.maven.surefire.junitcore;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License 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.
- */
-
-import org.apache.maven.surefire.junitcore.pc.ParallelComputer;
-import org.apache.maven.surefire.junitcore.pc.ParallelComputerBuilder;
-import org.apache.maven.surefire.junitcore.pc.RunnerCounter;
-import org.apache.maven.surefire.testset.TestSetFailedException;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * An algorithm which configures {@link ParallelComputer} with allocated thread resources by given
- * {@link JUnitCoreParameters}.
- * The <code>AbstractSurefireMojo</code> has to provide correct combinations of thread-counts and <em>parallel</em>.
- *
- * @author Tibor Digana (tibor17)
- * @see org.apache.maven.surefire.junitcore.pc.ParallelComputerBuilder
- * @since 2.16
- */
-final class ParallelComputerFactory
-{
-    private static int availableProcessors = Runtime.getRuntime().availableProcessors();
-
-    private ParallelComputerFactory()
-    {
-        throw new IllegalStateException( "Suppresses calling constructor, ensuring non-instantiability." );
-    }
-
-    /*
-    * For testing purposes.
-    */
-    static void overrideAvailableProcessors( int availableProcessors )
-    {
-        ParallelComputerFactory.availableProcessors = availableProcessors;
-    }
-
-    /*
-    * For testing purposes.
-    */
-    static void setDefaultAvailableProcessors()
-    {
-        ParallelComputerFactory.availableProcessors = Runtime.getRuntime().availableProcessors();
-    }
-
-    static ParallelComputer createParallelComputer( JUnitCoreParameters params, RunnerCounter counts )
-        throws TestSetFailedException
-    {
-        Concurrency concurrency = resolveConcurrency( params, counts );
-        ParallelComputerBuilder builder = new ParallelComputerBuilder();
-
-        if ( params.isParallelSuites() )
-        {
-            resolveSuitesConcurrency( builder, concurrency.suites );
-        }
-
-        if ( params.isParallelClasses() )
-        {
-            resolveClassesConcurrency( builder, concurrency.classes );
-        }
-
-        if ( params.isParallelMethods() )
-        {
-            resolveMethodsConcurrency( builder, concurrency.methods );
-        }
-
-        long timeout = secondsToNanos( params.getParallelTestsTimeoutInSeconds() );
-        long timeoutForced = secondsToNanos( params.getParallelTestsTimeoutForcedInSeconds() );
-        resolveCapacity( builder, concurrency.capacity );
-        return builder.buildComputer( timeout, timeoutForced, TimeUnit.NANOSECONDS );
-    }
-
-    static Concurrency resolveConcurrency( JUnitCoreParameters params, RunnerCounter counts )
-        throws TestSetFailedException
-    {
-        if ( !params.isAnyParallelitySelected() )
-        {
-            throw new TestSetFailedException( "Unspecified parameter '" + JUnitCoreParameters.PARALLEL_KEY + "'." );
-        }
-
-        if ( !params.isUseUnlimitedThreads() && !hasThreadCount( params ) && !hasThreadCounts( params ) )
-        {
-            throw new TestSetFailedException( "Unspecified thread-count(s). " +
-                                                  "See the parameters " + JUnitCoreParameters.USEUNLIMITEDTHREADS_KEY
-                                                  + ", " + JUnitCoreParameters.THREADCOUNT_KEY + ", "
-                                                  + JUnitCoreParameters.THREADCOUNTSUITES_KEY + ", "
-                                                  + JUnitCoreParameters.THREADCOUNTCLASSES_KEY + ", "
-                                                  + JUnitCoreParameters.THREADCOUNTMETHODS_KEY + "." );
-        }
-
-        if ( params.isUseUnlimitedThreads() )
-        {
-            return concurrencyForUnlimitedThreads( params );
-        }
-        else if ( hasThreadCount( params ) )
-        {
-            if ( hasThreadCounts( params ) )
-            {
-                return isLeafUnspecified( params )
-                    ? concurrencyFromAllThreadCountsButUnspecifiedLeafCount( params, counts )
-                    : concurrencyFromAllThreadCounts( params );
-            }
-            else
-            {
-                return estimateConcurrency( params, counts );
-            }
-        }
-        else
-        {
-            return concurrencyFromThreadCounts( params );
-        }
-    }
-
-    private static long secondsToNanos( double seconds )
-    {
-        double nanos = seconds > 0 ? seconds * 1E9 : 0;
-        return Double.isInfinite( nanos ) || nanos >= Long.MAX_VALUE ? 0 : (long) nanos;
-    }
-
-    private static void resolveSuitesConcurrency( ParallelComputerBuilder builder, int concurrency )
-    {
-        if ( concurrency > 0 )
-        {
-            if ( concurrency == Integer.MAX_VALUE )
-            {
-                builder.parallelSuites();
-            }
-            else
-            {
-                builder.parallelSuites( concurrency );
-            }
-        }
-    }
-
-    private static void resolveClassesConcurrency( ParallelComputerBuilder builder, int concurrency )
-    {
-        if ( concurrency > 0 )
-        {
-            if ( concurrency == Integer.MAX_VALUE )
-            {
-                builder.parallelClasses();
-            }
-            else
-            {
-                builder.parallelClasses( concurrency );
-            }
-        }
-    }
-
-    private static void resolveMethodsConcurrency( ParallelComputerBuilder builder, int concurrency )
-    {
-        if ( concurrency > 0 )
-        {
-            if ( concurrency == Integer.MAX_VALUE )
-            {
-                builder.parallelMethods();
-            }
-            else
-            {
-                builder.parallelMethods( concurrency );
-            }
-        }
-    }
-
-    private static void resolveCapacity( ParallelComputerBuilder builder, int capacity )
-    {
-        if ( capacity > 0 )
-        {
-            builder.useOnePool( capacity );
-        }
-    }
-
-    private static Concurrency concurrencyForUnlimitedThreads( JUnitCoreParameters params )
-    {
-        Concurrency concurrency = new Concurrency();
-        concurrency.suites = params.isParallelSuites() ? threadCountSuites( params ) : 0;
-        concurrency.classes = params.isParallelClasses() ? threadCountClasses( params ) : 0;
-        concurrency.methods = params.isParallelMethods() ? threadCountMethods( params ) : 0;
-        concurrency.capacity = Integer.MAX_VALUE;
-        return concurrency;
-    }
-
-    private static Concurrency estimateConcurrency( JUnitCoreParameters params, RunnerCounter counts )
-    {
-        final Concurrency concurrency = new Concurrency();
-        final int parallelEntities = countParallelEntities( params );
-        concurrency.capacity = multiplyByCoreCount( params, params.getThreadCount() );
-        if ( parallelEntities == 1 || counts == null || counts.classes == 0 )
-        {
-            // Estimate parallel thread counts.
-            double ratio = 1d / parallelEntities;
-            int threads = multiplyByCoreCount( params, ratio * params.getThreadCount() );
-            concurrency.suites = params.isParallelSuites() ? minSuites( threads, counts ) : 0;
-            concurrency.classes = params.isParallelClasses() ? minClasses( threads, counts ) : 0;
-            concurrency.methods = params.isParallelMethods() ? minMethods( threads, counts ) : 0;
-            if ( parallelEntities == 1 )
-            {
-                concurrency.capacity = 0;
-            }
-            else
-            {
-                adjustLeaf( params, concurrency );
-            }
-        }
-        else
-        {
-            // Try to allocate suites+classes+methods within threadCount,
-            concurrency.suites = params.isParallelSuites() ? toNonNegative( counts.suites ) : 0;
-            concurrency.classes = params.isParallelClasses() ? toNonNegative( counts.classes ) : 0;
-            concurrency.methods =
-                params.isParallelMethods() ? toNonNegative( Math.ceil( counts.methods / (double) counts.classes ) ) : 0;
-            double sum = toNonNegative( concurrency.suites + concurrency.classes + concurrency.methods );
-            if ( concurrency.capacity < sum && sum != 0 )
-            {
-                // otherwise allocate them using the weighting factor < 1.
-                double weight = concurrency.capacity / sum;
-                concurrency.suites *= weight;
-                concurrency.classes *= weight;
-                concurrency.methods *= weight;
-            }
-            adjustLeaf( params, concurrency );
-        }
-        return concurrency;
-    }
-
-    private static Concurrency concurrencyFromAllThreadCountsButUnspecifiedLeafCount( JUnitCoreParameters params,
-                                                                                      RunnerCounter counts )
-    {
-        Concurrency concurrency = new Concurrency();
-        concurrency.suites = params.isParallelSuites() ? params.getThreadCountSuites() : 0;
-        concurrency.suites = params.isParallelSuites() ? multiplyByCoreCount( params, concurrency.suites ) : 0;
-        concurrency.classes = params.isParallelClasses() ? params.getThreadCountClasses() : 0;
-        concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, concurrency.classes ) : 0;
-        concurrency.methods = params.isParallelMethods() ? params.getThreadCountMethods() : 0;
-        concurrency.methods = params.isParallelMethods() ? multiplyByCoreCount( params, concurrency.methods ) : 0;
-        concurrency.capacity = multiplyByCoreCount( params, params.getThreadCount() );
-
-        if ( counts != null )
-        {
-            concurrency.suites = toNonNegative( Math.min( concurrency.suites, counts.suites ) );
-            concurrency.classes = toNonNegative( Math.min( concurrency.classes, counts.classes ) );
-        }
-
-        setLeafInfinite( params, concurrency );
-
-        return concurrency;
-    }
-
-    private static Concurrency concurrencyFromAllThreadCounts( JUnitCoreParameters params )
-    {
-        Concurrency concurrency = new Concurrency();
-        concurrency.suites = params.isParallelSuites() ? params.getThreadCountSuites() : 0;
-        concurrency.classes = params.isParallelClasses() ? params.getThreadCountClasses() : 0;
-        concurrency.methods = params.isParallelMethods() ? params.getThreadCountMethods() : 0;
-        concurrency.capacity = params.getThreadCount();
-        double all = sumThreadCounts( concurrency );
-
-        concurrency.suites = params.isParallelSuites() ? multiplyByCoreCount( params, concurrency.capacity * (
-            concurrency.suites / all ) ) : 0;
-
-        concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, concurrency.capacity * (
-            concurrency.classes / all ) ) : 0;
-
-        concurrency.methods = params.isParallelMethods() ? multiplyByCoreCount( params, concurrency.capacity * (
-            concurrency.methods / all ) ) : 0;
-
-        concurrency.capacity = multiplyByCoreCount( params, concurrency.capacity );
-        adjustPrecisionInLeaf( params, concurrency );
-        return concurrency;
-    }
-
-    private static Concurrency concurrencyFromThreadCounts( JUnitCoreParameters params )
-    {
-        Concurrency concurrency = new Concurrency();
-        concurrency.suites = params.isParallelSuites() ? threadCountSuites( params ) : 0;
-        concurrency.classes = params.isParallelClasses() ? threadCountClasses( params ) : 0;
-        concurrency.methods = params.isParallelMethods() ? threadCountMethods( params ) : 0;
-        concurrency.capacity = toNonNegative( sumThreadCounts( concurrency ) );
-        return concurrency;
-    }
-
-    private static int countParallelEntities( JUnitCoreParameters params )
-    {
-        int count = 0;
-        if ( params.isParallelSuites() )
-        {
-            count++;
-        }
-
-        if ( params.isParallelClasses() )
-        {
-            count++;
-        }
-
-        if ( params.isParallelMethods() )
-        {
-            count++;
-        }
-        return count;
-    }
-
-    private static void adjustPrecisionInLeaf( JUnitCoreParameters params, Concurrency concurrency )
-    {
-        if ( params.isParallelMethods() )
-        {
-            concurrency.methods = concurrency.capacity - concurrency.suites - concurrency.classes;
-        }
-        else if ( params.isParallelClasses() )
-        {
-            concurrency.classes = concurrency.capacity - concurrency.suites;
-        }
-    }
-
-    private static void adjustLeaf( JUnitCoreParameters params, Concurrency concurrency )
-    {
-        if ( params.isParallelMethods() )
-        {
-            concurrency.methods = Integer.MAX_VALUE;
-        }
-        else if ( params.isParallelClasses() )
-        {
-            concurrency.classes = Integer.MAX_VALUE;
-        }
-    }
-
-    private static void setLeafInfinite( JUnitCoreParameters params, Concurrency concurrency )
-    {
-        if ( params.isParallelMethods() )
-        {
-            concurrency.methods = Integer.MAX_VALUE;
-        }
-        else if ( params.isParallelClasses() )
-        {
-            concurrency.classes = Integer.MAX_VALUE;
-        }
-        else if ( params.isParallelSuites() )
-        {
-            concurrency.suites = Integer.MAX_VALUE;
-        }
-    }
-
-    private static boolean isLeafUnspecified( JUnitCoreParameters params )
-    {
-        int maskOfParallel = params.isParallelSuites() ? 4 : 0;
-        maskOfParallel |= params.isParallelClasses() ? 2 : 0;
-        maskOfParallel |= params.isParallelMethods() ? 1 : 0;
-
-        int maskOfConcurrency = params.getThreadCountSuites() > 0 ? 4 : 0;
-        maskOfConcurrency |= params.getThreadCountClasses() > 0 ? 2 : 0;
-        maskOfConcurrency |= params.getThreadCountMethods() > 0 ? 1 : 0;
-
-        maskOfConcurrency &= maskOfParallel;
-
-        int leaf = Integer.lowestOneBit( maskOfParallel );
-        return maskOfConcurrency == maskOfParallel - leaf;
-    }
-
-    private static double sumThreadCounts( Concurrency concurrency )
-    {
-        double sum = concurrency.suites;
-        sum += concurrency.classes;
-        sum += concurrency.methods;
-        return sum;
-    }
-
-    private static boolean hasThreadCounts( JUnitCoreParameters jUnitCoreParameters )
-    {
-        return jUnitCoreParameters.isParallelSuites() && jUnitCoreParameters.getThreadCountSuites() > 0 ||
-            jUnitCoreParameters.isParallelClasses() && jUnitCoreParameters.getThreadCountClasses() > 0 ||
-            jUnitCoreParameters.isParallelMethods() && jUnitCoreParameters.getThreadCountMethods() > 0;
-    }
-
-    private static boolean hasThreadCount( JUnitCoreParameters jUnitCoreParameters )
-    {
-        return jUnitCoreParameters.getThreadCount() > 0;
-    }
-
-    private static int threadCountMethods( JUnitCoreParameters jUnitCoreParameters )
-    {
-        return multiplyByCoreCount( jUnitCoreParameters, jUnitCoreParameters.getThreadCountMethods() );
-    }
-
-    private static int threadCountClasses( JUnitCoreParameters jUnitCoreParameters )
-    {
-        return multiplyByCoreCount( jUnitCoreParameters, jUnitCoreParameters.getThreadCountClasses() );
-    }
-
-    private static int threadCountSuites( JUnitCoreParameters jUnitCoreParameters )
-    {
-        return multiplyByCoreCount( jUnitCoreParameters, jUnitCoreParameters.getThreadCountSuites() );
-    }
-
-    private static int multiplyByCoreCount( JUnitCoreParameters jUnitCoreParameters, double threadsPerCore )
-    {
-        double numberOfThreads =
-            jUnitCoreParameters.isPerCoreThreadCount() ? threadsPerCore * (double) availableProcessors : threadsPerCore;
-
-        return numberOfThreads > 0 ? toNonNegative( numberOfThreads ) : Integer.MAX_VALUE;
-    }
-
-    private static int minSuites( int threads, RunnerCounter counts )
-    {
-        long count = counts == null ? Integer.MAX_VALUE : counts.suites;
-        return Math.min( threads, toNonNegative( count ) );
-    }
-
-    private static int minClasses( int threads, RunnerCounter counts )
-    {
-        long count = counts == null ? Integer.MAX_VALUE : counts.classes;
-        return Math.min( threads, toNonNegative( count ) );
-    }
-
-    private static int minMethods( int threads, RunnerCounter counts )
-    {
-        long count = counts == null ? Integer.MAX_VALUE : counts.methods;
-        return Math.min( threads, toNonNegative( count ) );
-    }
-
-    private static int toNonNegative( long num )
-    {
-        return (int) Math.min( num > 0 ? num : 0, Integer.MAX_VALUE );
-    }
-
-    private static int toNonNegative( double num )
-    {
-        return (int) Math.min( num > 0 ? num : 0, Integer.MAX_VALUE );
-    }
-
-    static class Concurrency
-    {
-        int suites, classes, methods, capacity;
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/Concurrency.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/Concurrency.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/Concurrency.java
new file mode 100644
index 0000000..c05af7f
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/Concurrency.java
@@ -0,0 +1,29 @@
+package org.apache.maven.surefire.junitcore.pc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+/**
+ * @author tibor17 (Tibor Digana)
+ * @since 2.17
+ */
+final class Concurrency
+{
+    int suites, classes, methods, capacity;
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputer.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputer.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputer.java
index 242df2e..79ca87a 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputer.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputer.java
@@ -30,7 +30,8 @@ import java.util.concurrent.Callable;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
 import java.util.concurrent.ScheduledExecutorService;
-import java.util.concurrent.TimeUnit;
+
+import static java.util.concurrent.TimeUnit.*;
 
 /**
  * ParallelComputer extends JUnit {@link Computer} and has a shutdown functionality.
@@ -52,10 +53,16 @@ public abstract class ParallelComputer
 
     private Future<Collection<Description>> testsBeforeForcedShutdown;
 
-    public ParallelComputer( long timeout, long timeoutForced, TimeUnit timeoutUnit )
+    public ParallelComputer( double timeoutInSeconds, double timeoutForcedInSeconds  )
+    {
+        this.timeoutNanos = secondsToNanos( timeoutInSeconds );
+        this.timeoutForcedNanos = secondsToNanos( timeoutForcedInSeconds );
+    }
+
+    private static long secondsToNanos( double seconds )
     {
-        this.timeoutNanos = timeoutUnit.toNanos( timeout );
-        this.timeoutForcedNanos = timeoutUnit.toNanos( timeoutForced );
+        double nanos = seconds > 0 ? seconds * 1E9 : 0;
+        return Double.isInfinite( nanos ) || nanos >= Long.MAX_VALUE ? 0 : (long) nanos;
     }
 
     private static long minTimeout( long timeout1, long timeout2 )
@@ -146,12 +153,12 @@ public abstract class ParallelComputer
 
     private Future<Collection<Description>> scheduleShutdown()
     {
-        return getShutdownScheduler().schedule( createShutdownTask( false ), timeoutNanos, TimeUnit.NANOSECONDS );
+        return getShutdownScheduler().schedule( createShutdownTask( false ), timeoutNanos, NANOSECONDS );
     }
 
     private Future<Collection<Description>> scheduleForcedShutdown()
     {
-        return getShutdownScheduler().schedule( createShutdownTask( true ), timeoutForcedNanos, TimeUnit.NANOSECONDS );
+        return getShutdownScheduler().schedule( createShutdownTask( true ), timeoutForcedNanos, NANOSECONDS );
     }
 
     private ScheduledExecutorService getShutdownScheduler()

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java
index ca49561..04813ad 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilder.java
@@ -20,6 +20,7 @@ package org.apache.maven.surefire.junitcore.pc;
  */
 
 import org.apache.maven.surefire.junitcore.JUnitCoreParameters;
+import org.apache.maven.surefire.testset.TestSetFailedException;
 import org.junit.internal.runners.ErrorReportingRunner;
 import org.junit.runner.Description;
 import org.junit.runner.Runner;
@@ -40,13 +41,16 @@ import java.util.LinkedHashSet;
 import java.util.Map;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
-import java.util.concurrent.TimeUnit;
+
+import static org.apache.maven.surefire.junitcore.pc.ParallelComputerUtil.*;
+import static org.apache.maven.surefire.junitcore.pc.Type.*;
 
 /**
  * Executing suites, classes and methods with defined concurrency. In this example the threads which completed
  * the suites and classes can be reused in parallel methods.
  * <pre>
- * ParallelComputerBuilder builder = new ParallelComputerBuilder();
+ * JUnitCoreParameters parameters = ...;
+ * ParallelComputerBuilder builder = new ParallelComputerBuilder(parameters);
  * builder.useOnePool(8).parallelSuites(2).parallelClasses(4).parallelMethods();
  * ParallelComputerBuilder.ParallelComputer computer = builder.buildComputer();
  * Class<?>[] tests = {...};
@@ -79,31 +83,42 @@ public final class ParallelComputerBuilder
 
     private boolean optimize;
 
+    private boolean runningInTests;
+
     /**
      * Calling {@link #useSeparatePools()}.
+     * Can be used only in unit tests.
+     * Do NOT call this constructor in production.
      */
-    public ParallelComputerBuilder()
+    ParallelComputerBuilder()
     {
+        runningInTests = true;
         useSeparatePools();
-        parallelGroups.put( Type.SUITES, 0 );
-        parallelGroups.put( Type.CLASSES, 0 );
-        parallelGroups.put( Type.METHODS, 0 );
+        parallelGroups.put( SUITES, 0 );
+        parallelGroups.put( CLASSES, 0 );
+        parallelGroups.put( METHODS, 0 );
     }
 
     public ParallelComputerBuilder( JUnitCoreParameters parameters )
     {
         this();
+        runningInTests = false;
         this.parameters = parameters;
     }
 
-    public ParallelComputerBuilder useSeparatePools()
+    public ParallelComputer buildComputer()
+    {
+        return new PC();
+    }
+
+    ParallelComputerBuilder useSeparatePools()
     {
         totalPoolSize = TOTAL_POOL_SIZE_UNDEFINED;
         useSeparatePools = true;
         return this;
     }
 
-    public ParallelComputerBuilder useOnePool()
+    ParallelComputerBuilder useOnePool()
     {
         totalPoolSize = TOTAL_POOL_SIZE_UNDEFINED;
         useSeparatePools = false;
@@ -116,7 +131,7 @@ public final class ParallelComputerBuilder
      *                      limited.
      * @throws IllegalArgumentException If <tt>totalPoolSize</tt> is &lt; 1.
      */
-    public ParallelComputerBuilder useOnePool( int totalPoolSize )
+    ParallelComputerBuilder useOnePool( int totalPoolSize )
     {
         if ( totalPoolSize < 1 )
         {
@@ -127,40 +142,45 @@ public final class ParallelComputerBuilder
         return this;
     }
 
-    public ParallelComputerBuilder optimize( boolean optimize )
+    boolean isOptimized()
+    {
+        return optimize;
+    }
+
+    ParallelComputerBuilder optimize( boolean optimize )
     {
         this.optimize = optimize;
         return this;
     }
 
-    public ParallelComputerBuilder parallelSuites()
+    ParallelComputerBuilder parallelSuites()
     {
-        return parallel( Type.SUITES );
+        return parallel( SUITES );
     }
 
-    public ParallelComputerBuilder parallelSuites( int nThreads )
+    ParallelComputerBuilder parallelSuites( int nThreads )
     {
-        return parallel( nThreads, Type.SUITES );
+        return parallel( nThreads, SUITES );
     }
 
-    public ParallelComputerBuilder parallelClasses()
+    ParallelComputerBuilder parallelClasses()
     {
-        return parallel( Type.CLASSES );
+        return parallel( CLASSES );
     }
 
-    public ParallelComputerBuilder parallelClasses( int nThreads )
+    ParallelComputerBuilder parallelClasses( int nThreads )
     {
-        return parallel( nThreads, Type.CLASSES );
+        return parallel( nThreads, CLASSES );
     }
 
-    public ParallelComputerBuilder parallelMethods()
+    ParallelComputerBuilder parallelMethods()
     {
-        return parallel( Type.METHODS );
+        return parallel( METHODS );
     }
 
-    public ParallelComputerBuilder parallelMethods( int nThreads )
+    ParallelComputerBuilder parallelMethods( int nThreads )
     {
-        return parallel( nThreads, Type.METHODS );
+        return parallel( nThreads, METHODS );
     }
 
     private ParallelComputerBuilder parallel( int nThreads, Type parallelType )
@@ -184,21 +204,14 @@ public final class ParallelComputerBuilder
         return parallel( Integer.MAX_VALUE, parallelType );
     }
 
-    public ParallelComputer buildComputer()
-    {
-        return buildComputer( 0, 0, TimeUnit.NANOSECONDS );
-    }
-
-    public ParallelComputer buildComputer( long timeout, long timeoutForced, TimeUnit timeUnit )
+    private double parallelTestsTimeoutInSeconds()
     {
-        return new PC( timeout, timeoutForced, timeUnit );
+        return parameters == null ? 0d : parameters.getParallelTestsTimeoutInSeconds();
     }
 
-    private static enum Type
+    private double parallelTestsTimeoutForcedInSeconds()
     {
-        SUITES,
-        CLASSES,
-        METHODS
+        return parameters == null ? 0d : parameters.getParallelTestsTimeoutForcedInSeconds();
     }
 
     final class PC
@@ -214,9 +227,9 @@ public final class ParallelComputerBuilder
 
         final Collection<Runner> unscheduledRunners = new LinkedHashSet<Runner>();
 
-        final int poolCapacity;
+        int poolCapacity;
 
-        final boolean splitPool;
+        boolean splitPool;
 
         private final Map<Type, Integer> allGroups;
 
@@ -224,9 +237,9 @@ public final class ParallelComputerBuilder
 
         private volatile Scheduler master;
 
-        private PC( long timeout, long timeoutForced, TimeUnit timeoutUnit )
+        private PC()
         {
-            super( timeout, timeoutForced, timeoutUnit );
+            super( parallelTestsTimeoutInSeconds(), parallelTestsTimeoutForcedInSeconds() );
             allGroups = new EnumMap<Type, Integer>( ParallelComputerBuilder.this.parallelGroups );
             poolCapacity = ParallelComputerBuilder.this.totalPoolSize;
             splitPool = ParallelComputerBuilder.this.useSeparatePools;
@@ -243,18 +256,28 @@ public final class ParallelComputerBuilder
         public Runner getSuite( RunnerBuilder builder, Class<?>[] cls )
             throws InitializationError
         {
-            super.getSuite( builder, cls );
-            populateChildrenFromSuites();
+            try
+            {
+                super.getSuite( builder, cls );
+                populateChildrenFromSuites();
 
-            WrappedRunners suiteSuites = wrapRunners( suites );
-            WrappedRunners suiteClasses = wrapRunners( classes );
+                WrappedRunners suiteSuites = wrapRunners( suites );
+                WrappedRunners suiteClasses = wrapRunners( classes );
 
-            long suitesCount = suites.size();
-            long classesCount = classes.size() + nestedClasses.size();
-            long methodsCount = suiteClasses.embeddedChildrenCount + nestedClassesChildren;
-            tryOptimize( suitesCount, classesCount, methodsCount );
+                long suitesCount = suites.size();
+                long classesCount = classes.size() + nestedClasses.size();
+                long methodsCount = suiteClasses.embeddedChildrenCount + nestedClassesChildren;
+                if (!ParallelComputerBuilder.this.runningInTests)
+                {
+                    determineThreadCounts( suitesCount, classesCount, methodsCount );
+                }
 
-            return setSchedulers( suiteSuites.wrappingSuite, suiteClasses.wrappingSuite );
+                return setSchedulers( suiteSuites.wrappingSuite, suiteClasses.wrappingSuite );
+            }
+            catch ( TestSetFailedException e )
+            {
+                throw new InitializationError( e );
+            }
         }
 
         @Override
@@ -280,19 +303,24 @@ public final class ParallelComputerBuilder
             return runner;
         }
 
-        private void tryOptimize( long suites, long classes, long methods )
+        private void determineThreadCounts( long suites, long classes, long methods )
+            throws TestSetFailedException
         {
-            //todo remove statement, we will rely on single non-default constructor. Final class.
             final JUnitCoreParameters parameters = ParallelComputerBuilder.this.parameters;
-            if ( ParallelComputerBuilder.this.optimize && parameters != null )
-            {
-                ;//todo
-            }
+            final boolean optimize = ParallelComputerBuilder.this.optimize;
+            RunnerCounter counts = new RunnerCounter( suites, classes, methods );
+            Concurrency concurrency = resolveConcurrency( parameters, optimize ? counts : null );
+            allGroups.put( SUITES, concurrency.suites );
+            allGroups.put( CLASSES, concurrency.classes );
+            allGroups.put( METHODS, concurrency.methods );
+            poolCapacity = concurrency.capacity;
+            splitPool &= concurrency.capacity <= 0;//fault if negative; should not happen
         }
 
         private <T extends Runner> WrappedRunners wrapRunners( Collection<T> runners )
             throws InitializationError
         {
+            // Do NOT use allGroups here.
             long childrenCounter = 0;
             ArrayList<Runner> runs = new ArrayList<Runner>();
             for ( T runner : runners )
@@ -346,12 +374,13 @@ public final class ParallelComputerBuilder
 
         private boolean areSuitesAndClassesParallel()
         {
-            return !suites.isEmpty() && allGroups.get( Type.SUITES ) > 0 && !classes.isEmpty()
-                && allGroups.get( Type.CLASSES ) > 0;
+            return !suites.isEmpty() && allGroups.get( SUITES ) > 0 && !classes.isEmpty()
+                && allGroups.get( CLASSES ) > 0;
         }
 
         private void populateChildrenFromSuites()
         {
+            // Do NOT use allGroups here.
             Filter filter = new SuiteFilter();
             for ( Iterator<ParentRunner> it = suites.iterator(); it.hasNext(); )
             {
@@ -392,9 +421,9 @@ public final class ParallelComputerBuilder
         private Runner setSchedulers( ParentRunner suiteSuites, ParentRunner suiteClasses )
             throws InitializationError
         {
-            int parallelSuites = allGroups.get( Type.SUITES );
-            int parallelClasses = allGroups.get( Type.CLASSES );
-            int parallelMethods = allGroups.get( Type.METHODS );
+            int parallelSuites = allGroups.get( SUITES );
+            int parallelClasses = allGroups.get( CLASSES );
+            int parallelMethods = allGroups.get( METHODS );
             int poolSize = totalPoolSize();
             ExecutorService commonPool = splitPool || poolSize == 0 ? null : createPool( poolSize );
             master = createMaster( commonPool, poolSize );
@@ -533,6 +562,8 @@ public final class ParallelComputerBuilder
         private class SuiteFilter
             extends Filter
         {
+            // Do NOT use allGroups in SuiteFilter.
+
             @Override
             public boolean shouldRun( Description description )
             {

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtil.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtil.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtil.java
new file mode 100644
index 0000000..f93e9b6
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerUtil.java
@@ -0,0 +1,355 @@
+package org.apache.maven.surefire.junitcore.pc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.apache.maven.surefire.junitcore.JUnitCoreParameters;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+
+/**
+ * An algorithm which configures {@link ParallelComputer} with allocated thread resources by given
+ * {@link org.apache.maven.surefire.junitcore.JUnitCoreParameters}.
+ * The <code>AbstractSurefireMojo</code> has to provide correct combinations of thread-counts and <em>parallel</em>.
+ *
+ * @author Tibor Digana (tibor17)
+ * @see org.apache.maven.surefire.junitcore.pc.ParallelComputerBuilder
+ * @since 2.16
+ */
+final class ParallelComputerUtil
+{
+    private static int availableProcessors = Runtime.getRuntime().availableProcessors();
+
+    private ParallelComputerUtil()
+    {
+        throw new IllegalStateException( "Suppresses calling constructor, ensuring non-instantiability." );
+    }
+
+    /*
+    * For testing purposes.
+    */
+    static void overrideAvailableProcessors( int availableProcessors )
+    {
+        ParallelComputerUtil.availableProcessors = availableProcessors;
+    }
+
+    /*
+    * For testing purposes.
+    */
+    static void setDefaultAvailableProcessors()
+    {
+        ParallelComputerUtil.availableProcessors = Runtime.getRuntime().availableProcessors();
+    }
+
+    static Concurrency resolveConcurrency( JUnitCoreParameters params, RunnerCounter counts )
+        throws TestSetFailedException
+    {
+        if ( !params.isParallelismSelected() )
+        {
+            throw new TestSetFailedException( "Unspecified parameter '" + JUnitCoreParameters.PARALLEL_KEY + "'." );
+        }
+
+        if ( !params.isUseUnlimitedThreads() && !hasThreadCount( params ) && !hasThreadCounts( params ) )
+        {
+            throw new TestSetFailedException( "Unspecified thread-count(s). " +
+                                                  "See the parameters " + JUnitCoreParameters.USEUNLIMITEDTHREADS_KEY
+                                                  + ", " + JUnitCoreParameters.THREADCOUNT_KEY + ", "
+                                                  + JUnitCoreParameters.THREADCOUNTSUITES_KEY + ", "
+                                                  + JUnitCoreParameters.THREADCOUNTCLASSES_KEY + ", "
+                                                  + JUnitCoreParameters.THREADCOUNTMETHODS_KEY + "." );
+        }
+
+        if ( params.isUseUnlimitedThreads() )
+        {
+            return concurrencyForUnlimitedThreads( params );
+        }
+        else if ( hasThreadCount( params ) )
+        {
+            if ( hasThreadCounts( params ) )
+            {
+                return isLeafUnspecified( params )
+                    ? concurrencyFromAllThreadCountsButUnspecifiedLeafCount( params, counts )
+                    : concurrencyFromAllThreadCounts( params );
+            }
+            else
+            {
+                return estimateConcurrency( params, counts );
+            }
+        }
+        else
+        {
+            return concurrencyFromThreadCounts( params );
+        }
+    }
+
+    private static Concurrency concurrencyForUnlimitedThreads( JUnitCoreParameters params )
+    {
+        Concurrency concurrency = new Concurrency();
+        concurrency.suites = params.isParallelSuites() ? threadCountSuites( params ) : 0;
+        concurrency.classes = params.isParallelClasses() ? threadCountClasses( params ) : 0;
+        concurrency.methods = params.isParallelMethods() ? threadCountMethods( params ) : 0;
+        concurrency.capacity = Integer.MAX_VALUE;
+        return concurrency;
+    }
+
+    private static Concurrency estimateConcurrency( JUnitCoreParameters params, RunnerCounter counts )
+    {
+        final Concurrency concurrency = new Concurrency();
+        final int parallelEntities = countParallelEntities( params );
+        concurrency.capacity = multiplyByCoreCount( params, params.getThreadCount() );
+        if ( parallelEntities == 1 || counts == null || counts.classes == 0 )
+        {
+            // Estimate parallel thread counts.
+            double ratio = 1d / parallelEntities;
+            int threads = multiplyByCoreCount( params, ratio * params.getThreadCount() );
+            concurrency.suites = params.isParallelSuites() ? minSuites( threads, counts ) : 0;
+            concurrency.classes = params.isParallelClasses() ? minClasses( threads, counts ) : 0;
+            concurrency.methods = params.isParallelMethods() ? minMethods( threads, counts ) : 0;
+            if ( parallelEntities == 1 )
+            {
+                concurrency.capacity = 0;
+            }
+            else
+            {
+                adjustLeaf( params, concurrency );
+            }
+        }
+        else
+        {
+            // Try to allocate suites+classes+methods within threadCount,
+            concurrency.suites = params.isParallelSuites() ? toNonNegative( counts.suites ) : 0;
+            concurrency.classes = params.isParallelClasses() ? toNonNegative( counts.classes ) : 0;
+            concurrency.methods =
+                params.isParallelMethods() ? toNonNegative( Math.ceil( counts.methods / (double) counts.classes ) ) : 0;
+            double sum = toNonNegative( concurrency.suites + concurrency.classes + concurrency.methods );
+            if ( concurrency.capacity < sum && sum != 0 )
+            {
+                // otherwise allocate them using the weighting factor < 1.
+                double weight = concurrency.capacity / sum;
+                concurrency.suites *= weight;
+                concurrency.classes *= weight;
+                concurrency.methods *= weight;
+            }
+            adjustLeaf( params, concurrency );
+        }
+        return concurrency;
+    }
+
+    private static Concurrency concurrencyFromAllThreadCountsButUnspecifiedLeafCount( JUnitCoreParameters params,
+                                                                                      RunnerCounter counts )
+    {
+        Concurrency concurrency = new Concurrency();
+        concurrency.suites = params.isParallelSuites() ? params.getThreadCountSuites() : 0;
+        concurrency.suites = params.isParallelSuites() ? multiplyByCoreCount( params, concurrency.suites ) : 0;
+        concurrency.classes = params.isParallelClasses() ? params.getThreadCountClasses() : 0;
+        concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, concurrency.classes ) : 0;
+        concurrency.methods = params.isParallelMethods() ? params.getThreadCountMethods() : 0;
+        concurrency.methods = params.isParallelMethods() ? multiplyByCoreCount( params, concurrency.methods ) : 0;
+        concurrency.capacity = multiplyByCoreCount( params, params.getThreadCount() );
+
+        if ( counts != null )
+        {
+            concurrency.suites = toNonNegative( Math.min( concurrency.suites, counts.suites ) );
+            concurrency.classes = toNonNegative( Math.min( concurrency.classes, counts.classes ) );
+        }
+
+        setLeafInfinite( params, concurrency );
+
+        return concurrency;
+    }
+
+    private static Concurrency concurrencyFromAllThreadCounts( JUnitCoreParameters params )
+    {
+        Concurrency concurrency = new Concurrency();
+        concurrency.suites = params.isParallelSuites() ? params.getThreadCountSuites() : 0;
+        concurrency.classes = params.isParallelClasses() ? params.getThreadCountClasses() : 0;
+        concurrency.methods = params.isParallelMethods() ? params.getThreadCountMethods() : 0;
+        concurrency.capacity = params.getThreadCount();
+        double all = sumThreadCounts( concurrency );
+
+        concurrency.suites = params.isParallelSuites() ? multiplyByCoreCount( params, concurrency.capacity * (
+            concurrency.suites / all ) ) : 0;
+
+        concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, concurrency.capacity * (
+            concurrency.classes / all ) ) : 0;
+
+        concurrency.methods = params.isParallelMethods() ? multiplyByCoreCount( params, concurrency.capacity * (
+            concurrency.methods / all ) ) : 0;
+
+        concurrency.capacity = multiplyByCoreCount( params, concurrency.capacity );
+        adjustPrecisionInLeaf( params, concurrency );
+        return concurrency;
+    }
+
+    private static Concurrency concurrencyFromThreadCounts( JUnitCoreParameters params )
+    {
+        Concurrency concurrency = new Concurrency();
+        concurrency.suites = params.isParallelSuites() ? threadCountSuites( params ) : 0;
+        concurrency.classes = params.isParallelClasses() ? threadCountClasses( params ) : 0;
+        concurrency.methods = params.isParallelMethods() ? threadCountMethods( params ) : 0;
+        concurrency.capacity = toNonNegative( sumThreadCounts( concurrency ) );
+        return concurrency;
+    }
+
+    private static int countParallelEntities( JUnitCoreParameters params )
+    {
+        int count = 0;
+        if ( params.isParallelSuites() )
+        {
+            count++;
+        }
+
+        if ( params.isParallelClasses() )
+        {
+            count++;
+        }
+
+        if ( params.isParallelMethods() )
+        {
+            count++;
+        }
+        return count;
+    }
+
+    private static void adjustPrecisionInLeaf( JUnitCoreParameters params, Concurrency concurrency )
+    {
+        if ( params.isParallelMethods() )
+        {
+            concurrency.methods = concurrency.capacity - concurrency.suites - concurrency.classes;
+        }
+        else if ( params.isParallelClasses() )
+        {
+            concurrency.classes = concurrency.capacity - concurrency.suites;
+        }
+    }
+
+    private static void adjustLeaf( JUnitCoreParameters params, Concurrency concurrency )
+    {
+        if ( params.isParallelMethods() )
+        {
+            concurrency.methods = Integer.MAX_VALUE;
+        }
+        else if ( params.isParallelClasses() )
+        {
+            concurrency.classes = Integer.MAX_VALUE;
+        }
+    }
+
+    private static void setLeafInfinite( JUnitCoreParameters params, Concurrency concurrency )
+    {
+        if ( params.isParallelMethods() )
+        {
+            concurrency.methods = Integer.MAX_VALUE;
+        }
+        else if ( params.isParallelClasses() )
+        {
+            concurrency.classes = Integer.MAX_VALUE;
+        }
+        else if ( params.isParallelSuites() )
+        {
+            concurrency.suites = Integer.MAX_VALUE;
+        }
+    }
+
+    private static boolean isLeafUnspecified( JUnitCoreParameters params )
+    {
+        int maskOfParallel = params.isParallelSuites() ? 4 : 0;
+        maskOfParallel |= params.isParallelClasses() ? 2 : 0;
+        maskOfParallel |= params.isParallelMethods() ? 1 : 0;
+
+        int maskOfConcurrency = params.getThreadCountSuites() > 0 ? 4 : 0;
+        maskOfConcurrency |= params.getThreadCountClasses() > 0 ? 2 : 0;
+        maskOfConcurrency |= params.getThreadCountMethods() > 0 ? 1 : 0;
+
+        maskOfConcurrency &= maskOfParallel;
+
+        int leaf = Integer.lowestOneBit( maskOfParallel );
+        return maskOfConcurrency == maskOfParallel - leaf;
+    }
+
+    private static double sumThreadCounts( Concurrency concurrency )
+    {
+        double sum = concurrency.suites;
+        sum += concurrency.classes;
+        sum += concurrency.methods;
+        return sum;
+    }
+
+    private static boolean hasThreadCounts( JUnitCoreParameters jUnitCoreParameters )
+    {
+        return jUnitCoreParameters.isParallelSuites() && jUnitCoreParameters.getThreadCountSuites() > 0 ||
+            jUnitCoreParameters.isParallelClasses() && jUnitCoreParameters.getThreadCountClasses() > 0 ||
+            jUnitCoreParameters.isParallelMethods() && jUnitCoreParameters.getThreadCountMethods() > 0;
+    }
+
+    private static boolean hasThreadCount( JUnitCoreParameters jUnitCoreParameters )
+    {
+        return jUnitCoreParameters.getThreadCount() > 0;
+    }
+
+    private static int threadCountMethods( JUnitCoreParameters jUnitCoreParameters )
+    {
+        return multiplyByCoreCount( jUnitCoreParameters, jUnitCoreParameters.getThreadCountMethods() );
+    }
+
+    private static int threadCountClasses( JUnitCoreParameters jUnitCoreParameters )
+    {
+        return multiplyByCoreCount( jUnitCoreParameters, jUnitCoreParameters.getThreadCountClasses() );
+    }
+
+    private static int threadCountSuites( JUnitCoreParameters jUnitCoreParameters )
+    {
+        return multiplyByCoreCount( jUnitCoreParameters, jUnitCoreParameters.getThreadCountSuites() );
+    }
+
+    private static int multiplyByCoreCount( JUnitCoreParameters jUnitCoreParameters, double threadsPerCore )
+    {
+        double numberOfThreads =
+            jUnitCoreParameters.isPerCoreThreadCount() ? threadsPerCore * (double) availableProcessors : threadsPerCore;
+
+        return numberOfThreads > 0 ? toNonNegative( numberOfThreads ) : Integer.MAX_VALUE;
+    }
+
+    private static int minSuites( int threads, RunnerCounter counts )
+    {
+        long count = counts == null ? Integer.MAX_VALUE : counts.suites;
+        return Math.min( threads, toNonNegative( count ) );
+    }
+
+    private static int minClasses( int threads, RunnerCounter counts )
+    {
+        long count = counts == null ? Integer.MAX_VALUE : counts.classes;
+        return Math.min( threads, toNonNegative( count ) );
+    }
+
+    private static int minMethods( int threads, RunnerCounter counts )
+    {
+        long count = counts == null ? Integer.MAX_VALUE : counts.methods;
+        return Math.min( threads, toNonNegative( count ) );
+    }
+
+    private static int toNonNegative( long num )
+    {
+        return (int) Math.min( num > 0 ? num : 0, Integer.MAX_VALUE );
+    }
+
+    private static int toNonNegative( double num )
+    {
+        return (int) Math.min( num > 0 ? num : 0, Integer.MAX_VALUE );
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
index ec0e80d..26f5fa0 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
@@ -26,15 +26,15 @@ package org.apache.maven.surefire.junitcore.pc;
  * @see ParallelComputerBuilder
  * @since 2.17
  */
-final public class RunnerCounter//todo needs refactoring, remove public
+final class RunnerCounter
 {
-    public final long suites;
+    final long suites;
 
-    public final long classes;
+    final long classes;
 
-    public final long methods;
+    final long methods;
 
-    public RunnerCounter( long suites, long classes, long methods )
+    RunnerCounter( long suites, long classes, long methods )
     {
         this.suites = suites;
         this.classes = classes;

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/Type.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/Type.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/Type.java
new file mode 100644
index 0000000..3f9685f
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/Type.java
@@ -0,0 +1,31 @@
+package org.apache.maven.surefire.junitcore.pc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+/**
+ * @author tibor17 (Tibor Digana)
+ * @since 2.17
+ */
+enum Type
+{
+    SUITES,
+    CLASSES,
+    METHODS
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnit4SuiteTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnit4SuiteTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnit4SuiteTest.java
index 455f280..6bb58e1 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnit4SuiteTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnit4SuiteTest.java
@@ -21,7 +21,9 @@ package org.apache.maven.surefire.junitcore;
 
 import junit.framework.JUnit4TestAdapter;
 import junit.framework.Test;
+import org.apache.maven.surefire.junitcore.pc.OptimizedParallelComputerTest;
 import org.apache.maven.surefire.junitcore.pc.ParallelComputerBuilderTest;
+import org.apache.maven.surefire.junitcore.pc.ParallelComputerUtilTest;
 import org.apache.maven.surefire.junitcore.pc.SchedulingStrategiesTest;
 import org.junit.runner.RunWith;
 import org.junit.runners.Suite;
@@ -35,9 +37,11 @@ import org.junit.runners.Suite;
 @Suite.SuiteClasses( {
         Surefire746Test.class,
         Surefire813IncorrectResultTest.class,
-        ParallelComputerFactoryTest.class,
+        ParallelComputerUtilTest.class,
         ParallelComputerBuilderTest.class,
-        SchedulingStrategiesTest.class
+        SchedulingStrategiesTest.class,
+        JUnitCoreParametersTest.class,
+        OptimizedParallelComputerTest.class
 } )
 @RunWith( Suite.class )
 public class JUnit4SuiteTest

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java
index c73fa01..acfe429 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/JUnitCoreParametersTest.java
@@ -21,87 +21,116 @@ package org.apache.maven.surefire.junitcore;
 
 import java.util.Properties;
 
-import junit.framework.TestCase;
+import org.junit.Test;
+
+import static org.junit.Assert.*;
+import static org.hamcrest.core.Is.is;
 
 /*
  * @author Kristian Rosenvold, kristian.rosenvold@gmail com
  */
 public class JUnitCoreParametersTest
-    extends TestCase
 {
-    public void testIsParallelMethod()
-        throws Exception
+    @Test
+    public void defaultParameters()
+    {
+        assertFalse( newTestSetDefault().isParallelismSelected() );
+        assertTrue( newTestSetDefault().isPerCoreThreadCount() );
+        assertThat( newTestSetDefault().getThreadCount(), is( 0 ) );
+        assertThat( newTestSetDefault().getThreadCountMethods(), is( 0 ) );
+        assertThat( newTestSetDefault().getThreadCountClasses(), is( 0 ) );
+        assertThat( newTestSetDefault().getThreadCountSuites(), is( 0 ) );
+        assertFalse( newTestSetDefault().isUseUnlimitedThreads() );
+        assertThat( newTestSetDefault().getParallelTestsTimeoutInSeconds(), is( 0d ) );
+        assertThat( newTestSetDefault().getParallelTestsTimeoutForcedInSeconds(), is( 0d ) );
+        assertTrue( newTestSetDefault().isParallelOptimization() );
+    }
+
+    @Test
+    public void optimizationParameter()
+    {
+        assertFalse( newTestSetOptimization( false ).isParallelOptimization() );
+    }
+
+    @Test
+    public void timeoutParameters()
     {
-        assertFalse( getTestSetClasses().isParallelMethods() );
-        assertTrue( getTestSetMethods().isParallelMethods() );
-        assertTrue( getTestSetBoth().isParallelMethods() );
+        JUnitCoreParameters parameters = newTestSetTimeouts( 5.5d, 11.1d );
+        assertThat( parameters.getParallelTestsTimeoutInSeconds(), is( 5.5d ) );
+        assertThat( parameters.getParallelTestsTimeoutForcedInSeconds(), is( 11.1d ) );
     }
 
-    public void testIsParallelClasses()
-        throws Exception
+    @Test
+    public void isParallelMethod()
     {
-        assertTrue( getTestSetClasses().isParallelClasses() );
-        assertFalse( getTestSetMethods().isParallelClasses() );
-        assertTrue( getTestSetBoth().isParallelClasses() );
+        assertFalse( newTestSetClasses().isParallelMethods() );
+        assertTrue( newTestSetMethods().isParallelMethods() );
+        assertTrue( newTestSetBoth().isParallelMethods() );
     }
 
-    public void testIsParallelBoth()
-        throws Exception
+    @Test
+    public void isParallelClasses()
     {
-        assertFalse( isParallelMethodsAndClasses( getTestSetClasses() ) );
-        assertFalse( isParallelMethodsAndClasses( getTestSetMethods() ) );
-        assertTrue( isParallelMethodsAndClasses( getTestSetBoth() ) );
+        assertTrue( newTestSetClasses().isParallelClasses() );
+        assertFalse( newTestSetMethods().isParallelClasses() );
+        assertTrue( newTestSetBoth().isParallelClasses() );
     }
 
-    public void testIsPerCoreThreadCount()
-        throws Exception
+    @Test
+    public void isParallelBoth()
     {
-        assertFalse( getTestSetClasses().isPerCoreThreadCount() );
-        assertFalse( getTestSetMethods().isPerCoreThreadCount() );
-        assertTrue( getTestSetBoth().isPerCoreThreadCount() );
+        assertFalse( isParallelMethodsAndClasses( newTestSetClasses() ) );
+        assertFalse( isParallelMethodsAndClasses( newTestSetMethods() ) );
+        assertTrue( isParallelMethodsAndClasses( newTestSetBoth() ) );
     }
 
-    public void testGetThreadCount()
-        throws Exception
+    @Test
+    public void isPerCoreThreadCount()
     {
-        assertFalse( getTestSetClasses().isPerCoreThreadCount() );
-        assertFalse( getTestSetMethods().isPerCoreThreadCount() );
-        assertTrue( getTestSetBoth().isPerCoreThreadCount() );
+        assertFalse( newTestSetClasses().isPerCoreThreadCount() );
+        assertFalse( newTestSetMethods().isPerCoreThreadCount() );
+        assertTrue( newTestSetBoth().isPerCoreThreadCount() );
     }
 
-    public void testIsUseUnlimitedThreads()
-        throws Exception
+    @Test
+    public void getThreadCount()
     {
-        assertFalse( getTestSetClasses().isUseUnlimitedThreads() );
-        assertTrue( getTestSetMethods().isUseUnlimitedThreads() );
-        assertFalse( getTestSetBoth().isUseUnlimitedThreads() );
+        assertFalse( newTestSetClasses().isPerCoreThreadCount() );
+        assertFalse( newTestSetMethods().isPerCoreThreadCount() );
+        assertTrue( newTestSetBoth().isPerCoreThreadCount() );
     }
 
-    public void testIsNoThreading()
-        throws Exception
+    @Test
+    public void isUseUnlimitedThreads()
     {
-        assertFalse( getTestSetClasses().isNoThreading() );
-        assertFalse( getTestSetMethods().isNoThreading() );
-        assertFalse( getTestSetBoth().isNoThreading() );
+        assertFalse( newTestSetClasses().isUseUnlimitedThreads() );
+        assertTrue( newTestSetMethods().isUseUnlimitedThreads() );
+        assertFalse( newTestSetBoth().isUseUnlimitedThreads() );
     }
 
-    public void testIsAnyParallelitySelected()
-        throws Exception
+    @Test
+    public void isNoThreading()
     {
-        assertTrue( getTestSetClasses().isAnyParallelitySelected() );
-        assertTrue( getTestSetMethods().isAnyParallelitySelected() );
-        assertTrue( getTestSetBoth().isAnyParallelitySelected() );
+        assertFalse( newTestSetClasses().isNoThreading() );
+        assertFalse( newTestSetMethods().isNoThreading() );
+        assertFalse( newTestSetBoth().isNoThreading() );
     }
 
+    @Test
+    public void isAnyParallelismSelected()
+    {
+        assertTrue( newTestSetClasses().isParallelismSelected() );
+        assertTrue( newTestSetMethods().isParallelismSelected() );
+        assertTrue( newTestSetBoth().isParallelismSelected() );
+    }
 
-    public void testToString()
-        throws Exception
+    private Properties newDefaultProperties()
     {
-        assertNotNull( getTestSetBoth().toString() );
+        return new Properties();
     }
 
 
-    public Properties getPropsetClasses()
+    private Properties newPropertiesClasses()
     {
         Properties props = new Properties();
         props.setProperty( JUnitCoreParameters.PARALLEL_KEY, "classes" );
@@ -111,7 +140,7 @@ public class JUnitCoreParametersTest
         return props;
     }
 
-    public Properties getPropsetMethods()
+    private Properties newPropertiesMethods()
     {
         Properties props = new Properties();
         props.setProperty( JUnitCoreParameters.PARALLEL_KEY, "methods" );
@@ -121,7 +150,7 @@ public class JUnitCoreParametersTest
         return props;
     }
 
-    public Properties getPropsetBoth()
+    private Properties newPropertiesBoth()
     {
         Properties props = new Properties();
         props.setProperty( JUnitCoreParameters.PARALLEL_KEY, "both" );
@@ -131,19 +160,49 @@ public class JUnitCoreParametersTest
         return props;
     }
 
-    private JUnitCoreParameters getTestSetBoth()
+    private Properties newPropertiesTimeouts( double timeout, double forcedTimeout )
+    {
+        Properties props = new Properties();
+        props.setProperty( JUnitCoreParameters.PARALLEL_TIMEOUT_KEY, Double.toString( timeout ) );
+        props.setProperty( JUnitCoreParameters.PARALLEL_TIMEOUTFORCED_KEY, Double.toString( forcedTimeout ) );
+        return props;
+    }
+
+    private Properties newPropertiesOptimization( boolean optimize )
+    {
+        Properties props = new Properties();
+        props.setProperty( JUnitCoreParameters.PARALLEL_OPTIMIZE_KEY, Boolean.toString( optimize ) );
+        return props;
+    }
+
+    private JUnitCoreParameters newTestSetDefault()
+    {
+        return new JUnitCoreParameters( newDefaultProperties() );
+    }
+
+    private JUnitCoreParameters newTestSetBoth()
+    {
+        return new JUnitCoreParameters( newPropertiesBoth() );
+    }
+
+    private JUnitCoreParameters newTestSetClasses()
+    {
+        return new JUnitCoreParameters( newPropertiesClasses() );
+    }
+
+    private JUnitCoreParameters newTestSetMethods()
     {
-        return new JUnitCoreParameters( getPropsetBoth() );
+        return new JUnitCoreParameters( newPropertiesMethods() );
     }
 
-    private JUnitCoreParameters getTestSetClasses()
+    private JUnitCoreParameters newTestSetOptimization( boolean optimize )
     {
-        return new JUnitCoreParameters( getPropsetClasses() );
+        return new JUnitCoreParameters( newPropertiesOptimization( optimize ) );
     }
 
-    private JUnitCoreParameters getTestSetMethods()
+    private JUnitCoreParameters newTestSetTimeouts( double timeout, double forcedTimeout )
     {
-        return new JUnitCoreParameters( getPropsetMethods() );
+        return new JUnitCoreParameters( newPropertiesTimeouts( timeout, forcedTimeout ) );
     }
 
     private boolean isParallelMethodsAndClasses( JUnitCoreParameters jUnitCoreParameters )

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/OptimizedParallelComputerTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/OptimizedParallelComputerTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/OptimizedParallelComputerTest.java
deleted file mode 100644
index c1ac0b4..0000000
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/OptimizedParallelComputerTest.java
+++ /dev/null
@@ -1,323 +0,0 @@
-package org.apache.maven.surefire.junitcore;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License 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.
- */
-
-import org.apache.maven.surefire.junitcore.pc.RunnerCounter;
-import org.apache.maven.surefire.testset.TestSetFailedException;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.experimental.theories.DataPoint;
-import org.junit.experimental.theories.Theories;
-import org.junit.experimental.theories.Theory;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.RunWith;
-
-import java.util.Properties;
-
-import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.*;
-import static org.apache.maven.surefire.junitcore.ParallelComputerFactory.resolveConcurrency;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.*;
-
-/**
- * Testing an algorithm in {@link ParallelComputerFactory} which configures
- * optimized thread resources in ParallelComputer by given {@link JUnitCoreParameters}.
- *
- * @author Tibor Digana (tibor17)
- * @see org.apache.maven.surefire.junitcore.ParallelComputerFactory
- * @since 2.17
- */
-@RunWith( Theories.class )
-public final class OptimizedParallelComputerTest
-{
-    @DataPoint
-    public static final int CPU_1 = 1;
-
-    @DataPoint
-    public static final int CPU_4 = 4;
-
-    @Rule
-    public final ExpectedException exception = ExpectedException.none();
-
-    @Rule
-    public final Stopwatch runtime = new Stopwatch();
-
-    @BeforeClass
-    public static void beforeClass()
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( 1 );
-    }
-
-    @AfterClass
-    public static void afterClass()
-    {
-        ParallelComputerFactory.setDefaultAvailableProcessors();
-    }
-
-    @Theory
-    public void threadCountSuites( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suites" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 5, 10, 20 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 0 ) );
-        assertThat( concurrency.suites, is( (int) Math.min( 3 * cpu, counter.suites ) ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void threadCountClasses( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classes" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 1, 5, 10 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 0 ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( (int) Math.min( 3 * cpu, counter.classes ) ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void threadCountMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "methods" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertFalse( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 0 ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( (int) Math.min( 3 * cpu, counter.methods ) ) );
-    }
-
-    @Theory
-    public void threadCountBoth( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "both" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void threadCountClassesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void threadCountSuitesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 2, 3, 5 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void threadCountSuitesAndClasses( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 7 ) * cpu, 2 ) ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void threadCountAll( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 11 ) * cpu, 2 ) ) );
-        assertThat( concurrency.classes, is( (int) Math.min( ( 5d * 3 / 11 ) * cpu, 5 ) ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void reusableThreadCountSuitesAndClasses( int cpu )
-        throws TestSetFailedException
-    {
-        // 4 * cpu to 5 * cpu threads to run test classes
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
-        properties.setProperty( THREADCOUNT_KEY, "6" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 6 * cpu ) );
-        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void reusableThreadCountSuitesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        // 4 * cpu to 5 * cpu threads to run test methods
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "6" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 6 * cpu ) );
-        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void reusableThreadCountClassesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        // 4 * cpu to 5 * cpu threads to run test methods
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "6" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "2" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 6 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( Math.min( 2 * cpu, 5 ) ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void reusableThreadCountAll( int cpu )
-        throws TestSetFailedException
-    {
-        // 8 * cpu to 13 * cpu threads to run test methods
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( THREADCOUNT_KEY, "14" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "4" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
-        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 14 * cpu ) );
-        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
-        assertThat( concurrency.classes, is( Math.min( 4 * cpu, 5 ) ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-}
\ No newline at end of file


[05/11] git commit: unit tests for algorithm

Posted by ag...@apache.org.
unit tests for algorithm


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/c85e6e83
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/c85e6e83
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/c85e6e83

Branch: refs/heads/master
Commit: c85e6e83eee7513d9e1d4ae9c5aa7286b4ee3920
Parents: eaeaa28
Author: Tibor Digana <ti...@lycos.com>
Authored: Fri Feb 28 02:56:39 2014 +0100
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 19:46:40 2014 +0100

----------------------------------------------------------------------
 .../junitcore/ParallelComputerFactory.java      |  51 ++-
 .../surefire/junitcore/pc/RunnerCounter.java    |   2 +-
 .../OptimizedParallelComputerTest.java          | 323 +++++++++++++++++++
 3 files changed, 363 insertions(+), 13 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c85e6e83/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
index 91ef5bc..70d4a64 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/ParallelComputerFactory.java
@@ -207,9 +207,9 @@ final class ParallelComputerFactory
             // Estimate parallel thread counts.
             double ratio = 1d / parallelEntities;
             int threads = multiplyByCoreCount( params, ratio * params.getThreadCount() );
-            concurrency.suites = params.isParallelSuites() ? threads : 0;
-            concurrency.classes = params.isParallelClasses() ? threads : 0;
-            concurrency.methods = params.isParallelMethods() ? threads : 0;
+            concurrency.suites = params.isParallelSuites() ? minSuites( threads, counts ) : 0;
+            concurrency.classes = params.isParallelClasses() ? minClasses( threads, counts ) : 0;
+            concurrency.methods = params.isParallelMethods() ? minMethods( threads, counts ) : 0;
             if ( parallelEntities == 1 )
             {
                 concurrency.capacity = 0;
@@ -222,11 +222,11 @@ final class ParallelComputerFactory
         else
         {
             // Try to allocate suites+classes+methods within threadCount,
-            concurrency.suites = params.isParallelSuites() ? multiplyByCoreCount( params, counts.suites ) : 0;
-            concurrency.classes = params.isParallelClasses() ? multiplyByCoreCount( params, counts.classes ) : 0;
+            concurrency.suites = params.isParallelSuites() ? toNonNegative( counts.suites ) : 0;
+            concurrency.classes = params.isParallelClasses() ? toNonNegative( counts.classes ) : 0;
             concurrency.methods =
-                params.isParallelMethods() ? multiplyByCoreCount( params, counts.methods / counts.classes ) : 0;
-            double sum = (double) concurrency.suites + concurrency.classes + concurrency.methods;
+                params.isParallelMethods() ? toNonNegative( Math.ceil( counts.methods / (double) counts.classes ) ) : 0;
+            double sum = toNonNegative( concurrency.suites + concurrency.classes + concurrency.methods );
             if ( concurrency.capacity < sum && sum != 0 )
             {
                 // otherwise allocate them using the weighting factor < 1.
@@ -234,7 +234,6 @@ final class ParallelComputerFactory
                 concurrency.suites *= weight;
                 concurrency.classes *= weight;
                 concurrency.methods *= weight;
-                adjustPrecisionInLeaf( params, concurrency );
             }
             adjustLeaf( params, concurrency );
         }
@@ -255,8 +254,8 @@ final class ParallelComputerFactory
 
         if ( counts != null )
         {
-            concurrency.suites = (int) Math.min( Math.min( concurrency.suites, counts.suites ), Integer.MAX_VALUE );
-            concurrency.classes = (int) Math.min( Math.min( concurrency.classes, counts.classes ), Integer.MAX_VALUE );
+            concurrency.suites = toNonNegative( Math.min( concurrency.suites, counts.suites ) );
+            concurrency.classes = toNonNegative( Math.min( concurrency.classes, counts.classes ) );
         }
 
         setLeafInfinite( params, concurrency );
@@ -293,7 +292,7 @@ final class ParallelComputerFactory
         concurrency.suites = params.isParallelSuites() ? threadCountSuites( params ) : 0;
         concurrency.classes = params.isParallelClasses() ? threadCountClasses( params ) : 0;
         concurrency.methods = params.isParallelMethods() ? threadCountMethods( params ) : 0;
-        concurrency.capacity = (int) Math.min( sumThreadCounts( concurrency ), Integer.MAX_VALUE );
+        concurrency.capacity = toNonNegative( sumThreadCounts( concurrency ) );
         return concurrency;
     }
 
@@ -413,7 +412,35 @@ final class ParallelComputerFactory
         double numberOfThreads =
             jUnitCoreParameters.isPerCoreThreadCount() ? threadsPerCore * (double) availableProcessors : threadsPerCore;
 
-        return numberOfThreads > 0 ? (int) Math.min( numberOfThreads, Integer.MAX_VALUE ) : Integer.MAX_VALUE;
+        return numberOfThreads > 0 ? toNonNegative( numberOfThreads ) : Integer.MAX_VALUE;
+    }
+
+    private static int minSuites( int threads, RunnerCounter counts )
+    {
+        long count = counts == null ? Integer.MAX_VALUE : counts.suites;
+        return Math.min( threads, toNonNegative( count ) );
+    }
+
+    private static int minClasses( int threads, RunnerCounter counts )
+    {
+        long count = counts == null ? Integer.MAX_VALUE : counts.classes;
+        return Math.min( threads, toNonNegative( count ) );
+    }
+
+    private static int minMethods( int threads, RunnerCounter counts )
+    {
+        long count = counts == null ? Integer.MAX_VALUE : counts.methods;
+        return Math.min( threads, toNonNegative( count ) );
+    }
+
+    private static int toNonNegative( long num )
+    {
+        return (int) Math.min( num > 0 ? num : 0, Integer.MAX_VALUE );
+    }
+
+    private static int toNonNegative( double num )
+    {
+        return (int) Math.min( num > 0 ? num : 0, Integer.MAX_VALUE );
     }
 
     static class Concurrency

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c85e6e83/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
index 48ef73a..ec0e80d 100644
--- a/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
+++ b/surefire-providers/surefire-junit47/src/main/java/org/apache/maven/surefire/junitcore/pc/RunnerCounter.java
@@ -34,7 +34,7 @@ final public class RunnerCounter//todo needs refactoring, remove public
 
     public final long methods;
 
-    RunnerCounter( long suites, long classes, long methods )
+    public RunnerCounter( long suites, long classes, long methods )
     {
         this.suites = suites;
         this.classes = classes;

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/c85e6e83/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/OptimizedParallelComputerTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/OptimizedParallelComputerTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/OptimizedParallelComputerTest.java
new file mode 100644
index 0000000..c1ac0b4
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/OptimizedParallelComputerTest.java
@@ -0,0 +1,323 @@
+package org.apache.maven.surefire.junitcore;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.apache.maven.surefire.junitcore.pc.RunnerCounter;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+import java.util.Properties;
+
+import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.*;
+import static org.apache.maven.surefire.junitcore.ParallelComputerFactory.resolveConcurrency;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.*;
+
+/**
+ * Testing an algorithm in {@link ParallelComputerFactory} which configures
+ * optimized thread resources in ParallelComputer by given {@link JUnitCoreParameters}.
+ *
+ * @author Tibor Digana (tibor17)
+ * @see org.apache.maven.surefire.junitcore.ParallelComputerFactory
+ * @since 2.17
+ */
+@RunWith( Theories.class )
+public final class OptimizedParallelComputerTest
+{
+    @DataPoint
+    public static final int CPU_1 = 1;
+
+    @DataPoint
+    public static final int CPU_4 = 4;
+
+    @Rule
+    public final ExpectedException exception = ExpectedException.none();
+
+    @Rule
+    public final Stopwatch runtime = new Stopwatch();
+
+    @BeforeClass
+    public static void beforeClass()
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( 1 );
+    }
+
+    @AfterClass
+    public static void afterClass()
+    {
+        ParallelComputerFactory.setDefaultAvailableProcessors();
+    }
+
+    @Theory
+    public void threadCountSuites( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suites" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 5, 10, 20 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( (int) Math.min( 3 * cpu, counter.suites ) ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountClasses( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classes" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 1, 5, 10 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( (int) Math.min( 3 * cpu, counter.classes ) ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "methods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( (int) Math.min( 3 * cpu, counter.methods ) ) );
+    }
+
+    @Theory
+    public void threadCountBoth( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "both" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountClassesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountSuitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 2, 3, 5 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountSuitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 7 ) * cpu, 2 ) ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountAll( int cpu )
+        throws TestSetFailedException
+    {
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 11 ) * cpu, 2 ) ) );
+        assertThat( concurrency.classes, is( (int) Math.min( ( 5d * 3 / 11 ) * cpu, 5 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void reusableThreadCountSuitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test classes
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void reusableThreadCountSuitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test methods
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void reusableThreadCountClassesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test methods
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( Math.min( 2 * cpu, 5 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void reusableThreadCountAll( int cpu )
+        throws TestSetFailedException
+    {
+        // 8 * cpu to 13 * cpu threads to run test methods
+        ParallelComputerFactory.overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNT_KEY, "14" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "4" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
+        ParallelComputerFactory.Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 14 * cpu ) );
+        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
+        assertThat( concurrency.classes, is( Math.min( 4 * cpu, 5 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+}
\ No newline at end of file


[09/11] git commit: [SUREFIRE-1062] TestNG listeners on separate lines in pom.xml

Posted by ag...@apache.org.
[SUREFIRE-1062] TestNG listeners on separate lines in pom.xml


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/a1d86c7d
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/a1d86c7d
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/a1d86c7d

Branch: refs/heads/master
Commit: a1d86c7d63b90e397c39db0efc008ad47cef0239
Parents: 4f97226
Author: Kirill Kozlov <ko...@gmail.com>
Authored: Mon Feb 24 23:14:20 2014 +0400
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 20:17:08 2014 +0100

----------------------------------------------------------------------
 .../testng/conf/AbstractDirectConfigurator.java |  2 +-
 .../testng/conf/TestNGMapConfiguratorTest.java  | 26 ++++++++++++++++++++
 2 files changed, 27 insertions(+), 1 deletion(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/a1d86c7d/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java
index 3c1e95e..b344d3d 100644
--- a/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java
+++ b/surefire-providers/surefire-testng/src/main/java/org/apache/maven/surefire/testng/conf/AbstractDirectConfigurator.java
@@ -119,7 +119,7 @@ public abstract class AbstractDirectConfigurator
         }
 
         List classes = new ArrayList();
-        String[] classNames = listenerClasses.split( " *, *" );
+        String[] classNames = listenerClasses.split( "\\s*,\\s*(\\r?\\n)?\\s*" );
         for ( int i = 0; i < classNames.length; i++ )
         {
             String className = classNames[i];

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/a1d86c7d/surefire-providers/surefire-testng/src/test/java/org/apache/maven/surefire/testng/conf/TestNGMapConfiguratorTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-testng/src/test/java/org/apache/maven/surefire/testng/conf/TestNGMapConfiguratorTest.java b/surefire-providers/surefire-testng/src/test/java/org/apache/maven/surefire/testng/conf/TestNGMapConfiguratorTest.java
index ac785a6..556ebea 100755
--- a/surefire-providers/surefire-testng/src/test/java/org/apache/maven/surefire/testng/conf/TestNGMapConfiguratorTest.java
+++ b/surefire-providers/surefire-testng/src/test/java/org/apache/maven/surefire/testng/conf/TestNGMapConfiguratorTest.java
@@ -20,7 +20,9 @@ package org.apache.maven.surefire.testng.conf;
  */
 
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
+
 import org.apache.maven.surefire.testset.TestSetFailedException;
 
 import junit.framework.TestCase;
@@ -31,6 +33,10 @@ import junit.framework.TestCase;
 public class TestNGMapConfiguratorTest
     extends TestCase
 {
+    private static final String FIRST_LISTENER = "org.testng.TestListenerAdapter";
+    private static final String SECOND_LISTENER = "org.testng.reporters.ExitCodeListener";
+    public static final String LISTENER_PROP = "listener";
+
     public void testGetConvertedOptions()
         throws Exception
     {
@@ -39,6 +45,26 @@ public class TestNGMapConfiguratorTest
         assertTrue( bool.booleanValue() );
     }
 
+    public void testListenersOnSeparateLines()
+        throws Exception
+    {
+        String listenersOnSeveralLines = String.format( "%s , %n %s",
+                FIRST_LISTENER, SECOND_LISTENER);
+        Map convertedOptions = getConvertedOptions(LISTENER_PROP, listenersOnSeveralLines);
+        List listeners = (List) convertedOptions.get( String.format("-%s", LISTENER_PROP));
+        assertEquals(2, listeners.size());
+    }
+
+    public void testListenersOnTheSameLine()
+        throws Exception
+    {
+        String listenersOnSeveralLines = String.format( "%s,%s",
+                FIRST_LISTENER, SECOND_LISTENER);
+        Map convertedOptions = getConvertedOptions( LISTENER_PROP, listenersOnSeveralLines);
+        List listeners = (List) convertedOptions.get( String.format("-%s", LISTENER_PROP));
+        assertEquals(2, listeners.size());
+    }
+
     public void testGroupByInstances()
         throws Exception
     {


[06/11] git commit: [SUREFIRE-1055] Integration Tests

Posted by ag...@apache.org.
[SUREFIRE-1055] Integration Tests


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/1c843d67
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/1c843d67
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/1c843d67

Branch: refs/heads/master
Commit: 1c843d672ad8c7406ac2c62b93684771aff81014
Parents: 01c39b0
Author: Tibor Digana <ti...@lycos.com>
Authored: Sun Mar 9 12:57:10 2014 +0100
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 19:46:42 2014 +0100

----------------------------------------------------------------------
 .../maven/surefire/its/JUnit47ParallelIT.java   | 202 +++++++++++++------
 .../surefire/its/fixture/SurefireLauncher.java  |   8 +-
 .../src/test/resources/junit47-parallel/pom.xml |  15 +-
 .../test/java/surefireparallel/TestClass.java   |   5 +-
 4 files changed, 157 insertions(+), 73 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/1c843d67/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit47ParallelIT.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit47ParallelIT.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit47ParallelIT.java
index 5edfb6a..03c0628 100644
--- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit47ParallelIT.java
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/JUnit47ParallelIT.java
@@ -26,7 +26,7 @@ import org.junit.Test;
 /**
  * Testing JUnitCoreWrapper with ParallelComputerBuilder.
  *
- * @author Tibor Digana (tibor17)
+ * @author <a href="mailto:tibor.digana@gmail.com">Tibor Digana (tibor17)</a>
  * @since 2.16
  */
 public class JUnit47ParallelIT
@@ -124,59 +124,59 @@ public class JUnit47ParallelIT
     }
 
     @Test
-    public void useUnlimitedThreadsSuites1()
+    public void unlimitedThreadsSuites1()
     {
         // takes 3.6 sec
-        unpack().parallelSuites().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelSuites().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree(
+            24 );
     }
 
     @Test
-    public void useUnlimitedThreadsSuites2()
+    public void unlimitedThreadsSuites2()
     {
         // takes 3.6 sec
-        unpack().parallelSuites().useUnlimitedThreads().threadCountSuites( 5 ).setTestToRun( "Suite*Test" )
-            .executeTest().verifyErrorFree( 24 );
+        unpack().parallelSuites().useUnlimitedThreads().threadCountSuites( 5 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
-    public void useUnlimitedThreadsClasses1()
+    public void unlimitedThreadsClasses1()
     {
         // takes 1.8 sec
-        unpack().parallelClasses().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelClasses().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree(
+            24 );
     }
 
     @Test
-    public void useUnlimitedThreadsClasses2()
+    public void unlimitedThreadsClasses2()
     {
         // takes 1.8 sec
-        unpack().parallelClasses().useUnlimitedThreads().threadCountClasses( 5 ).setTestToRun( "Suite*Test" )
-            .executeTest().verifyErrorFree( 24 );
+        unpack().parallelClasses().useUnlimitedThreads().threadCountClasses( 5 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
-    public void useUnlimitedThreadsMethods1()
+    public void unlimitedThreadsMethods1()
     {
         // takes 2.4 sec
-        unpack().parallelMethods().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelMethods().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree(
+            24 );
     }
 
     @Test
-    public void useUnlimitedThreadsMethods2()
+    public void unlimitedThreadsMethods2()
     {
         // takes 2.4 sec
-        unpack().parallelMethods().useUnlimitedThreads().threadCountMethods( 5 ).setTestToRun( "Suite*Test" )
-            .executeTest().verifyErrorFree( 24 );
+        unpack().parallelMethods().useUnlimitedThreads().threadCountMethods( 5 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
     public void unlimitedThreadsSuitesAndClasses1()
     {
         // takes 0.9 sec
-        unpack().parallelSuitesAndClasses().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest()
-        .verifyErrorFree( 24 );
+        unpack().parallelSuitesAndClasses().useUnlimitedThreads().setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -184,40 +184,40 @@ public class JUnit47ParallelIT
     {
         // takes 0.9 sec
         // 1.8 sec with 4 parallel classes
-        unpack().parallelSuitesAndClasses().useUnlimitedThreads().threadCountSuites( 5 ).threadCountClasses( 15 )
-            .setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().parallelSuitesAndClasses().useUnlimitedThreads().threadCountSuites( 5 ).threadCountClasses(
+            15 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
     public void unlimitedThreadsSuitesAndMethods1()
     {
         // takes 1.2 sec
-        unpack().parallelSuitesAndMethods().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelSuitesAndMethods().useUnlimitedThreads().setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
     public void unlimitedThreadsSuitesAndMethods2()
     {
         // takes 1.2 sec
-        unpack().parallelSuitesAndMethods().useUnlimitedThreads().threadCountSuites( 5 ).threadCountMethods( 15 )
-            .setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().parallelSuitesAndMethods().useUnlimitedThreads().threadCountSuites( 5 ).threadCountMethods(
+            15 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
     public void unlimitedThreadsClassesAndMethods1()
     {
         // takes 0.6 sec
-        unpack().parallelClassesAndMethods().useUnlimitedThreads().setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelClassesAndMethods().useUnlimitedThreads().setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
     public void unlimitedThreadsClassesAndMethods2()
     {
         // takes 0.6 sec
-        unpack().parallelClassesAndMethods().useUnlimitedThreads().threadCountClasses( 5 ).threadCountMethods( 15 )
-            .setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().parallelClassesAndMethods().useUnlimitedThreads().threadCountClasses( 5 ).threadCountMethods(
+            15 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -231,8 +231,8 @@ public class JUnit47ParallelIT
     public void unlimitedThreadsAll2()
     {
         // takes 0.3 sec
-        unpack().parallelAll().useUnlimitedThreads().threadCountSuites( 5 ).threadCountClasses( 15 )
-            .threadCountMethods( 30 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().parallelAll().useUnlimitedThreads().threadCountSuites( 5 ).threadCountClasses( 15 ).threadCountMethods(
+            30 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -247,8 +247,7 @@ public class JUnit47ParallelIT
     {
         // takes 3.6 sec for single core
         // takes 1.8 sec for double core
-        unpack().parallelClasses().threadCount( 3 ).setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelClasses().threadCount( 3 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -262,16 +261,32 @@ public class JUnit47ParallelIT
     public void threadCountClassesAndMethodsOneCore()
     {
         // takes 4.8 sec
-        unpack().disablePerCoreThreadCount().parallelClassesAndMethods().threadCount( 3 ).setTestToRun( "Suite*Test" )
-            .executeTest().verifyErrorFree( 24 );
+        unpack().disablePerCoreThreadCount().disableParallelOptimization().parallelClassesAndMethods().threadCount(
+            3 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void threadCountClassesAndMethodsOneCoreOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
+        unpack().disablePerCoreThreadCount().parallelClassesAndMethods().threadCount( 3 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
     public void threadCountClassesAndMethods()
     {
         // takes 2.4 sec for double core CPU
-        unpack().parallelClassesAndMethods().threadCount( 3 ).setTestToRun( "Suite*Test" ).executeTest()
-        .verifyErrorFree( 24 );
+        unpack().disableParallelOptimization().parallelClassesAndMethods().threadCount( 3 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void threadCountClassesAndMethodsOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
+        unpack().parallelClassesAndMethods().threadCount( 3 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -279,20 +294,44 @@ public class JUnit47ParallelIT
     {
         // usually 24 times 0.3 sec = 7.2 sec with one core CPU
         // takes 1.8 sec for double core CPU
-        unpack().parallelSuitesAndMethods().threadCount( 3 ).setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().disableParallelOptimization().parallelSuitesAndMethods().threadCount( 3 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void threadCountSuitesAndMethodsOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
+        unpack().parallelSuitesAndMethods().threadCount( 3 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree(
+            24 );
     }
 
     @Test
     public void threadCountSuitesAndClasses()
     {
-        unpack().parallelSuitesAndClasses().threadCount( 3 ).setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().disableParallelOptimization().parallelSuitesAndClasses().threadCount( 3 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void threadCountSuitesAndClassesOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
+        unpack().parallelSuitesAndClasses().threadCount( 3 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree(
+            24 );
     }
 
     @Test
     public void threadCountAll()
     {
+        unpack().disableParallelOptimization().parallelAll().threadCount( 3 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void threadCountAllOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
         unpack().parallelAll().threadCount( 3 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
@@ -300,25 +339,24 @@ public class JUnit47ParallelIT
     public void everyThreadCountSuitesAndClasses()
     {
         // takes 1.8 sec for double core CPU
-        unpack().parallelSuitesAndClasses().threadCount( 3 ).threadCountSuites( 34 ).threadCountClasses( 66 )
-            .setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelSuitesAndClasses().threadCount( 3 ).threadCountSuites( 34 ).threadCountClasses(
+            66 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
     public void everyThreadCountSuitesAndMethods()
     {
         // takes 1.8 sec for double core CPU
-        unpack().parallelSuitesAndMethods().threadCount( 3 ).threadCountSuites( 34 ).threadCountMethods( 66 )
-            .setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().parallelSuitesAndMethods().threadCount( 3 ).threadCountSuites( 34 ).threadCountMethods(
+            66 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
     public void everyThreadCountClassesAndMethods()
     {
         // takes 1.8 sec for double core CPU
-        unpack().parallelClassesAndMethods().threadCount( 3 ).threadCountClasses( 34 ).threadCountMethods( 66 )
-            .setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().parallelClassesAndMethods().threadCount( 3 ).threadCountClasses( 34 ).threadCountMethods(
+            66 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -334,8 +372,16 @@ public class JUnit47ParallelIT
     {
         // 4 * cpu to 5 * cpu threads to run test classes
         // takes cca 1.8 sec
-        unpack().parallelSuitesAndClasses().disablePerCoreThreadCount().threadCount( 6 ).threadCountSuites( 2 )
-            .setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().disableParallelOptimization().parallelSuitesAndClasses().disablePerCoreThreadCount().threadCount(
+            6 ).threadCountSuites( 2 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void reusableThreadCountSuitesAndClassesOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
+        unpack().parallelSuitesAndClasses().disablePerCoreThreadCount().threadCount( 6 ).threadCountSuites(
+            2 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -343,8 +389,16 @@ public class JUnit47ParallelIT
     {
         // 4 * cpu to 5 * cpu threads to run test methods
         // takes cca 1.8 sec
-        unpack().parallelSuitesAndMethods().disablePerCoreThreadCount().threadCount( 6 ).threadCountSuites( 2 )
-            .setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().disableParallelOptimization().parallelSuitesAndMethods().disablePerCoreThreadCount().threadCount(
+            6 ).threadCountSuites( 2 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void reusableThreadCountSuitesAndMethodsOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
+        unpack().parallelSuitesAndMethods().disablePerCoreThreadCount().threadCount( 6 ).threadCountSuites(
+            2 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -352,8 +406,16 @@ public class JUnit47ParallelIT
     {
         // 4 * cpu to 5 * cpu threads to run test methods
         // takes cca 1.8 sec
-        unpack().parallelClassesAndMethods().disablePerCoreThreadCount().threadCount( 6 ).threadCountClasses( 2 )
-            .setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+        unpack().disableParallelOptimization().parallelClassesAndMethods().disablePerCoreThreadCount().threadCount(
+            6 ).threadCountClasses( 2 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void reusableThreadCountClassesAndMethodsOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
+        unpack().parallelClassesAndMethods().disablePerCoreThreadCount().threadCount( 6 ).threadCountClasses(
+            2 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
 
     @Test
@@ -361,6 +423,15 @@ public class JUnit47ParallelIT
     {
         // 8 * cpu to 13 * cpu threads to run test methods
         // takes 0.9 sec
+        unpack().disableParallelOptimization().parallelAll().disablePerCoreThreadCount().threadCount(
+            14 ).threadCountSuites( 2 ).threadCountClasses( 4 ).setTestToRun(
+            "Suite*Test" ).executeTest().verifyErrorFree( 24 );
+    }
+
+    @Test
+    public void reusableThreadCountAllOptimized()
+    {
+        // the number of reused threads in leafs depends on the number of runners and CPU
         unpack().parallelAll().disablePerCoreThreadCount().threadCount( 14 ).threadCountSuites( 2 ).threadCountClasses(
             4 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree( 24 );
     }
@@ -369,16 +440,16 @@ public class JUnit47ParallelIT
     public void suites()
     {
         // takes 3.6 sec
-        unpack().parallelSuites().threadCountSuites( 5 ).setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelSuites().threadCountSuites( 5 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree(
+            24 );
     }
 
     @Test
     public void classes()
     {
         // takes 1.8 sec on any CPU because the suites are running in a sequence
-        unpack().parallelClasses().threadCountClasses( 5 ).setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelClasses().threadCountClasses( 5 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree(
+            24 );
     }
 
     @Test
@@ -386,8 +457,8 @@ public class JUnit47ParallelIT
     {
         // takes 2.4 sec on any CPU because every class has only three methods
         // and the suites and classes are running in a sequence
-        unpack().parallelMethods().threadCountMethods( 5 ).setTestToRun( "Suite*Test" ).executeTest()
-            .verifyErrorFree( 24 );
+        unpack().parallelMethods().threadCountMethods( 5 ).setTestToRun( "Suite*Test" ).executeTest().verifyErrorFree(
+            24 );
     }
 
     @Test
@@ -444,9 +515,10 @@ public class JUnit47ParallelIT
     public void timeoutAndForcedShutdown()
     {
         // executes for one sec until timeout has elapsed
-        unpack().parallelMethods().threadCountMethods( 2 ).parallelTestsTimeoutInSeconds( 1 )
-            .parallelTestsTimeoutForcedInSeconds( 2.5d ).setTestToRun( "TestClass" ).failNever().executeTest()
-            .verifyTextInLog( "The test run has finished abruptly after timeout of 1.0 seconds." );
+        unpack().parallelMethods().threadCountMethods( 2 ).parallelTestsTimeoutInSeconds(
+            1 ).parallelTestsTimeoutForcedInSeconds( 2.5d ).setTestToRun(
+            "TestClass" ).failNever().executeTest().verifyTextInLog(
+            "The test run has finished abruptly after timeout of 1.0 seconds." );
     }
 
     private SurefireLauncher unpack()

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/1c843d67/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java
index 3ac3e20..149adcc 100755
--- a/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java
+++ b/surefire-integration-tests/src/test/java/org/apache/maven/surefire/its/fixture/SurefireLauncher.java
@@ -130,7 +130,6 @@ public class SurefireLauncher
         return this;
     }
 
-
     public SurefireLauncher showErrorStackTraces()
     {
         mavenLauncher.showErrorStackTraces();
@@ -162,7 +161,6 @@ public class SurefireLauncher
         return this;
     }
 
-
     public SurefireLauncher addGoal( String goal )
     {
         mavenLauncher.addGoal( goal );
@@ -319,6 +317,12 @@ public class SurefireLauncher
         return this;
     }
 
+    public SurefireLauncher disableParallelOptimization()
+    {
+        mavenLauncher.sysProp( "parallelOptimized", "false" );
+        return this;
+    }
+
     public SurefireLauncher parallel( String parallel )
     {
         mavenLauncher.sysProp( "parallel", parallel );

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/1c843d67/surefire-integration-tests/src/test/resources/junit47-parallel/pom.xml
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/junit47-parallel/pom.xml b/surefire-integration-tests/src/test/resources/junit47-parallel/pom.xml
index d8de300..69a743d 100644
--- a/surefire-integration-tests/src/test/resources/junit47-parallel/pom.xml
+++ b/surefire-integration-tests/src/test/resources/junit47-parallel/pom.xml
@@ -6,6 +6,13 @@
   <version>1.0-SNAPSHOT</version>
   <name>junit47-parallel</name>
   <url>http://maven.apache.org</url>
+  <contributors>
+    <contributor>
+      <name>Tibor Digana (tibor17)</name>
+      <email>tibor.digana@gmail.com</email>
+      <timezone>+1</timezone>
+    </contributor>
+  </contributors>
   <dependencies>
     <dependency>
       <groupId>junit</groupId>
@@ -16,17 +23,21 @@
   <build>
     <plugins>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
+        <version>2.5.1</version>
         <configuration>
           <source>1.5</source>
           <target>1.5</target>
         </configuration>
       </plugin>
       <plugin>
-        <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-surefire-plugin</artifactId>
         <version>${surefire.version}</version>
+        <configuration>
+          <perCoreThreadCount>false</perCoreThreadCount>
+          <threadCount>4</threadCount>
+          <parallel>methods</parallel>
+        </configuration>
       </plugin>
     </plugins>
   </build>

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/1c843d67/surefire-integration-tests/src/test/resources/junit47-parallel/src/test/java/surefireparallel/TestClass.java
----------------------------------------------------------------------
diff --git a/surefire-integration-tests/src/test/resources/junit47-parallel/src/test/java/surefireparallel/TestClass.java b/surefire-integration-tests/src/test/resources/junit47-parallel/src/test/java/surefireparallel/TestClass.java
index 3b1f842..e3906fd 100644
--- a/surefire-integration-tests/src/test/resources/junit47-parallel/src/test/java/surefireparallel/TestClass.java
+++ b/surefire-integration-tests/src/test/resources/junit47-parallel/src/test/java/surefireparallel/TestClass.java
@@ -19,13 +19,10 @@ package surefireparallel;
  * under the License.
  */
 
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
 import org.junit.Test;
-import org.junit.runners.BlockJUnit4ClassRunner;
 
 /**
- * @author Tibor Digana (tibor17)
+ * @author <a href="mailto:tibor.digana@gmail.com">Tibor Digana (tibor17)</a>
  * @since 2.16
  */
 public class TestClass


[07/11] git commit: fixed typos and simplification of documentation

Posted by ag...@apache.org.
fixed typos and simplification of documentation


Project: http://git-wip-us.apache.org/repos/asf/maven-surefire/repo
Commit: http://git-wip-us.apache.org/repos/asf/maven-surefire/commit/aff26226
Tree: http://git-wip-us.apache.org/repos/asf/maven-surefire/tree/aff26226
Diff: http://git-wip-us.apache.org/repos/asf/maven-surefire/diff/aff26226

Branch: refs/heads/master
Commit: aff2622662becd48c933531b149f20f32f877555
Parents: 1c843d6
Author: Tibor Digana <ti...@lycos.com>
Authored: Sun Mar 9 18:33:20 2014 +0100
Committer: Andreas Gudian <ag...@apache.org>
Committed: Sun Mar 9 19:46:43 2014 +0100

----------------------------------------------------------------------
 .../plugin/surefire/AbstractSurefireMojo.java   | 63 ++++++++++----------
 .../fork-options-and-parallel-execution.apt.vm  |  8 +--
 2 files changed, 34 insertions(+), 37 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/aff26226/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
----------------------------------------------------------------------
diff --git a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
index f4da5a3..730b0ad 100644
--- a/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
+++ b/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
@@ -458,7 +458,8 @@ public abstract class AbstractSurefireMojo
     private boolean reuseForks;
 
     /**
-     * (JUnit 4.7 provider) Indicates that threadCount is per cpu core.
+     * (JUnit 4.7 provider) Indicates that threadCount, threadCountSuites, threadCountClasses, threadCountMethods
+     * are per cpu core.
      *
      * @since 2.5
      */
@@ -506,21 +507,14 @@ public abstract class AbstractSurefireMojo
     protected boolean parallelOptimized;
 
     /**
-     * (JUnit 4.7 provider) The attribute thread-count-suites allows you to specify the concurrency in test suites, i.e.:
+     * (JUnit 4.7 provider) This attribute allows you to specify the concurrency in test suites, i.e.:
      * <ul>
-     *  <li>number of threads executing JUnit test suites if <code>threadCount</code> is 0 or unspecified</li>
-     *  <li>In a special case <code>threadCountSuites</code> and <code>threadCount</code> are specified
-     *      without <code>threadCountMethods</code> for <code>parallel</code>=<code>suitesAndMethods</code>.
-     *      <br/>Example1: threadCount=8 and threadCountSuites=3, the number of parallel methods is varying from 5 to 7 in your tests.
-     *      <br/>In another special case when <code>parallel</code>=<code>all</code> and the only <code>threadCountMethods</code>
-     *      is unspecified, then threads from suites and classes are reused in favor of methods.
-     *      <br/>Example2: parallel=all, threadCount=16 , threadCountSuites=2 , threadCountClasses=5,
-     *      the number of parallel methods is varying from 9 to 14 in your tests.
-     *  </li>
-     *  <li>integer number which represents the weight in ratio between
-     *      <em>threadCountSuites</em>:<code>threadCountClasses</code>:<code>threadCountMethods</code>.
-     *      As an example 2 is 20% of <code>threadCount</code> if the ratio is <em>2</em>:3:5</li>
-     *  <li>You can impose limitation on parallel suites if <code>useUnlimitedThreads</code> is specified.</li>
+     *  <li>number of concurrent suites if <code>threadCount</code> is 0 or unspecified</li>
+     *  <li>limited suites concurrency if <code>useUnlimitedThreads</code> is set to <strong>true</strong></li>
+     *  <li>if <code>threadCount</code> and certain thread-count parameters are &gt; 0 for <code>parallel</code>, the
+     *  concurrency is computed from ratio. For instance parallel=all and the ratio between
+     *      <em>threadCountSuites</em>:<code>threadCountClasses</code>:<code>threadCountMethods</code> is
+     *      <em>2</em>:3:5, there is 20% of <code>threadCount</code> in concurrent suites.</li>
      * </ul>
      *
      * Only makes sense to use in conjunction with the <code>parallel</code> parameter.
@@ -532,21 +526,18 @@ public abstract class AbstractSurefireMojo
     protected int threadCountSuites;
 
     /**
-     * (JUnit 4.7 provider) The attribute thread-count-classes allows you to specify the concurrency in test classes, i.e.:
+     * (JUnit 4.7 provider) This attribute allows you to specify the concurrency in test classes, i.e.:
      * <ul>
-     *  <li>number of threads executing JUnit test classes if <code>threadCount</code> is 0 or unspecified</li>
-     *  <li>In a special case <code>threadCountClasses</code> and <code>threadCount</code> are specified
-     *      without <code>threadCountMethods</code> for <code>parallel</code>=<code>classesAndMethods</code>.
-     *      <br/>Example1: threadCount=8 and threadCountClasses=3, the number of parallel methods is varying from 5 to 7 in your tests.
-     *      <br/>In another special case when <code>parallel</code>=<code>all</code> and the only <code>threadCountMethods</code>
-     *      is unspecified, then threads from suites and classes are reused in favor of methods.
-     *      <br/>Example2: parallel=all, threadCount=16 , threadCountSuites=2 , threadCountClasses=5,
-     *      the number of parallel methods is varying from 9 to 14 in your tests.
+     *  <li>number of concurrent classes if <code>threadCount</code> is 0 or unspecified</li>
+     *  <li>limited classes concurrency if <code>useUnlimitedThreads</code> is set to <strong>true</strong></li>
+     *  <li>if <code>threadCount</code> and certain thread-count parameters are &gt; 0 for <code>parallel</code>, the
+     *  concurrency is computed from ratio. For instance parallel=all and the ratio between
+     *      <code>threadCountSuites</code>:<em>threadCountClasses</em>:<code>threadCountMethods</code> is
+     *      2:<em>3</em>:5, there is 30% of <code>threadCount</code> in concurrent classes.</li>
+     *  <li>as in the previous case but without this leaf thread-count. Example: parallel=suitesAndClasses,
+     *  threadCount=16, threadCountSuites=5, threadCountClasses is unspecified leaf, the number of concurrent classes
+     *  is varying from &gt;= 11 to 14 or 15. The threadCountSuites become number of threads.
      *  </li>
-     *  <li>integer number which represents the weight in ratio between
-     *      <code>threadCountSuites</code>:<em>threadCountClasses</em>:<code>threadCountMethods</code>.
-     *      As an example 3 is 30% of <code>threadCount</code> if the ratio is 2:<em>3</em>:5</li>
-     *  <li>You can impose limitation on parallel classes if <code>useUnlimitedThreads</code> is specified.</li>
      * </ul>
      *
      * Only makes sense to use in conjunction with the <code>parallel</code> parameter.
@@ -558,12 +549,18 @@ public abstract class AbstractSurefireMojo
     protected int threadCountClasses;
 
     /**
-     * (JUnit 4.7 provider) The attribute thread-count-methods allows you to specify the concurrency in test methods, i.e.:
+     * (JUnit 4.7 provider) This attribute allows you to specify the concurrency in test methods, i.e.:
      * <ul>
-     *  <li>number of threads executing JUnit test methods if <code>threadCount</code> is 0 or unspecified;</li>
-     *  <li>integer number which represents the weight in ratio between <code>threadCountSuites</code>:<code>threadCountClasses</code>:<em>threadCountMethods</em>.
-     *      As an example 5 is 50% of <code>threadCount</code> if the ratio is 2:3:<em>5</em>.</li>
-     *  <li>You can impose limitation on parallel methods if <code>useUnlimitedThreads</code> is specified.</li>
+     *  <li>number of concurrent methods if <code>threadCount</code> is 0 or unspecified</li>
+     *  <li>limited concurrency of methods if <code>useUnlimitedThreads</code> is set to <strong>true</strong></li>
+     *  <li>if <code>threadCount</code> and certain thread-count parameters are &gt; 0 for <code>parallel</code>, the
+     *  concurrency is computed from ratio. For instance parallel=all and the ratio between
+     *      <code>threadCountSuites</code>:<code>threadCountClasses</code>:<em>threadCountMethods</em> is
+     *      2:3:<em>5</em>, there is 50% of <code>threadCount</code> in concurrent methods.</li>
+     *  <li>as in the previous case but without this leaf thread-count. Example: parallel=all, threadCount=16,
+     *  threadCountSuites=2, threadCountClasses=3, but threadCountMethods is unspecified leaf, the number of concurrent
+     *  methods is varying from &gt;= 11 to 14 or 15. The threadCountSuites and threadCountClasses become number of threads.
+     *  </li>
      * </ul>
      *
      * Only makes sense to use in conjunction with the <code>parallel</code> parameter.

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/aff26226/maven-surefire-plugin/src/site/apt/examples/fork-options-and-parallel-execution.apt.vm
----------------------------------------------------------------------
diff --git a/maven-surefire-plugin/src/site/apt/examples/fork-options-and-parallel-execution.apt.vm b/maven-surefire-plugin/src/site/apt/examples/fork-options-and-parallel-execution.apt.vm
index 6e9f15c..d9a6c6a 100644
--- a/maven-surefire-plugin/src/site/apt/examples/fork-options-and-parallel-execution.apt.vm
+++ b/maven-surefire-plugin/src/site/apt/examples/fork-options-and-parallel-execution.apt.vm
@@ -67,7 +67,7 @@ Fork Options and Parallel Test Execution
   <<<threadCountClasses>>> or <<<threadCountMethods>>>.
   If the only <<<threadCount>>> is specified, the surefire attempts to estimate
   thread-counts for suites, classes and methods and reuse the threads in favor
-  of parallel methods (possibly increasing concurrent methods).
+  of a leaf, e.g. parallel methods (possibly increasing concurrent methods).
   
   As an example with unlimited number of threads, there is maximum of three
   concurrent threads to execute suites:
@@ -77,8 +77,8 @@ Fork Options and Parallel Test Execution
   limited:
   parallel = classesAndMethods, threadCount = 8, threadCountClasses = 3.
   Here the number of parallel methods is varying from 5 to 7.
-  Similarily with parallel = all, but the sum of <<<threadCountSuites>>> and
-  <<<threadCountClasses>>> must not excit certain <<<threadCount>>> - 1.
+  Accordingly parallel = all, but the sum of <<<threadCountSuites>>> and
+  <<<threadCountClasses>>> must not exceed certain (<<<threadCount>>> - 1).
   Other combinations are possible with unspecified thread-count leaf. Make sure
   that the leaf is last from the order suites-classes-methods in <<<parallel>>>.
   
@@ -148,7 +148,7 @@ Fork Options and Parallel Test Execution
   builds, i.e. the effective value of the <<<-T>>> command line argument of 
   maven core.
 
-  In case forkig is disabled (<<<forkCount=0>>>), the place holder will be
+  In case of disabled forking (<<<forkCount=0>>>), the place holder will be
   replaced with <1>.
 
   The following is an example configuration that makes use of up to three forked


[03/11] PC optimization refactoring (Only unit tests. Missing IT tests refactoring.)

Posted by ag...@apache.org.
http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java
deleted file mode 100644
index 6803265..0000000
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/ParallelComputerFactoryTest.java
+++ /dev/null
@@ -1,1063 +0,0 @@
-package org.apache.maven.surefire.junitcore;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License 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.
- */
-
-import org.apache.maven.surefire.junitcore.pc.ParallelComputer;
-import org.apache.maven.surefire.testset.TestSetFailedException;
-import org.junit.AfterClass;
-import org.junit.BeforeClass;
-import org.junit.Rule;
-import org.junit.Test;
-import org.junit.experimental.theories.DataPoint;
-import org.junit.experimental.theories.Theories;
-import org.junit.experimental.theories.Theory;
-import org.junit.rules.ExpectedException;
-import org.junit.runner.JUnitCore;
-import org.junit.runner.Result;
-import org.junit.runner.RunWith;
-
-import java.util.Properties;
-import java.util.concurrent.ExecutionException;
-
-import static org.apache.maven.surefire.junitcore.ParallelComputerFactory.*;
-import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.*;
-import static org.hamcrest.core.Is.is;
-import static org.junit.Assert.*;
-
-/**
- * Testing an algorithm in {@link ParallelComputerFactory} which configures
- * allocated thread resources in ParallelComputer by given {@link JUnitCoreParameters}.
- *
- * @author Tibor Digana (tibor17)
- * @see org.apache.maven.surefire.junitcore.ParallelComputerFactory
- * @since 2.16
- */
-@RunWith( Theories.class )
-public final class ParallelComputerFactoryTest
-{
-    @DataPoint
-    public static final int CPU_1 = 1;
-
-    @DataPoint
-    public static final int CPU_4 = 4;
-
-    @Rule
-    public final ExpectedException exception = ExpectedException.none();
-
-    @Rule
-    public final Stopwatch runtime = new Stopwatch();
-
-    @BeforeClass
-    public static void beforeClass()
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( 1 );
-    }
-
-    @AfterClass
-    public static void afterClass()
-    {
-        ParallelComputerFactory.setDefaultAvailableProcessors();
-    }
-
-    private static Properties parallel( String parallel )
-    {
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, parallel );
-        return properties;
-    }
-
-    @Test
-    public void unknownParallel()
-        throws TestSetFailedException
-    {
-        Properties properties = new Properties();
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( new JUnitCoreParameters( properties ), null );
-    }
-
-    @Test
-    public void unknownThreadCountSuites()
-        throws TestSetFailedException
-    {
-        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suites" ) );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params, null );
-    }
-
-    @Test
-    public void unknownThreadCountClasses()
-        throws TestSetFailedException
-    {
-        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classes" ) );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params, null );
-    }
-
-    @Test
-    public void unknownThreadCountMethods()
-        throws TestSetFailedException
-    {
-        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "methods" ) );
-        assertFalse( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params, null );
-    }
-
-    @Test
-    public void unknownThreadCountBoth()
-        throws TestSetFailedException
-    {
-        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "both" ) );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params, null );
-    }
-
-    @Test
-    public void unknownThreadCountAll()
-        throws TestSetFailedException
-    {
-        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "all" ) );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params, null );
-    }
-
-    @Test
-    public void unknownThreadCountSuitesAndClasses()
-        throws TestSetFailedException
-    {
-        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndClasses" ) );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params, null );
-    }
-
-    @Test
-    public void unknownThreadCountSuitesAndMethods()
-        throws TestSetFailedException
-    {
-        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "suitesAndMethods" ) );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params, null );
-    }
-
-    @Test
-    public void unknownThreadCountClassesAndMethods()
-        throws TestSetFailedException
-    {
-        JUnitCoreParameters params = new JUnitCoreParameters( parallel( "classesAndMethods" ) );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        exception.expect( TestSetFailedException.class );
-        resolveConcurrency( params, null );
-    }
-
-    @Theory
-    public void useUnlimitedThreadsSuites( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suites" );
-        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 0 ) );
-
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void useUnlimitedThreadsClasses( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classes" );
-        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( 0 ) );
-
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 5 * cpu ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void unlimitedThreadsMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "methods" );
-        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "5" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 5 * cpu ) );
-    }
-
-    @Theory
-    public void unlimitedThreadsSuitesAndClasses( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
-        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( 0 ) );
-
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 15 * cpu ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void unlimitedThreadsSuitesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
-        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 15 * cpu ) );
-    }
-
-    @Theory
-    public void unlimitedThreadsClassesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
-        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 5 * cpu ) );
-        assertThat( concurrency.methods, is( 15 * cpu ) );
-    }
-
-    @Theory
-    public void unlimitedThreadsAll( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( USEUNLIMITEDTHREADS_KEY, "true" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "30" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 15 * cpu ) );
-        assertThat( concurrency.methods, is( 30 * cpu ) );
-    }
-
-    @Theory
-    public void threadCountSuites( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suites" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 0 ) );
-        assertThat( concurrency.suites, is( 3 * cpu ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void threadCountClasses( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classes" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 0 ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 3 * cpu ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void threadCountMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "methods" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 0 ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 3 * cpu ) );
-    }
-
-    @Theory
-    public void threadCountBoth( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "both" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void threadCountClassesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( (int) ( ( 3d / 2 ) * cpu ) ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void threadCountSuitesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void threadCountSuitesAndClasses( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( (int) ( ( 3d / 2 ) * cpu ) ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void threadCountAll( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( cpu ) );
-        assertThat( concurrency.classes, is( cpu ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void everyThreadCountSuitesAndClasses( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        // % percentage ratio
-        properties.setProperty( THREADCOUNTSUITES_KEY, "34" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "66" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
-        assertThat( concurrency.suites, is( concurrentSuites ) );
-        assertThat( concurrency.classes, is( concurrency.capacity - concurrentSuites ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void everyThreadCountSuitesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        // % percentage ratio
-        properties.setProperty( THREADCOUNTSUITES_KEY, "34" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "66" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        int concurrentSuites = (int) ( 0.34d * concurrency.capacity );
-        assertThat( concurrency.suites, is( concurrentSuites ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( concurrency.capacity - concurrentSuites ) );
-    }
-
-    @Theory
-    public void everyThreadCountClassesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        // % percentage ratio
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "34" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "66" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
-        assertThat( concurrency.classes, is( concurrentClasses ) );
-        assertThat( concurrency.methods, is( concurrency.capacity - concurrentClasses ) );
-    }
-
-    @Theory
-    public void everyThreadCountAll( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( THREADCOUNT_KEY, "3" );
-        // % percentage ratio
-        properties.setProperty( THREADCOUNTSUITES_KEY, "17" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "34" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "49" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 3 * cpu ) );
-        int concurrentSuites = (int) ( 0.17d * concurrency.capacity );
-        int concurrentClasses = (int) ( 0.34d * concurrency.capacity );
-        assertThat( concurrency.suites, is( concurrentSuites ) );
-        assertThat( concurrency.classes, is( concurrentClasses ) );
-        assertThat( concurrency.methods, is( concurrency.capacity - concurrentSuites - concurrentClasses ) );
-    }
-
-    @Theory
-    public void reusableThreadCountSuitesAndClasses( int cpu )
-        throws TestSetFailedException
-    {
-        // 4 * cpu to 5 * cpu threads to run test classes
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
-        properties.setProperty( THREADCOUNT_KEY, "6" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 6 * cpu ) );
-        assertThat( concurrency.suites, is( 2 * cpu ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void reusableThreadCountSuitesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        // 4 * cpu to 5 * cpu threads to run test methods
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "6" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 6 * cpu ) );
-        assertThat( concurrency.suites, is( 2 * cpu ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void reusableThreadCountClassesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        // 4 * cpu to 5 * cpu threads to run test methods
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
-        properties.setProperty( THREADCOUNT_KEY, "6" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "2" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 6 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 2 * cpu ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void reusableThreadCountAll( int cpu )
-        throws TestSetFailedException
-    {
-        // 8 * cpu to 13 * cpu threads to run test methods
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( THREADCOUNT_KEY, "14" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "4" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 14 * cpu ) );
-        assertThat( concurrency.suites, is( 2 * cpu ) );
-        assertThat( concurrency.classes, is( 4 * cpu ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void suites( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suites" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 5 * cpu ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void classes( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classes" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 5 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 5 * cpu ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void methods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "methods" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "5" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 5 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 5 * cpu ) );
-    }
-
-    @Theory
-    public void suitesAndClasses( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-
-        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 20 * cpu ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 15 * cpu ) );
-        assertThat( concurrency.methods, is( 0 ) );
-
-        // Warning: this case works but is not enabled in AbstractSurefireMojo
-        // Instead use the 'useUnlimitedThreads' parameter.
-        properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertFalse( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.methods, is( 0 ) );
-    }
-
-    @Theory
-    public void suitesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-
-        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 20 * cpu ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( 15 * cpu ) );
-
-        // Warning: this case works but is not enabled in AbstractSurefireMojo
-        // Instead use the 'useUnlimitedThreads' parameter.
-        properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertFalse( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 0 ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void classesAndMethods( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-
-        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "15" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 20 * cpu ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 5 * cpu ) );
-        assertThat( concurrency.methods, is( 15 * cpu ) );
-
-        // Warning: this case works but is not enabled in AbstractSurefireMojo
-        // Instead use the 'useUnlimitedThreads' parameter.
-        properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "5" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertFalse( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 0 ) );
-        assertThat( concurrency.classes, is( 5 * cpu ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Theory
-    public void all( int cpu )
-        throws TestSetFailedException
-    {
-        ParallelComputerFactory.overrideAvailableProcessors( cpu );
-        Properties properties = new Properties();
-
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "30" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        Concurrency concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( 50 * cpu ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 15 * cpu ) );
-        assertThat( concurrency.methods, is( 30 * cpu ) );
-
-        // Warning: these cases work but they are not enabled in AbstractSurefireMojo
-        // Instead use the 'useUnlimitedThreads' parameter.
-        properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( THREADCOUNTSUITES_KEY, "5" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( 5 * cpu ) );
-        assertThat( concurrency.classes, is( 15 * cpu ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-
-        properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "all" );
-        properties.setProperty( THREADCOUNTCLASSES_KEY, "15" );
-        params = new JUnitCoreParameters( properties );
-        concurrency = resolveConcurrency( params, null );
-        assertTrue( params.isParallelSuites() );
-        assertTrue( params.isParallelClasses() );
-        assertTrue( params.isParallelMethods() );
-        assertThat( concurrency.capacity, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.suites, is( Integer.MAX_VALUE ) );
-        assertThat( concurrency.classes, is( 15 * cpu ) );
-        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
-    }
-
-    @Test
-    public void withoutShutdown()
-        throws TestSetFailedException, ExecutionException, InterruptedException
-    {
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "methods" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        ParallelComputer pc = createParallelComputer( params, null );
-
-        Result result = new JUnitCore().run( pc, TestClass.class );
-        long timeSpent = runtime.stop();
-        long deltaTime = 500L;
-
-        assertTrue( result.wasSuccessful() );
-        assertThat( result.getRunCount(), is( 3 ) );
-        assertThat( result.getFailureCount(), is( 0 ) );
-        assertThat( result.getIgnoreCount(), is( 0 ) );
-        assertEquals( 10000L, timeSpent, deltaTime );
-    }
-
-    @Test
-    public void shutdown()
-        throws TestSetFailedException, ExecutionException, InterruptedException
-    {
-        // The JUnitCore returns after 2.5s.
-        // The test-methods in TestClass are NOT interrupted, and return normally after 5s.
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "methods" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
-        properties.setProperty( PARALLEL_TIMEOUT_KEY, Double.toString( 2.5d ) );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        ParallelComputer pc = createParallelComputer( params, null );
-
-        new JUnitCore().run( pc, TestClass.class );
-        long timeSpent = runtime.stop();
-        long deltaTime = 500L;
-
-        assertEquals( 2500L, timeSpent, deltaTime );
-        assertTrue( pc.describeElapsedTimeout().contains(
-            "The test run has finished abruptly after timeout of 2.5 seconds." ) );
-        assertTrue( pc.describeElapsedTimeout().contains( TestClass.class.getName() ) );
-    }
-
-    @Test
-    public void forcedShutdown()
-        throws TestSetFailedException, ExecutionException, InterruptedException
-    {
-        // The JUnitCore returns after 2.5s, and the test-methods in TestClass are interrupted.
-        Properties properties = new Properties();
-        properties.setProperty( PARALLEL_KEY, "methods" );
-        properties.setProperty( THREADCOUNTMETHODS_KEY, "2" );
-        properties.setProperty( PARALLEL_TIMEOUTFORCED_KEY, Double.toString( 2.5d ) );
-        JUnitCoreParameters params = new JUnitCoreParameters( properties );
-        ParallelComputer pc = createParallelComputer( params, null );
-
-        new JUnitCore().run( pc, TestClass.class );
-        long timeSpent = runtime.stop();
-        long deltaTime = 500L;
-
-        assertEquals( 2500L, timeSpent, deltaTime );
-        assertTrue( pc.describeElapsedTimeout().contains(
-            "The test run has finished abruptly after timeout of 2.5 seconds." ) );
-        assertTrue( pc.describeElapsedTimeout().contains( TestClass.class.getName() ) );
-    }
-
-    public static class TestClass
-    {
-        @Test
-        public void a()
-            throws InterruptedException
-        {
-            long t1 = System.currentTimeMillis();
-            try{
-                Thread.sleep( 5000L );
-            }
-            finally
-            {
-                System.out.println( getClass().getSimpleName() + "#a() spent " + ( System.currentTimeMillis() - t1 ) );
-            }
-        }
-
-        @Test
-        public void b()
-            throws InterruptedException
-        {
-            long t1 = System.currentTimeMillis();
-            try{
-                Thread.sleep( 5000L );
-            }
-            finally
-            {
-                System.out.println( getClass().getSimpleName() + "#b() spent " + ( System.currentTimeMillis() - t1 ) );
-            }
-        }
-
-        @Test
-        public void c()
-            throws InterruptedException
-        {
-            long t1 = System.currentTimeMillis();
-            try{
-                Thread.sleep( 5000L );
-            }
-            finally
-            {
-                System.out.println( getClass().getSimpleName() + "#c() spent " + ( System.currentTimeMillis() - t1 ) );
-            }
-        }
-    }
-}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Stopwatch.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Stopwatch.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Stopwatch.java
deleted file mode 100644
index 558fc06..0000000
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/Stopwatch.java
+++ /dev/null
@@ -1,46 +0,0 @@
-package org.apache.maven.surefire.junitcore;
-
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License 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.
- */
-
-import org.junit.rules.TestWatchman;
-import org.junit.runners.model.FrameworkMethod;
-
-import java.util.concurrent.TimeUnit;
-
-/**
- * @author Tibor Digana (tibor17)
- * @since 2.16
- */
-public final class Stopwatch
-    extends TestWatchman
-{
-    private long startNanos;
-
-    public long stop()
-    {
-        return TimeUnit.MILLISECONDS.convert( System.nanoTime() - startNanos, TimeUnit.NANOSECONDS );
-    }
-
-    @Override
-    public void starting( FrameworkMethod method )
-    {
-        startNanos = System.nanoTime();
-    }
-}

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/OptimizedParallelComputerTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/OptimizedParallelComputerTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/OptimizedParallelComputerTest.java
new file mode 100644
index 0000000..7860f9f
--- /dev/null
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/OptimizedParallelComputerTest.java
@@ -0,0 +1,323 @@
+package org.apache.maven.surefire.junitcore.pc;
+
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License 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.
+ */
+
+import org.apache.maven.surefire.junitcore.JUnitCoreParameters;
+import org.apache.maven.surefire.testset.TestSetFailedException;
+import org.junit.AfterClass;
+import org.junit.BeforeClass;
+import org.junit.Rule;
+import org.junit.experimental.theories.DataPoint;
+import org.junit.experimental.theories.Theories;
+import org.junit.experimental.theories.Theory;
+import org.junit.rules.ExpectedException;
+import org.junit.runner.RunWith;
+
+import java.util.Properties;
+
+import static org.apache.maven.surefire.junitcore.JUnitCoreParameters.*;
+import static org.apache.maven.surefire.junitcore.pc.ParallelComputerUtil.*;
+import static org.hamcrest.core.Is.is;
+import static org.junit.Assert.*;
+
+/**
+ * Testing an algorithm in {@link ParallelComputerUtil} which configures
+ * optimized thread resources in ParallelComputer by given {@link org.apache.maven.surefire.junitcore.JUnitCoreParameters}.
+ *
+ * @author Tibor Digana (tibor17)
+ * @see ParallelComputerUtil
+ * @since 2.17
+ */
+@RunWith( Theories.class )
+public final class OptimizedParallelComputerTest
+{
+    @DataPoint
+    public static final int CPU_1 = 1;
+
+    @DataPoint
+    public static final int CPU_4 = 4;
+
+    @Rule
+    public final ExpectedException exception = ExpectedException.none();
+
+    @Rule
+    public final Stopwatch runtime = new Stopwatch();
+
+    @BeforeClass
+    public static void beforeClass()
+    {
+        overrideAvailableProcessors( 1 );
+    }
+
+    @AfterClass
+    public static void afterClass()
+    {
+        setDefaultAvailableProcessors();
+    }
+
+    @Theory
+    public void threadCountSuites( int cpu )
+        throws TestSetFailedException
+    {
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suites" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 5, 10, 20 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( (int) Math.min( 3 * cpu, counter.suites ) ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountClasses( int cpu )
+        throws TestSetFailedException
+    {
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classes" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 1, 5, 10 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( (int) Math.min( 3 * cpu, counter.classes ) ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountMethods( int cpu )
+        throws TestSetFailedException
+    {
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "methods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 0 ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( (int) Math.min( 3 * cpu, counter.methods ) ) );
+    }
+
+    @Theory
+    public void threadCountBoth( int cpu )
+        throws TestSetFailedException
+    {
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "both" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountClassesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 1, 2, 5 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountSuitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 2, 3, 5 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( (int) Math.min( ( 3d / 2 ) * cpu, 2 ) ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void threadCountSuitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 7 ) * cpu, 2 ) ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void threadCountAll( int cpu )
+        throws TestSetFailedException
+    {
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNT_KEY, "3" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 2, 5, 20 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 3 * cpu ) );
+        assertThat( concurrency.suites, is( (int) Math.min( ( 2d * 3 / 11 ) * cpu, 2 ) ) );
+        assertThat( concurrency.classes, is( (int) Math.min( ( 5d * 3 / 11 ) * cpu, 5 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void reusableThreadCountSuitesAndClasses( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test classes
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndClasses" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertFalse( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
+        assertThat( concurrency.classes, is( Integer.MAX_VALUE ) );
+        assertThat( concurrency.methods, is( 0 ) );
+    }
+
+    @Theory
+    public void reusableThreadCountSuitesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test methods
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "suitesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertFalse( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
+        assertThat( concurrency.classes, is( 0 ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void reusableThreadCountClassesAndMethods( int cpu )
+        throws TestSetFailedException
+    {
+        // 4 * cpu to 5 * cpu threads to run test methods
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "classesAndMethods" );
+        properties.setProperty( THREADCOUNT_KEY, "6" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "2" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertFalse( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 6 * cpu ) );
+        assertThat( concurrency.suites, is( 0 ) );
+        assertThat( concurrency.classes, is( Math.min( 2 * cpu, 5 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+
+    @Theory
+    public void reusableThreadCountAll( int cpu )
+        throws TestSetFailedException
+    {
+        // 8 * cpu to 13 * cpu threads to run test methods
+        overrideAvailableProcessors( cpu );
+        Properties properties = new Properties();
+        properties.setProperty( PARALLEL_KEY, "all" );
+        properties.setProperty( THREADCOUNT_KEY, "14" );
+        properties.setProperty( THREADCOUNTSUITES_KEY, "2" );
+        properties.setProperty( THREADCOUNTCLASSES_KEY, "4" );
+        JUnitCoreParameters params = new JUnitCoreParameters( properties );
+        RunnerCounter counter = new RunnerCounter( 3, 5, 20 );
+        Concurrency concurrency = resolveConcurrency( params, counter );
+        assertTrue( params.isParallelSuites() );
+        assertTrue( params.isParallelClasses() );
+        assertTrue( params.isParallelMethods() );
+        assertThat( concurrency.capacity, is( 14 * cpu ) );
+        assertThat( concurrency.suites, is( Math.min( 2 * cpu, 3 ) ) );
+        assertThat( concurrency.classes, is( Math.min( 4 * cpu, 5 ) ) );
+        assertThat( concurrency.methods, is( Integer.MAX_VALUE ) );
+    }
+}
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/maven-surefire/blob/01c39b01/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java
----------------------------------------------------------------------
diff --git a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java
index 4dda465..e3fbf3a 100644
--- a/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java
+++ b/surefire-providers/surefire-junit47/src/test/java/org/apache/maven/surefire/junitcore/pc/ParallelComputerBuilderTest.java
@@ -19,7 +19,6 @@ package org.apache.maven.surefire.junitcore.pc;
  * under the License.
  */
 
-import org.apache.maven.surefire.junitcore.Stopwatch;
 import org.junit.AfterClass;
 import org.junit.Before;
 import org.junit.BeforeClass;
@@ -103,6 +102,8 @@ public class ParallelComputerBuilderTest
         // and next thread may be reused from finished class, however the capacity is 3.
         parallelComputerBuilder.parallelMethods( 3 );
 
+        assertFalse( parallelComputerBuilder.isOptimized() );
+
         ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
         Result result = new JUnitCore().run( computer, TestSuite.class );
         long timeSpent = runtime.stop();
@@ -136,6 +137,7 @@ public class ParallelComputerBuilderTest
         parallelComputerBuilder.parallelSuites( 5 );
         parallelComputerBuilder.parallelClasses( 5 );
         parallelComputerBuilder.parallelMethods( 3 );
+        assertFalse( parallelComputerBuilder.isOptimized() );
 
         ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
         Result result = new JUnitCore().run( computer, TestSuite.class, Class1.class );
@@ -161,6 +163,7 @@ public class ParallelComputerBuilderTest
         parallelComputerBuilder.parallelSuites( 2 );
         parallelComputerBuilder.parallelClasses( 4 );
         parallelComputerBuilder.parallelMethods();
+        assertFalse( parallelComputerBuilder.isOptimized() );
 
         ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
         Result result = new JUnitCore().run( computer, TestSuite.class, Class1.class );
@@ -192,6 +195,8 @@ public class ParallelComputerBuilderTest
         // One thread remains from '#useOnePool(3)'.
         parallelComputerBuilder.parallelMethods( 3 );
 
+        assertFalse( parallelComputerBuilder.isOptimized() );
+
         ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
         Result result = new JUnitCore().run( computer, TestSuite.class );
         long timeSpent = runtime.stop();
@@ -214,6 +219,7 @@ public class ParallelComputerBuilderTest
         parallelComputerBuilder.parallelSuites( 5 );
         parallelComputerBuilder.parallelClasses( 5 );
         parallelComputerBuilder.parallelMethods( 3 );
+        assertFalse( parallelComputerBuilder.isOptimized() );
 
         ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
         Result result = new JUnitCore().run( computer, TestSuite.class );
@@ -237,6 +243,7 @@ public class ParallelComputerBuilderTest
         parallelComputerBuilder.parallelSuites( 5 );
         parallelComputerBuilder.parallelClasses( 5 );
         parallelComputerBuilder.parallelMethods( 3 );
+        assertFalse( parallelComputerBuilder.isOptimized() );
 
         // 6 methods altogether.
         // 2 groups with 3 threads.
@@ -263,6 +270,7 @@ public class ParallelComputerBuilderTest
         parallelComputerBuilder.parallelSuites( 5 );
         parallelComputerBuilder.parallelClasses( 1 );
         parallelComputerBuilder.parallelMethods( 3 );
+        assertFalse( parallelComputerBuilder.isOptimized() );
 
         ParallelComputerBuilder.PC computer = (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();
         Result result = new JUnitCore().run( computer, TestSuite.class, Class1.class );
@@ -303,6 +311,7 @@ public class ParallelComputerBuilderTest
     {
         JUnitCore core = new JUnitCore();
         ParallelComputerBuilder builder = new ParallelComputerBuilder();
+        assertFalse( builder.isOptimized() );
 
         Result result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingTest2.class );
         assertTrue( result.wasSuccessful() );
@@ -310,30 +319,44 @@ public class ParallelComputerBuilderTest
         result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingSuite.class );
         assertTrue( result.wasSuccessful() );
 
-        result = core.run( builder.useOnePool( 1 ).buildComputer(), NothingDoingTest1.class, NothingDoingTest2.class );
+        builder.useOnePool( 1 );
+        assertFalse( builder.isOptimized() );
+        result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingTest2.class );
         assertTrue( result.wasSuccessful() );
 
-        result = core.run( builder.useOnePool( 1 ).buildComputer(), NothingDoingTest1.class, NothingDoingSuite.class );
+        builder.useOnePool( 1 );
+        assertFalse( builder.isOptimized() );
+        result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingSuite.class );
         assertTrue( result.wasSuccessful() );
 
-        result = core.run( builder.useOnePool( 2 ).buildComputer(), NothingDoingTest1.class, NothingDoingSuite.class );
+        builder.useOnePool( 2 );
+        assertFalse( builder.isOptimized() );
+        result = core.run( builder.buildComputer(), NothingDoingTest1.class, NothingDoingSuite.class );
         assertTrue( result.wasSuccessful() );
 
         Class<?>[] classes = { NothingDoingTest1.class, NothingDoingSuite.class };
 
-        result = core.run( builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses( 1 ).buildComputer(), classes );
+        builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses( 1 );
+        assertFalse( builder.isOptimized() );
+        result = core.run( builder.buildComputer(), classes );
         assertTrue( result.wasSuccessful() );
 
-        result = core.run( builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses().buildComputer(), classes );
+        builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses();
+        assertFalse( builder.isOptimized() );
+        result = core.run( builder.buildComputer(), classes );
         assertTrue( result.wasSuccessful() );
 
         classes = new Class<?>[]{ NothingDoingSuite.class, NothingDoingSuite.class, NothingDoingTest1.class,
             NothingDoingTest2.class, NothingDoingTest3.class };
 
-        result = core.run( builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses( 1 ).buildComputer(), classes );
+        builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses( 1 );
+        assertFalse( builder.isOptimized() );
+        result = core.run( builder.buildComputer(), classes );
         assertTrue( result.wasSuccessful() );
 
-        result = core.run( builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses().buildComputer(), classes );
+        builder.useOnePool( 2 ).parallelSuites( 1 ).parallelClasses();
+        assertFalse( builder.isOptimized() );
+        result = core.run( builder.buildComputer(), classes );
         assertTrue( result.wasSuccessful() );
     }
 
@@ -342,6 +365,7 @@ public class ParallelComputerBuilderTest
     {
         ParallelComputerBuilder builder = new ParallelComputerBuilder();
         builder.parallelMethods();
+        assertFalse( builder.isOptimized() );
         testKeepBeforeAfter( builder, NothingDoingTest1.class );
     }
 
@@ -350,6 +374,7 @@ public class ParallelComputerBuilderTest
     {
         ParallelComputerBuilder builder = new ParallelComputerBuilder();
         builder.useOnePool( 5 ).parallelClasses( 1 ).parallelMethods( 2 );
+        assertFalse( builder.isOptimized() );
         testKeepBeforeAfter( builder, NothingDoingTest1.class, NothingDoingTest2.class );
     }
 
@@ -358,6 +383,7 @@ public class ParallelComputerBuilderTest
     {
         ParallelComputerBuilder builder = new ParallelComputerBuilder();
         builder.useOnePool( 8 ).parallelClasses( 2 ).parallelMethods( 2 );
+        assertFalse( builder.isOptimized() );
         JUnitCore core = new JUnitCore();
         NothingDoingTest1.methods.clear();
         Class<?>[] classes = { NothingDoingTest1.class, NothingDoingTest2.class, NothingDoingTest3.class };
@@ -376,6 +402,7 @@ public class ParallelComputerBuilderTest
             parallelComputerBuilder.parallelSuites( 2 );
             parallelComputerBuilder.parallelClasses( 3 );
             parallelComputerBuilder.parallelMethods( 3 );
+            assertFalse( parallelComputerBuilder.isOptimized() );
 
             final ParallelComputerBuilder.PC computer =
                 (ParallelComputerBuilder.PC) parallelComputerBuilder.buildComputer();