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