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