1
2 package org.apache.maven.plugin.surefire;
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23 import java.io.File;
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.HashMap;
30 import java.util.HashSet;
31 import java.util.LinkedHashSet;
32 import java.util.List;
33 import java.util.Map;
34 import java.util.Map.Entry;
35 import java.util.Properties;
36 import java.util.Set;
37
38 import org.apache.maven.artifact.Artifact;
39 import org.apache.maven.artifact.factory.ArtifactFactory;
40 import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
41 import org.apache.maven.artifact.repository.ArtifactRepository;
42 import org.apache.maven.artifact.resolver.ArtifactNotFoundException;
43 import org.apache.maven.artifact.resolver.ArtifactResolutionException;
44 import org.apache.maven.artifact.resolver.ArtifactResolutionResult;
45 import org.apache.maven.artifact.resolver.ArtifactResolver;
46 import org.apache.maven.artifact.resolver.filter.ArtifactFilter;
47 import org.apache.maven.artifact.resolver.filter.ExcludesArtifactFilter;
48 import org.apache.maven.artifact.resolver.filter.ScopeArtifactFilter;
49 import org.apache.maven.artifact.versioning.ArtifactVersion;
50 import org.apache.maven.artifact.versioning.DefaultArtifactVersion;
51 import org.apache.maven.artifact.versioning.InvalidVersionSpecificationException;
52 import org.apache.maven.artifact.versioning.VersionRange;
53 import org.apache.maven.execution.MavenSession;
54 import org.apache.maven.model.Plugin;
55 import org.apache.maven.plugin.AbstractMojo;
56 import org.apache.maven.plugin.MojoExecutionException;
57 import org.apache.maven.plugin.MojoFailureException;
58 import org.apache.maven.plugin.descriptor.PluginDescriptor;
59 import org.apache.maven.plugin.logging.Log;
60 import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
61 import org.apache.maven.plugin.surefire.booterclient.ForkConfiguration;
62 import org.apache.maven.plugin.surefire.booterclient.ForkStarter;
63 import org.apache.maven.plugin.surefire.util.DependencyScanner;
64 import org.apache.maven.plugin.surefire.util.DirectoryScanner;
65 import org.apache.maven.plugins.annotations.Component;
66 import org.apache.maven.plugins.annotations.Parameter;
67 import org.apache.maven.project.MavenProject;
68 import org.apache.maven.shared.artifact.filter.PatternIncludesArtifactFilter;
69 import org.apache.maven.shared.utils.StringUtils;
70 import org.apache.maven.shared.utils.io.FileUtils;
71 import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
72 import org.apache.maven.surefire.booter.Classpath;
73 import org.apache.maven.surefire.booter.ClasspathConfiguration;
74 import org.apache.maven.surefire.booter.KeyValueSource;
75 import org.apache.maven.surefire.booter.ProviderConfiguration;
76 import org.apache.maven.surefire.booter.ProviderParameterNames;
77 import org.apache.maven.surefire.booter.StartupConfiguration;
78 import org.apache.maven.surefire.booter.SurefireBooterForkException;
79 import org.apache.maven.surefire.booter.SurefireExecutionException;
80 import org.apache.maven.surefire.report.ReporterConfiguration;
81 import org.apache.maven.surefire.suite.RunResult;
82 import org.apache.maven.surefire.testset.DirectoryScannerParameters;
83 import org.apache.maven.surefire.testset.RunOrderParameters;
84 import org.apache.maven.surefire.testset.TestArtifactInfo;
85 import org.apache.maven.surefire.testset.TestRequest;
86 import org.apache.maven.surefire.testset.TestSetFailedException;
87 import org.apache.maven.surefire.util.DefaultScanResult;
88 import org.apache.maven.surefire.util.RunOrder;
89 import org.apache.maven.toolchain.Toolchain;
90 import org.apache.maven.toolchain.ToolchainManager;
91
92 import javax.annotation.Nonnull;
93
94
95
96
97
98
99
100 public abstract class AbstractSurefireMojo
101 extends AbstractMojo
102 implements SurefireExecutionParameters
103 {
104
105
106
107
108
109
110
111
112
113 @Parameter( defaultValue = "${plugin}", readonly = true )
114 protected PluginDescriptor pluginDescriptor;
115
116
117
118
119
120
121
122 @Parameter( property = "skipTests", defaultValue = "false" )
123 protected boolean skipTests;
124
125
126
127
128
129
130
131 @Parameter( property = "maven.test.skip.exec" )
132 protected boolean skipExec;
133
134
135
136
137
138
139 @Parameter( property = "maven.test.skip", defaultValue = "false" )
140 protected boolean skip;
141
142
143
144
145 @Component
146 protected MavenProject project;
147
148
149
150
151
152 @Parameter( defaultValue = "${basedir}" )
153 protected File basedir;
154
155
156
157
158
159 @Parameter( defaultValue = "${project.build.testOutputDirectory}" )
160 protected File testClassesDirectory;
161
162
163
164
165
166 @Parameter( defaultValue = "${project.build.outputDirectory}" )
167 protected File classesDirectory;
168
169
170
171
172
173
174
175 @Parameter( property = "maven.test.dependency.excludes" )
176 private String[] classpathDependencyExcludes;
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192 @Parameter( defaultValue = "" )
193 private String classpathDependencyScopeExclude;
194
195
196
197
198
199
200 @Parameter( property = "maven.test.additionalClasspath" )
201 private String[] additionalClasspathElements;
202
203
204
205
206
207
208 @Parameter( defaultValue = "${project.build.testSourceDirectory}", required = true )
209 protected File testSourceDirectory;
210
211
212
213
214
215 @Parameter
216 protected File includesFile;
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235 @Parameter
236 protected List<String> excludes;
237
238
239
240
241
242 @Parameter
243 protected File excludesFile;
244
245
246
247
248
249 @Parameter( defaultValue = "${localRepository}", required = true, readonly = true )
250 protected ArtifactRepository localRepository;
251
252
253
254
255
256
257 @Parameter
258 protected Properties systemProperties;
259
260
261
262
263
264
265 @Parameter
266 protected Map<String, String> systemPropertyVariables;
267
268
269
270
271
272
273 @Parameter
274 protected File systemPropertiesFile;
275
276
277
278
279
280
281
282 @Parameter
283 protected Properties properties;
284
285
286
287
288
289 @Parameter( property = "plugin.artifactMap", required = true, readonly = true )
290 protected Map<String, Artifact> pluginArtifactMap;
291
292
293
294
295
296 @Parameter( property = "project.artifactMap", readonly = true, required = true )
297 protected Map<String, Artifact> projectArtifactMap;
298
299
300
301
302
303
304
305 @Parameter( property = "surefire.reportNameSuffix", defaultValue = "" )
306 protected String reportNameSuffix;
307
308
309
310
311
312
313
314 @Parameter( property = "maven.test.redirectTestOutputToFile", defaultValue = "false" )
315 protected boolean redirectTestOutputToFile;
316
317
318
319
320
321
322 @Parameter( property = "failIfNoTests" )
323 protected Boolean failIfNoTests;
324
325
326
327
328
329
330
331
332
333
334
335
336 @Parameter( property = "forkMode", defaultValue = "once" )
337 protected String forkMode;
338
339
340
341
342
343
344
345
346 @Parameter( property = "jvm" )
347 protected String jvm;
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364 @Parameter( property = "argLine" )
365 protected String argLine;
366
367
368
369
370
371
372 @Parameter
373 protected Map<String, String> environmentVariables = new HashMap<String, String>();
374
375
376
377
378
379
380 @Parameter( property = "basedir" )
381 protected File workingDirectory;
382
383
384
385
386
387
388
389
390
391 @Parameter( property = "childDelegation", defaultValue = "false" )
392 protected boolean childDelegation;
393
394
395
396
397
398
399
400
401
402
403
404
405 @Parameter( property = "groups" )
406 protected String groups;
407
408
409
410
411
412
413
414
415
416
417
418
419 @Parameter( property = "excludedGroups" )
420 protected String excludedGroups;
421
422
423
424
425
426
427 @Parameter( property = "junitArtifactName", defaultValue = "junit:junit" )
428 protected String junitArtifactName;
429
430
431
432
433
434
435 @Parameter( property = "testNGArtifactName", defaultValue = "org.testng:testng" )
436 protected String testNGArtifactName;
437
438
439
440
441
442
443
444 @Parameter( property = "threadCount" )
445 protected int threadCount;
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462 @Parameter( property = "forkCount", defaultValue = "1" )
463 private String forkCount;
464
465
466
467
468
469
470
471
472 @Parameter( property = "reuseForks", defaultValue = "true" )
473 private boolean reuseForks;
474
475
476
477
478
479
480
481 @Parameter( property = "perCoreThreadCount", defaultValue = "true" )
482 protected boolean perCoreThreadCount;
483
484
485
486
487
488
489
490
491 @Parameter( property = "useUnlimitedThreads", defaultValue = "false" )
492 protected boolean useUnlimitedThreads;
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510 @Parameter( property = "parallel" )
511 protected String parallel;
512
513
514
515
516
517
518
519
520
521 @Parameter( property = "parallelOptimized", defaultValue = "true" )
522 protected boolean parallelOptimized;
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540 @Parameter( property = "threadCountSuites", defaultValue = "0" )
541 protected int threadCountSuites;
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563 @Parameter( property = "threadCountClasses", defaultValue = "0" )
564 protected int threadCountClasses;
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585 @Parameter( property = "threadCountMethods", defaultValue = "0" )
586 protected int threadCountMethods;
587
588
589
590
591
592
593 @Parameter( property = "trimStackTrace", defaultValue = "true" )
594 protected boolean trimStackTrace;
595
596
597
598
599 @Component
600 protected ArtifactResolver artifactResolver;
601
602
603
604
605 @Component
606 protected ArtifactFactory artifactFactory;
607
608
609
610
611
612
613 @Parameter( defaultValue = "${project.pluginArtifactRepositories}" )
614 protected List<ArtifactRepository> remoteRepositories;
615
616
617
618
619 @Component
620 protected ArtifactMetadataSource metadataSource;
621
622
623
624
625
626
627 @Parameter( property = "disableXmlReport", defaultValue = "false" )
628 protected boolean disableXmlReport;
629
630
631
632
633
634
635
636 @Parameter( property = "enableAssertions", defaultValue = "true" )
637 protected boolean enableAssertions;
638
639
640
641
642 @Component
643 protected MavenSession session;
644
645
646
647
648
649
650 @Parameter( property = "objectFactory" )
651 protected String objectFactory;
652
653
654
655
656 @Parameter( defaultValue = "${session.parallel}", readonly = true )
657 protected Boolean parallelMavenExecution;
658
659
660
661
662
663
664
665
666
667
668 @Parameter( property = "dependenciesToScan" )
669 private String[] dependenciesToScan;
670
671
672
673
674 @Component
675 protected ToolchainManager toolchainManager;
676
677 private Artifact surefireBooterArtifact;
678
679 private Toolchain toolchain;
680
681 private int effectiveForkCount = -1;
682
683
684
685
686
687
688 public static final String THREAD_NUMBER_PLACEHOLDER = "${surefire.threadNumber}";
689
690
691
692
693
694 public static final String FORK_NUMBER_PLACEHOLDER = "${surefire.forkNumber}";
695
696 protected abstract String getPluginName();
697
698 protected abstract int getRerunFailingTestsCount();
699
700 private SurefireDependencyResolver dependencyResolver;
701
702 public void execute()
703 throws MojoExecutionException, MojoFailureException
704 {
705
706 setupStuff();
707
708 if ( verifyParameters() && !hasExecutedBefore() )
709 {
710 DefaultScanResult scan = scanForTestClasses();
711 if ( !isValidSuiteXmlFileConfig() && scan.isEmpty() )
712 {
713 if ( getEffectiveFailIfNoTests() )
714 {
715 throw new MojoFailureException(
716 "No tests were executed! (Set -DfailIfNoTests=false to ignore this error.)" );
717 }
718 handleSummary( RunResult.noTestsRun(), null );
719 return;
720 }
721 logReportsDirectory();
722 executeAfterPreconditionsChecked( scan );
723 }
724 }
725
726 private void setupStuff()
727 {
728 createDependencyResolver();
729 surefireBooterArtifact = getSurefireBooterArtifact();
730 toolchain = getToolchain();
731 }
732
733 private DefaultScanResult scanForTestClasses()
734 {
735 DefaultScanResult scan = scanDirectories();
736 DefaultScanResult scanDeps = scanDependencies();
737 return scan.append( scanDeps );
738 }
739
740 private DefaultScanResult scanDirectories()
741 {
742 return new DirectoryScanner( getTestClassesDirectory(), getIncludeList(), getExcludeList(),
743 getSpecificTests() ).scan();
744 }
745
746 private DefaultScanResult scanDependencies()
747 {
748 if ( getDependenciesToScan() == null )
749 {
750 return null;
751 }
752 else
753 {
754 try
755 {
756
757 return new DependencyScanner( DependencyScanner.filter( project.getTestArtifacts(),
758 Arrays.asList( getDependenciesToScan() ) ),
759 getIncludeList(), getExcludeList(), getSpecificTests() ).scan();
760 }
761 catch ( Exception e )
762 {
763 throw new RuntimeException( e );
764 }
765 }
766 }
767
768 boolean verifyParameters()
769 throws MojoFailureException, MojoExecutionException
770 {
771 setProperties( new SurefireProperties( getProperties() ) );
772 if ( isSkipExecution() )
773 {
774 getLog().info( "Tests are skipped." );
775 return false;
776 }
777
778 String jvmToUse = getJvm();
779 if ( toolchain != null )
780 {
781 getLog().info( "Toolchain in maven-" + getPluginName() + "-plugin: " + toolchain );
782 if ( jvmToUse != null )
783 {
784 getLog().warn( "Toolchains are ignored, 'executable' parameter is set to " + jvmToUse );
785 }
786 }
787
788 if ( !getTestClassesDirectory().exists()
789 && ( getDependenciesToScan() == null || getDependenciesToScan().length == 0 ) )
790 {
791 if ( Boolean.TRUE.equals( getFailIfNoTests() ) )
792 {
793 throw new MojoFailureException( "No tests to run!" );
794 }
795 getLog().info( "No tests to run." );
796 }
797 else
798 {
799 convertDeprecatedForkMode();
800 ensureWorkingDirectoryExists();
801 ensureParallelRunningCompatibility();
802 ensureThreadCountWithPerThread();
803 warnIfUselessUseSystemClassLoaderParameter();
804 warnIfDefunctGroupsCombinations();
805 }
806 return true;
807 }
808
809 protected abstract boolean isSkipExecution();
810
811 protected void executeAfterPreconditionsChecked( DefaultScanResult scanResult )
812 throws MojoExecutionException, MojoFailureException
813 {
814
815 List<ProviderInfo> providers = createProviders();
816
817 RunResult current = RunResult.noTestsRun();
818
819 Exception firstForkException = null;
820 for ( ProviderInfo provider : providers )
821 {
822 try
823 {
824 current = current.aggregate( executeProvider( provider, scanResult ) );
825 }
826 catch ( SurefireBooterForkException e )
827 {
828 if ( firstForkException == null )
829 {
830 firstForkException = e;
831 }
832 }
833 catch ( SurefireExecutionException e )
834 {
835 if ( firstForkException == null )
836 {
837 firstForkException = e;
838 }
839 }
840 catch ( TestSetFailedException e )
841 {
842 if ( firstForkException == null )
843 {
844 firstForkException = e;
845 }
846 }
847 }
848
849 if ( firstForkException != null )
850 {
851 current = RunResult.failure( current, firstForkException );
852 }
853
854 handleSummary( current, firstForkException );
855 }
856
857
858 private void createDependencyResolver()
859 {
860 dependencyResolver =
861 new SurefireDependencyResolver( getArtifactResolver(), getArtifactFactory(), getLog(), getLocalRepository(),
862 getRemoteRepositories(), getMetadataSource(), getPluginName() );
863 }
864
865 protected List<ProviderInfo> createProviders()
866 throws MojoFailureException, MojoExecutionException
867 {
868 final Artifact junitDepArtifact = getJunitDepArtifact();
869 ProviderList wellKnownProviders =
870 new ProviderList( new DynamicProviderInfo( null ), new TestNgProviderInfo( getTestNgArtifact() ),
871 new JUnitCoreProviderInfo( getJunitArtifact(), junitDepArtifact ),
872 new JUnit4ProviderInfo( getJunitArtifact(), junitDepArtifact ),
873 new JUnit3ProviderInfo() );
874
875 return wellKnownProviders.resolve( getLog() );
876 }
877
878 private SurefireProperties setupProperties()
879 {
880 SurefireProperties sysProps = null;
881 try
882 {
883 sysProps = SurefireProperties.loadProperties( systemPropertiesFile );
884 }
885 catch ( IOException e )
886 {
887 String msg = "The system property file '" + systemPropertiesFile.getAbsolutePath() + "' can't be read.";
888 if ( getLog().isDebugEnabled() )
889 {
890 getLog().warn( msg, e );
891 }
892 else
893 {
894 getLog().warn( msg );
895 }
896 }
897
898 SurefireProperties result =
899 SurefireProperties.calculateEffectiveProperties( getSystemProperties(), getSystemPropertyVariables(),
900 getUserProperties(), sysProps );
901
902 result.setProperty( "basedir", getBasedir().getAbsolutePath() );
903 result.setProperty( "user.dir", getWorkingDirectory().getAbsolutePath() );
904 result.setProperty( "localRepository", getLocalRepository().getBasedir() );
905 if ( isForking() )
906 {
907 for ( Object o : result.propertiesThatCannotBeSetASystemProperties() )
908 {
909 if ( getArgLine() == null || !getArgLine().contains( "-D" + o + "=" ) )
910 {
911 getLog().warn( o + " cannot be set as system property, use <argLine>-D"
912 + o + "=...<argLine> instead" );
913 }
914 }
915 for ( Object systemPropertyMatchingArgLine : systemPropertiesMatchingArgLine( result ) )
916 {
917 getLog().warn( "The system property " + systemPropertyMatchingArgLine + " is configured twice! "
918 + "The property appears in <argLine/> and any of <systemPropertyVariables/>, "
919 + "<systemProperties/> or user property." );
920 }
921 }
922 if ( getLog().isDebugEnabled() )
923 {
924 showToLog( result, getLog(), "system property" );
925 }
926 return result;
927 }
928
929 private Set<Object> systemPropertiesMatchingArgLine( SurefireProperties result )
930 {
931 Set<Object> intersection = new HashSet<Object>();
932 if ( StringUtils.isNotBlank( getArgLine() ) )
933 {
934 for ( Object systemProperty : result.getStringKeySet() )
935 {
936 if ( getArgLine().contains( "-D" + systemProperty + "=" ) )
937 {
938 intersection.add( systemProperty );
939 }
940 }
941
942 Set<Object> ignored = result.propertiesThatCannotBeSetASystemProperties();
943 intersection.removeAll( ignored );
944 }
945 return intersection;
946 }
947
948 public void showToLog( SurefireProperties props, org.apache.maven.plugin.logging.Log log, String setting )
949 {
950 for ( Object key : props.getStringKeySet() )
951 {
952 String value = props.getProperty( (String) key );
953 log.debug( "Setting " + setting + " [" + key + "]=[" + value + "]" );
954 }
955 }
956
957
958 private RunResult executeProvider( ProviderInfo provider, DefaultScanResult scanResult )
959 throws MojoExecutionException, MojoFailureException, SurefireExecutionException, SurefireBooterForkException,
960 TestSetFailedException
961 {
962 SurefireProperties effectiveProperties = setupProperties();
963 ClassLoaderConfiguration classLoaderConfiguration = getClassLoaderConfiguration( isForking() );
964 provider.addProviderProperties();
965 RunOrderParameters runOrderParameters =
966 new RunOrderParameters( getRunOrder(), getStatisticsFileName( getConfigChecksum() ) );
967
968 if ( isNotForking() )
969 {
970 createCopyAndReplaceForkNumPlaceholder( effectiveProperties, 1 ).copyToSystemProperties();
971
972 InPluginVMSurefireStarter surefireStarter =
973 createInprocessStarter( provider, classLoaderConfiguration, runOrderParameters );
974 return surefireStarter.runSuitesInProcess( scanResult );
975 }
976 else
977 {
978 ForkConfiguration forkConfiguration = getForkConfiguration();
979 if ( getLog().isDebugEnabled() )
980 {
981 showMap( getEnvironmentVariables(), "environment variable" );
982 }
983
984 Properties originalSystemProperties = (Properties) System.getProperties().clone();
985 try
986 {
987 ForkStarter forkStarter =
988 createForkStarter( provider, forkConfiguration, classLoaderConfiguration, runOrderParameters,
989 getLog() );
990 return forkStarter.run( effectiveProperties, scanResult );
991 }
992 finally
993 {
994 System.setProperties( originalSystemProperties );
995 cleanupForkConfiguration( forkConfiguration );
996 }
997 }
998 }
999
1000
1001 public static SurefireProperties createCopyAndReplaceForkNumPlaceholder(
1002 SurefireProperties effectiveSystemProperties, int threadNumber )
1003 {
1004 SurefireProperties filteredProperties = new SurefireProperties( ( KeyValueSource) effectiveSystemProperties );
1005 String threadNumberString = String.valueOf( threadNumber );
1006 for ( Entry<Object, Object> entry : effectiveSystemProperties.entrySet() )
1007 {
1008 if ( entry.getValue() instanceof String )
1009 {
1010 String value = (String) entry.getValue();
1011 value = value.replace( THREAD_NUMBER_PLACEHOLDER, threadNumberString );
1012 value = value.replace( FORK_NUMBER_PLACEHOLDER, threadNumberString );
1013
1014 filteredProperties.put( entry.getKey(), value );
1015 }
1016 }
1017 return filteredProperties;
1018 }
1019
1020 protected void cleanupForkConfiguration( ForkConfiguration forkConfiguration )
1021 {
1022 if ( !getLog().isDebugEnabled() && forkConfiguration != null )
1023 {
1024 File tempDirectory = forkConfiguration.getTempDirectory();
1025 try
1026 {
1027 FileUtils.deleteDirectory( tempDirectory );
1028 }
1029 catch ( IOException ioe )
1030 {
1031 getLog().warn( "Could not delete temp direcotry " + tempDirectory + " because " + ioe.getMessage() );
1032 }
1033 }
1034 }
1035
1036 protected abstract void handleSummary( RunResult summary, Exception firstForkException )
1037 throws MojoExecutionException, MojoFailureException;
1038
1039 protected void logReportsDirectory()
1040 {
1041 getLog().info(
1042 StringUtils.capitalizeFirstLetter( getPluginName() ) + " report directory: " + getReportsDirectory() );
1043 }
1044
1045
1046 final Toolchain getToolchain()
1047 {
1048 Toolchain tc = null;
1049
1050 if ( getToolchainManager() != null )
1051 {
1052 tc = getToolchainManager().getToolchainFromBuildContext( "jdk", getSession() );
1053 }
1054
1055 return tc;
1056 }
1057
1058
1059
1060
1061
1062 private void convertTestNGParameters() throws MojoExecutionException
1063 {
1064 if ( this.getParallel() != null )
1065 {
1066 getProperties().setProperty( ProviderParameterNames.PARALLEL_PROP, this.getParallel() );
1067 }
1068 convertGroupParameters();
1069
1070 if ( this.getThreadCount() > 0 )
1071 {
1072 getProperties().setProperty( ProviderParameterNames.THREADCOUNT_PROP,
1073 Integer.toString( this.getThreadCount() ) );
1074 }
1075 if ( this.getObjectFactory() != null )
1076 {
1077 getProperties().setProperty( "objectfactory", this.getObjectFactory() );
1078 }
1079 if ( this.getTestClassesDirectory() != null )
1080 {
1081 getProperties().setProperty( "testng.test.classpath", getTestClassesDirectory().getAbsolutePath() );
1082 }
1083
1084 Artifact testNgArtifact = getTestNgArtifact();
1085 if ( testNgArtifact != null )
1086 {
1087 DefaultArtifactVersion defaultArtifactVersion = new DefaultArtifactVersion( testNgArtifact.getVersion() );
1088 getProperties().setProperty( "testng.configurator", getConfiguratorName( defaultArtifactVersion ) );
1089 }
1090
1091
1092 }
1093
1094 private static String getConfiguratorName( ArtifactVersion version )
1095 throws MojoExecutionException
1096 {
1097 try
1098 {
1099 VersionRange range = VersionRange.createFromVersionSpec( "[4.7,5.1]" );
1100 if ( range.containsVersion( version ) )
1101 {
1102 return "org.apache.maven.surefire.testng.conf.TestNG4751Configurator";
1103 }
1104 range = VersionRange.createFromVersionSpec( "[5.2]" );
1105 if ( range.containsVersion( version ) )
1106 {
1107 return "org.apache.maven.surefire.testng.conf.TestNG52Configurator";
1108 }
1109 range = VersionRange.createFromVersionSpec( "[5.3,6.4]" );
1110 if ( range.containsVersion( version ) )
1111 {
1112 return "org.apache.maven.surefire.testng.conf.TestNGMapConfigurator";
1113 }
1114 range = VersionRange.createFromVersionSpec( "[6.5,)" );
1115 if ( range.containsVersion( version ) )
1116 {
1117 return "org.apache.maven.surefire.testng.conf.TestNG652Configurator";
1118 }
1119
1120 throw new MojoExecutionException( "Unknown TestNG version " + version );
1121 }
1122 catch ( InvalidVersionSpecificationException invsex )
1123 {
1124 throw new MojoExecutionException( "Bug in plugin. Please report it with the attached stacktrace", invsex );
1125 }
1126 }
1127
1128
1129 private void convertGroupParameters()
1130 {
1131 if ( this.getExcludedGroups() != null )
1132 {
1133 getProperties().setProperty( ProviderParameterNames.TESTNG_EXCLUDEDGROUPS_PROP, this.getExcludedGroups() );
1134 }
1135 if ( this.getGroups() != null )
1136 {
1137 getProperties().setProperty( ProviderParameterNames.TESTNG_GROUPS_PROP, this.getGroups() );
1138 }
1139 }
1140
1141 protected boolean isAnyConcurrencySelected()
1142 {
1143 return this.getParallel() != null && this.getParallel().trim().length() > 0;
1144 }
1145
1146 protected boolean isAnyGroupsSelected()
1147 {
1148 return this.getGroups() != null || this.getExcludedGroups() != null;
1149 }
1150
1151
1152
1153
1154
1155 private void convertJunitCoreParameters() throws MojoExecutionException
1156 {
1157 checkThreadCountEntity( getThreadCountSuites(), "suites" );
1158 checkThreadCountEntity( getThreadCountClasses(), "classes" );
1159 checkThreadCountEntity( getThreadCountMethods(), "methods" );
1160
1161 String usedParallel = ( getParallel() != null ) ? getParallel() : "none";
1162
1163 if ( !"none".equals( usedParallel ) )
1164 {
1165 checkNonForkedThreads( parallel );
1166 }
1167
1168 String usedThreadCount = Integer.toString( getThreadCount() );
1169 getProperties().setProperty( ProviderParameterNames.PARALLEL_PROP, usedParallel );
1170 getProperties().setProperty( ProviderParameterNames.THREADCOUNT_PROP, usedThreadCount );
1171 getProperties().setProperty( "perCoreThreadCount", Boolean.toString( getPerCoreThreadCount() ) );
1172 getProperties().setProperty( "useUnlimitedThreads", Boolean.toString( getUseUnlimitedThreads() ) );
1173 getProperties().setProperty( ProviderParameterNames.THREADCOUNTSUITES_PROP,
1174 Integer.toString( getThreadCountSuites() ) );
1175 getProperties().setProperty( ProviderParameterNames.THREADCOUNTCLASSES_PROP,
1176 Integer.toString( getThreadCountClasses() ) );
1177 getProperties().setProperty( ProviderParameterNames.THREADCOUNTMETHODS_PROP,
1178 Integer.toString( getThreadCountMethods() ) );
1179 getProperties().setProperty( ProviderParameterNames.PARALLEL_TIMEOUT_PROP,
1180 Double.toString( getParallelTestsTimeoutInSeconds() ) );
1181 getProperties().setProperty( ProviderParameterNames.PARALLEL_TIMEOUTFORCED_PROP,
1182 Double.toString( getParallelTestsTimeoutForcedInSeconds() ) );
1183 getProperties().setProperty( ProviderParameterNames.PARALLEL_OPTIMIZE_PROP,
1184 Boolean.toString( isParallelOptimized() ) );
1185
1186 String message =
1187 "parallel='" + usedParallel + '\'' + ", perCoreThreadCount=" + getPerCoreThreadCount() + ", threadCount="
1188 + usedThreadCount + ", useUnlimitedThreads=" + getUseUnlimitedThreads()
1189 + ", threadCountSuites=" + getThreadCountSuites()
1190 + ", threadCountClasses=" + getThreadCountClasses()
1191 + ", threadCountMethods=" + getThreadCountMethods()
1192 + ", parallelOptimized=" + isParallelOptimized();
1193
1194 getLog().info( message );
1195 }
1196
1197 private void checkNonForkedThreads( String parallel ) throws MojoExecutionException
1198 {
1199 if ( "suites".equals( parallel ) )
1200 {
1201 if ( !( getUseUnlimitedThreads() || getThreadCount() > 0 ^ getThreadCountSuites() > 0 ) )
1202 {
1203 throw new MojoExecutionException(
1204 "Use threadCount or threadCountSuites > 0 or useUnlimitedThreads=true for parallel='suites'" );
1205 }
1206 setThreadCountClasses( 0 );
1207 setThreadCountMethods( 0 );
1208 }
1209 else if ( "classes".equals( parallel ) )
1210 {
1211 if ( !( getUseUnlimitedThreads() || getThreadCount() > 0 ^ getThreadCountClasses() > 0 ) )
1212 {
1213 throw new MojoExecutionException(
1214 "Use threadCount or threadCountClasses > 0 or useUnlimitedThreads=true for parallel='classes'"
1215 );
1216 }
1217 setThreadCountSuites( 0 );
1218 setThreadCountMethods( 0 );
1219 }
1220 else if ( "methods".equals( parallel ) )
1221 {
1222 if ( !( getUseUnlimitedThreads() || getThreadCount() > 0 ^ getThreadCountMethods() > 0 ) )
1223 {
1224 throw new MojoExecutionException(
1225 "Use threadCount or threadCountMethods > 0 or useUnlimitedThreads=true for parallel='methods'"
1226 );
1227 }
1228 setThreadCountSuites( 0 );
1229 setThreadCountClasses( 0 );
1230 }
1231 else if ( "suitesAndClasses".equals( parallel ) )
1232 {
1233 if ( !( getUseUnlimitedThreads()
1234 || onlyThreadCount()
1235 || getThreadCountSuites() > 0 && getThreadCountClasses() > 0
1236 && getThreadCount() == 0 && getThreadCountMethods() == 0
1237 || getThreadCount() > 0 && getThreadCountSuites() > 0 && getThreadCountClasses() > 0
1238 && getThreadCountMethods() == 0
1239 || getThreadCount() > 0 && getThreadCountSuites() > 0 && getThreadCount() > getThreadCountSuites()
1240 && getThreadCountClasses() == 0 && getThreadCountMethods() == 0 ) )
1241 {
1242 throw new MojoExecutionException( "Use useUnlimitedThreads=true, "
1243 + "or only threadCount > 0, "
1244 + "or (threadCountSuites > 0 and threadCountClasses > 0), "
1245 + "or (threadCount > 0 and threadCountSuites > 0 and threadCountClasses > 0) "
1246 + "or (threadCount > 0 and threadCountSuites > 0 and threadCount > threadCountSuites) "
1247 + "for parallel='suitesAndClasses' or 'both'" );
1248 }
1249 setThreadCountMethods( 0 );
1250 }
1251 else if ( "suitesAndMethods".equals( parallel ) )
1252 {
1253 if ( !( getUseUnlimitedThreads()
1254 || onlyThreadCount()
1255 || getThreadCountSuites() > 0 && getThreadCountMethods() > 0
1256 && getThreadCount() == 0 && getThreadCountClasses() == 0
1257 || getThreadCount() > 0 && getThreadCountSuites() > 0 && getThreadCountMethods() > 0
1258 && getThreadCountClasses() == 0
1259 || getThreadCount() > 0 && getThreadCountSuites() > 0 && getThreadCount() > getThreadCountSuites()
1260 && getThreadCountClasses() == 0 && getThreadCountMethods() == 0 ) )
1261 {
1262 throw new MojoExecutionException( "Use useUnlimitedThreads=true, "
1263 + "or only threadCount > 0, "
1264 + "or (threadCountSuites > 0 and threadCountMethods > 0), "
1265 + "or (threadCount > 0 and threadCountSuites > 0 and threadCountMethods > 0), "
1266 + "or (threadCount > 0 and threadCountSuites > 0 and threadCount > threadCountSuites) "
1267 + "for parallel='suitesAndMethods'" );
1268 }
1269 setThreadCountClasses( 0 );
1270 }
1271 else if ( "both".equals( parallel ) || "classesAndMethods".equals( parallel ) )
1272 {
1273 if ( !( getUseUnlimitedThreads()
1274 || onlyThreadCount()
1275 || getThreadCountClasses() > 0 && getThreadCountMethods() > 0
1276 && getThreadCount() == 0 && getThreadCountSuites() == 0
1277 || getThreadCount() > 0 && getThreadCountClasses() > 0 && getThreadCountMethods() > 0
1278 && getThreadCountSuites() == 0
1279 || getThreadCount() > 0 && getThreadCountClasses() > 0 && getThreadCount() > getThreadCountClasses()
1280 && getThreadCountSuites() == 0 && getThreadCountMethods() == 0 ) )
1281 {
1282 throw new MojoExecutionException( "Use useUnlimitedThreads=true, "
1283 + "or only threadCount > 0, "
1284 + "or (threadCountClasses > 0 and threadCountMethods > 0), "
1285 + "or (threadCount > 0 and threadCountClasses > 0 and threadCountMethods > 0), "
1286 + "or (threadCount > 0 and threadCountClasses > 0 and threadCount > threadCountClasses) "
1287 + "for parallel='both' or parallel='classesAndMethods'" );
1288 }
1289 setThreadCountSuites( 0 );
1290 }
1291 else if ( "all".equals( parallel ) )
1292 {
1293 if ( !( getUseUnlimitedThreads()
1294 || onlyThreadCount()
1295 || getThreadCountSuites() > 0 && getThreadCountClasses() > 0 && getThreadCountMethods() > 0
1296 || getThreadCount() > 0 && getThreadCountSuites() > 0 && getThreadCountClasses() > 0
1297 && getThreadCountMethods() == 0
1298 && getThreadCount() > ( getThreadCountSuites() + getThreadCountClasses() ) ) )
1299 {
1300 throw new MojoExecutionException( "Use useUnlimitedThreads=true, "
1301 + "or only threadCount > 0, "
1302 + "or (threadCountSuites > 0 and threadCountClasses > 0 and threadCountMethods > 0), "
1303 + "or every thread-count is specified, "
1304 + "or (threadCount > 0 and threadCountSuites > 0 and threadCountClasses > 0 "
1305 + "and threadCount > threadCountSuites + threadCountClasses) "
1306 + "for parallel='all'" );
1307 }
1308 }
1309 else
1310 {
1311 throw new MojoExecutionException( "Illegal parallel='" + parallel + "'" );
1312 }
1313 }
1314
1315 private boolean onlyThreadCount()
1316 {
1317 return getThreadCount() > 0 && getThreadCountSuites() == 0 && getThreadCountClasses() == 0
1318 && getThreadCountMethods() == 0;
1319 }
1320
1321 private static void checkThreadCountEntity( int count, String entity )
1322 throws MojoExecutionException
1323 {
1324 if ( count < 0 )
1325 {
1326 throw new MojoExecutionException(
1327 "parallel maven execution does not allow negative thread-count" + entity );
1328 }
1329 }
1330
1331 private boolean isJunit47Compatible( Artifact artifact )
1332 {
1333 return dependencyResolver.isWithinVersionSpec( artifact, "[4.7,)" );
1334 }
1335
1336 private boolean isAnyJunit4( Artifact artifact )
1337 {
1338 return dependencyResolver.isWithinVersionSpec( artifact, "[4.0,)" );
1339 }
1340
1341 static boolean isForkModeNever( String forkMode )
1342 {
1343 return ForkConfiguration.FORK_NEVER.equals( forkMode );
1344 }
1345
1346 boolean isForking()
1347 {
1348 return 0 < getEffectiveForkCount();
1349 }
1350
1351 String getEffectiveForkMode()
1352 {
1353 String forkMode1 = getForkMode();
1354
1355 if ( toolchain != null && isForkModeNever( forkMode1 ) )
1356 {
1357 return ForkConfiguration.FORK_ONCE;
1358 }
1359
1360 return ForkConfiguration.getEffectiveForkMode( forkMode1 );
1361 }
1362
1363 private List<RunOrder> getRunOrders()
1364 {
1365 String runOrderString = getRunOrder();
1366 RunOrder[] runOrder = runOrderString == null ? RunOrder.DEFAULT : RunOrder.valueOfMulti( runOrderString );
1367 return Arrays.asList( runOrder );
1368 }
1369
1370 private boolean requiresRunHistory()
1371 {
1372 final List<RunOrder> runOrders = getRunOrders();
1373 return runOrders.contains( RunOrder.BALANCED ) || runOrders.contains( RunOrder.FAILEDFIRST );
1374 }
1375
1376 private boolean getEffectiveFailIfNoTests()
1377 {
1378 if ( isSpecificTestSpecified() )
1379 {
1380 if ( getFailIfNoSpecifiedTests() != null )
1381 {
1382 return getFailIfNoSpecifiedTests();
1383 }
1384 else if ( getFailIfNoTests() != null )
1385 {
1386 return getFailIfNoTests();
1387 }
1388 else
1389 {
1390 return true;
1391 }
1392 }
1393 else
1394 {
1395 return getFailIfNoTests() != null && getFailIfNoTests();
1396 }
1397 }
1398
1399 private ProviderConfiguration createProviderConfiguration( RunOrderParameters runOrderParameters )
1400 throws MojoExecutionException, MojoFailureException
1401 {
1402 ReporterConfiguration reporterConfiguration =
1403 new ReporterConfiguration( getReportsDirectory(), isTrimStackTrace() );
1404
1405 Artifact testNgArtifact;
1406 testNgArtifact = getTestNgArtifact();
1407
1408 DirectoryScannerParameters directoryScannerParameters = null;
1409 final boolean isTestNg = testNgArtifact != null;
1410 TestArtifactInfo testNg =
1411 isTestNg ? new TestArtifactInfo( testNgArtifact.getVersion(), testNgArtifact.getClassifier() ) : null;
1412 List<File> testXml = getSuiteXmlFiles() != null ? Arrays.asList( getSuiteXmlFiles() ) : null;
1413 TestRequest testSuiteDefinition =
1414 new TestRequest( testXml, getTestSourceDirectory(), getTest(), getTestMethod(),
1415 getRerunFailingTestsCount() );
1416
1417 final boolean actualFailIfNoTests;
1418
1419 if ( isValidSuiteXmlFileConfig() && getTest() == null )
1420 {
1421 actualFailIfNoTests = getFailIfNoTests() != null && getFailIfNoTests();
1422 if ( !isTestNg )
1423 {
1424 throw new MojoExecutionException( "suiteXmlFiles is configured, but there is no TestNG dependency" );
1425 }
1426 }
1427 else
1428 {
1429 if ( isSpecificTestSpecified() )
1430 {
1431 actualFailIfNoTests = getEffectiveFailIfNoTests();
1432 setFailIfNoTests( actualFailIfNoTests );
1433 }
1434 else
1435 {
1436 actualFailIfNoTests = getFailIfNoTests() != null && getFailIfNoTests();
1437 }
1438
1439 List<String> actualIncludes = getIncludeList();
1440 List<String> actualExcludes = getExcludeList();
1441 List<String> specificTests = getSpecificTests();
1442 directoryScannerParameters =
1443 new DirectoryScannerParameters( getTestClassesDirectory(), actualIncludes, actualExcludes,
1444 specificTests, actualFailIfNoTests, getRunOrder() );
1445 }
1446
1447 Properties providerProperties = getProperties();
1448
1449 return new ProviderConfiguration( directoryScannerParameters, runOrderParameters, actualFailIfNoTests,
1450 reporterConfiguration, testNg, testSuiteDefinition, providerProperties, null,
1451 false );
1452 }
1453
1454 public String getStatisticsFileName( String configurationHash )
1455 {
1456 return getReportsDirectory().getParentFile().getParentFile() + File.separator + ".surefire-"
1457 + configurationHash;
1458 }
1459
1460
1461 StartupConfiguration createStartupConfiguration( ProviderInfo provider,
1462 ClassLoaderConfiguration classLoaderConfiguration )
1463 throws MojoExecutionException, MojoFailureException
1464 {
1465
1466 try
1467 {
1468
1469 String providerName = provider.getProviderName();
1470 Classpath providerClasspath = ClasspathCache.getCachedClassPath( providerName );
1471 if ( providerClasspath == null )
1472 {
1473 providerClasspath = provider.getProviderClasspath();
1474 ClasspathCache.setCachedClasspath( providerName, providerClasspath );
1475
1476 }
1477 Artifact surefireArtifact = getCommonArtifact();
1478 Classpath inprocClassPath = providerClasspath.
1479 addClassPathElementUrl( surefireArtifact.getFile().getAbsolutePath() )
1480 .addClassPathElementUrl( getApiArtifact().getFile().getAbsolutePath() );
1481
1482 final Classpath testClasspath = generateTestClasspath();
1483
1484 getLog().debug( testClasspath.getLogMessage( "test" ) );
1485 getLog().debug( providerClasspath.getLogMessage( "provider" ) );
1486
1487 getLog().debug( testClasspath.getCompactLogMessage( "test(compact)" ) );
1488 getLog().debug( providerClasspath.getCompactLogMessage( "provider(compact)" ) );
1489
1490 final ClasspathConfiguration classpathConfiguration =
1491 new ClasspathConfiguration( testClasspath, providerClasspath, inprocClassPath,
1492 effectiveIsEnableAssertions(), isChildDelegation() );
1493
1494 return new StartupConfiguration( providerName, classpathConfiguration, classLoaderConfiguration,
1495 isForking(), false );
1496 }
1497 catch ( ArtifactResolutionException e )
1498 {
1499 throw new MojoExecutionException( "Unable to generate classpath: " + e, e );
1500 }
1501 catch ( ArtifactNotFoundException e )
1502 {
1503 throw new MojoExecutionException( "Unable to generate classpath: " + e, e );
1504 }
1505 catch ( InvalidVersionSpecificationException e )
1506 {
1507 throw new MojoExecutionException( "Unable to generate classpath: " + e, e );
1508 }
1509
1510 }
1511
1512 private Artifact getCommonArtifact()
1513 {
1514 return getPluginArtifactMap().get( "org.apache.maven.surefire:maven-surefire-common" );
1515 }
1516
1517 private Artifact getApiArtifact()
1518 {
1519 return getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-api" );
1520 }
1521
1522 private StartupReportConfiguration getStartupReportConfiguration( String configChecksum )
1523 {
1524 return new StartupReportConfiguration( isUseFile(), isPrintSummary(), getReportFormat(),
1525 isRedirectTestOutputToFile(), isDisableXmlReport(),
1526 getReportsDirectory(), isTrimStackTrace(), getReportNameSuffix(),
1527 configChecksum, requiresRunHistory(), getRerunFailingTestsCount() );
1528 }
1529
1530 private boolean isSpecificTestSpecified()
1531 {
1532 return getTest() != null;
1533 }
1534
1535 private boolean isValidSuiteXmlFileConfig()
1536 {
1537 return getSuiteXmlFiles() != null && getSuiteXmlFiles().length > 0;
1538 }
1539
1540 @SuppressWarnings( "checkstyle:modifierorder" )
1541 private @Nonnull List<String> readListFromFile( @Nonnull final File file )
1542 {
1543 List<String> list;
1544
1545 getLog().debug( "Reading list from: " + file );
1546
1547 if ( !file.exists() )
1548 {
1549 throw new RuntimeException( "Failed to load list from file: " + file );
1550 }
1551
1552 try
1553 {
1554 list = FileUtils.loadFile( file );
1555 }
1556 catch ( IOException e )
1557 {
1558 throw new RuntimeException( "Failed to load list from file: " + file, e );
1559 }
1560
1561 if ( getLog().isDebugEnabled() )
1562 {
1563 getLog().debug( "List contents:" );
1564 for ( String entry : list )
1565 {
1566 getLog().debug( " " + entry );
1567 }
1568 }
1569 return list;
1570 }
1571
1572 private void maybeAppendList( final List<String> base, final List<String> list )
1573 {
1574 if ( list != null )
1575 {
1576 base.addAll( list );
1577 }
1578 }
1579
1580 @SuppressWarnings( "checkstyle:modifierorder" )
1581 private @Nonnull List<String> getExcludeList()
1582 {
1583 List<String> actualExcludes = null;
1584 if ( isSpecificTestSpecified() )
1585 {
1586
1587
1588
1589
1590 actualExcludes = new ArrayList<String>();
1591 }
1592 else
1593 {
1594 if ( getExcludesFile() != null )
1595 {
1596 actualExcludes = readListFromFile( getExcludesFile() );
1597 }
1598
1599
1600 if ( actualExcludes == null )
1601 {
1602 actualExcludes = this.getExcludes();
1603 }
1604 else
1605 {
1606 maybeAppendList( actualExcludes, this.getExcludes() );
1607 }
1608
1609
1610
1611 if ( actualExcludes == null || actualExcludes.size() == 0 )
1612 {
1613 actualExcludes = Arrays.asList( "**/*$*" );
1614 }
1615 }
1616 return filterNulls( actualExcludes );
1617 }
1618
1619 private List<String> getIncludeList()
1620 {
1621 List<String> includes = null;
1622 if ( isSpecificTestSpecified() && !isMultipleExecutionBlocksDetected() )
1623 {
1624 includes = getSpecificTests();
1625 }
1626 else
1627 {
1628 if ( getIncludesFile() != null )
1629 {
1630 includes = readListFromFile( getIncludesFile() );
1631 }
1632
1633
1634 if ( includes == null )
1635 {
1636 includes = this.getIncludes();
1637 }
1638 else
1639 {
1640 maybeAppendList( includes, this.getIncludes() );
1641 }
1642 }
1643
1644
1645
1646 if ( includes == null || includes.size() == 0 )
1647 {
1648 includes = Arrays.asList( getDefaultIncludes() );
1649 }
1650
1651 return filterNulls( includes );
1652 }
1653
1654 @SuppressWarnings( "checkstyle:modifierorder" )
1655 private @Nonnull List<String> filterNulls( @Nonnull List<String> toFilter )
1656 {
1657 List<String> result = new ArrayList<String>( toFilter.size() );
1658 for ( String item : toFilter )
1659 {
1660 if ( item != null )
1661 {
1662 result.add( item );
1663 }
1664 }
1665
1666 return result;
1667 }
1668
1669 private boolean isMultipleExecutionBlocksDetected()
1670 {
1671 MavenProject project = getProject();
1672 if ( project != null )
1673 {
1674 String key = getPluginDescriptor().getPluginLookupKey();
1675 Plugin plugin = (Plugin) project.getBuild().getPluginsAsMap().get( key );
1676
1677 if ( plugin != null )
1678 {
1679 @SuppressWarnings( "rawtypes" ) List executions = plugin.getExecutions();
1680 return executions != null && executions.size() > 1;
1681 }
1682 }
1683
1684 return false;
1685 }
1686
1687 private List<String> getSpecificTests()
1688 {
1689 if ( !isSpecificTestSpecified() )
1690 {
1691 return Collections.emptyList();
1692 }
1693
1694 List<String> specificTests = new ArrayList<String>();
1695 String[] testRegexes = StringUtils.split( getTest(), "," );
1696
1697 for ( String testRegexe : testRegexes )
1698 {
1699 String testRegex = testRegexe;
1700 if ( testRegex.endsWith( ".java" ) )
1701 {
1702 testRegex = testRegex.substring( 0, testRegex.length() - 5 );
1703 }
1704
1705 testRegex = testRegex.replace( '.', '/' );
1706 specificTests.add( "**/" + testRegex + ".java" );
1707 }
1708
1709 return specificTests;
1710 }
1711
1712 private Artifact getTestNgArtifact()
1713 throws MojoExecutionException
1714 {
1715 Artifact artifact = getProjectArtifactMap().get( getTestNGArtifactName() );
1716
1717 if ( artifact != null )
1718 {
1719 VersionRange range = createVersionRange();
1720 if ( !range.containsVersion( new DefaultArtifactVersion( artifact.getVersion() ) ) )
1721 {
1722 throw new MojoExecutionException(
1723 "TestNG support requires version 4.7 or above. You have declared version "
1724 + artifact.getVersion() );
1725 }
1726 }
1727 return artifact;
1728
1729 }
1730
1731 private VersionRange createVersionRange()
1732 {
1733 try
1734 {
1735 return VersionRange.createFromVersionSpec( "[4.7,)" );
1736 }
1737 catch ( InvalidVersionSpecificationException e )
1738 {
1739 throw new RuntimeException( e );
1740 }
1741 }
1742
1743 private Artifact getJunitArtifact()
1744 {
1745 return getProjectArtifactMap().get( getJunitArtifactName() );
1746 }
1747
1748 private Artifact getJunitDepArtifact()
1749 {
1750 return getProjectArtifactMap().get( "junit:junit-dep" );
1751 }
1752
1753 protected ForkStarter createForkStarter( ProviderInfo provider, ForkConfiguration forkConfiguration,
1754 ClassLoaderConfiguration classLoaderConfiguration,
1755 RunOrderParameters runOrderParameters, Log log )
1756 throws MojoExecutionException, MojoFailureException
1757 {
1758 StartupConfiguration startupConfiguration = createStartupConfiguration( provider, classLoaderConfiguration );
1759 String configChecksum = getConfigChecksum();
1760 StartupReportConfiguration startupReportConfiguration = getStartupReportConfiguration( configChecksum );
1761 ProviderConfiguration providerConfiguration = createProviderConfiguration( runOrderParameters );
1762 return new ForkStarter( providerConfiguration, startupConfiguration, forkConfiguration,
1763 getForkedProcessTimeoutInSeconds(), startupReportConfiguration, log );
1764 }
1765
1766 protected InPluginVMSurefireStarter createInprocessStarter( ProviderInfo provider,
1767 ClassLoaderConfiguration classLoaderConfiguration,
1768 RunOrderParameters runOrderParameters )
1769 throws MojoExecutionException, MojoFailureException
1770 {
1771 StartupConfiguration startupConfiguration = createStartupConfiguration( provider, classLoaderConfiguration );
1772 String configChecksum = getConfigChecksum();
1773 StartupReportConfiguration startupReportConfiguration = getStartupReportConfiguration( configChecksum );
1774 ProviderConfiguration providerConfiguration = createProviderConfiguration( runOrderParameters );
1775 return new InPluginVMSurefireStarter( startupConfiguration, providerConfiguration, startupReportConfiguration );
1776
1777 }
1778
1779 protected ForkConfiguration getForkConfiguration()
1780 {
1781 File tmpDir = getSurefireTempDir();
1782
1783 tmpDir.mkdirs();
1784
1785 Artifact shadeFire = getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-shadefire" );
1786
1787 final Classpath bootClasspathConfiguration =
1788 getArtifactClasspath( shadeFire != null ? shadeFire : surefireBooterArtifact );
1789
1790 return new ForkConfiguration( bootClasspathConfiguration, tmpDir, getEffectiveDebugForkedProcess(),
1791 getEffectiveJvm(),
1792 getWorkingDirectory() != null ? getWorkingDirectory() : getBasedir(),
1793 getProject().getModel().getProperties(),
1794 getArgLine(), getEnvironmentVariables(), getLog().isDebugEnabled(),
1795 getEffectiveForkCount(), reuseForks );
1796 }
1797
1798 private void convertDeprecatedForkMode()
1799 {
1800 String effectiveForkMode = getEffectiveForkMode();
1801
1802 if ( ForkConfiguration.FORK_PERTHREAD.equals( effectiveForkMode ) )
1803 {
1804 forkCount = String.valueOf( threadCount );
1805 }
1806 else if ( ForkConfiguration.FORK_NEVER.equals( effectiveForkMode ) )
1807 {
1808 forkCount = "0";
1809 }
1810 else if ( ForkConfiguration.FORK_ALWAYS.equals( effectiveForkMode ) )
1811 {
1812 forkCount = "1";
1813 reuseForks = false;
1814 }
1815
1816 if ( !ForkConfiguration.FORK_ONCE.equals( getForkMode() ) )
1817 {
1818 getLog().warn(
1819 "The parameter forkMode is deprecated since version 2.14. Use forkCount and reuseForks instead." );
1820 }
1821 }
1822
1823 @SuppressWarnings( "checkstyle:emptyblock" )
1824 protected int getEffectiveForkCount()
1825 {
1826 if ( effectiveForkCount < 0 )
1827 {
1828 try
1829 {
1830 effectiveForkCount = convertWithCoreCount( forkCount );
1831 }
1832 catch ( NumberFormatException ignored )
1833 {
1834 }
1835
1836 if ( effectiveForkCount < 0 )
1837 {
1838 throw new IllegalArgumentException( "Fork count " + forkCount.trim() + " is not a legal value." );
1839 }
1840 }
1841
1842 return effectiveForkCount;
1843 }
1844
1845 protected int convertWithCoreCount( String count )
1846 {
1847 String trimmed = count.trim();
1848 if ( trimmed.endsWith( "C" ) )
1849 {
1850 double multiplier = Double.parseDouble( trimmed.substring( 0, trimmed.length() - 1 ) );
1851 double calculated = multiplier * ( (double) Runtime.getRuntime().availableProcessors() );
1852 return calculated > 0d ? Math.max( (int) calculated, 1 ) : 0;
1853 }
1854 else
1855 {
1856 return Integer.parseInt( trimmed );
1857 }
1858 }
1859
1860 private String getEffectiveDebugForkedProcess()
1861 {
1862 String debugForkedProcess = getDebugForkedProcess();
1863 if ( "true".equals( debugForkedProcess ) )
1864 {
1865 return "-Xdebug -Xnoagent -Djava.compiler=NONE"
1866 + " -Xrunjdwp:transport=dt_socket,server=y,suspend=y,address=5005";
1867 }
1868 return debugForkedProcess;
1869 }
1870
1871 private String getEffectiveJvm()
1872 {
1873 String jvmToUse = getJvm();
1874 if ( toolchain != null && jvmToUse == null )
1875 {
1876 jvmToUse = toolchain.findTool( "java" );
1877 }
1878
1879 if ( StringUtils.isEmpty( jvmToUse ) )
1880 {
1881
1882 jvmToUse = System.getProperty( "java.home" ) + File.separator + "bin" + File.separator + "java";
1883 getLog().debug( "Using JVM: " + jvmToUse );
1884 }
1885
1886 return jvmToUse;
1887 }
1888
1889
1890 private Artifact getSurefireBooterArtifact()
1891 {
1892 Artifact artifact = getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-booter" );
1893 if ( artifact == null )
1894 {
1895 throw new RuntimeException( "Unable to locate surefire-booter in the list of plugin artifacts" );
1896 }
1897 artifact.isSnapshot();
1898 return artifact;
1899 }
1900
1901
1902
1903
1904
1905
1906
1907 private File getSurefireTempDir()
1908 {
1909 return new File( getReportsDirectory().getParentFile(), "surefire" );
1910 }
1911
1912
1913
1914
1915
1916
1917 private String getConfigChecksum()
1918 {
1919 ChecksumCalculator checksum = new ChecksumCalculator();
1920 checksum.add( getPluginName() );
1921 checksum.add( isSkipTests() );
1922 checksum.add( isSkipExec() );
1923 checksum.add( isSkip() );
1924 checksum.add( getTestClassesDirectory() );
1925 checksum.add( getClassesDirectory() );
1926 checksum.add( getClasspathDependencyExcludes() );
1927 checksum.add( getClasspathDependencyScopeExclude() );
1928 checksum.add( getAdditionalClasspathElements() );
1929 checksum.add( getReportsDirectory() );
1930 checksum.add( getTestSourceDirectory() );
1931 checksum.add( getTest() );
1932 checksum.add( getIncludes() );
1933 checksum.add( getExcludes() );
1934 checksum.add( getLocalRepository() );
1935 checksum.add( getSystemProperties() );
1936 checksum.add( getSystemPropertyVariables() );
1937 checksum.add( getSystemPropertiesFile() );
1938 checksum.add( getProperties() );
1939 checksum.add( isPrintSummary() );
1940 checksum.add( getReportFormat() );
1941 checksum.add( getReportNameSuffix() );
1942 checksum.add( isUseFile() );
1943 checksum.add( isRedirectTestOutputToFile() );
1944 checksum.add( getForkMode() );
1945 checksum.add( getForkCount() );
1946 checksum.add( isReuseForks() );
1947 checksum.add( getJvm() );
1948 checksum.add( getArgLine() );
1949 checksum.add( getDebugForkedProcess() );
1950 checksum.add( getForkedProcessTimeoutInSeconds() );
1951 checksum.add( getParallelTestsTimeoutInSeconds() );
1952 checksum.add( getParallelTestsTimeoutForcedInSeconds() );
1953 checksum.add( getEnvironmentVariables() );
1954 checksum.add( getWorkingDirectory() );
1955 checksum.add( isChildDelegation() );
1956 checksum.add( getGroups() );
1957 checksum.add( getExcludedGroups() );
1958 checksum.add( getSuiteXmlFiles() );
1959 checksum.add( getJunitArtifact() );
1960 checksum.add( getTestNGArtifactName() );
1961 checksum.add( getThreadCount() );
1962 checksum.add( getThreadCountSuites() );
1963 checksum.add( getThreadCountClasses() );
1964 checksum.add( getThreadCountMethods() );
1965 checksum.add( getPerCoreThreadCount() );
1966 checksum.add( getUseUnlimitedThreads() );
1967 checksum.add( getParallel() );
1968 checksum.add( isParallelOptimized() );
1969 checksum.add( isTrimStackTrace() );
1970 checksum.add( getRemoteRepositories() );
1971 checksum.add( isDisableXmlReport() );
1972 checksum.add( isUseSystemClassLoader() );
1973 checksum.add( isUseManifestOnlyJar() );
1974 checksum.add( isEnableAssertions() );
1975 checksum.add( getObjectFactory() );
1976 checksum.add( getFailIfNoTests() );
1977 checksum.add( getRunOrder() );
1978 checksum.add( getDependenciesToScan() );
1979 addPluginSpecificChecksumItems( checksum );
1980 return checksum.getSha1();
1981
1982 }
1983
1984 protected void addPluginSpecificChecksumItems( ChecksumCalculator checksum )
1985 {
1986
1987 }
1988
1989 protected boolean hasExecutedBefore()
1990 {
1991
1992 String configChecksum = getConfigChecksum();
1993 @SuppressWarnings( "unchecked" ) Map<String, String> pluginContext = getPluginContext();
1994 if ( pluginContext.containsKey( configChecksum ) )
1995 {
1996 getLog().info( "Skipping execution of surefire because it has already been run for this configuration" );
1997 return true;
1998 }
1999 pluginContext.put( configChecksum, configChecksum );
2000
2001 return false;
2002 }
2003
2004 protected ClassLoaderConfiguration getClassLoaderConfiguration( boolean isForking )
2005 {
2006 return isForking
2007 ? new ClassLoaderConfiguration( isUseSystemClassLoader(), isUseManifestOnlyJar() )
2008 : new ClassLoaderConfiguration( false, false );
2009 }
2010
2011 protected abstract String[] getDefaultIncludes();
2012
2013
2014
2015
2016
2017
2018
2019
2020
2021
2022
2023 Classpath generateTestClasspath()
2024 throws InvalidVersionSpecificationException, MojoFailureException, ArtifactResolutionException,
2025 ArtifactNotFoundException, MojoExecutionException
2026 {
2027 List<String> classpath = new ArrayList<String>( 2 + getProject().getArtifacts().size() );
2028
2029 classpath.add( getTestClassesDirectory().getAbsolutePath() );
2030
2031 classpath.add( getClassesDirectory().getAbsolutePath() );
2032
2033 @SuppressWarnings( "unchecked" ) Set<Artifact> classpathArtifacts = getProject().getArtifacts();
2034
2035 if ( getClasspathDependencyScopeExclude() != null && !getClasspathDependencyScopeExclude().equals( "" ) )
2036 {
2037 ArtifactFilter dependencyFilter = new ScopeArtifactFilter( getClasspathDependencyScopeExclude() );
2038 classpathArtifacts = this.filterArtifacts( classpathArtifacts, dependencyFilter );
2039 }
2040
2041 if ( getClasspathDependencyExcludes() != null )
2042 {
2043 ArtifactFilter dependencyFilter =
2044 new PatternIncludesArtifactFilter( Arrays.asList( getClasspathDependencyExcludes() ) );
2045 classpathArtifacts = this.filterArtifacts( classpathArtifacts, dependencyFilter );
2046 }
2047
2048 for ( Artifact artifact : classpathArtifacts )
2049 {
2050 if ( artifact.getArtifactHandler().isAddedToClasspath() )
2051 {
2052 File file = artifact.getFile();
2053 if ( file != null )
2054 {
2055 classpath.add( file.getPath() );
2056 }
2057 }
2058 }
2059
2060
2061 if ( getAdditionalClasspathElements() != null )
2062 {
2063 for ( String classpathElement : getAdditionalClasspathElements() )
2064 {
2065 if ( classpathElement != null )
2066 {
2067 classpath.add( classpathElement );
2068 }
2069 }
2070 }
2071
2072
2073
2074 if ( getTestNgArtifact() != null )
2075 {
2076 addTestNgUtilsArtifacts( classpath );
2077 }
2078
2079 return new Classpath( classpath );
2080 }
2081
2082 void addTestNgUtilsArtifacts( List<String> classpath )
2083 throws ArtifactResolutionException, ArtifactNotFoundException
2084 {
2085 Artifact surefireArtifact = getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-booter" );
2086 String surefireVersion = surefireArtifact.getBaseVersion();
2087
2088 Artifact[] extraTestNgArtifacts =
2089 { getArtifactFactory().createArtifact( "org.apache.maven.surefire", "surefire-testng-utils",
2090 surefireVersion, "runtime", "jar" ),
2091 getArtifactFactory().createArtifact( "org.apache.maven.surefire", "surefire-grouper", surefireVersion,
2092 "runtime", "jar" ) };
2093
2094 for ( Artifact artifact : extraTestNgArtifacts )
2095 {
2096 getArtifactResolver().resolve( artifact, getRemoteRepositories(), getLocalRepository() );
2097
2098 String path = artifact.getFile().getPath();
2099 classpath.add( path );
2100 }
2101 }
2102
2103
2104
2105
2106
2107
2108
2109
2110 private Set<Artifact> filterArtifacts( Set<Artifact> artifacts, ArtifactFilter filter )
2111 {
2112 Set<Artifact> filteredArtifacts = new LinkedHashSet<Artifact>();
2113
2114 for ( Artifact artifact : artifacts )
2115 {
2116 if ( !filter.include( artifact ) )
2117 {
2118 filteredArtifacts.add( artifact );
2119 }
2120 }
2121
2122 return filteredArtifacts;
2123 }
2124
2125 private void showMap( Map<?, ?> map, String setting )
2126 {
2127 for ( Object o : map.keySet() )
2128 {
2129 String key = (String) o;
2130 String value = (String) map.get( key );
2131 getLog().debug( "Setting " + setting + " [" + key + "]=[" + value + "]" );
2132 }
2133 }
2134
2135
2136 private ArtifactResolutionResult resolveArtifact( Artifact filteredArtifact, Artifact providerArtifact )
2137 {
2138 ArtifactFilter filter = null;
2139 if ( filteredArtifact != null )
2140 {
2141 filter = new ExcludesArtifactFilter(
2142 Collections.singletonList( filteredArtifact.getGroupId() + ":" + filteredArtifact.getArtifactId() ) );
2143 }
2144
2145 Artifact originatingArtifact = getArtifactFactory().createBuildArtifact( "dummy", "dummy", "1.0", "jar" );
2146
2147 try
2148 {
2149 return getArtifactResolver().resolveTransitively( Collections.singleton( providerArtifact ),
2150 originatingArtifact, getLocalRepository(),
2151 getRemoteRepositories(), getMetadataSource(), filter );
2152 }
2153 catch ( ArtifactResolutionException e )
2154 {
2155 throw new RuntimeException( e );
2156 }
2157 catch ( ArtifactNotFoundException e )
2158 {
2159 throw new RuntimeException( e );
2160 }
2161 }
2162
2163 private Classpath getArtifactClasspath( Artifact surefireArtifact )
2164 {
2165 Classpath existing = ClasspathCache.getCachedClassPath( surefireArtifact.getArtifactId() );
2166 if ( existing == null )
2167 {
2168 ArtifactResolutionResult result = resolveArtifact( null, surefireArtifact );
2169
2170 List<String> items = new ArrayList<String>();
2171 for ( Object o : result.getArtifacts() )
2172 {
2173 Artifact artifact = (Artifact) o;
2174
2175 getLog().debug(
2176 "Adding to " + getPluginName() + " booter test classpath: " + artifact.getFile().getAbsolutePath()
2177 + " Scope: " + artifact.getScope() );
2178
2179 items.add( artifact.getFile().getAbsolutePath() );
2180 }
2181 existing = new Classpath( items );
2182 ClasspathCache.setCachedClasspath( surefireArtifact.getArtifactId(), existing );
2183 }
2184 return existing;
2185 }
2186
2187 private Properties getUserProperties()
2188 {
2189 Properties props = null;
2190 try
2191 {
2192
2193 Method getUserProperties = getSession().getClass().getMethod( "getUserProperties" );
2194 props = (Properties) getUserProperties.invoke( getSession() );
2195 }
2196 catch ( Exception e )
2197 {
2198 String msg = "Build uses Maven 2.0.x, cannot propagate system properties"
2199 + " from command line to tests (cf. SUREFIRE-121)";
2200 if ( getLog().isDebugEnabled() )
2201 {
2202 getLog().warn( msg, e );
2203 }
2204 else
2205 {
2206 getLog().warn( msg );
2207 }
2208 }
2209 if ( props == null )
2210 {
2211 props = new Properties();
2212 }
2213 return props;
2214 }
2215
2216
2217 void ensureWorkingDirectoryExists()
2218 throws MojoFailureException
2219 {
2220 if ( getWorkingDirectory() == null )
2221 {
2222 throw new MojoFailureException( "workingDirectory cannot be null" );
2223 }
2224
2225 if ( !getWorkingDirectory().exists() )
2226 {
2227 if ( !getWorkingDirectory().mkdirs() )
2228 {
2229 throw new MojoFailureException( "Cannot create workingDirectory " + getWorkingDirectory() );
2230 }
2231 }
2232
2233 if ( !getWorkingDirectory().isDirectory() )
2234 {
2235 throw new MojoFailureException(
2236 "workingDirectory " + getWorkingDirectory() + " exists and is not a directory" );
2237 }
2238 }
2239
2240 void ensureParallelRunningCompatibility()
2241 throws MojoFailureException
2242 {
2243 if ( isMavenParallel() && isNotForking() )
2244 {
2245 throw new MojoFailureException( "parallel maven execution is not compatible with surefire forkCount 0" );
2246 }
2247 }
2248
2249 void ensureThreadCountWithPerThread()
2250 throws MojoFailureException
2251 {
2252 if ( ForkConfiguration.FORK_PERTHREAD.equals( getEffectiveForkMode() ) && getThreadCount() < 1 )
2253 {
2254 throw new MojoFailureException( "Fork mode perthread requires a thread count" );
2255 }
2256 }
2257
2258 void warnIfUselessUseSystemClassLoaderParameter()
2259 {
2260 if ( isUseSystemClassLoader() && isNotForking() )
2261 {
2262 getLog().warn( "useSystemClassloader setting has no effect when not forking" );
2263 }
2264 }
2265
2266 private boolean isNotForking()
2267 {
2268 return !isForking();
2269 }
2270
2271 void warnIfDefunctGroupsCombinations()
2272 throws MojoFailureException, MojoExecutionException
2273 {
2274 if ( isAnyGroupsSelected() )
2275 {
2276 if ( getTestNgArtifact() != null )
2277 {
2278 return;
2279 }
2280 Artifact junitArtifact = getJunitArtifact();
2281 boolean junit47Compatible = isJunit47Compatible( junitArtifact );
2282 if ( junit47Compatible )
2283 {
2284 return;
2285 }
2286 if ( junitArtifact != null )
2287 {
2288 throw new MojoFailureException( "groups/excludedGroups are specified but JUnit version on classpath"
2289 + " is too old to support groups. Check your dependency:tree to see if your project"
2290 + " is picking up an old junit version" );
2291 }
2292 throw new MojoFailureException(
2293 "groups/excludedGroups require TestNG or JUnit48+ on project test classpath" );
2294
2295 }
2296 }
2297
2298 class TestNgProviderInfo
2299 implements ProviderInfo
2300 {
2301 private final Artifact testNgArtifact;
2302
2303 TestNgProviderInfo( Artifact testNgArtifact )
2304 {
2305 this.testNgArtifact = testNgArtifact;
2306 }
2307
2308 @SuppressWarnings( "checkstyle:modifierorder" )
2309 public @Nonnull String getProviderName()
2310 {
2311 return "org.apache.maven.surefire.testng.TestNGProvider";
2312 }
2313
2314 public boolean isApplicable()
2315 {
2316 return testNgArtifact != null;
2317 }
2318
2319 public void addProviderProperties() throws MojoExecutionException
2320 {
2321 convertTestNGParameters();
2322 }
2323
2324 public Classpath getProviderClasspath()
2325 throws ArtifactResolutionException, ArtifactNotFoundException
2326 {
2327 Artifact surefireArtifact = getPluginArtifactMap().get( "org.apache.maven.surefire:surefire-booter" );
2328 return dependencyResolver.getProviderClasspath( "surefire-testng", surefireArtifact.getBaseVersion(),
2329 testNgArtifact );
2330 }
2331 }
2332
2333 class JUnit3ProviderInfo
2334 implements ProviderInfo
2335 {
2336 @Nonnull public String getProviderName()
2337 {
2338 return "org.apache.maven.surefire.junit.JUnit3Provider";
2339 }
2340
2341 public boolean isApplicable()
2342 {
2343 return true;
2344 }
2345
2346 public void addProviderProperties() throws MojoExecutionException
2347 {
2348 }
2349
2350 public Classpath getProviderClasspath()
2351 throws ArtifactResolutionException, ArtifactNotFoundException
2352 {
2353
2354
2355 return dependencyResolver.getProviderClasspath( "surefire-junit3", surefireBooterArtifact.getBaseVersion(),
2356 null );
2357
2358 }
2359
2360 }
2361
2362 class JUnit4ProviderInfo
2363 implements ProviderInfo
2364 {
2365 private final Artifact junitArtifact;
2366
2367 private final Artifact junitDepArtifact;
2368
2369 JUnit4ProviderInfo( Artifact junitArtifact, Artifact junitDepArtifact )
2370 {
2371 this.junitArtifact = junitArtifact;
2372 this.junitDepArtifact = junitDepArtifact;
2373 }
2374
2375 @Nonnull public String getProviderName()
2376 {
2377 return "org.apache.maven.surefire.junit4.JUnit4Provider";
2378 }
2379
2380 public boolean isApplicable()
2381 {
2382 return junitDepArtifact != null || isAnyJunit4( junitArtifact );
2383 }
2384
2385 public void addProviderProperties() throws MojoExecutionException
2386 {
2387 }
2388
2389 public Classpath getProviderClasspath()
2390 throws ArtifactResolutionException, ArtifactNotFoundException
2391 {
2392 return dependencyResolver.getProviderClasspath( "surefire-junit4", surefireBooterArtifact.getBaseVersion(),
2393 null );
2394
2395 }
2396
2397 }
2398
2399 class JUnitCoreProviderInfo
2400 implements ProviderInfo
2401 {
2402 private final Artifact junitArtifact;
2403
2404 private final Artifact junitDepArtifact;
2405
2406 JUnitCoreProviderInfo( Artifact junitArtifact, Artifact junitDepArtifact )
2407 {
2408 this.junitArtifact = junitArtifact;
2409 this.junitDepArtifact = junitDepArtifact;
2410 }
2411
2412 @Nonnull public String getProviderName()
2413 {
2414 return "org.apache.maven.surefire.junitcore.JUnitCoreProvider";
2415 }
2416
2417 private boolean is47CompatibleJunitDep()
2418 {
2419 return junitDepArtifact != null && isJunit47Compatible( junitDepArtifact );
2420 }
2421
2422 public boolean isApplicable()
2423 {
2424 final boolean isJunitArtifact47 = isAnyJunit4( junitArtifact ) && isJunit47Compatible( junitArtifact );
2425 final boolean isAny47ProvidersForcers = isAnyConcurrencySelected() || isAnyGroupsSelected();
2426 return isAny47ProvidersForcers && ( isJunitArtifact47 || is47CompatibleJunitDep() );
2427 }
2428
2429 public void addProviderProperties() throws MojoExecutionException
2430 {
2431 convertJunitCoreParameters();
2432 convertGroupParameters();
2433 }
2434
2435 public Classpath getProviderClasspath()
2436 throws ArtifactResolutionException, ArtifactNotFoundException
2437 {
2438 return dependencyResolver.getProviderClasspath( "surefire-junit47", surefireBooterArtifact.getBaseVersion(),
2439 null );
2440 }
2441
2442 }
2443
2444
2445
2446
2447
2448 public class DynamicProviderInfo
2449 implements ConfigurableProviderInfo
2450 {
2451 final String providerName;
2452
2453 DynamicProviderInfo( String providerName )
2454 {
2455 this.providerName = providerName;
2456 }
2457
2458 public ProviderInfo instantiate( String providerName )
2459 {
2460 return new DynamicProviderInfo( providerName );
2461 }
2462
2463 @Nonnull
2464 public String getProviderName()
2465 {
2466 return providerName;
2467 }
2468
2469 public boolean isApplicable()
2470 {
2471 return true;
2472 }
2473
2474 public void addProviderProperties() throws MojoExecutionException
2475 {
2476
2477 convertJunitCoreParameters();
2478 convertTestNGParameters();
2479 }
2480
2481
2482 public Classpath getProviderClasspath()
2483 throws ArtifactResolutionException, ArtifactNotFoundException
2484 {
2485 final Map<String, Artifact> pluginArtifactMap = getPluginArtifactMap();
2486 Artifact plugin = pluginArtifactMap.get( "org.apache.maven.plugins:maven-surefire-plugin" );
2487 return dependencyResolver.addProviderToClasspath( pluginArtifactMap, plugin );
2488 }
2489
2490 }
2491
2492 public abstract List<String> getIncludes();
2493
2494 public File getIncludesFile()
2495 {
2496 return includesFile;
2497 }
2498
2499 public abstract void setIncludes( List<String> includes );
2500
2501 public List<String> getExcludes()
2502 {
2503 return excludes;
2504 }
2505
2506 public File getExcludesFile()
2507 {
2508 return excludesFile;
2509 }
2510
2511 public void setExcludes( List<String> excludes )
2512 {
2513 this.excludes = excludes;
2514 }
2515
2516 public ArtifactRepository getLocalRepository()
2517 {
2518 return localRepository;
2519 }
2520
2521 public void setLocalRepository( ArtifactRepository localRepository )
2522 {
2523 this.localRepository = localRepository;
2524 }
2525
2526
2527
2528
2529 public Properties getSystemProperties()
2530 {
2531 return systemProperties;
2532 }
2533
2534 @SuppressWarnings( { "UnusedDeclaration", "deprecation" } )
2535 public void setSystemProperties( Properties systemProperties )
2536 {
2537 this.systemProperties = systemProperties;
2538 }
2539
2540 public Map<String, String> getSystemPropertyVariables()
2541 {
2542 return systemPropertyVariables;
2543 }
2544
2545 @SuppressWarnings( "UnusedDeclaration" )
2546 public void setSystemPropertyVariables( Map<String, String> systemPropertyVariables )
2547 {
2548 this.systemPropertyVariables = systemPropertyVariables;
2549 }
2550
2551 public File getSystemPropertiesFile()
2552 {
2553 return systemPropertiesFile;
2554 }
2555
2556 @SuppressWarnings( "UnusedDeclaration" )
2557 public void setSystemPropertiesFile( File systemPropertiesFile )
2558 {
2559 this.systemPropertiesFile = systemPropertiesFile;
2560 }
2561
2562 public Properties getProperties()
2563 {
2564 return properties;
2565 }
2566
2567 public void setProperties( Properties properties )
2568 {
2569 this.properties = properties;
2570 }
2571
2572 public Map<String, Artifact> getPluginArtifactMap()
2573 {
2574 return pluginArtifactMap;
2575 }
2576
2577 @SuppressWarnings( "UnusedDeclaration" )
2578 public void setPluginArtifactMap( Map<String, Artifact> pluginArtifactMap )
2579 {
2580 this.pluginArtifactMap = pluginArtifactMap;
2581 }
2582
2583 public Map<String, Artifact> getProjectArtifactMap()
2584 {
2585 return projectArtifactMap;
2586 }
2587
2588 @SuppressWarnings( "UnusedDeclaration" )
2589 public void setProjectArtifactMap( Map<String, Artifact> projectArtifactMap )
2590 {
2591 this.projectArtifactMap = projectArtifactMap;
2592 }
2593
2594
2595 public String getReportNameSuffix()
2596 {
2597 return reportNameSuffix;
2598 }
2599
2600 @SuppressWarnings( "UnusedDeclaration" )
2601 public void setReportNameSuffix( String reportNameSuffix )
2602 {
2603 this.reportNameSuffix = reportNameSuffix;
2604 }
2605
2606
2607 public boolean isRedirectTestOutputToFile()
2608 {
2609 return redirectTestOutputToFile;
2610 }
2611
2612 @SuppressWarnings( "UnusedDeclaration" )
2613 public void setRedirectTestOutputToFile( boolean redirectTestOutputToFile )
2614 {
2615 this.redirectTestOutputToFile = redirectTestOutputToFile;
2616 }
2617
2618
2619 public Boolean getFailIfNoTests()
2620 {
2621 return failIfNoTests;
2622 }
2623
2624 public void setFailIfNoTests( Boolean failIfNoTests )
2625 {
2626 this.failIfNoTests = failIfNoTests;
2627 }
2628
2629 public String getForkMode()
2630 {
2631 return forkMode;
2632 }
2633
2634 @SuppressWarnings( "UnusedDeclaration" )
2635 public void setForkMode( String forkMode )
2636 {
2637 this.forkMode = forkMode;
2638 }
2639
2640 public String getJvm()
2641 {
2642 return jvm;
2643 }
2644
2645 public String getArgLine()
2646 {
2647 return argLine;
2648 }
2649
2650 @SuppressWarnings( "UnusedDeclaration" )
2651 public void setArgLine( String argLine )
2652 {
2653 this.argLine = argLine;
2654 }
2655
2656
2657 public Map<String, String> getEnvironmentVariables()
2658 {
2659 return environmentVariables;
2660 }
2661
2662 @SuppressWarnings( "UnusedDeclaration" )
2663 public void setEnvironmentVariables( Map<String, String> environmentVariables )
2664 {
2665 this.environmentVariables = environmentVariables;
2666 }
2667
2668 public File getWorkingDirectory()
2669 {
2670 return workingDirectory;
2671 }
2672
2673 @SuppressWarnings( "UnusedDeclaration" )
2674 public void setWorkingDirectory( File workingDirectory )
2675 {
2676 this.workingDirectory = workingDirectory;
2677 }
2678
2679 public boolean isChildDelegation()
2680 {
2681 return childDelegation;
2682 }
2683
2684 @SuppressWarnings( "UnusedDeclaration" )
2685 public void setChildDelegation( boolean childDelegation )
2686 {
2687 this.childDelegation = childDelegation;
2688 }
2689
2690 public String getGroups()
2691 {
2692 return groups;
2693 }
2694
2695 @SuppressWarnings( "UnusedDeclaration" )
2696 public void setGroups( String groups )
2697 {
2698 this.groups = groups;
2699 }
2700
2701 public String getExcludedGroups()
2702 {
2703 return excludedGroups;
2704 }
2705
2706 @SuppressWarnings( "UnusedDeclaration" )
2707 public void setExcludedGroups( String excludedGroups )
2708 {
2709 this.excludedGroups = excludedGroups;
2710 }
2711
2712 public abstract File[] getSuiteXmlFiles();
2713
2714 public abstract void setSuiteXmlFiles( File[] suiteXmlFiles );
2715
2716 public String getJunitArtifactName()
2717 {
2718 return junitArtifactName;
2719 }
2720
2721 @SuppressWarnings( "UnusedDeclaration" )
2722 public void setJunitArtifactName( String junitArtifactName )
2723 {
2724 this.junitArtifactName = junitArtifactName;
2725 }
2726
2727 public String getTestNGArtifactName()
2728 {
2729 return testNGArtifactName;
2730 }
2731
2732 @SuppressWarnings( "UnusedDeclaration" )
2733 public void setTestNGArtifactName( String testNGArtifactName )
2734 {
2735 this.testNGArtifactName = testNGArtifactName;
2736 }
2737
2738 public int getThreadCount()
2739 {
2740 return threadCount;
2741 }
2742
2743 @SuppressWarnings( "UnusedDeclaration" )
2744 public void setThreadCount( int threadCount )
2745 {
2746 this.threadCount = threadCount;
2747 }
2748
2749 public boolean getPerCoreThreadCount()
2750 {
2751 return perCoreThreadCount;
2752 }
2753
2754 @SuppressWarnings( "UnusedDeclaration" )
2755 public void setPerCoreThreadCount( boolean perCoreThreadCount )
2756 {
2757 this.perCoreThreadCount = perCoreThreadCount;
2758 }
2759
2760 public boolean getUseUnlimitedThreads()
2761 {
2762 return useUnlimitedThreads;
2763 }
2764
2765 @SuppressWarnings( "UnusedDeclaration" )
2766 public void setUseUnlimitedThreads( boolean useUnlimitedThreads )
2767 {
2768 this.useUnlimitedThreads = useUnlimitedThreads;
2769 }
2770
2771 public String getParallel()
2772 {
2773 return parallel;
2774 }
2775
2776 @SuppressWarnings( "UnusedDeclaration" )
2777 public void setParallel( String parallel )
2778 {
2779 this.parallel = parallel;
2780 }
2781
2782 public boolean isParallelOptimized()
2783 {
2784 return parallelOptimized;
2785 }
2786
2787 @SuppressWarnings( "UnusedDeclaration" )
2788 public void setParallelOptimized( boolean parallelOptimized )
2789 {
2790 this.parallelOptimized = parallelOptimized;
2791 }
2792
2793 public int getThreadCountSuites()
2794 {
2795 return threadCountSuites;
2796 }
2797
2798 public void setThreadCountSuites( int threadCountSuites )
2799 {
2800 this.threadCountSuites = threadCountSuites;
2801 }
2802
2803 public int getThreadCountClasses()
2804 {
2805 return threadCountClasses;
2806 }
2807
2808 public void setThreadCountClasses( int threadCountClasses )
2809 {
2810 this.threadCountClasses = threadCountClasses;
2811 }
2812
2813 public int getThreadCountMethods()
2814 {
2815 return threadCountMethods;
2816 }
2817
2818 public void setThreadCountMethods( int threadCountMethods )
2819 {
2820 this.threadCountMethods = threadCountMethods;
2821 }
2822
2823 public boolean isTrimStackTrace()
2824 {
2825 return trimStackTrace;
2826 }
2827
2828 @SuppressWarnings( "UnusedDeclaration" )
2829 public void setTrimStackTrace( boolean trimStackTrace )
2830 {
2831 this.trimStackTrace = trimStackTrace;
2832 }
2833
2834 public ArtifactResolver getArtifactResolver()
2835 {
2836 return artifactResolver;
2837 }
2838
2839 @SuppressWarnings( "UnusedDeclaration" )
2840 public void setArtifactResolver( ArtifactResolver artifactResolver )
2841 {
2842 this.artifactResolver = artifactResolver;
2843 }
2844
2845 public ArtifactFactory getArtifactFactory()
2846 {
2847 return artifactFactory;
2848 }
2849
2850 @SuppressWarnings( "UnusedDeclaration" )
2851 public void setArtifactFactory( ArtifactFactory artifactFactory )
2852 {
2853 this.artifactFactory = artifactFactory;
2854 }
2855
2856 public List<ArtifactRepository> getRemoteRepositories()
2857 {
2858 return remoteRepositories;
2859 }
2860
2861 @SuppressWarnings( "UnusedDeclaration" )
2862 public void setRemoteRepositories( List<ArtifactRepository> remoteRepositories )
2863 {
2864 this.remoteRepositories = remoteRepositories;
2865 }
2866
2867 public ArtifactMetadataSource getMetadataSource()
2868 {
2869 return metadataSource;
2870 }
2871
2872 @SuppressWarnings( "UnusedDeclaration" )
2873 public void setMetadataSource( ArtifactMetadataSource metadataSource )
2874 {
2875 this.metadataSource = metadataSource;
2876 }
2877
2878
2879 public boolean isDisableXmlReport()
2880 {
2881 return disableXmlReport;
2882 }
2883
2884 @SuppressWarnings( "UnusedDeclaration" )
2885 public void setDisableXmlReport( boolean disableXmlReport )
2886 {
2887 this.disableXmlReport = disableXmlReport;
2888 }
2889
2890
2891 public boolean isEnableAssertions()
2892 {
2893 return enableAssertions;
2894 }
2895
2896 public boolean effectiveIsEnableAssertions()
2897 {
2898 if ( getArgLine() != null )
2899 {
2900 List<String> args = Arrays.asList( getArgLine().split( " " ) );
2901 if ( args.contains( "-da" ) || args.contains( "-disableassertions" ) )
2902 {
2903 return false;
2904 }
2905 }
2906 return isEnableAssertions();
2907 }
2908
2909 @SuppressWarnings( "UnusedDeclaration" )
2910 public void setEnableAssertions( boolean enableAssertions )
2911 {
2912 this.enableAssertions = enableAssertions;
2913 }
2914
2915 public MavenSession getSession()
2916 {
2917 return session;
2918 }
2919
2920 @SuppressWarnings( "UnusedDeclaration" )
2921 public void setSession( MavenSession session )
2922 {
2923 this.session = session;
2924 }
2925
2926 public String getObjectFactory()
2927 {
2928 return objectFactory;
2929 }
2930
2931 @SuppressWarnings( "UnusedDeclaration" )
2932 public void setObjectFactory( String objectFactory )
2933 {
2934 this.objectFactory = objectFactory;
2935 }
2936
2937 public ToolchainManager getToolchainManager()
2938 {
2939 return toolchainManager;
2940 }
2941
2942 @SuppressWarnings( "UnusedDeclaration" )
2943 public void setToolchainManager( ToolchainManager toolchainManager )
2944 {
2945 this.toolchainManager = toolchainManager;
2946 }
2947
2948 public boolean isMavenParallel()
2949 {
2950 return parallelMavenExecution != null && parallelMavenExecution;
2951 }
2952
2953 public abstract String getRunOrder();
2954
2955 public abstract void setRunOrder( String runOrder );
2956
2957 public String[] getDependenciesToScan()
2958 {
2959 return dependenciesToScan;
2960 }
2961
2962 public void setDependenciesToScan( String[] dependenciesToScan )
2963 {
2964 this.dependenciesToScan = dependenciesToScan;
2965 }
2966
2967 public PluginDescriptor getPluginDescriptor()
2968 {
2969 return pluginDescriptor;
2970 }
2971
2972 public MavenProject getProject()
2973 {
2974 return project;
2975 }
2976
2977 @SuppressWarnings( "UnusedDeclaration" )
2978 public void setProject( MavenProject project )
2979 {
2980 this.project = project;
2981 }
2982
2983 public File getTestSourceDirectory()
2984 {
2985 return testSourceDirectory;
2986 }
2987
2988 public void setTestSourceDirectory( File testSourceDirectory )
2989 {
2990 this.testSourceDirectory = testSourceDirectory;
2991 }
2992
2993 public String getForkCount()
2994 {
2995 return forkCount;
2996 }
2997
2998 public boolean isReuseForks()
2999 {
3000 return reuseForks;
3001 }
3002
3003 public String[] getAdditionalClasspathElements()
3004 {
3005 return additionalClasspathElements;
3006 }
3007
3008 public void setAdditionalClasspathElements( String[] additionalClasspathElements )
3009 {
3010 this.additionalClasspathElements = additionalClasspathElements;
3011 }
3012
3013 public String[] getClasspathDependencyExcludes()
3014 {
3015 return classpathDependencyExcludes;
3016 }
3017
3018 public void setClasspathDependencyExcludes( String[] classpathDependencyExcludes )
3019 {
3020 this.classpathDependencyExcludes = classpathDependencyExcludes;
3021 }
3022
3023 public String getClasspathDependencyScopeExclude()
3024 {
3025 return classpathDependencyScopeExclude;
3026 }
3027
3028 public void setClasspathDependencyScopeExclude( String classpathDependencyScopeExclude )
3029 {
3030 this.classpathDependencyScopeExclude = classpathDependencyScopeExclude;
3031 }
3032 }