maven-surefire-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From krosenv...@apache.org
Subject svn commit: r1099576 - in /maven/surefire/trunk: maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/ maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/ maven-surefire-common/src/test/java/org/apache/maven/plugin/sur...
Date Wed, 04 May 2011 19:54:41 GMT
Author: krosenvold
Date: Wed May  4 19:54:41 2011
New Revision: 1099576

URL: http://svn.apache.org/viewvc?rev=1099576&view=rev
Log:
o Reduced duplication in mojos, extracted nice methods

Patch by Stefan Birkner, submitted via github. Reformatted to IntelliJ maven template by me, otherwise
unchanged

Added:
    maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/Summary.java   (with props)
    maven/surefire/trunk/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SummaryTest.java   (with props)
Modified:
    maven/surefire/trunk/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
    maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
    maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java

Modified: maven/surefire/trunk/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java?rev=1099576&r1=1099575&r2=1099576&view=diff
==============================================================================
--- maven/surefire/trunk/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java (original)
+++ maven/surefire/trunk/maven-failsafe-plugin/src/main/java/org/apache/maven/plugin/failsafe/IntegrationTestMojo.java Wed May  4 19:54:41 2011
@@ -26,7 +26,6 @@ import java.io.IOException;
 import java.io.OutputStreamWriter;
 import java.io.Writer;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -38,15 +37,10 @@ import org.apache.maven.execution.MavenS
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.surefire.AbstractSurefireMojo;
-import org.apache.maven.plugin.surefire.ProviderInfo;
+import org.apache.maven.plugin.surefire.Summary;
 import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
-import org.apache.maven.plugin.surefire.booterclient.ForkConfiguration;
-import org.apache.maven.plugin.surefire.booterclient.ForkStarter;
 import org.apache.maven.project.MavenProject;
-import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
 import org.apache.maven.surefire.booter.ProviderConfiguration;
-import org.apache.maven.surefire.booter.SurefireBooterForkException;
-import org.apache.maven.surefire.booter.SurefireExecutionException;
 import org.apache.maven.surefire.failsafe.model.FailsafeSummary;
 import org.apache.maven.surefire.failsafe.model.io.xpp3.FailsafeSummaryXpp3Writer;
 import org.apache.maven.surefire.suite.RunResult;
@@ -80,8 +74,8 @@ public class IntegrationTestMojo
     private boolean skipTests;
 
     /**
-     * Set this to "true" to skip running integration tests, but still compile them. Its use is NOT RECOMMENDED, but quite
-     * convenient on occasion.
+     * Set this to "true" to skip running integration tests, but still compile them. Its use is NOT RECOMMENDED, but
+     * quite convenient on occasion.
      *
      * @parameter expression="${skipITs}"
      * @since 2.4.3-alpha-2
@@ -98,9 +92,9 @@ public class IntegrationTestMojo
     private boolean skipExec;
 
     /**
-     * Set this to "true" to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you
-     * enable it using the "maven.test.skip" property, because maven.test.skip disables both running the
-     * tests and compiling the tests.  Consider using the <code>skipTests parameter</code> instead.
+     * Set this to "true" to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you enable it using
+     * the "maven.test.skip" property, because maven.test.skip disables both running the tests and compiling the tests.
+     * Consider using the <code>skipTests parameter</code> instead.
      *
      * @parameter default-value="false" expression="${maven.test.skip}"
      */
@@ -115,16 +109,16 @@ public class IntegrationTestMojo
     private File basedir;
 
     /**
-     * The directory containing generated test classes of the project being tested.
-     * This will be included at the beginning of the test classpath.
+     * The directory containing generated test classes of the project being tested. This will be included at the
+     * beginning of the test classpath.
      *
      * @parameter default-value="${project.build.testOutputDirectory}"
      */
     private File testClassesDirectory;
 
     /**
-     * The directory containing generated classes of the project being tested.
-     * This will be included after the test classes in the test classpath.
+     * The directory containing generated classes of the project being tested. This will be included after the test
+     * classes in the test classpath.
      *
      * @parameter default-value="${project.build.outputDirectory}"
      */
@@ -139,9 +133,8 @@ public class IntegrationTestMojo
     private MavenProject project;
 
     /**
-     * List of dependencies to exclude from the test classpath.
-     * Each dependency string must follow the format <i>groupId:artifactId</i>.
-     * For example: <i>org.acme:project-a</i>
+     * List of dependencies to exclude from the test classpath. Each dependency string must follow the format
+     * <i>groupId:artifactId</i>. For example: <i>org.acme:project-a</i>
      *
      * @parameter
      * @since 2.6
@@ -149,9 +142,8 @@ public class IntegrationTestMojo
     private List classpathDependencyExcludes;
 
     /**
-     * A dependency scope to exclude from the test classpath.
-     * The scope should be one of the scopes defined by org.apache.maven.artifact.Artifact.
-     * This includes the following:
+     * A dependency scope to exclude from the test classpath. The scope should be one of the scopes defined by
+     * org.apache.maven.artifact.Artifact. This includes the following:
      * <p/>
      * <ul>
      * <li><i>compile</i> - system, provided, compile
@@ -192,16 +184,14 @@ public class IntegrationTestMojo
 
     /**
      * Specify this parameter to run individual tests by file name, overriding the <code>includes/excludes</code>
-     * parameters.  Each pattern you specify here will be used to create an
-     * include pattern formatted like <code>**&#47;${test}.java</code>, so you can just type "-Dit.test=MyTest"
-     * to run a single test called "foo/MyTest.java".<br/>
-     * This parameter overrides the <code>includes/excludes</code> parameters, and the TestNG
-     * <code>suiteXmlFiles</code> parameter.
+     * parameters. Each pattern you specify here will be used to create an include pattern formatted like
+     * <code>**&#47;${test}.java</code>, so you can just type "-Dit.test=MyTest" to run a single test called
+     * "foo/MyTest.java".<br/>
+     * This parameter overrides the <code>includes/excludes</code> parameters, and the TestNG <code>suiteXmlFiles</code>
+     * parameter.
      * <p/>
-     * since 2.7.3
-     * You can execute a limited number of method in the test with adding #myMethod or #my*ethod.
-     * Si type "-Dtest=MyTest#myMethod"
-     * <b>supported for junit 4.x and testNg</b>
+     * since 2.7.3 You can execute a limited number of method in the test with adding #myMethod or #my*ethod. Si type
+     * "-Dtest=MyTest#myMethod" <b>supported for junit 4.x and testNg</b>
      *
      * @parameter expression="${it.test}"
      */
@@ -209,8 +199,7 @@ public class IntegrationTestMojo
 
     /**
      * A list of &lt;include> elements specifying the tests (by pattern) that should be included in testing. When not
-     * specified and when the <code>test</code> parameter is not specified, the default includes will be
-     * <code><br/>
+     * specified and when the <code>test</code> parameter is not specified, the default includes will be <code><br/>
      * &lt;includes><br/>
      * &nbsp;&lt;include>**&#47;IT*.java&lt;/include><br/>
      * &nbsp;&lt;include>**&#47;*IT.java&lt;/include><br/>
@@ -218,8 +207,8 @@ public class IntegrationTestMojo
      * &lt;/includes><br/>
      * </code>
      * <p/>
-     * Each include item may also contain a comma-separated sublist of items, which will be treated as multiple &nbsp;&lt;include>
-     * entries.<br/>
+     * Each include item may also contain a comma-separated sublist of items, which will be treated as multiple
+     * &nbsp;&lt;include> entries.<br/>
      * <p/>
      * This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
      *
@@ -229,17 +218,15 @@ public class IntegrationTestMojo
 
     /**
      * A list of &lt;exclude> elements specifying the tests (by pattern) that should be excluded in testing. When not
-     * specified and when the <code>test</code> parameter is not specified, the default excludes will be
-     * <code><br/>
+     * specified and when the <code>test</code> parameter is not specified, the default excludes will be <code><br/>
      * &lt;excludes><br/>
      * &nbsp;&lt;exclude>**&#47;*$*&lt;/exclude><br/>
      * &lt;/excludes><br/>
-     * </code>
-     * (which excludes all inner classes).<br>
+     * </code> (which excludes all inner classes).<br>
      * This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
      * <p/>
-     * Each exclude item may also contain a comma-separated sublist of items, which will be treated as multiple &nbsp;&lt;exclude>
-     * entries.<br/>
+     * Each exclude item may also contain a comma-separated sublist of items, which will be treated as multiple
+     * &nbsp;&lt;exclude> entries.<br/>
      *
      * @parameter
      */
@@ -272,8 +259,8 @@ public class IntegrationTestMojo
     private Map systemPropertyVariables;
 
     /**
-     * List of properties for configuring all TestNG related configurations. This is the new
-     * preferred method of configuring TestNG.
+     * List of properties for configuring all TestNG related configurations. This is the new preferred method of
+     * configuring TestNG.
      *
      * @parameter
      * @since 2.4
@@ -372,10 +359,9 @@ public class IntegrationTestMojo
     private String argLine;
 
     /**
-     * Attach a debugger to the forked JVM.  If set to "true", the process will suspend and
-     * wait for a debugger to attach on port 5005.  If set to some other string, that
-     * string will be appended to the argLine, allowing you to configure arbitrary
-     * debuggability options (without overwriting the other options specified through the <code>argLine</code>
+     * Attach a debugger to the forked JVM. If set to "true", the process will suspend and wait for a debugger to attach
+     * on port 5005. If set to some other string, that string will be appended to the argLine, allowing you to configure
+     * arbitrary debuggability options (without overwriting the other options specified through the <code>argLine</code>
      * parameter).
      *
      * @parameter expression="${maven.failsafe.debug}"
@@ -384,8 +370,8 @@ public class IntegrationTestMojo
     private String debugForkedProcess;
 
     /**
-     * Kill the forked test process after a certain number of seconds.  If set to 0,
-     * wait forever for the process, never timing out.
+     * Kill the forked test process after a certain number of seconds. If set to 0, wait forever for the process, never
+     * timing out.
      *
      * @parameter expression="${failsafe.timeout}"
      * @since 2.4
@@ -410,8 +396,9 @@ public class IntegrationTestMojo
 
     /**
      * When false it makes tests run using the standard classloader delegation instead of the default Maven isolated
-     * classloader. Only used when forking (forkMode is not "none").<br/> Setting it to false helps with some problems
-     * caused by conflicts between xml parsers in the classpath and the Java 5 provider parser.
+     * classloader. Only used when forking (forkMode is not "none").<br/>
+     * Setting it to false helps with some problems caused by conflicts between xml parsers in the classpath and the
+     * Java 5 provider parser.
      *
      * @parameter expression="${childDelegation}" default-value="false"
      * @since 2.1
@@ -419,8 +406,8 @@ public class IntegrationTestMojo
     private boolean childDelegation;
 
     /**
-     * (TestNG only) Groups for this test. Only classes/methods/etc decorated with one of the groups specified here will be included
-     * in test run, if specified.<br/>
+     * (TestNG only) Groups for this test. Only classes/methods/etc decorated with one of the groups specified here will
+     * be included in test run, if specified.<br/>
      * This parameter is ignored if the <code>suiteXmlFiles</code> parameter is specified.
      *
      * @parameter expression="${groups}"
@@ -429,8 +416,8 @@ public class IntegrationTestMojo
     private String groups;
 
     /**
-     * (TestNG only) Excluded groups. Any methods/classes/etc with one of the groups specified in this list will specifically not be
-     * run.<br/>
+     * (TestNG only) Excluded groups. Any methods/classes/etc with one of the groups specified in this list will
+     * specifically not be run.<br/>
      * This parameter is ignored if the <code>suiteXmlFiles</code> parameter is specified.
      *
      * @parameter expression="${excludedGroups}"
@@ -439,10 +426,11 @@ public class IntegrationTestMojo
     private String excludedGroups;
 
     /**
-     * (TestNG only) List of &lt;suiteXmlFile> elements specifying TestNG suite xml file locations. Note that <code>suiteXmlFiles</code> is incompatible
-     * with several other parameters of this plugin, like <code>includes/excludes</code>.<br/>
-     * This parameter is ignored if the <code>test</code> parameter is specified (allowing you to run a single
-     * test instead of an entire suite).
+     * (TestNG only) List of &lt;suiteXmlFile> elements specifying TestNG suite xml file locations. Note that
+     * <code>suiteXmlFiles</code> is incompatible with several other parameters of this plugin, like
+     * <code>includes/excludes</code>.<br/>
+     * This parameter is ignored if the <code>test</code> parameter is specified (allowing you to run a single test
+     * instead of an entire suite).
      *
      * @parameter
      * @since 2.2
@@ -466,8 +454,8 @@ public class IntegrationTestMojo
     private String testNGArtifactName;
 
     /**
-     * (TestNG/JUnit 4.7 provider only) The attribute thread-count allows you to specify how many threads should be allocated for this execution. Only
-     * makes sense to use in conjunction with the <code>parallel</code> parameter.
+     * (TestNG/JUnit 4.7 provider only) The attribute thread-count allows you to specify how many threads should be
+     * allocated for this execution. Only makes sense to use in conjunction with the <code>parallel</code> parameter.
      *
      * @parameter expression="${threadCount}"
      * @since 2.2
@@ -483,8 +471,9 @@ public class IntegrationTestMojo
     private boolean perCoreThreadCount;
 
     /**
-     * (JUnit 4.7 provider) Indicates that the thread pool will be unlimited. The <code>parallel</code> parameter and the actual number of classes/methods
-     * will decide. Setting this to "true" effectively disables <code>perCoreThreadCount</code> and <code>threadCount</code>. Defaults to "false".
+     * (JUnit 4.7 provider) Indicates that the thread pool will be unlimited. The <code>parallel</code> parameter and
+     * the actual number of classes/methods will decide. Setting this to "true" effectively disables
+     * <code>perCoreThreadCount</code> and <code>threadCount</code>. Defaults to "false".
      *
      * @parameter expression="${useUnlimitedThreads}" default-value="false"
      * @since 2.5
@@ -492,11 +481,12 @@ public class IntegrationTestMojo
     private boolean useUnlimitedThreads;
 
     /**
-     * (TestNG only) When you use the <code>parallel</code> attribute, TestNG will try to run all your test methods in separate threads, except for
-     * methods that depend on each other, which will be run in the same thread in order to respect their order of
-     * execution.
+     * (TestNG only) When you use the <code>parallel</code> attribute, TestNG will try to run all your test methods in
+     * separate threads, except for methods that depend on each other, which will be run in the same thread in order to
+     * respect their order of execution.
      * <p/>
-     * (JUnit 4.7 provider) Supports values "classes"/"methods"/"both" to run in separate threads, as controlled by <code>threadCount</code>.
+     * (JUnit 4.7 provider) Supports values "classes"/"methods"/"both" to run in separate threads, as controlled by
+     * <code>threadCount</code>.
      *
      * @parameter expression="${parallel}"
      * @todo test how this works with forking, and console/file output parallelism
@@ -567,13 +557,12 @@ public class IntegrationTestMojo
     private boolean useSystemClassLoader;
 
     /**
-     * By default, Surefire forks your tests using a manifest-only JAR; set this parameter
-     * to "false" to force it to launch your tests with a plain old Java classpath.
-     * (See http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
-     * for a more detailed explanation of manifest-only JARs and their benefits.)
+     * By default, Surefire forks your tests using a manifest-only JAR; set this parameter to "false" to force it to
+     * launch your tests with a plain old Java classpath. (See
+     * http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html for a more detailed explanation
+     * of manifest-only JARs and their benefits.)
      * <p/>
-     * Beware, setting this to "false" may cause your tests to
-     * fail on Windows if your classpath is too long.
+     * Beware, setting this to "false" may cause your tests to fail on Windows if your classpath is too long.
      *
      * @parameter expression="${failsafe.useManifestOnlyJar}" default-value="true"
      * @since 2.4.3
@@ -620,11 +609,12 @@ public class IntegrationTestMojo
     private Boolean parallelMavenExecution;
 
     /**
-     * Defines the order the tests will be run in. Supported values are "alphabetical", "reversealphabetical",
-     * "random", "hourly" (alphabetical on even hours, reverse alphabetical on odd hours) and "filesystem".<p/>
+     * Defines the order the tests will be run in. Supported values are "alphabetical", "reversealphabetical", "random",
+     * "hourly" (alphabetical on even hours, reverse alphabetical on odd hours) and "filesystem".
      * <p/>
-     * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during
-     * a multi-module build.
+     * <p/>
+     * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during a
+     * multi-module build.
      *
      * @parameter default-value="filesystem"
      * @since 2.7
@@ -636,56 +626,30 @@ public class IntegrationTestMojo
      */
     private ToolchainManager toolchainManager;
 
-
-    public void executeAfterPreconditionsChecked()
+    protected void handleSummary( Summary summary )
         throws MojoExecutionException, MojoFailureException
     {
-        final List providers = initialize();
-        String exceptionMessage = null;
-        FailsafeSummary result = new FailsafeSummary();
+        FailsafeSummary failsafeSummary = createFailsafeSummaryFromSummary( summary );
+        writeSummary( failsafeSummary );
+    }
 
-        ForkConfiguration forkConfiguration = null;
-        for ( Iterator iter = providers.iterator(); iter.hasNext(); )
+    private FailsafeSummary createFailsafeSummaryFromSummary( Summary summary )
+    {
+        FailsafeSummary failsafeSummary = new FailsafeSummary();
+        if ( summary.isErrorFree() )
         {
-            ProviderInfo provider = (ProviderInfo) iter.next();
-            forkConfiguration = getForkConfiguration();
-            ClassLoaderConfiguration classLoaderConfiguration = getClassLoaderConfiguration( forkConfiguration );
-            ForkStarter forkStarter = createForkStarter( provider, forkConfiguration, classLoaderConfiguration );
-            try
-            {
-                final RunResult runResult = forkStarter.run();
-                result.setResult( runResult.getForkedProcessCode() );
-            }
-            catch ( SurefireBooterForkException e )
-            {
-                if ( exceptionMessage == null )
-                {
-                    exceptionMessage = e.getMessage();
-                }
-            }
-            catch ( SurefireExecutionException e )
+            RunResult result = summary.getResultOfLastSuccessfulRun();
+            if ( result != null )
             {
-                if ( exceptionMessage == null )
-                {
-                    exceptionMessage = e.getMessage();
-                }
+                failsafeSummary.setResult( result.getForkedProcessCode() );
             }
         }
-
-        if ( exceptionMessage != null )
-        {
-            // Fail no matter what as long as any provider failed
-            result.setResult( ProviderConfiguration.TESTS_FAILED_EXIT_CODE );
-            result.setException( exceptionMessage );
-        }
-
-        if ( getOriginalSystemProperties() != null && forkConfiguration != null && !forkConfiguration.isForking() )
+        else
         {
-            // restore system properties, only makes sense when not forking..
-            System.setProperties( getOriginalSystemProperties() );
+            failsafeSummary.setResult( ProviderConfiguration.TESTS_FAILED_EXIT_CODE );
+            failsafeSummary.setException( summary.getFirstException().getMessage() );
         }
-
-        writeSummary( result );
+        return failsafeSummary;
     }
 
     private void writeSummary( FailsafeSummary summary )
@@ -698,21 +662,9 @@ public class IntegrationTestMojo
         }
         try
         {
-            String encoding;
-            if ( StringUtils.isEmpty( this.encoding ) )
-            {
-                getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
-                                   + ", i.e. build is platform dependent!" );
-                encoding = ReaderFactory.FILE_ENCODING;
-            }
-            else
-            {
-                encoding = this.encoding;
-            }
-
             FileOutputStream fileOutputStream = new FileOutputStream( summaryFile );
             BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( fileOutputStream );
-            Writer writer = new OutputStreamWriter( bufferedOutputStream, encoding );
+            Writer writer = new OutputStreamWriter( bufferedOutputStream, getEncodingOrDefault() );
             FailsafeSummaryXpp3Writer xpp3Writer = new FailsafeSummaryXpp3Writer();
             xpp3Writer.write( writer, summary );
             writer.close();
@@ -725,6 +677,20 @@ public class IntegrationTestMojo
         }
     }
 
+    private String getEncodingOrDefault()
+    {
+        if ( StringUtils.isEmpty( encoding ) )
+        {
+            getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
+                               + ", i.e. build is platform dependent!" );
+            return ReaderFactory.FILE_ENCODING;
+        }
+        else
+        {
+            return encoding;
+        }
+    }
+
     protected boolean isSkipExecution()
     {
         return isSkip() || isSkipTests() || isSkipITs() || isSkipExec();

Modified: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java?rev=1099576&r1=1099575&r2=1099576&view=diff
==============================================================================
--- maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java (original)
+++ maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/AbstractSurefireMojo.java Wed May  4 19:54:41 2011
@@ -53,7 +53,10 @@ import org.apache.maven.surefire.booter.
 import org.apache.maven.surefire.booter.ProviderConfiguration;
 import org.apache.maven.surefire.booter.StartupConfiguration;
 import org.apache.maven.surefire.booter.StartupReportConfiguration;
+import org.apache.maven.surefire.booter.SurefireBooterForkException;
+import org.apache.maven.surefire.booter.SurefireExecutionException;
 import org.apache.maven.surefire.report.ReporterConfiguration;
+import org.apache.maven.surefire.suite.RunResult;
 import org.apache.maven.surefire.testset.DirectoryScannerParameters;
 import org.apache.maven.surefire.testset.TestArtifactInfo;
 import org.apache.maven.surefire.testset.TestRequest;
@@ -120,19 +123,27 @@ public abstract class AbstractSurefireMo
 
     protected abstract boolean isSkipExecution();
 
-    protected abstract void executeAfterPreconditionsChecked()
-        throws MojoExecutionException, MojoFailureException;
+    protected void executeAfterPreconditionsChecked()
+        throws MojoExecutionException, MojoFailureException
+    {
+        createDependencyResolver();
+        Summary summary = executeAllProviders();
+        restoreOriginalSystemPropertiesWhenNotForking( summary );
+        handleSummary( summary );
+    }
 
     private Artifact surefireArtifact;
 
-
-    protected List initialize()
-        throws MojoFailureException
+    private void createDependencyResolver()
     {
         dependencyResolver =
             new SurefireDependencyResolver( getArtifactResolver(), getArtifactFactory(), getLog(), getLocalRepository(),
                                             getRemoteRepositories(), getMetadataSource(), getPluginName() );
+    }
 
+    protected List createProviders()
+        throws MojoFailureException
+    {
         try
         {
             final Artifact junitDepArtifact = getJunitDepArtifact();
@@ -150,6 +161,52 @@ public abstract class AbstractSurefireMo
         }
     }
 
+    private Summary executeAllProviders()
+        throws MojoExecutionException, MojoFailureException
+    {
+        List providers = createProviders();
+        Summary summary = new Summary();
+        for ( Iterator iter = providers.iterator(); iter.hasNext(); )
+        {
+            ProviderInfo provider = (ProviderInfo) iter.next();
+            executeProvider( provider, summary );
+        }
+        return summary;
+    }
+
+    private void executeProvider( ProviderInfo provider, Summary summary )
+        throws MojoExecutionException, MojoFailureException
+    {
+        ForkConfiguration forkConfiguration = getForkConfiguration();
+        summary.reportForkConfiguration( forkConfiguration );
+        ClassLoaderConfiguration classLoaderConfiguration = getClassLoaderConfiguration( forkConfiguration );
+        ForkStarter forkStarter = createForkStarter( provider, forkConfiguration, classLoaderConfiguration );
+        try
+        {
+            RunResult result = forkStarter.run();
+            summary.registerRunResult( result );
+        }
+        catch ( SurefireBooterForkException e )
+        {
+            summary.registerException( e );
+        }
+        catch ( SurefireExecutionException e )
+        {
+            summary.registerException( e );
+        }
+    }
+
+    protected abstract void handleSummary( Summary summary )
+        throws MojoExecutionException, MojoFailureException;
+
+    protected void restoreOriginalSystemPropertiesWhenNotForking( Summary summary )
+    {
+        if ( ( getOriginalSystemProperties() != null ) && ( summary.isForking() ) )
+        {
+            System.setProperties( getOriginalSystemProperties() );
+        }
+    }
+
     protected void logReportsDirectory()
     {
         getLog().info(
@@ -333,9 +390,8 @@ public abstract class AbstractSurefireMo
         return providerConfiguration1;
     }
 
-    StartupConfiguration createStartupConfiguration( ForkConfiguration forkConfiguration,
-                                                               ProviderInfo provider,
-                                                               ClassLoaderConfiguration classLoaderConfiguration )
+    StartupConfiguration createStartupConfiguration( ForkConfiguration forkConfiguration, ProviderInfo provider,
+                                                     ClassLoaderConfiguration classLoaderConfiguration )
         throws MojoExecutionException, MojoFailureException
     {
 
@@ -721,8 +777,8 @@ public abstract class AbstractSurefireMo
      * @throws ArtifactResolutionException when it happens
      */
     Classpath generateTestClasspath()
-        throws InvalidVersionSpecificationException,
-        MojoFailureException, ArtifactResolutionException, ArtifactNotFoundException
+        throws InvalidVersionSpecificationException, MojoFailureException, ArtifactResolutionException,
+        ArtifactNotFoundException
     {
         List classpath = new ArrayList( 2 + getProject().getArtifacts().size() );
 

Added: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/Summary.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/Summary.java?rev=1099576&view=auto
==============================================================================
--- maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/Summary.java (added)
+++ maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/Summary.java Wed May  4 19:54:41 2011
@@ -0,0 +1,75 @@
+package org.apache.maven.plugin.surefire;
+
+/*
+ * 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.plugin.surefire.booterclient.ForkConfiguration;
+import org.apache.maven.surefire.suite.RunResult;
+
+public class Summary
+{
+    private boolean forking = false;
+
+    private RunResult runResult;
+
+    private Exception exception;
+
+    public void reportForkConfiguration( ForkConfiguration configuration )
+    {
+        forking = configuration.isForking();
+    }
+
+    public void registerException( Exception exception )
+    {
+        if ( this.exception == null )
+        {
+            this.exception = exception;
+        }
+    }
+
+    public void registerRunResult( RunResult result )
+    {
+        runResult = result;
+    }
+
+    public boolean isErrorFree()
+    {
+        return exception == null;
+    }
+
+    public boolean isFailureOrTimeout()
+    {
+        return runResult != null && runResult.isFailureOrTimeout();
+    }
+
+    public boolean isForking()
+    {
+        return forking;
+    }
+
+    public Exception getFirstException()
+    {
+        return exception;
+    }
+
+    public RunResult getResultOfLastSuccessfulRun()
+    {
+        return runResult;
+    }
+}

Propchange: maven/surefire/trunk/maven-surefire-common/src/main/java/org/apache/maven/plugin/surefire/Summary.java
------------------------------------------------------------------------------
    svn:eol-style = native

Added: maven/surefire/trunk/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SummaryTest.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SummaryTest.java?rev=1099576&view=auto
==============================================================================
--- maven/surefire/trunk/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SummaryTest.java (added)
+++ maven/surefire/trunk/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SummaryTest.java Wed May  4 19:54:41 2011
@@ -0,0 +1,113 @@
+package org.apache.maven.plugin.surefire;
+
+/*
+ * 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.plugin.surefire.booterclient.ForkConfiguration;
+import org.apache.maven.surefire.suite.RunResult;
+
+import junit.framework.TestCase;
+
+public class SummaryTest
+    extends TestCase
+{
+    Summary summary = new Summary();
+
+    public void testEmptySummaryShouldBeErrorFree()
+    {
+        assertTrue( summary.isErrorFree() );
+    }
+
+    public void testSummaryShouldBeErrorFreeAfterAddingAnException()
+    {
+        summary.registerException( new RuntimeException() );
+        assertFalse( summary.isErrorFree() );
+    }
+
+    public void testEmptySummaryShouldHaveNoFailureOrTimeOut()
+    {
+        assertFalse( summary.isFailureOrTimeout() );
+    }
+
+    public void testSummaryReturnsFailureOrTimeOutStateOfLastRun()
+    {
+        RunResult resultWithoutFailure = new RunResult( 0, 0, 0, 0, false, false );
+        RunResult resultWithFailure = new RunResult( 0, 0, 0, 0, true, true );
+        summary.registerRunResult( resultWithoutFailure );
+        summary.registerRunResult( resultWithFailure );
+        assertTrue( summary.isFailureOrTimeout() );
+    }
+
+    public void testEmptySummaryHasNoFirstException()
+    {
+        assertNull( summary.getFirstException() );
+    }
+
+    public void testSummaryReturnsTheFirstOfTwoExceptions()
+    {
+        Exception exceptionOne = new RuntimeException();
+        Exception exceptionTwo = new RuntimeException();
+        summary.registerException( exceptionOne );
+        summary.registerException( exceptionTwo );
+        assertEquals( "Wrong exception.", exceptionOne, summary.getFirstException() );
+    }
+
+    public void testEmptySummaryHasNoResultOfLastSuccessfulRun()
+    {
+        assertNull( summary.getResultOfLastSuccessfulRun() );
+    }
+
+    public void testSummaryReturnsTheSecondOfTwoResult()
+    {
+        RunResult resultOne = new RunResult( 0, 0, 0, 0 );
+        RunResult resultTwo = new RunResult( 0, 0, 0, 0 );
+        summary.registerRunResult( resultOne );
+        summary.registerRunResult( resultTwo );
+        assertEquals( "Wrong exception.", resultTwo, summary.getResultOfLastSuccessfulRun() );
+    }
+
+    public void testEmptySummaryIsNotForking()
+    {
+        assertFalse( summary.isForking() );
+    }
+
+    public void testSummaryIsForkingIfTheLastConfigurationIsForking()
+    {
+        summary.reportForkConfiguration( createNonForkingConfiguration() );
+        summary.reportForkConfiguration( createForkingConfiguration() );
+        assertTrue( summary.isForking() );
+    }
+
+    public void testSummaryIsNotForkingIfTheLastConfigurationIsNotForking()
+    {
+        summary.reportForkConfiguration( createForkingConfiguration() );
+        summary.reportForkConfiguration( createNonForkingConfiguration() );
+        assertFalse( summary.isForking() );
+    }
+
+    private ForkConfiguration createForkingConfiguration()
+    {
+        return new ForkConfiguration( null, ForkConfiguration.FORK_ALWAYS, null );
+    }
+
+    private ForkConfiguration createNonForkingConfiguration()
+    {
+        return new ForkConfiguration( null, ForkConfiguration.FORK_NEVER, null );
+    }
+}

Propchange: maven/surefire/trunk/maven-surefire-common/src/test/java/org/apache/maven/plugin/surefire/SummaryTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Modified: maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java
URL: http://svn.apache.org/viewvc/maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java?rev=1099576&r1=1099575&r2=1099576&view=diff
==============================================================================
--- maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java (original)
+++ maven/surefire/trunk/maven-surefire-plugin/src/main/java/org/apache/maven/plugin/surefire/SurefirePlugin.java Wed May  4 19:54:41 2011
@@ -21,7 +21,6 @@ package org.apache.maven.plugin.surefire
 
 import java.io.File;
 import java.util.HashMap;
-import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Properties;
@@ -33,12 +32,7 @@ import org.apache.maven.execution.MavenS
 import org.apache.maven.plugin.MojoExecutionException;
 import org.apache.maven.plugin.MojoFailureException;
 import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
-import org.apache.maven.plugin.surefire.booterclient.ForkConfiguration;
-import org.apache.maven.plugin.surefire.booterclient.ForkStarter;
 import org.apache.maven.project.MavenProject;
-import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
-import org.apache.maven.surefire.booter.SurefireBooterForkException;
-import org.apache.maven.surefire.booter.SurefireExecutionException;
 import org.apache.maven.surefire.suite.RunResult;
 import org.apache.maven.toolchain.ToolchainManager;
 import org.codehaus.plexus.util.StringUtils;
@@ -78,9 +72,9 @@ public class SurefirePlugin
     private boolean skipExec;
 
     /**
-     * Set this to "true" to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you
-     * enable it using the "maven.test.skip" property, because maven.test.skip disables both running the
-     * tests and compiling the tests.  Consider using the <code>skipTests</code> parameter instead.
+     * Set this to "true" to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you enable it using
+     * the "maven.test.skip" property, because maven.test.skip disables both running the tests and compiling the tests.
+     * Consider using the <code>skipTests</code> parameter instead.
      *
      * @parameter default-value="false" expression="${maven.test.skip}"
      */
@@ -103,16 +97,16 @@ public class SurefirePlugin
     private File basedir;
 
     /**
-     * The directory containing generated test classes of the project being tested.
-     * This will be included at the beginning of the test classpath.                                                                                                                            *
+     * The directory containing generated test classes of the project being tested. This will be included at the
+     * beginning of the test classpath. *
      *
      * @parameter default-value="${project.build.testOutputDirectory}"
      */
     private File testClassesDirectory;
 
     /**
-     * The directory containing generated classes of the project being tested.
-     * This will be included after the test classes in the test classpath.
+     * The directory containing generated classes of the project being tested. This will be included after the test
+     * classes in the test classpath.
      *
      * @parameter default-value="${project.build.outputDirectory}"
      */
@@ -127,9 +121,8 @@ public class SurefirePlugin
     private MavenProject project;
 
     /**
-     * List of dependencies to exclude from the test classpath.
-     * Each dependency string must follow the format <i>groupId:artifactId</i>.
-     * For example: <i>org.acme:project-a</i>
+     * List of dependencies to exclude from the test classpath. Each dependency string must follow the format
+     * <i>groupId:artifactId</i>. For example: <i>org.acme:project-a</i>
      *
      * @parameter
      * @since 2.6
@@ -137,12 +130,13 @@ public class SurefirePlugin
     private List classpathDependencyExcludes;
 
     /**
-     * A dependency scope to exclude from the test classpath.
-     * The scope can be one of the following scopes:
+     * A dependency scope to exclude from the test classpath. The scope can be one of the following scopes:
      * <p/>
-     * <ul><li><i>compile</i> - system, provided, compile
+     * <ul>
+     * <li><i>compile</i> - system, provided, compile
      * <li><i>runtime</i> - compile, runtime
-     * <li><i>test</i> - system, provided, compile, runtime, test</ul>
+     * <li><i>test</i> - system, provided, compile, runtime, test
+     * </ul>
      *
      * @parameter default-value=""
      * @since 2.6
@@ -175,16 +169,14 @@ public class SurefirePlugin
 
     /**
      * Specify this parameter to run individual tests by file name, overriding the <code>includes/excludes</code>
-     * parameters.  Each pattern you specify here will be used to create an
-     * include pattern formatted like <code>**&#47;${test}.java</code>, so you can just type "-Dtest=MyTest"
-     * to run a single test called "foo/MyTest.java".<br/>
-     * This parameter overrides the <code>includes/excludes</code> parameters, and the TestNG
-     * <code>suiteXmlFiles</code> parameter.
+     * parameters. Each pattern you specify here will be used to create an include pattern formatted like
+     * <code>**&#47;${test}.java</code>, so you can just type "-Dtest=MyTest" to run a single test called
+     * "foo/MyTest.java".<br/>
+     * This parameter overrides the <code>includes/excludes</code> parameters, and the TestNG <code>suiteXmlFiles</code>
+     * parameter.
      * <p/>
-     * since 2.7.3
-     * You can execute a limited number of method in the test with adding #myMethod or #my*ethod.
-     * Si type "-Dtest=MyTest#myMethod"
-     * <b>supported for junit 4.x and testNg</b>
+     * since 2.7.3 You can execute a limited number of method in the test with adding #myMethod or #my*ethod. Si type
+     * "-Dtest=MyTest#myMethod" <b>supported for junit 4.x and testNg</b>
      *
      * @parameter expression="${test}"
      */
@@ -192,15 +184,13 @@ public class SurefirePlugin
 
     /**
      * A list of &lt;include> elements specifying the tests (by pattern) that should be included in testing. When not
-     * specified and when the <code>test</code> parameter is not specified, the default includes will be
-     * <code><br/>
+     * specified and when the <code>test</code> parameter is not specified, the default includes will be <code><br/>
      * &lt;includes><br/>
      * &nbsp;&lt;include>**&#47;Test*.java&lt;/include><br/>
      * &nbsp;&lt;include>**&#47;*Test.java&lt;/include><br/>
      * &nbsp;&lt;include>**&#47;*TestCase.java&lt;/include><br/>
      * &lt;/includes><br/>
-     * </code>
-     * This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
+     * </code> This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
      *
      * @parameter
      */
@@ -208,13 +198,11 @@ public class SurefirePlugin
 
     /**
      * A list of &lt;exclude> elements specifying the tests (by pattern) that should be excluded in testing. When not
-     * specified and when the <code>test</code> parameter is not specified, the default excludes will be
-     * <code><br/>
+     * specified and when the <code>test</code> parameter is not specified, the default excludes will be <code><br/>
      * &lt;excludes><br/>
      * &nbsp;&lt;exclude>**&#47;*$*&lt;/exclude><br/>
      * &lt;/excludes><br/>
-     * </code>
-     * (which excludes all inner classes).<br>
+     * </code> (which excludes all inner classes).<br>
      * This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
      *
      * @parameter
@@ -248,8 +236,8 @@ public class SurefirePlugin
     private Map systemPropertyVariables;
 
     /**
-     * List of properties for configuring all TestNG related configurations. This is the new
-     * preferred method of configuring TestNG.
+     * List of properties for configuring all TestNG related configurations. This is the new preferred method of
+     * configuring TestNG.
      *
      * @parameter
      * @since 2.4
@@ -340,10 +328,9 @@ public class SurefirePlugin
     private String argLine;
 
     /**
-     * Attach a debugger to the forked JVM.  If set to "true", the process will suspend and
-     * wait for a debugger to attach on port 5005.  If set to some other string, that
-     * string will be appended to the argLine, allowing you to configure arbitrary
-     * debuggability options (without overwriting the other options specified through the <code>argLine</code>
+     * Attach a debugger to the forked JVM. If set to "true", the process will suspend and wait for a debugger to attach
+     * on port 5005. If set to some other string, that string will be appended to the argLine, allowing you to configure
+     * arbitrary debuggability options (without overwriting the other options specified through the <code>argLine</code>
      * parameter).
      *
      * @parameter expression="${maven.surefire.debug}"
@@ -352,8 +339,8 @@ public class SurefirePlugin
     private String debugForkedProcess;
 
     /**
-     * Kill the forked test process after a certain number of seconds.  If set to 0,
-     * wait forever for the process, never timing out.
+     * Kill the forked test process after a certain number of seconds. If set to 0, wait forever for the process, never
+     * timing out.
      *
      * @parameter expression="${surefire.timeout}"
      * @since 2.4
@@ -378,8 +365,9 @@ public class SurefirePlugin
 
     /**
      * When false it makes tests run using the standard classloader delegation instead of the default Maven isolated
-     * classloader. Only used when forking (forkMode is not "none").<br/> Setting it to false helps with some problems
-     * caused by conflicts between xml parsers in the classpath and the Java 5 provider parser.
+     * classloader. Only used when forking (forkMode is not "none").<br/>
+     * Setting it to false helps with some problems caused by conflicts between xml parsers in the classpath and the
+     * Java 5 provider parser.
      *
      * @parameter expression="${childDelegation}" default-value="false"
      * @since 2.1
@@ -387,8 +375,8 @@ public class SurefirePlugin
     private boolean childDelegation;
 
     /**
-     * (TestNG only) Groups for this test. Only classes/methods/etc decorated with one of the groups specified here will be included
-     * in test run, if specified.<br/>
+     * (TestNG only) Groups for this test. Only classes/methods/etc decorated with one of the groups specified here will
+     * be included in test run, if specified.<br/>
      * This parameter is ignored if the <code>suiteXmlFiles</code> parameter is specified.
      *
      * @parameter expression="${groups}"
@@ -397,8 +385,8 @@ public class SurefirePlugin
     private String groups;
 
     /**
-     * (TestNG only) Excluded groups. Any methods/classes/etc with one of the groups specified in this list will specifically not be
-     * run.<br/>
+     * (TestNG only) Excluded groups. Any methods/classes/etc with one of the groups specified in this list will
+     * specifically not be run.<br/>
      * This parameter is ignored if the <code>suiteXmlFiles</code> parameter is specified.
      *
      * @parameter expression="${excludedGroups}"
@@ -407,10 +395,11 @@ public class SurefirePlugin
     private String excludedGroups;
 
     /**
-     * (TestNG only) List of &lt;suiteXmlFile> elements specifying TestNG suite xml file locations. Note that <code>suiteXmlFiles</code> is incompatible
-     * with several other parameters of this plugin, like <code>includes/excludes</code>.<br/>
-     * This parameter is ignored if the <code>test</code> parameter is specified (allowing you to run a single
-     * test instead of an entire suite).
+     * (TestNG only) List of &lt;suiteXmlFile> elements specifying TestNG suite xml file locations. Note that
+     * <code>suiteXmlFiles</code> is incompatible with several other parameters of this plugin, like
+     * <code>includes/excludes</code>.<br/>
+     * This parameter is ignored if the <code>test</code> parameter is specified (allowing you to run a single test
+     * instead of an entire suite).
      *
      * @parameter
      * @since 2.2
@@ -434,8 +423,8 @@ public class SurefirePlugin
     private String testNGArtifactName;
 
     /**
-     * (TestNG/JUnit 4.7 provider only) The attribute thread-count allows you to specify how many threads should be allocated for this execution. Only
-     * makes sense to use in conjunction with the <code>parallel</code> parameter.
+     * (TestNG/JUnit 4.7 provider only) The attribute thread-count allows you to specify how many threads should be
+     * allocated for this execution. Only makes sense to use in conjunction with the <code>parallel</code> parameter.
      *
      * @parameter expression="${threadCount}"
      * @since 2.2
@@ -451,8 +440,9 @@ public class SurefirePlugin
     private boolean perCoreThreadCount;
 
     /**
-     * (JUnit 4.7 provider) Indicates that the thread pool will be unlimited. The <code>parallel</code> parameter and the actual number of classes/methods
-     * will decide. Setting this to "true" effectively disables <code>perCoreThreadCount</code> and <code>threadCount</code>. Defaults to "false".
+     * (JUnit 4.7 provider) Indicates that the thread pool will be unlimited. The <code>parallel</code> parameter and
+     * the actual number of classes/methods will decide. Setting this to "true" effectively disables
+     * <code>perCoreThreadCount</code> and <code>threadCount</code>. Defaults to "false".
      *
      * @parameter expression="${useUnlimitedThreads}" default-value="false"
      * @since 2.5
@@ -460,11 +450,12 @@ public class SurefirePlugin
     private boolean useUnlimitedThreads;
 
     /**
-     * (TestNG only) When you use the <code>parallel</code> attribute, TestNG will try to run all your test methods in separate threads, except for
-     * methods that depend on each other, which will be run in the same thread in order to respect their order of
-     * execution.
+     * (TestNG only) When you use the <code>parallel</code> attribute, TestNG will try to run all your test methods in
+     * separate threads, except for methods that depend on each other, which will be run in the same thread in order to
+     * respect their order of execution.
      * <p/>
-     * (JUnit 4.7 provider) Supports values "classes"/"methods"/"both" to run in separate threads, as controlled by <code>threadCount</code>.
+     * (JUnit 4.7 provider) Supports values "classes"/"methods"/"both" to run in separate threads, as controlled by
+     * <code>threadCount</code>.
      *
      * @parameter expression="${parallel}"
      * @since 2.2
@@ -534,13 +525,12 @@ public class SurefirePlugin
     private boolean useSystemClassLoader;
 
     /**
-     * By default, Surefire forks your tests using a manifest-only JAR; set this parameter
-     * to "false" to force it to launch your tests with a plain old Java classpath.
-     * (See http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
-     * for a more detailed explanation of manifest-only JARs and their benefits.)
+     * By default, Surefire forks your tests using a manifest-only JAR; set this parameter to "false" to force it to
+     * launch your tests with a plain old Java classpath. (See
+     * http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html for a more detailed explanation
+     * of manifest-only JARs and their benefits.)
      * <p/>
-     * Beware, setting this to "false" may cause your tests to
-     * fail on Windows if your classpath is too long.
+     * Beware, setting this to "false" may cause your tests to fail on Windows if your classpath is too long.
      *
      * @parameter expression="${surefire.useManifestOnlyJar}" default-value="true"
      * @since 2.4.3
@@ -573,7 +563,6 @@ public class SurefirePlugin
      */
     private String objectFactory;
 
-
     /**
      * @parameter default-value="${session.parallel}"
      * @readonly
@@ -582,11 +571,12 @@ public class SurefirePlugin
     private Boolean parallelMavenExecution;
 
     /**
-     * Defines the order the tests will be run in. Supported values are "alphabetical", "reversealphabetical",
-     * "random", "hourly" (alphabetical on even hours, reverse alphabetical on odd hours) and "filesystem".<p/>
+     * Defines the order the tests will be run in. Supported values are "alphabetical", "reversealphabetical", "random",
+     * "hourly" (alphabetical on even hours, reverse alphabetical on odd hours) and "filesystem".
      * <p/>
-     * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during
-     * a multi-module build.
+     * <p/>
+     * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during a
+     * multi-module build.
      *
      * @parameter default-value="filesystem"
      * @since 2.7
@@ -598,55 +588,37 @@ public class SurefirePlugin
      */
     private ToolchainManager toolchainManager;
 
-    public void executeAfterPreconditionsChecked()
+    protected void handleSummary( Summary summary )
         throws MojoExecutionException, MojoFailureException
     {
-        final List providers = initialize();
-        Exception exception = null;
-        ForkConfiguration forkConfiguration = null;
-        RunResult result = null;
-        for ( Iterator iter = providers.iterator(); iter.hasNext(); )
-        {
-            ProviderInfo provider = (ProviderInfo) iter.next();
-            forkConfiguration = getForkConfiguration();
-            ClassLoaderConfiguration classLoaderConfiguration = getClassLoaderConfiguration( forkConfiguration );
-            ForkStarter forkStarter = createForkStarter( provider, forkConfiguration, classLoaderConfiguration );
-
-            try
-            {
-                result = forkStarter.run();
-            }
-            catch ( SurefireBooterForkException e )
-            {
-                exception = e;
-            }
-            catch ( SurefireExecutionException e )
-            {
-                exception = e;
-            }
-        }
+        assertNoException( summary );
+        assertNoFailureOrTimeout( summary );
+        writeSummary( summary );
+    }
 
-        if ( result.isFailureOrTimeout() )
-        {
-            throw new MojoExecutionException( "Failure or timeout" );
-        }
-        if ( exception != null )
+    private void assertNoException( Summary summary )
+        throws MojoExecutionException
+    {
+        if ( !summary.isErrorFree() )
         {
-            throw new MojoExecutionException( exception.getMessage(), exception );
+            Exception cause = summary.getFirstException();
+            throw new MojoExecutionException( cause.getMessage(), cause );
         }
+    }
 
-        if ( getOriginalSystemProperties() != null && forkConfiguration != null && !forkConfiguration.isForking() )
+    private void assertNoFailureOrTimeout( Summary summary )
+        throws MojoExecutionException
+    {
+        if ( summary.isFailureOrTimeout() )
         {
-            // restore system properties, only makes sense when not forking..
-            System.setProperties( getOriginalSystemProperties() );
+            throw new MojoExecutionException( "Failure or timeout" );
         }
-
-        writeSummary( result );
     }
 
-    private void writeSummary( RunResult result )
+    private void writeSummary( Summary summary )
         throws MojoFailureException
     {
+        RunResult result = summary.getResultOfLastSuccessfulRun();
         SurefireHelper.reportExecution( this, result, getLog() );
     }
 
@@ -672,7 +644,6 @@ public class SurefirePlugin
         return skipTests;
     }
 
-
     public void setSkipTests( boolean skipTests )
     {
         this.skipTests = skipTests;
@@ -835,7 +806,6 @@ public class SurefirePlugin
         return null;
     }
 
-
     public void setTest( String test )
     {
         this.test = test;



Mime
View raw message