Coverage Report - org.apache.maven.plugin.surefire.AbstractSurefireMojo
 
Classes in this File Line Coverage Branch Coverage Complexity
AbstractSurefireMojo
0%
0/442
0%
0/222
2.635
AbstractSurefireMojo$DynamicProviderInfo
0%
0/12
N/A
2.635
AbstractSurefireMojo$JUnit3ProviderInfo
0%
0/5
N/A
2.635
AbstractSurefireMojo$JUnit4ProviderInfo
0%
0/8
0%
0/4
2.635
AbstractSurefireMojo$JUnitCoreProviderInfo
0%
0/13
0%
0/18
2.635
AbstractSurefireMojo$TestNgProviderInfo
0%
0/9
0%
0/2
2.635
 
 1  
 package org.apache.maven.plugin.surefire;
 2  
 
 3  
 /*
 4  
  * Licensed to the Apache Software Foundation (ASF) under one
 5  
  * or more contributor license agreements.  See the NOTICE file
 6  
  * distributed with this work for additional information
 7  
  * regarding copyright ownership.  The ASF licenses this file
 8  
  * to you under the Apache License, Version 2.0 (the
 9  
  * "License"); you may not use this file except in compliance
 10  
  * with the License.  You may obtain a copy of the License at
 11  
  *
 12  
  *     http://www.apache.org/licenses/LICENSE-2.0
 13  
  *
 14  
  * Unless required by applicable law or agreed to in writing,
 15  
  * software distributed under the License is distributed on an
 16  
  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
 17  
  * KIND, either express or implied.  See the License for the
 18  
  * specific language governing permissions and limitations
 19  
  * under the License.
 20  
  */
 21  
 
 22  
 import java.io.File;
 23  
 import java.io.FileInputStream;
 24  
 import java.io.IOException;
 25  
 import java.lang.reflect.Method;
 26  
 import java.util.ArrayList;
 27  
 import java.util.Arrays;
 28  
 import java.util.Collections;
 29  
 import java.util.Enumeration;
 30  
 import java.util.Iterator;
 31  
 import java.util.LinkedHashSet;
 32  
 import java.util.List;
 33  
 import java.util.Map;
 34  
 import java.util.Properties;
 35  
 import java.util.Set;
 36  
 import org.apache.maven.artifact.Artifact;
 37  
 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
 38  
 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
 39  
 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
 40  
 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
 41  
 import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
 42  
 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
 43  
 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
 44  
 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
 45  
 import org.apache.maven.artifact.versioning.VersionRange;
 46  
 import org.apache.maven.plugin.AbstractMojo;
 47  
 import org.apache.maven.plugin.MojoExecutionException;
 48  
 import org.apache.maven.plugin.MojoFailureException;
 49  
 import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
 50  
 import org.apache.maven.plugin.surefire.booterclient.ForkConfiguration;
 51  
 import org.apache.maven.plugin.surefire.booterclient.ForkStarter;
 52  
 import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;
 53  
 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
 54  
 import org.apache.maven.surefire.booter.Classpath;
 55  
 import org.apache.maven.surefire.booter.ClasspathConfiguration;
 56  
 import org.apache.maven.surefire.booter.ProviderConfiguration;
 57  
 import org.apache.maven.surefire.booter.StartupConfiguration;
 58  
 import org.apache.maven.surefire.booter.StartupReportConfiguration;
 59  
 import org.apache.maven.surefire.booter.SurefireBooterForkException;
 60  
 import org.apache.maven.surefire.booter.SurefireExecutionException;
 61  
 import org.apache.maven.surefire.report.ReporterConfiguration;
 62  
 import org.apache.maven.surefire.suite.RunResult;
 63  
 import org.apache.maven.surefire.testset.DirectoryScannerParameters;
 64  
 import org.apache.maven.surefire.testset.RunOrderParameters;
 65  
 import org.apache.maven.surefire.testset.TestArtifactInfo;
 66  
 import org.apache.maven.surefire.testset.TestRequest;
 67  
 import org.apache.maven.surefire.util.NestedRuntimeException;
 68  
 import org.apache.maven.surefire.util.RunOrder;
 69  
 import org.apache.maven.toolchain.Toolchain;
 70  
 import org.codehaus.plexus.util.StringUtils;
 71  
 
 72  
 /**
 73  
  * Abstract base class for running tests using Surefire.
 74  
  *
 75  
  * @author Stephen Connolly
 76  
  * @version $Id: SurefirePlugin.java 945065 2010-05-17 10:26:22Z stephenc $
 77  
  */
 78  0
 public abstract class AbstractSurefireMojo
 79  
     extends AbstractMojo
 80  
     implements SurefireExecutionParameters
 81  
 {
 82  
 
 83  
     // common field getters/setters
 84  
 
 85  
     // common code
 86  
 
 87  
     protected abstract String getPluginName();
 88  
 
 89  
     private SurefireDependencyResolver dependencyResolver;
 90  
 
 91  
     public void execute()
 92  
         throws MojoExecutionException, MojoFailureException
 93  
     {
 94  0
         if ( verifyParameters() && !hasExecutedBefore() )
 95  
         {
 96  0
             logReportsDirectory();
 97  0
             executeAfterPreconditionsChecked();
 98  
         }
 99  0
     }
 100  
 
 101  
     boolean verifyParameters()
 102  
         throws MojoFailureException
 103  
     {
 104  0
         if ( isSkipExecution() )
 105  
         {
 106  0
             getLog().info( "Tests are skipped." );
 107  0
             return false;
 108  
         }
 109  
 
 110  0
         if ( !getTestClassesDirectory().exists() )
 111  
         {
 112  0
             if ( Boolean.TRUE.equals( getFailIfNoTests() ) )
 113  
             {
 114  0
                 throw new MojoFailureException( "No tests to run!" );
 115  
             }
 116  0
             getLog().info( "No tests to run." );
 117  
         }
 118  
         else
 119  
         {
 120  0
             ensureWorkingDirectoryExists();
 121  0
             ensureParallelRunningCompatibility();
 122  0
             warnIfUselessUseSystemClassLoaderParameter();
 123  
         }
 124  
 
 125  0
         return true;
 126  
     }
 127  
 
 128  
     protected abstract boolean isSkipExecution();
 129  
 
 130  
     protected void executeAfterPreconditionsChecked()
 131  
         throws MojoExecutionException, MojoFailureException
 132  
     {
 133  0
         createDependencyResolver();
 134  0
         Summary summary = executeAllProviders();
 135  0
         restoreOriginalSystemPropertiesWhenNotForking( summary );
 136  0
         handleSummary( summary );
 137  0
     }
 138  
 
 139  
     private Artifact surefireBooterArtifact;
 140  
 
 141  
     private void createDependencyResolver()
 142  
     {
 143  0
         dependencyResolver =
 144  
             new SurefireDependencyResolver( getArtifactResolver(), getArtifactFactory(), getLog(), getLocalRepository(),
 145  
                                             getRemoteRepositories(), getMetadataSource(), getPluginName() );
 146  0
     }
 147  
 
 148  
     protected List createProviders()
 149  
         throws MojoFailureException
 150  
     {
 151  
         try
 152  
         {
 153  0
             final Artifact junitDepArtifact = getJunitDepArtifact();
 154  0
             ProviderList wellKnownProviders = new ProviderList(
 155  
                 new ProviderInfo[]{ new TestNgProviderInfo( getTestNgArtifact() ),
 156  
                     new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
 157  
                     new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ), new JUnit3ProviderInfo() },
 158  
                 new DynamicProviderInfo( null ) );
 159  
 
 160  0
             return wellKnownProviders.resolve( getLog() );
 161  
         }
 162  0
         catch ( InvalidVersionSpecificationException e )
 163  
         {
 164  0
             throw new NestedRuntimeException( e );
 165  
         }
 166  
     }
 167  
 
 168  
     private Summary executeAllProviders()
 169  
         throws MojoExecutionException, MojoFailureException
 170  
     {
 171  0
         List providers = createProviders();
 172  0
         Summary summary = new Summary();
 173  0
         for ( Iterator iter = providers.iterator(); iter.hasNext(); )
 174  
         {
 175  0
             ProviderInfo provider = (ProviderInfo) iter.next();
 176  0
             executeProvider( provider, summary );
 177  0
         }
 178  0
         return summary;
 179  
     }
 180  
 
 181  
     private void executeProvider( ProviderInfo provider, Summary summary )
 182  
         throws MojoExecutionException, MojoFailureException
 183  
     {
 184  0
         ForkConfiguration forkConfiguration = getForkConfiguration();
 185  0
         summary.reportForkConfiguration( forkConfiguration );
 186  0
         ClassLoaderConfiguration classLoaderConfiguration = getClassLoaderConfiguration( forkConfiguration );
 187  
         try
 188  
         {
 189  
             final RunResult result;
 190  0
             if ( ForkConfiguration.FORK_NEVER.equals( forkConfiguration.getForkMode() ) )
 191  
             {
 192  0
                 InPluginVMSurefireStarter surefireStarter =
 193  
                     createInprocessStarter( provider, forkConfiguration, classLoaderConfiguration );
 194  0
                 result = surefireStarter.runSuitesInProcess();
 195  0
             }
 196  
             else
 197  
             {
 198  0
                 ForkStarter forkStarter = createForkStarter( provider, forkConfiguration, classLoaderConfiguration );
 199  0
                 result = forkStarter.run();
 200  
             }
 201  0
             summary.registerRunResult( result );
 202  
         }
 203  0
         catch ( SurefireBooterForkException e )
 204  
         {
 205  0
             summary.registerException( e );
 206  
         }
 207  0
         catch ( SurefireExecutionException e )
 208  
         {
 209  0
             summary.registerException( e );
 210  0
         }
 211  0
     }
 212  
 
 213  
     protected abstract void handleSummary( Summary summary )
 214  
         throws MojoExecutionException, MojoFailureException;
 215  
 
 216  
     protected void restoreOriginalSystemPropertiesWhenNotForking( Summary summary )
 217  
     {
 218  0
         if ( ( getOriginalSystemProperties() != null ) && ( summary.isForking() ) )
 219  
         {
 220  0
             System.setProperties( getOriginalSystemProperties() );
 221  
         }
 222  0
     }
 223  
 
 224  
     protected void logReportsDirectory()
 225  
     {
 226  0
         getLog().info(
 227  
             StringUtils.capitalizeFirstLetter( getPluginName() ) + " report directory: " + getReportsDirectory() );
 228  0
     }
 229  
 
 230  
 
 231  
     final Toolchain getToolchain()
 232  
     {
 233  0
         Toolchain tc = null;
 234  
 
 235  0
         if ( getToolchainManager() != null )
 236  
         {
 237  0
             tc = getToolchainManager().getToolchainFromBuildContext( "jdk", getSession() );
 238  
         }
 239  
 
 240  0
         return tc;
 241  
     }
 242  
 
 243  
     /**
 244  
      * Converts old TestNG configuration parameters over to new properties based configuration
 245  
      * method. (if any are defined the old way)
 246  
      */
 247  
     private void convertTestNGParameters()
 248  
     {
 249  0
         if ( getProperties() == null ) // May be predefined from plugin paramaters
 250  
         {
 251  0
             setProperties( new Properties() );
 252  
         }
 253  
 
 254  0
         if ( this.getParallel() != null )
 255  
         {
 256  0
             getProperties().setProperty( "parallel", this.getParallel() );
 257  
         }
 258  0
         convertGroupParameters();
 259  
 
 260  0
         if ( this.getThreadCount() > 0 )
 261  
         {
 262  0
             getProperties().setProperty( "threadcount", Integer.toString( this.getThreadCount() ) );
 263  
         }
 264  0
         if ( this.getObjectFactory() != null )
 265  
         {
 266  0
             getProperties().setProperty( "objectfactory", this.getObjectFactory() );
 267  
         }
 268  0
         if ( this.getTestClassesDirectory() != null )
 269  
         {
 270  0
             getProperties().setProperty( "testng.test.classpath", getTestClassesDirectory().getAbsolutePath() );
 271  
         }
 272  
 
 273  
 
 274  0
     }
 275  
 
 276  
     private void convertGroupParameters()
 277  
     {
 278  0
         if ( getProperties() == null ) // May be predefined from plugin paramaters
 279  
         {
 280  0
             setProperties( new Properties() );
 281  
         }
 282  0
         if ( this.getExcludedGroups() != null )
 283  
         {
 284  0
             getProperties().setProperty( "excludedgroups", this.getExcludedGroups() );
 285  
         }
 286  0
         if ( this.getGroups() != null )
 287  
         {
 288  0
             getProperties().setProperty( "groups", this.getGroups() );
 289  
         }
 290  0
     }
 291  
 
 292  
     protected boolean isAnyConcurrencySelected()
 293  
     {
 294  0
         return this.getParallel() != null && this.getParallel().trim().length() > 0;
 295  
     }
 296  
 
 297  
     protected boolean isAnyGroupsSelected()
 298  
     {
 299  0
         return this.getGroups() != null && this.getExcludedGroups() != null;
 300  
     }
 301  
 
 302  
     /**
 303  
      * Converts old JUnit configuration parameters over to new properties based configuration
 304  
      * method. (if any are defined the old way)
 305  
      */
 306  
     private void convertJunitCoreParameters()
 307  
     {
 308  0
         if ( getProperties() == null )
 309  
         {
 310  0
             setProperties( new Properties() );
 311  
         }
 312  
 
 313  0
         if ( this.getParallel() != null )
 314  
         {
 315  0
             getProperties().setProperty( "parallel", this.getParallel() );
 316  
         }
 317  0
         if ( this.getThreadCount() > 0 )
 318  
         {
 319  0
             getProperties().setProperty( "threadCount", Integer.toString( this.getThreadCount() ) );
 320  
         }
 321  0
         getProperties().setProperty( "perCoreThreadCount", Boolean.toString( getPerCoreThreadCount() ) );
 322  0
         getProperties().setProperty( "useUnlimitedThreads", Boolean.toString( getUseUnlimitedThreads() ) );
 323  0
     }
 324  
 
 325  
     private boolean isJunit47Compatible( Artifact artifact )
 326  
     {
 327  0
         return dependencyResolver.isWithinVersionSpec( artifact, "[4.7,)" );
 328  
     }
 329  
 
 330  
     private boolean isAnyJunit4( Artifact artifact )
 331  
     {
 332  0
         return dependencyResolver.isWithinVersionSpec( artifact, "[4.0,)" );
 333  
     }
 334  
 
 335  
     boolean isForkModeNever()
 336  
     {
 337  0
         return ForkConfiguration.FORK_NEVER.equals( getForkMode() );
 338  
     }
 339  
 
 340  
     private java.util.List getRunOrders()
 341  
     {
 342  0
         String runOrderString = getRunOrder();
 343  0
         RunOrder[] runOrder = runOrderString == null ? RunOrder.DEFAULT : RunOrder.valueOfMulti( runOrderString );
 344  0
         return Arrays.asList( runOrder );
 345  
     }
 346  
 
 347  
     private boolean requiresRunHistory()
 348  
     {
 349  0
         final List runOrders = getRunOrders();
 350  0
         return runOrders.contains( RunOrder.BALANCED ) || runOrders.contains( RunOrder.FAILEDFIRST );
 351  
     }
 352  
 
 353  
     protected ProviderConfiguration createProviderConfiguration( String configurationHash )
 354  
         throws MojoExecutionException, MojoFailureException
 355  
     {
 356  0
         ReporterConfiguration reporterConfiguration =
 357  
             new ReporterConfiguration( getReportsDirectory(), Boolean.valueOf( isTrimStackTrace() ) );
 358  
 
 359  
         Artifact testNgArtifact;
 360  
         try
 361  
         {
 362  0
             testNgArtifact = getTestNgArtifact();
 363  
         }
 364  0
         catch ( InvalidVersionSpecificationException e )
 365  
         {
 366  0
             throw new MojoExecutionException( "Error determining the TestNG version requested: " + e.getMessage(), e );
 367  0
         }
 368  
 
 369  0
         DirectoryScannerParameters directoryScannerParameters = null;
 370  0
         final boolean isTestNg = testNgArtifact != null;
 371  0
         TestArtifactInfo testNg =
 372  
             isTestNg ? new TestArtifactInfo( testNgArtifact.getVersion(), testNgArtifact.getClassifier() ) : null;
 373  0
         List testXml = getSuiteXmlFiles() != null ? Arrays.asList( getSuiteXmlFiles() ) : null;
 374  0
         TestRequest testSuiteDefinition =
 375  
             new TestRequest( testXml, getTestSourceDirectory(), getTest(), getTestMethod() );
 376  
         final boolean failIfNoTests;
 377  
 
 378  0
         if ( isValidSuiteXmlFileConfig() && getTest() == null )
 379  
         {
 380  0
             failIfNoTests = getFailIfNoTests() != null && getFailIfNoTests().booleanValue();
 381  0
             if ( !isTestNg )
 382  
             {
 383  0
                 throw new MojoExecutionException( "suiteXmlFiles is configured, but there is no TestNG dependency" );
 384  
             }
 385  
         }
 386  
         else
 387  
         {
 388  0
             if ( isSpecificTestSpecified() && getFailIfNoTests() == null )
 389  
             {
 390  0
                 setFailIfNoTests( Boolean.TRUE );
 391  
             }
 392  
 
 393  0
             failIfNoTests = getFailIfNoTests() != null && getFailIfNoTests().booleanValue();
 394  
 
 395  0
             List includes = getIncludeList();
 396  0
             List excludes = getExcludeList();
 397  0
             directoryScannerParameters = new DirectoryScannerParameters( getTestClassesDirectory(), includes, excludes,
 398  
                                                                          Boolean.valueOf( failIfNoTests ),
 399  
                                                                          getRunOrder() );
 400  
         }
 401  
 
 402  0
         Properties providerProperties = getProperties();
 403  0
         if ( providerProperties == null )
 404  
         {
 405  0
             providerProperties = new Properties();
 406  
         }
 407  
 
 408  0
         RunOrderParameters runOrderParameters =
 409  
             new RunOrderParameters( getRunOrder(), getStatisticsFileName( configurationHash ) );
 410  
 
 411  0
         return new ProviderConfiguration( directoryScannerParameters, runOrderParameters, failIfNoTests,
 412  
                                           reporterConfiguration, testNg, testSuiteDefinition, providerProperties,
 413  
                                           null );
 414  
     }
 415  
 
 416  
     public File getStatisticsFile( String configurationHash )
 417  
     {
 418  0
         return new File( getStatisticsFileName( configurationHash ) );
 419  
     }
 420  
 
 421  
     public String getStatisticsFileName( String configurationHash )
 422  
     {
 423  0
         return getReportsDirectory().getParentFile().getParentFile() + File.separator + ".surefire-"
 424  
             + configurationHash;
 425  
     }
 426  
 
 427  
 
 428  
     StartupConfiguration createStartupConfiguration( ForkConfiguration forkConfiguration, ProviderInfo provider,
 429  
                                                      ClassLoaderConfiguration classLoaderConfiguration )
 430  
         throws MojoExecutionException, MojoFailureException
 431  
     {
 432  
 
 433  
         try
 434  
         {
 435  0
             provider.addProviderProperties();
 436  0
             String providerName = provider.getProviderName();
 437  0
             Classpath providerClasspath = provider.getProviderClasspath();
 438  0
             Classpath inprocClassPath = new Classpath( providerClasspath );
 439  0
             Artifact surefireArtifact = getCommonArtifact();
 440  0
             inprocClassPath.addClassPathElementUrl( surefireArtifact.getFile().getAbsolutePath() );
 441  
 
 442  0
             final Classpath testClasspath = generateTestClasspath();
 443  
 
 444  0
             logClasspath( testClasspath, "test classpath" );
 445  0
             logClasspath( providerClasspath, "provider classpath" );
 446  0
             final ClasspathConfiguration classpathConfiguration =
 447  
                 new ClasspathConfiguration( testClasspath, providerClasspath, inprocClassPath, isEnableAssertions(),
 448  
                                             isChildDelegation() );
 449  
 
 450  0
             return new StartupConfiguration( providerName, classpathConfiguration, classLoaderConfiguration,
 451  
                                              forkConfiguration.getForkMode(), false );
 452  
         }
 453  0
         catch ( ArtifactResolutionException e )
 454  
         {
 455  0
             throw new MojoExecutionException( "Unable to generate classpath: " + e, e );
 456  
         }
 457  0
         catch ( ArtifactNotFoundException e )
 458  
         {
 459  0
             throw new MojoExecutionException( "Unable to generate classpath: " + e, e );
 460  
         }
 461  0
         catch ( InvalidVersionSpecificationException e )
 462  
         {
 463  0
             throw new MojoExecutionException( "Unable to generate classpath: " + e, e );
 464  
         }
 465  
 
 466  
     }
 467  
 
 468  
     private Artifact getCommonArtifact()
 469  
     {
 470  0
         return (Artifact) getPluginArtifactMap().get( "org.apache.maven.surefire:maven-surefire-common" );
 471  
     }
 472  
 
 473  
     private StartupReportConfiguration getStartupReportConfiguration( String configChecksum )
 474  
     {
 475  0
         return new StartupReportConfiguration( isUseFile(), isPrintSummary(), getReportFormat(),
 476  
                                                isRedirectTestOutputToFile(), isDisableXmlReport(),
 477  
                                                getReportsDirectory(), isTrimStackTrace(), getReportNameSuffix(),
 478  
                                                configChecksum, requiresRunHistory() );
 479  
     }
 480  
 
 481  
     void logClasspath( Classpath classpath, String descriptor )
 482  
     {
 483  0
         getLog().debug( descriptor + " classpath:" );
 484  0
         for ( Iterator i = classpath.getClassPath().iterator(); i.hasNext(); )
 485  
         {
 486  0
             String classpathElement = (String) i.next();
 487  0
             if ( classpathElement == null )
 488  
             {
 489  0
                 getLog().warn( "The test classpath contains a null element." );
 490  
             }
 491  
             else
 492  
             {
 493  0
                 getLog().debug( "  " + classpathElement );
 494  
             }
 495  0
         }
 496  0
     }
 497  
 
 498  
 
 499  
     private boolean isSpecificTestSpecified()
 500  
     {
 501  0
         return getTest() != null;
 502  
     }
 503  
 
 504  
     private boolean isValidSuiteXmlFileConfig()
 505  
     {
 506  0
         return getSuiteXmlFiles() != null && getSuiteXmlFiles().length > 0;
 507  
     }
 508  
 
 509  
     private List getExcludeList()
 510  
     {
 511  
         List excludes;
 512  0
         if ( isSpecificTestSpecified() )
 513  
         {
 514  
             // Check to see if we are running a single test. The raw parameter will
 515  
             // come through if it has not been set.
 516  
             // FooTest -> **/FooTest.java
 517  
 
 518  0
             excludes = new ArrayList();
 519  
         }
 520  
         else
 521  
         {
 522  
 
 523  0
             excludes = this.getExcludes();
 524  
 
 525  
             // defaults here, qdox doesn't like the end javadoc value
 526  
             // Have to wrap in an ArrayList as surefire expects an ArrayList instead of a List for some reason
 527  0
             if ( excludes == null || excludes.size() == 0 )
 528  
             {
 529  0
                 excludes = new ArrayList( Arrays.asList( new String[]{ "**/*$*" } ) );
 530  
             }
 531  
         }
 532  0
         return excludes;
 533  
     }
 534  
 
 535  
     private List getIncludeList()
 536  
     {
 537  
         List includes;
 538  0
         if ( isSpecificTestSpecified() )
 539  
         {
 540  
             // Check to see if we are running a single test. The raw parameter will
 541  
             // come through if it has not been set.
 542  
 
 543  
             // FooTest -> **/FooTest.java
 544  
 
 545  0
             includes = new ArrayList();
 546  
 
 547  0
             String[] testRegexes = StringUtils.split( getTest(), "," );
 548  
 
 549  0
             for ( int i = 0; i < testRegexes.length; i++ )
 550  
             {
 551  0
                 String testRegex = testRegexes[i];
 552  0
                 if ( testRegex.endsWith( ".java" ) )
 553  
                 {
 554  0
                     testRegex = testRegex.substring( 0, testRegex.length() - 5 );
 555  
                 }
 556  
                 // Allow paths delimited by '.' or '/'
 557  0
                 testRegex = testRegex.replace( '.', '/' );
 558  0
                 includes.add( "**/" + testRegex + ".java" );
 559  
             }
 560  0
         }
 561  
         else
 562  
         {
 563  0
             includes = this.getIncludes();
 564  
 
 565  
             // defaults here, qdox doesn't like the end javadoc value
 566  
             // Have to wrap in an ArrayList as surefire expects an ArrayList instead of a List for some reason
 567  0
             if ( includes == null || includes.size() == 0 )
 568  
             {
 569  0
                 includes = new ArrayList( Arrays.asList( getDefaultIncludes() ) );
 570  
             }
 571  
         }
 572  0
         return includes;
 573  
     }
 574  
 
 575  
     private Artifact getTestNgArtifact()
 576  
         throws MojoFailureException, InvalidVersionSpecificationException
 577  
     {
 578  
         // TODO: this is pretty manual, but I'd rather not require the plugin > dependencies section right now
 579  0
         Artifact artifact = (Artifact) getProjectArtifactMap().get( getTestNGArtifactName() );
 580  
 
 581  0
         if ( artifact != null )
 582  
         {
 583  0
             VersionRange range = VersionRange.createFromVersionSpec( "[4.7,)" );
 584  0
             if ( !range.containsVersion( new DefaultArtifactVersion( artifact.getVersion() ) ) )
 585  
             {
 586  0
                 throw new MojoFailureException(
 587  
                     "TestNG support requires version 4.7 or above. You have declared version "
 588  
                         + artifact.getVersion() );
 589  
             }
 590  
         }
 591  0
         return artifact;
 592  
 
 593  
     }
 594  
 
 595  
     private Artifact getJunitArtifact()
 596  
     {
 597  0
         return (Artifact) getProjectArtifactMap().get( getJunitArtifactName() );
 598  
     }
 599  
 
 600  
     private Artifact getJunitDepArtifact()
 601  
     {
 602  0
         return (Artifact) getProjectArtifactMap().get( "junit:junit-dep" );
 603  
     }
 604  
 
 605  
     protected ForkStarter createForkStarter( ProviderInfo provider, ForkConfiguration forkConfiguration,
 606  
                                              ClassLoaderConfiguration classLoaderConfiguration )
 607  
         throws MojoExecutionException, MojoFailureException
 608  
     {
 609  0
         StartupConfiguration startupConfiguration =
 610  
             createStartupConfiguration( forkConfiguration, provider, classLoaderConfiguration );
 611  0
         String configChecksum = getConfigChecksum();
 612  0
         StartupReportConfiguration startupReportConfiguration = getStartupReportConfiguration( configChecksum );
 613  0
         ProviderConfiguration providerConfiguration = createProviderConfiguration( configChecksum );
 614  0
         return new ForkStarter( providerConfiguration, startupConfiguration, forkConfiguration,
 615  
                                 getForkedProcessTimeoutInSeconds(), startupReportConfiguration );
 616  
     }
 617  
 
 618  
     protected InPluginVMSurefireStarter createInprocessStarter( ProviderInfo provider,
 619  
                                                                 ForkConfiguration forkConfiguration,
 620  
                                                                 ClassLoaderConfiguration classLoaderConfiguration )
 621  
         throws MojoExecutionException, MojoFailureException
 622  
     {
 623  0
         StartupConfiguration startupConfiguration =
 624  
             createStartupConfiguration( forkConfiguration, provider, classLoaderConfiguration );
 625  0
         String configChecksum = getConfigChecksum();
 626  0
         StartupReportConfiguration startupReportConfiguration = getStartupReportConfiguration( configChecksum );
 627  0
         ProviderConfiguration providerConfiguration = createProviderConfiguration( configChecksum );
 628  0
         return new InPluginVMSurefireStarter( startupConfiguration, providerConfiguration, startupReportConfiguration );
 629  
 
 630  
     }
 631  
 
 632  
     protected ForkConfiguration getForkConfiguration()
 633  
     {
 634  0
         File tmpDir = getSurefireTempDir();
 635  
         //noinspection ResultOfMethodCallIgnored
 636  0
         tmpDir.mkdirs();
 637  
 
 638  0
         Artifact shadeFire = (Artifact) getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-shadefire" );
 639  
 
 640  0
         surefireBooterArtifact = (Artifact) getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-booter" );
 641  0
         if ( surefireBooterArtifact == null )
 642  
         {
 643  0
             throw new RuntimeException( "Unable to locate surefire-booter in the list of plugin artifacts" );
 644  
         }
 645  
 
 646  0
         surefireBooterArtifact.isSnapshot(); // MNG-2961: before Maven 2.0.8, fixes getBaseVersion to be -SNAPSHOT if needed
 647  
 
 648  0
         final Classpath bootClasspathConfiguration =
 649  
             getArtifactClasspath( shadeFire != null ? shadeFire : surefireBooterArtifact );
 650  
 
 651  0
         ForkConfiguration fork = new ForkConfiguration( bootClasspathConfiguration, getForkMode(), tmpDir );
 652  
 
 653  0
         fork.setTempDirectory( tmpDir );
 654  
 
 655  0
         processSystemProperties( !fork.isForking() );
 656  
 
 657  0
         verifyLegalSystemProperties();
 658  
 
 659  0
         if ( getLog().isDebugEnabled() )
 660  
         {
 661  0
             showMap( getInternalSystemProperties(), "system property" );
 662  
         }
 663  
 
 664  0
         Toolchain tc = getToolchain();
 665  
 
 666  0
         if ( tc != null )
 667  
         {
 668  0
             getLog().info( "Toolchain in " + getPluginName() + "-plugin: " + tc );
 669  0
             if ( isForkModeNever() )
 670  
             {
 671  0
                 setForkMode( ForkConfiguration.FORK_ONCE );
 672  
             }
 673  0
             if ( getJvm() != null )
 674  
             {
 675  0
                 getLog().warn( "Toolchains are ignored, 'executable' parameter is set to " + getJvm() );
 676  
             }
 677  
             else
 678  
             {
 679  0
                 setJvm( tc.findTool( "java" ) ); //NOI18N
 680  
             }
 681  
         }
 682  
 
 683  0
         if ( fork.isForking() )
 684  
         {
 685  0
             setUseSystemClassLoader( isUseSystemClassLoader() );
 686  
 
 687  0
             fork.setSystemProperties( getInternalSystemProperties() );
 688  
 
 689  0
             if ( "true".equals( getDebugForkedProcess() ) )
 690  
             {
 691  0
                 setDebugForkedProcess(
 692  
                     "-Xdebug -Xnoagent -Djava.compiler=NONE -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005" );
 693  
             }
 694  
 
 695  0
             fork.setDebugLine( getDebugForkedProcess() );
 696  
 
 697  0
             if ( ( getJvm() == null || "".equals( getJvm() ) ) )
 698  
             {
 699  
                 // use the same JVM as the one used to run Maven (the "java.home" one)
 700  0
                 setJvm( System.getProperty( "java.home" ) + File.separator + "bin" + File.separator + "java" );
 701  0
                 getLog().debug( "Using JVM: " + getJvm() );
 702  
             }
 703  
 
 704  0
             fork.setJvmExecutable( getJvm() );
 705  
 
 706  0
             if ( getWorkingDirectory() != null )
 707  
             {
 708  0
                 fork.setWorkingDirectory( getWorkingDirectory() );
 709  
             }
 710  
             else
 711  
             {
 712  0
                 fork.setWorkingDirectory( getBasedir() );
 713  
             }
 714  
 
 715  0
             fork.setArgLine( getArgLine() );
 716  
 
 717  0
             fork.setEnvironmentVariables( getEnvironmentVariables() );
 718  
 
 719  0
             if ( getLog().isDebugEnabled() )
 720  
             {
 721  0
                 showMap( getEnvironmentVariables(), "environment variable" );
 722  
 
 723  0
                 fork.setDebug( true );
 724  
             }
 725  
 
 726  0
             if ( getArgLine() != null )
 727  
             {
 728  0
                 List args = Arrays.asList( getArgLine().split( " " ) );
 729  0
                 if ( args.contains( "-da" ) || args.contains( "-disableassertions" ) )
 730  
                 {
 731  0
                     setEnableAssertions( false );
 732  
                 }
 733  
             }
 734  
         }
 735  0
         return fork;
 736  
     }
 737  
 
 738  
     private void verifyLegalSystemProperties()
 739  
     {
 740  0
         final Properties properties = getInternalSystemProperties();
 741  0
         Iterator iter = properties.keySet().iterator();
 742  
 
 743  0
         while ( iter.hasNext() )
 744  
         {
 745  0
             String key = (String) iter.next();
 746  
 
 747  0
             if ( "java.library.path".equals( key ) )
 748  
             {
 749  0
                 getLog().warn(
 750  
                     "java.library.path cannot be set as system property, use <argLine>-Djava.library.path=...<argLine> instead" );
 751  
             }
 752  0
         }
 753  0
     }
 754  
 
 755  
 
 756  
     /**
 757  
      * Where surefire stores its own temp files
 758  
      *
 759  
      * @return A file pointing to the location of surefire's own temp files
 760  
      */
 761  
     private File getSurefireTempDir()
 762  
     {
 763  0
         return new File( getReportsDirectory().getParentFile(), "surefire" );
 764  
     }
 765  
 
 766  
     private String getConfigChecksum()
 767  
     {
 768  0
         ChecksumCalculator checksum = new ChecksumCalculator();
 769  0
         checksum.add( getPluginName() );
 770  0
         checksum.add( isSkipTests() );
 771  0
         checksum.add( isSkipExec() );
 772  0
         checksum.add( isSkip() );
 773  0
         checksum.add( getTestClassesDirectory() );
 774  0
         checksum.add( getClassesDirectory() );
 775  0
         checksum.add( getClasspathDependencyExcludes() );
 776  0
         checksum.add( getClasspathDependencyScopeExclude() );
 777  0
         checksum.add( getAdditionalClasspathElements() );
 778  0
         checksum.add( getReportsDirectory() );
 779  0
         checksum.add( getTestSourceDirectory() );
 780  0
         checksum.add( getTest() );
 781  0
         checksum.add( getIncludes() );
 782  0
         checksum.add( getExcludes() );
 783  0
         checksum.add( getLocalRepository() );
 784  0
         checksum.add( getSystemProperties() );
 785  0
         checksum.add( getSystemPropertyVariables() );
 786  0
         checksum.add( getSystemPropertiesFile() );
 787  0
         checksum.add( getProperties() );
 788  0
         checksum.add( isPrintSummary() );
 789  0
         checksum.add( getReportFormat() );
 790  0
         checksum.add( getReportNameSuffix() );
 791  0
         checksum.add( isUseFile() );
 792  0
         checksum.add( isRedirectTestOutputToFile() );
 793  0
         checksum.add( getForkMode() );
 794  0
         checksum.add( getJvm() );
 795  0
         checksum.add( getArgLine() );
 796  0
         checksum.add( getDebugForkedProcess() );
 797  0
         checksum.add( getForkedProcessTimeoutInSeconds() );
 798  0
         checksum.add( getEnvironmentVariables() );
 799  0
         checksum.add( getWorkingDirectory() );
 800  0
         checksum.add( isChildDelegation() );
 801  0
         checksum.add( getGroups() );
 802  0
         checksum.add( getExcludedGroups() );
 803  0
         checksum.add( getSuiteXmlFiles() );
 804  0
         checksum.add( getJunitArtifact() );
 805  0
         checksum.add( getTestNGArtifactName() );
 806  0
         checksum.add( getThreadCount() );
 807  0
         checksum.add( getPerCoreThreadCount() );
 808  0
         checksum.add( getUseUnlimitedThreads() );
 809  0
         checksum.add( getParallel() );
 810  0
         checksum.add( isTrimStackTrace() );
 811  0
         checksum.add( getRemoteRepositories() );
 812  0
         checksum.add( isDisableXmlReport() );
 813  0
         checksum.add( isUseSystemClassLoader() );
 814  0
         checksum.add( isUseManifestOnlyJar() );
 815  0
         checksum.add( isEnableAssertions() );
 816  0
         checksum.add( getObjectFactory() );
 817  0
         checksum.add( getFailIfNoTests() );
 818  0
         checksum.add( getRunOrder() );
 819  0
         addPluginSpecificChecksumItems( checksum );
 820  0
         return checksum.getSha1();
 821  
 
 822  
     }
 823  
 
 824  
     protected abstract void addPluginSpecificChecksumItems( ChecksumCalculator checksum );
 825  
 
 826  
     protected boolean hasExecutedBefore()
 827  
     {
 828  
         // A tribute to Linus Torvalds
 829  0
         String configChecksum = getConfigChecksum();
 830  0
         Map pluginContext = getPluginContext();
 831  0
         if ( pluginContext.containsKey( configChecksum ) )
 832  
         {
 833  0
             getLog().info( "Skipping execution of surefire because it has already been run for this configuration" );
 834  0
             return true;
 835  
         }
 836  0
         pluginContext.put( configChecksum, configChecksum );
 837  
 
 838  0
         return false;
 839  
     }
 840  
 
 841  
     protected ClassLoaderConfiguration getClassLoaderConfiguration( ForkConfiguration fork )
 842  
     {
 843  0
         return fork.isForking()
 844  
             ? new ClassLoaderConfiguration( isUseSystemClassLoader(), isUseManifestOnlyJar() )
 845  
             : new ClassLoaderConfiguration( false, false );
 846  
     }
 847  
 
 848  
     protected abstract String[] getDefaultIncludes();
 849  
 
 850  
     /**
 851  
      * Generate the test classpath.
 852  
      *
 853  
      * @return List containing the classpath elements
 854  
      * @throws InvalidVersionSpecificationException
 855  
      *                                     when it happens
 856  
      * @throws MojoFailureException        when it happens
 857  
      * @throws ArtifactNotFoundException   when it happens
 858  
      * @throws ArtifactResolutionException when it happens
 859  
      */
 860  
     Classpath generateTestClasspath()
 861  
         throws InvalidVersionSpecificationException, MojoFailureException, ArtifactResolutionException,
 862  
         ArtifactNotFoundException
 863  
     {
 864  0
         List classpath = new ArrayList( 2 + getProject().getArtifacts().size() );
 865  
 
 866  0
         classpath.add( getTestClassesDirectory().getAbsolutePath() );
 867  
 
 868  0
         classpath.add( getClassesDirectory().getAbsolutePath() );
 869  
 
 870  0
         Set classpathArtifacts = getProject().getArtifacts();
 871  
 
 872  0
         if ( getClasspathDependencyScopeExclude() != null && !getClasspathDependencyScopeExclude().equals( "" ) )
 873  
         {
 874  0
             ArtifactFilter dependencyFilter = new ScopeArtifactFilter( getClasspathDependencyScopeExclude() );
 875  0
             classpathArtifacts = this.filterArtifacts( classpathArtifacts, dependencyFilter );
 876  
         }
 877  
 
 878  0
         if ( getClasspathDependencyExcludes() != null )
 879  
         {
 880  0
             ArtifactFilter dependencyFilter = new PatternIncludesArtifactFilter( getClasspathDependencyExcludes() );
 881  0
             classpathArtifacts = this.filterArtifacts( classpathArtifacts, dependencyFilter );
 882  
         }
 883  
 
 884  0
         for ( Iterator iter = classpathArtifacts.iterator(); iter.hasNext(); )
 885  
         {
 886  0
             Artifact artifact = (Artifact) iter.next();
 887  0
             if ( artifact.getArtifactHandler().isAddedToClasspath() )
 888  
             {
 889  0
                 File file = artifact.getFile();
 890  0
                 if ( file != null )
 891  
                 {
 892  0
                     classpath.add( file.getPath() );
 893  
                 }
 894  
             }
 895  0
         }
 896  
 
 897  
         // Add additional configured elements to the classpath
 898  0
         if ( getAdditionalClasspathElements() != null )
 899  
         {
 900  0
             for ( Iterator iter = getAdditionalClasspathElements().iterator(); iter.hasNext(); )
 901  
             {
 902  0
                 String classpathElement = (String) iter.next();
 903  0
                 if ( classpathElement != null )
 904  
                 {
 905  0
                     classpath.add( classpathElement );
 906  
                 }
 907  0
             }
 908  
         }
 909  
 
 910  
         // adding TestNG MethodSelector to the classpath
 911  
         // Todo: move
 912  0
         if ( getTestNgArtifact() != null )
 913  
         {
 914  0
             Artifact testNgUtils = getTestNgUtilsArtifact();
 915  0
             String path = testNgUtils.getFile().getPath();
 916  0
             classpath.add( path );
 917  
 
 918  
         }
 919  
 
 920  0
         return new Classpath( classpath );
 921  
     }
 922  
 
 923  
     Artifact getTestNgUtilsArtifact()
 924  
         throws ArtifactResolutionException, ArtifactNotFoundException
 925  
     {
 926  0
         Artifact surefireArtifact =
 927  
             (Artifact) getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-booter" );
 928  0
         String surefireVersion = surefireArtifact.getBaseVersion();
 929  0
         Artifact testNgUtils =
 930  
             getArtifactFactory().createArtifact( "org.apache.maven.surefire", "surefire-testng-utils", surefireVersion,
 931  
                                                  "runtime", "jar" );
 932  
 
 933  0
         getArtifactResolver().resolve( testNgUtils, getRemoteRepositories(), getLocalRepository() );
 934  0
         return testNgUtils;
 935  
     }
 936  
 
 937  
     /**
 938  
      * Return a new set containing only the artifacts accepted by the given filter.
 939  
      *
 940  
      * @param artifacts The unfiltered artifacts
 941  
      * @param filter    The filter to apply
 942  
      * @return The filtered result
 943  
      */
 944  
     private Set filterArtifacts( Set artifacts, ArtifactFilter filter )
 945  
     {
 946  0
         Set filteredArtifacts = new LinkedHashSet();
 947  
 
 948  0
         for ( Iterator iter = artifacts.iterator(); iter.hasNext(); )
 949  
         {
 950  0
             Artifact artifact = (Artifact) iter.next();
 951  0
             if ( !filter.include( artifact ) )
 952  
             {
 953  0
                 filteredArtifacts.add( artifact );
 954  
             }
 955  0
         }
 956  
 
 957  0
         return filteredArtifacts;
 958  
     }
 959  
 
 960  
     private void showMap( Map map, String setting )
 961  
     {
 962  0
         for ( Iterator i = map.keySet().iterator(); i.hasNext(); )
 963  
         {
 964  0
             String key = (String) i.next();
 965  0
             String value = (String) map.get( key );
 966  0
             getLog().debug( "Setting " + setting + " [" + key + "]=[" + value + "]" );
 967  0
         }
 968  0
     }
 969  
 
 970  
 
 971  
     private ArtifactResolutionResult resolveArtifact( Artifact filteredArtifact, Artifact providerArtifact )
 972  
     {
 973  0
         ArtifactFilter filter = null;
 974  0
         if ( filteredArtifact != null )
 975  
         {
 976  0
             filter = new ExcludesArtifactFilter(
 977  
                 Collections.singletonList( filteredArtifact.getGroupId() + ":" + filteredArtifact.getArtifactId() ) );
 978  
         }
 979  
 
 980  0
         Artifact originatingArtifact = getArtifactFactory().createBuildArtifact( "dummy", "dummy", "1.0", "jar" );
 981  
 
 982  
         try
 983  
         {
 984  0
             return getArtifactResolver().resolveTransitively( Collections.singleton( providerArtifact ),
 985  
                                                               originatingArtifact, getLocalRepository(),
 986  
                                                               getRemoteRepositories(), getMetadataSource(), filter );
 987  
         }
 988  0
         catch ( ArtifactResolutionException e )
 989  
         {
 990  0
             throw new NestedRuntimeException( e );
 991  
         }
 992  0
         catch ( ArtifactNotFoundException e )
 993  
         {
 994  0
             throw new NestedRuntimeException( e );
 995  
         }
 996  
     }
 997  
 
 998  
     private Classpath getArtifactClasspath( Artifact surefireArtifact )
 999  
     {
 1000  0
         ArtifactResolutionResult result = resolveArtifact( null, surefireArtifact );
 1001  
 
 1002  0
         List items = new ArrayList();
 1003  0
         for ( Iterator i = result.getArtifacts().iterator(); i.hasNext(); )
 1004  
         {
 1005  0
             Artifact artifact = (Artifact) i.next();
 1006  
 
 1007  0
             getLog().debug(
 1008  
                 "Adding to " + getPluginName() + " booter test classpath: " + artifact.getFile().getAbsolutePath() +
 1009  
                     " Scope: " + artifact.getScope() );
 1010  
 
 1011  0
             items.add( artifact.getFile().getAbsolutePath() );
 1012  0
         }
 1013  0
         return new Classpath( items );
 1014  
     }
 1015  
 
 1016  
     void processSystemProperties( boolean setInSystem )
 1017  
     {
 1018  0
         copyPropertiesToInternalSystemProperties( getSystemProperties() );
 1019  
 
 1020  0
         if ( this.getSystemPropertiesFile() != null )
 1021  
         {
 1022  0
             Properties props = new Properties();
 1023  
             try
 1024  
             {
 1025  0
                 FileInputStream fis = new FileInputStream( getSystemPropertiesFile() );
 1026  0
                 props.load( fis );
 1027  0
                 fis.close();
 1028  
             }
 1029  0
             catch ( IOException e )
 1030  
             {
 1031  0
                 String msg =
 1032  
                     "The system property file '" + getSystemPropertiesFile().getAbsolutePath() + "' can't be read.";
 1033  0
                 if ( getLog().isDebugEnabled() )
 1034  
                 {
 1035  0
                     getLog().warn( msg, e );
 1036  
                 }
 1037  
                 else
 1038  
                 {
 1039  0
                     getLog().warn( msg );
 1040  
                 }
 1041  0
             }
 1042  
 
 1043  0
             Enumeration keys = props.propertyNames();
 1044  
             //loop through all properties
 1045  0
             while ( keys.hasMoreElements() )
 1046  
             {
 1047  0
                 String key = (String) keys.nextElement();
 1048  0
                 String value = props.getProperty( key );
 1049  0
                 getInternalSystemProperties().setProperty( key, value );
 1050  0
             }
 1051  
         }
 1052  
 
 1053  0
         if ( this.getSystemPropertyVariables() != null )
 1054  
         {
 1055  0
             for ( Iterator i = getSystemPropertyVariables().keySet().iterator(); i.hasNext(); )
 1056  
             {
 1057  0
                 String key = (String) i.next();
 1058  0
                 String value = (String) getSystemPropertyVariables().get( key );
 1059  
                 //java Properties does not accept null value
 1060  0
                 if ( value != null )
 1061  
                 {
 1062  0
                     getInternalSystemProperties().setProperty( key, value );
 1063  
                 }
 1064  0
             }
 1065  
         }
 1066  
 
 1067  0
         setOriginalSystemProperties( (Properties) System.getProperties().clone() );
 1068  
 
 1069  
         // We used to take all of our system properties and dump them in with the
 1070  
         // user specified properties for SUREFIRE-121, causing SUREFIRE-491.
 1071  
         // Not gonna do THAT any more... instead, we only propagate those system properties
 1072  
         // that have been explicitly specified by the user via -Dkey=value on the CLI
 1073  
 
 1074  0
         copyPropertiesToInternalSystemProperties( getUserProperties() );
 1075  
 
 1076  0
         getInternalSystemProperties().setProperty( "basedir", getBasedir().getAbsolutePath() );
 1077  0
         getInternalSystemProperties().setProperty( "user.dir", getWorkingDirectory().getAbsolutePath() );
 1078  0
         getInternalSystemProperties().setProperty( "localRepository", getLocalRepository().getBasedir() );
 1079  
 
 1080  0
         if ( setInSystem )
 1081  
         {
 1082  
             // Add all system properties configured by the user
 1083  0
             Iterator iter = getInternalSystemProperties().keySet().iterator();
 1084  
 
 1085  0
             while ( iter.hasNext() )
 1086  
             {
 1087  0
                 String key = (String) iter.next();
 1088  
 
 1089  0
                 String value = getInternalSystemProperties().getProperty( key );
 1090  
 
 1091  0
                 System.setProperty( key, value );
 1092  0
             }
 1093  
         }
 1094  0
     }
 1095  
 
 1096  
     private void copyPropertiesToInternalSystemProperties( Properties properties )
 1097  
     {
 1098  0
         if ( properties != null )
 1099  
         {
 1100  0
             for ( Iterator i = properties.keySet().iterator(); i.hasNext(); )
 1101  
             {
 1102  0
                 String key = (String) i.next();
 1103  0
                 String value = properties.getProperty( key );
 1104  0
                 getInternalSystemProperties().setProperty( key, value );
 1105  0
             }
 1106  
         }
 1107  0
     }
 1108  
 
 1109  
     private Properties getUserProperties()
 1110  
     {
 1111  0
         Properties props = null;
 1112  
         try
 1113  
         {
 1114  
             // try calling MavenSession.getUserProperties() from Maven 2.1.0-M1+
 1115  0
             Method getUserProperties = getSession().getClass().getMethod( "getUserProperties", null );
 1116  0
             props = (Properties) getUserProperties.invoke( getSession(), null );
 1117  
         }
 1118  0
         catch ( Exception e )
 1119  
         {
 1120  0
             String msg = "Build uses Maven 2.0.x, cannot propagate system properties"
 1121  
                 + " from command line to tests (cf. SUREFIRE-121)";
 1122  0
             if ( getLog().isDebugEnabled() )
 1123  
             {
 1124  0
                 getLog().warn( msg, e );
 1125  
             }
 1126  
             else
 1127  
             {
 1128  0
                 getLog().warn( msg );
 1129  
             }
 1130  0
         }
 1131  0
         if ( props == null )
 1132  
         {
 1133  0
             props = new Properties();
 1134  
         }
 1135  0
         return props;
 1136  
     }
 1137  
 
 1138  
 
 1139  
     void ensureWorkingDirectoryExists()
 1140  
         throws MojoFailureException
 1141  
     {
 1142  0
         if ( getWorkingDirectory() == null )
 1143  
         {
 1144  0
             throw new MojoFailureException( "workingDirectory cannot be null" );
 1145  
         }
 1146  
 
 1147  0
         if ( !getWorkingDirectory().exists() )
 1148  
         {
 1149  0
             if ( !getWorkingDirectory().mkdirs() )
 1150  
             {
 1151  0
                 throw new MojoFailureException( "Cannot create workingDirectory " + getWorkingDirectory() );
 1152  
             }
 1153  
         }
 1154  
 
 1155  0
         if ( !getWorkingDirectory().isDirectory() )
 1156  
         {
 1157  0
             throw new MojoFailureException(
 1158  
                 "workingDirectory " + getWorkingDirectory() + " exists and is not a directory" );
 1159  
         }
 1160  0
     }
 1161  
 
 1162  
     void ensureParallelRunningCompatibility()
 1163  
         throws MojoFailureException
 1164  
     {
 1165  0
         if ( isMavenParallel() && isForkModeNever() )
 1166  
         {
 1167  0
             throw new MojoFailureException( "parallel maven execution is not compatible with surefire forkmode NEVER" );
 1168  
         }
 1169  0
     }
 1170  
 
 1171  
     void warnIfUselessUseSystemClassLoaderParameter()
 1172  
     {
 1173  0
         if ( isUseSystemClassLoader() && isForkModeNever() )
 1174  
         {
 1175  0
             getLog().warn( "useSystemClassloader setting has no effect when not forking" );
 1176  
         }
 1177  0
     }
 1178  
 
 1179  
     class TestNgProviderInfo
 1180  
         implements ProviderInfo
 1181  
     {
 1182  
         private final Artifact testNgArtifact;
 1183  
 
 1184  
         TestNgProviderInfo( Artifact testNgArtifact )
 1185  0
         {
 1186  0
             this.testNgArtifact = testNgArtifact;
 1187  0
         }
 1188  
 
 1189  
         public String getProviderName()
 1190  
         {
 1191  0
             return "org.apache.maven.surefire.testng.TestNGProvider";
 1192  
         }
 1193  
 
 1194  
         public boolean isApplicable()
 1195  
         {
 1196  0
             return testNgArtifact != null;
 1197  
         }
 1198  
 
 1199  
         public void addProviderProperties()
 1200  
         {
 1201  0
             convertTestNGParameters();
 1202  0
         }
 1203  
 
 1204  
         public Classpath getProviderClasspath()
 1205  
             throws ArtifactResolutionException, ArtifactNotFoundException
 1206  
         {
 1207  0
             Artifact surefireArtifact =
 1208  
                 (Artifact) getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-booter" );
 1209  0
             return dependencyResolver.getProviderClasspath( "surefire-testng", surefireArtifact.getBaseVersion(),
 1210  
                                                             testNgArtifact );
 1211  
         }
 1212  
     }
 1213  
 
 1214  0
     class JUnit3ProviderInfo
 1215  
         implements ProviderInfo
 1216  
     {
 1217  
         public String getProviderName()
 1218  
         {
 1219  0
             return "org.apache.maven.surefire.junit.JUnit3Provider";
 1220  
         }
 1221  
 
 1222  
         public boolean isApplicable()
 1223  
         {
 1224  0
             return true;
 1225  
         }
 1226  
 
 1227  
         public void addProviderProperties()
 1228  
         {
 1229  0
         }
 1230  
 
 1231  
         public Classpath getProviderClasspath()
 1232  
             throws ArtifactResolutionException, ArtifactNotFoundException
 1233  
         {
 1234  
             // add the JUnit provider as default - it doesn't require JUnit to be present,
 1235  
             // since it supports POJO tests.
 1236  0
             return dependencyResolver.getProviderClasspath( "surefire-junit3", surefireBooterArtifact.getBaseVersion(),
 1237  
                                                             null );
 1238  
 
 1239  
         }
 1240  
 
 1241  
     }
 1242  
 
 1243  
     class JUnit4ProviderInfo
 1244  
         implements ProviderInfo
 1245  
     {
 1246  
         private final Artifact junitArtifact;
 1247  
 
 1248  
         private final Artifact junitDepArtifact;
 1249  
 
 1250  
         JUnit4ProviderInfo( Artifact junitArtifact, Artifact junitDepArtifact )
 1251  0
         {
 1252  0
             this.junitArtifact = junitArtifact;
 1253  0
             this.junitDepArtifact = junitDepArtifact;
 1254  0
         }
 1255  
 
 1256  
         public String getProviderName()
 1257  
         {
 1258  0
             return "org.apache.maven.surefire.junit4.JUnit4Provider";
 1259  
         }
 1260  
 
 1261  
         public boolean isApplicable()
 1262  
         {
 1263  0
             return junitDepArtifact != null || isAnyJunit4( junitArtifact );
 1264  
         }
 1265  
 
 1266  
         public void addProviderProperties()
 1267  
         {
 1268  0
         }
 1269  
 
 1270  
         public Classpath getProviderClasspath()
 1271  
             throws ArtifactResolutionException, ArtifactNotFoundException
 1272  
         {
 1273  0
             return dependencyResolver.getProviderClasspath( "surefire-junit4", surefireBooterArtifact.getBaseVersion(),
 1274  
                                                             null );
 1275  
 
 1276  
         }
 1277  
 
 1278  
     }
 1279  
 
 1280  
     class JUnitCoreProviderInfo
 1281  
         implements ProviderInfo
 1282  
     {
 1283  
         private final Artifact junitArtifact;
 1284  
 
 1285  
         private final Artifact junitDepArtifact;
 1286  
 
 1287  
         JUnitCoreProviderInfo( Artifact junitArtifact, Artifact junitDepArtifact )
 1288  0
         {
 1289  0
             this.junitArtifact = junitArtifact;
 1290  0
             this.junitDepArtifact = junitDepArtifact;
 1291  0
         }
 1292  
 
 1293  
         public String getProviderName()
 1294  
         {
 1295  0
             return "org.apache.maven.surefire.junitcore.JUnitCoreProvider";
 1296  
         }
 1297  
 
 1298  
         private boolean is47CompatibleJunitDep()
 1299  
         {
 1300  0
             return junitDepArtifact != null && isJunit47Compatible( junitDepArtifact );
 1301  
         }
 1302  
 
 1303  
         public boolean isApplicable()
 1304  
         {
 1305  0
             final boolean isJunitArtifact47 = isAnyJunit4( junitArtifact ) && isJunit47Compatible( junitArtifact );
 1306  0
             final boolean isAny47ProvidersForcers = isAnyConcurrencySelected() || isAnyGroupsSelected();
 1307  0
             return isAny47ProvidersForcers && ( isJunitArtifact47 || is47CompatibleJunitDep() );
 1308  
         }
 1309  
 
 1310  
         public void addProviderProperties()
 1311  
         {
 1312  0
             convertJunitCoreParameters();
 1313  0
             convertGroupParameters();
 1314  0
         }
 1315  
 
 1316  
         public Classpath getProviderClasspath()
 1317  
             throws ArtifactResolutionException, ArtifactNotFoundException
 1318  
         {
 1319  0
             return dependencyResolver.getProviderClasspath( "surefire-junit47", surefireBooterArtifact.getBaseVersion(),
 1320  
                                                             null );
 1321  
         }
 1322  
 
 1323  
     }
 1324  
 
 1325  0
     public class DynamicProviderInfo
 1326  
         implements ConfigurableProviderInfo
 1327  
     {
 1328  
         final String providerName;
 1329  
 
 1330  
         DynamicProviderInfo( String providerName )
 1331  0
         {
 1332  0
             this.providerName = providerName;
 1333  0
         }
 1334  
 
 1335  
         public ProviderInfo instantiate( String providerName )
 1336  
         {
 1337  0
             return new DynamicProviderInfo( providerName );
 1338  
         }
 1339  
 
 1340  
         public String getProviderName()
 1341  
         {
 1342  0
             return providerName;
 1343  
         }
 1344  
 
 1345  
         public boolean isApplicable()
 1346  
         {
 1347  0
             return true;
 1348  
         }
 1349  
 
 1350  
         public void addProviderProperties()
 1351  
         {
 1352  
             // Ok this is a bit lazy.
 1353  0
             convertJunitCoreParameters();
 1354  0
             convertTestNGParameters();
 1355  0
         }
 1356  
 
 1357  
 
 1358  
         public Classpath getProviderClasspath()
 1359  
             throws ArtifactResolutionException, ArtifactNotFoundException
 1360  
         {
 1361  0
             final Map pluginArtifactMap = getPluginArtifactMap();
 1362  0
             Artifact plugin = (Artifact) pluginArtifactMap.get( "org.apache.maven.plugins:maven-surefire-plugin" );
 1363  0
             return dependencyResolver.addProviderToClasspath( pluginArtifactMap, plugin );
 1364  
         }
 1365  
 
 1366  
     }
 1367  
 
 1368  
 }