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