View Javadoc

1   package org.apache.maven.plugin.failsafe;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
20   */
21  
22  import org.apache.maven.artifact.factory.ArtifactFactory;
23  import org.apache.maven.artifact.metadata.ArtifactMetadataSource;
24  import org.apache.maven.artifact.repository.ArtifactRepository;
25  import org.apache.maven.artifact.resolver.ArtifactResolver;
26  import org.apache.maven.execution.MavenSession;
27  import org.apache.maven.plugin.MojoExecutionException;
28  import org.apache.maven.plugin.MojoFailureException;
29  import org.apache.maven.plugin.surefire.AbstractSurefireMojo;
30  import org.apache.maven.plugin.surefire.ProviderInfo;
31  import org.apache.maven.plugin.surefire.SurefireExecutionParameters;
32  import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
33  import org.apache.maven.plugin.surefire.booterclient.ForkConfiguration;
34  import org.apache.maven.plugin.surefire.booterclient.ForkStarter;
35  import org.apache.maven.project.MavenProject;
36  import org.apache.maven.surefire.booter.ClassLoaderConfiguration;
37  import org.apache.maven.surefire.booter.ProviderConfiguration;
38  import org.apache.maven.surefire.booter.SurefireBooterForkException;
39  import org.apache.maven.surefire.booter.SurefireExecutionException;
40  import org.apache.maven.surefire.failsafe.model.FailsafeSummary;
41  import org.apache.maven.surefire.failsafe.model.io.xpp3.FailsafeSummaryXpp3Writer;
42  import org.apache.maven.toolchain.ToolchainManager;
43  import org.codehaus.plexus.util.ReaderFactory;
44  import org.codehaus.plexus.util.StringUtils;
45  
46  import java.io.BufferedOutputStream;
47  import java.io.File;
48  import java.io.FileOutputStream;
49  import java.io.IOException;
50  import java.io.OutputStreamWriter;
51  import java.io.Writer;
52  import java.util.HashMap;
53  import java.util.Iterator;
54  import java.util.List;
55  import java.util.Map;
56  import java.util.Properties;
57  
58  /**
59   * Run integration tests using Surefire.
60   *
61   * @author Jason van Zyl
62   * @author Stephen Connolly
63   * @requiresProject true
64   * @requiresDependencyResolution test
65   * @goal integration-test
66   * @phase integration-test
67   * @threadSafe
68   * @noinspection JavaDoc
69   */
70  public class IntegrationTestMojo
71      extends AbstractSurefireMojo
72      implements SurefireExecutionParameters
73  {
74  
75      /**
76       * Set this to "true" to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite
77       * convenient on occasion.
78       *
79       * @parameter default-value="false" expression="${skipTests}"
80       * @since 2.4
81       */
82      private boolean skipTests;
83  
84      /**
85       * Set this to "true" to skip running integration tests, but still compile them. Its use is NOT RECOMMENDED, but quite
86       * convenient on occasion.
87       *
88       * @parameter expression="${skipITs}"
89       * @since 2.4.3-alpha-2
90       */
91      private boolean skipITs;
92  
93      /**
94       * This old parameter is just like <code>skipTests</code>, but bound to the old property "maven.test.skip.exec".
95       *
96       * @parameter expression="${maven.test.skip.exec}"
97       * @since 2.3
98       * @deprecated Use skipTests instead.
99       */
100     private boolean skipExec;
101 
102     /**
103      * Set this to "true" to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you
104      * enable it using the "maven.test.skip" property, because maven.test.skip disables both running the
105      * tests and compiling the tests.  Consider using the <code>skipTests parameter</code> instead.
106      *
107      * @parameter default-value="false" expression="${maven.test.skip}"
108      */
109     private boolean skip;
110 
111     /**
112      * The base directory of the project being tested. This can be obtained in your integration test via
113      * System.getProperty("basedir").
114      *
115      * @parameter default-value="${basedir}"
116      */
117     private File basedir;
118 
119     /**
120      * The directory containing generated test classes of the project being tested.
121      * This will be included at the beginning of the test classpath.
122      *
123      * @parameter default-value="${project.build.testOutputDirectory}"
124      */
125     private File testClassesDirectory;
126 
127     /**
128      * The directory containing generated classes of the project being tested.
129      * This will be included after the test classes in the test classpath.
130      *
131      * @parameter default-value="${project.build.outputDirectory}"
132      */
133     private File classesDirectory;
134 
135     /**
136      * The Maven Project Object.
137      *
138      * @parameter default-value="${project}"
139      * @readonly
140      */
141     private MavenProject project;
142 
143     /**
144      * List of dependencies to exclude from the test classpath.
145      * Each dependency string must follow the format <i>groupId:artifactId</i>.
146      * For example: <i>org.acme:project-a</i>
147      *
148      * @parameter
149      * @since 2.6
150      */
151     private List classpathDependencyExcludes;
152 
153     /**
154      * A dependency scope to exclude from the test classpath.
155      * The scope should be one of the scopes defined by org.apache.maven.artifact.Artifact.
156      * This includes the following:
157      * <p/>
158      * <ul>
159      * <li><i>compile</i> - system, provided, compile
160      * <li><i>runtime</i> - compile, runtime
161      * <li><i>compile+runtime</i> - system, provided, compile, runtime
162      * <li><i>runtime+system</i> - system, compile, runtime
163      * <li><i>test</i> - system, provided, compile, runtime, test
164      * </ul>
165      *
166      * @parameter default-value=""
167      * @since 2.6
168      */
169     private String classpathDependencyScopeExclude;
170 
171     /**
172      * Additional elements to be appended to the classpath.
173      *
174      * @parameter
175      * @since 2.4
176      */
177     private List additionalClasspathElements;
178 
179     /**
180      * Base directory where all reports are written to.
181      *
182      * @parameter default-value="${project.build.directory}/failsafe-reports"
183      */
184     private File reportsDirectory;
185 
186     /**
187      * The test source directory containing test class sources.
188      *
189      * @parameter default-value="${project.build.testSourceDirectory}"
190      * @required
191      * @since 2.2
192      */
193     private File testSourceDirectory;
194 
195     /**
196      * Specify this parameter to run individual tests by file name, overriding the <code>includes/excludes</code>
197      * parameters.  Each pattern you specify here will be used to create an
198      * include pattern formatted like <code>**&#47;${test}.java</code>, so you can just type "-Dtest=MyTest"
199      * to run a single test called "foo/MyTest.java".<br/>
200      * This parameter overrides the <code>includes/excludes</code> parameters, and the TestNG
201      * <code>suiteXmlFiles</code> parameter.
202      *
203      * @parameter expression="${it.test}"
204      */
205     private String test;
206 
207     /**
208      * A list of &lt;include> elements specifying the tests (by pattern) that should be included in testing. When not
209      * specified and when the <code>test</code> parameter is not specified, the default includes will be
210      * <code><br/>
211      * &lt;includes><br/>
212      * &nbsp;&lt;include>**&#47;IT*.java&lt;/include><br/>
213      * &nbsp;&lt;include>**&#47;*IT.java&lt;/include><br/>
214      * &nbsp;&lt;include>**&#47;*ITCase.java&lt;/include><br/>
215      * &lt;/includes><br/>
216      * </code>
217      * <p/>
218      * Each include item may also contain a comma-separated sublist of items, which will be treated as multiple &nbsp;&lt;include>
219      * entries.<br/>
220      * <p/>
221      * This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
222      *
223      * @parameter
224      */
225     private List includes;
226 
227     /**
228      * A list of &lt;exclude> elements specifying the tests (by pattern) that should be excluded in testing. When not
229      * specified and when the <code>test</code> parameter is not specified, the default excludes will be
230      * <code><br/>
231      * &lt;excludes><br/>
232      * &nbsp;&lt;exclude>**&#47;*$*&lt;/exclude><br/>
233      * &lt;/excludes><br/>
234      * </code>
235      * (which excludes all inner classes).<br>
236      * This parameter is ignored if the TestNG <code>suiteXmlFiles</code> parameter is specified.
237      * <p/>
238      * Each exclude item may also contain a comma-separated sublist of items, which will be treated as multiple &nbsp;&lt;exclude>
239      * entries.<br/>
240      *
241      * @parameter
242      */
243     private List excludes;
244 
245     /**
246      * ArtifactRepository of the localRepository. To obtain the directory of localRepository in unit tests use
247      * System.getProperty("localRepository").
248      *
249      * @parameter expression="${localRepository}"
250      * @required
251      * @readonly
252      */
253     private ArtifactRepository localRepository;
254 
255     /**
256      * List of System properties to pass to the JUnit tests.
257      *
258      * @parameter
259      * @deprecated Use systemPropertyVariables instead.
260      */
261     private Properties systemProperties;
262 
263     /**
264      * List of System properties to pass to the JUnit tests.
265      *
266      * @parameter
267      * @since 2.5
268      */
269     private Map systemPropertyVariables;
270 
271     /**
272      * List of properties for configuring all TestNG related configurations. This is the new
273      * preferred method of configuring TestNG.
274      *
275      * @parameter
276      * @since 2.4
277      */
278     private Properties properties;
279 
280     /**
281      * Map of plugin artifacts.
282      *
283      * @parameter expression="${plugin.artifactMap}"
284      * @required
285      * @readonly
286      */
287     private Map pluginArtifactMap;
288 
289     /**
290      * Map of project artifacts.
291      *
292      * @parameter expression="${project.artifactMap}"
293      * @required
294      * @readonly
295      */
296     private Map projectArtifactMap;
297 
298     /**
299      * The summary file to write integration test results to.
300      *
301      * @parameter expression="${project.build.directory}/failsafe-reports/failsafe-summary.xml"
302      * @required
303      */
304     private File summaryFile;
305 
306     /**
307      * Option to print summary of test suites or just print the test cases that have errors.
308      *
309      * @parameter expression="${failsafe.printSummary}" default-value="true"
310      */
311     private boolean printSummary;
312 
313     /**
314      * Selects the formatting for the test report to be generated. Can be set as "brief" or "plain".
315      *
316      * @parameter expression="${failsafe.reportFormat}" default-value="brief"
317      */
318     private String reportFormat;
319 
320     /**
321      * Option to generate a file test report or just output the test report to the console.
322      *
323      * @parameter expression="${failsafe.useFile}" default-value="true"
324      */
325     private boolean useFile;
326 
327     /**
328      * When forking, set this to "true" to redirect the unit test standard output to a file (found in
329      * reportsDirectory/testName-output.txt).
330      *
331      * @parameter expression="${maven.test.redirectTestOutputToFile}" default-value="false"
332      * @since 2.3
333      */
334     private boolean redirectTestOutputToFile;
335 
336     /**
337      * Set this to "true" to cause a failure if there are no tests to run. Defaults to "false".
338      *
339      * @parameter expression="${failIfNoTests}"
340      * @since 2.4
341      */
342     private Boolean failIfNoTests;
343 
344     /**
345      * Option to specify the forking mode. Can be "never", "once" or "always". "none" and "pertest" are also accepted
346      * for backwards compatibility. "always" forks for each test-class.
347      *
348      * @parameter expression="${forkMode}" default-value="once"
349      * @since 2.1
350      */
351     private String forkMode;
352 
353     /**
354      * Option to specify the jvm (or path to the java executable) to use with the forking options. For the default, the
355      * jvm will be a new instance of the same VM as the one used to run Maven. JVM settings are not inherited from
356      * MAVEN_OPTS.
357      *
358      * @parameter expression="${jvm}"
359      * @since 2.1
360      */
361     private String jvm;
362 
363     /**
364      * Arbitrary JVM options to set on the command line.
365      *
366      * @parameter expression="${argLine}"
367      * @since 2.1
368      */
369     private String argLine;
370 
371     /**
372      * Attach a debugger to the forked JVM.  If set to "true", the process will suspend and
373      * wait for a debugger to attach on port 5005.  If set to some other string, that
374      * string will be appended to the argLine, allowing you to configure arbitrary
375      * debuggability options (without overwriting the other options specified through the <code>argLine</code>
376      * parameter).
377      *
378      * @parameter expression="${maven.failsafe.debug}"
379      * @since 2.4
380      */
381     private String debugForkedProcess;
382 
383     /**
384      * Kill the forked test process after a certain number of seconds.  If set to 0,
385      * wait forever for the process, never timing out.
386      *
387      * @parameter expression="${failsafe.timeout}"
388      * @since 2.4
389      */
390     private int forkedProcessTimeoutInSeconds;
391 
392     /**
393      * Additional environment variables to set on the command line.
394      *
395      * @parameter
396      * @since 2.1.3
397      */
398     private Map environmentVariables = new HashMap();
399 
400     /**
401      * Command line working directory.
402      *
403      * @parameter expression="${basedir}"
404      * @since 2.1.3
405      */
406     private File workingDirectory;
407 
408     /**
409      * When false it makes tests run using the standard classloader delegation instead of the default Maven isolated
410      * classloader. Only used when forking (forkMode is not "none").<br/> Setting it to false helps with some problems
411      * caused by conflicts between xml parsers in the classpath and the Java 5 provider parser.
412      *
413      * @parameter expression="${childDelegation}" default-value="false"
414      * @since 2.1
415      */
416     private boolean childDelegation;
417 
418     /**
419      * (TestNG only) Groups for this test. Only classes/methods/etc decorated with one of the groups specified here will be included
420      * in test run, if specified.<br/>
421      * This parameter is ignored if the <code>suiteXmlFiles</code> parameter is specified.
422      *
423      * @parameter expression="${groups}"
424      * @since 2.2
425      */
426     private String groups;
427 
428     /**
429      * (TestNG only) Excluded groups. Any methods/classes/etc with one of the groups specified in this list will specifically not be
430      * run.<br/>
431      * This parameter is ignored if the <code>suiteXmlFiles</code> parameter is specified.
432      *
433      * @parameter expression="${excludedGroups}"
434      * @since 2.2
435      */
436     private String excludedGroups;
437 
438     /**
439      * (TestNG only) List of &lt;suiteXmlFile> elements specifying TestNG suite xml file locations. Note that <code>suiteXmlFiles</code> is incompatible
440      * with several other parameters of this plugin, like <code>includes/excludes</code>.<br/>
441      * This parameter is ignored if the <code>test</code> parameter is specified (allowing you to run a single
442      * test instead of an entire suite).
443      *
444      * @parameter
445      * @since 2.2
446      */
447     private File[] suiteXmlFiles;
448 
449     /**
450      * Allows you to specify the name of the JUnit artifact. If not set, <code>junit:junit</code> will be used.
451      *
452      * @parameter expression="${junitArtifactName}" default-value="junit:junit"
453      * @since 2.3.1
454      */
455     private String junitArtifactName;
456 
457     /**
458      * Allows you to specify the name of the TestNG artifact. If not set, <code>org.testng:testng</code> will be used.
459      *
460      * @parameter expression="${testNGArtifactName}" default-value="org.testng:testng"
461      * @since 2.3.1
462      */
463     private String testNGArtifactName;
464 
465     /**
466      * (TestNG/JUnit 4.7 provider only) The attribute thread-count allows you to specify how many threads should be allocated for this execution. Only
467      * makes sense to use in conjunction with the <code>parallel</code> parameter.
468      *
469      * @parameter expression="${threadCount}"
470      * @since 2.2
471      */
472     private int threadCount;
473 
474     /**
475      * (JUnit 4.7 provider) Indicates that threadCount is per cpu core.
476      *
477      * @parameter expression="${perCoreThreadCount}" default-value="true"
478      * @since 2.5
479      */
480     private boolean perCoreThreadCount;
481 
482     /**
483      * (JUnit 4.7 provider) Indicates that the thread pool will be unlimited. The <code>parallel</code> parameter and the actual number of classes/methods
484      * will decide. Setting this to "true" effectively disables <code>perCoreThreadCount</code> and <code>threadCount</code>. Defaults to "false".
485      *
486      * @parameter expression="${useUnlimitedThreads}" default-value="false"
487      * @since 2.5
488      */
489     private boolean useUnlimitedThreads;
490 
491     /**
492      * (TestNG only) When you use the <code>parallel</code> attribute, TestNG will try to run all your test methods in separate threads, except for
493      * methods that depend on each other, which will be run in the same thread in order to respect their order of
494      * execution.
495      * <p/>
496      * (JUnit 4.7 provider) Supports values "classes"/"methods"/"both" to run in separate threads, as controlled by <code>threadCount</code>.
497      *
498      * @parameter expression="${parallel}"
499      * @todo test how this works with forking, and console/file output parallelism
500      * @since 2.2
501      */
502     private String parallel;
503 
504     /**
505      * Whether to trim the stack trace in the reports to just the lines within the test, or show the full trace.
506      *
507      * @parameter expression="${trimStackTrace}" default-value="true"
508      * @since 2.2
509      */
510     private boolean trimStackTrace;
511 
512     /**
513      * Resolves the artifacts needed.
514      *
515      * @component
516      */
517     private ArtifactResolver artifactResolver;
518 
519     /**
520      * Creates the artifact.
521      *
522      * @component
523      */
524     private ArtifactFactory artifactFactory;
525 
526     /**
527      * The remote plugin repositories declared in the POM.
528      *
529      * @parameter expression="${project.pluginArtifactRepositories}"
530      * @since 2.2
531      */
532     private List remoteRepositories;
533 
534     /**
535      * For retrieval of artifact's metadata.
536      *
537      * @component
538      */
539     private ArtifactMetadataSource metadataSource;
540 
541     private static final String BRIEF_REPORT_FORMAT = "brief";
542 
543     private static final String PLAIN_REPORT_FORMAT = "plain";
544 
545     private Properties originalSystemProperties;
546 
547     /**
548      * systemPropertyVariables + systemProperties
549      */
550     private Properties internalSystemProperties = new Properties();
551 
552     /**
553      * Flag to disable the generation of report files in xml format.
554      *
555      * @parameter expression="${disableXmlReport}" default-value="false"
556      * @since 2.2
557      */
558     private boolean disableXmlReport;
559 
560     /**
561      * Option to pass dependencies to the system's classloader instead of using an isolated class loader when forking.
562      * Prevents problems with JDKs which implement the service provider lookup mechanism by using the system's
563      * classloader.
564      *
565      * @parameter expression="${failsafe.useSystemClassLoader}" default-value="true"
566      * @since 2.3
567      */
568     private boolean useSystemClassLoader;
569 
570     /**
571      * By default, Surefire forks your tests using a manifest-only JAR; set this parameter
572      * to "false" to force it to launch your tests with a plain old Java classpath.
573      * (See http://maven.apache.org/plugins/maven-surefire-plugin/examples/class-loading.html
574      * for a more detailed explanation of manifest-only JARs and their benefits.)
575      * <p/>
576      * Beware, setting this to "false" may cause your tests to
577      * fail on Windows if your classpath is too long.
578      *
579      * @parameter expression="${failsafe.useManifestOnlyJar}" default-value="true"
580      * @since 2.4.3
581      */
582     private boolean useManifestOnlyJar;
583 
584     /**
585      * By default, Surefire enables JVM assertions for the execution of your test cases. To disable the assertions, set
586      * this flag to "false".
587      *
588      * @parameter expression="${enableAssertions}" default-value="true"
589      * @since 2.3.1
590      */
591     private boolean enableAssertions;
592 
593     /**
594      * The current build session instance.
595      *
596      * @parameter expression="${session}"
597      * @required
598      * @readonly
599      */
600     private MavenSession session;
601 
602     /**
603      * (TestNG only) Define the factory class used to create all test instances.
604      *
605      * @parameter expression="${objectFactory}"
606      * @since 2.5
607      */
608     private String objectFactory;
609 
610     /**
611      * The character encoding scheme to be applied.
612      *
613      * @parameter expression="${encoding}" default-value="${project.reporting.outputEncoding}"
614      */
615     private String encoding;
616 
617     /**
618      * @parameter default-value="${session.parallel}"
619      * @readonly
620      */
621     private Boolean parallelMavenExecution;
622 
623     /**
624      * Defines the order the tests will be run in. Supported values are "alphabetical", "reversealphabetical",
625      * "random", "hourly" (alphabetical on even hours, reverse alphabetical on odd hours) and "filesystem".<p/>
626      * <p/>
627      * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during
628      * a multi-module build.
629      *
630      * @parameter default-value="filesystem"
631      * @since 2.7
632      */
633     private String runOrder;
634 
635     /**
636      * @component
637      */
638     private ToolchainManager toolchainManager;
639 
640 
641     public void execute()
642         throws MojoExecutionException, MojoFailureException
643     {
644         if ( verifyParameters() )
645         {
646             if ( hasExecutedBefore() )
647             {
648                 return;
649             }
650             logReportsDirectory();
651 
652             final List providers = initialize();
653             String exceptionMessage = null;
654             FailsafeSummary result = new FailsafeSummary();
655 
656             ForkConfiguration forkConfiguration = null;
657             for ( Iterator iter = providers.iterator(); iter.hasNext(); )
658             {
659                 ProviderInfo provider = (ProviderInfo) iter.next();
660                 forkConfiguration = getForkConfiguration();
661                 ClassLoaderConfiguration classLoaderConfiguration = getClassLoaderConfiguration( forkConfiguration );
662                 ForkStarter forkStarter = createForkStarter( provider, forkConfiguration, classLoaderConfiguration );
663                 try
664                 {
665                     result.setResult( forkStarter.run() );
666                 }
667                 catch ( SurefireBooterForkException e )
668                 {
669                     if ( exceptionMessage == null )
670                     {
671                         exceptionMessage = e.getMessage();
672                     }
673                 }
674                 catch ( SurefireExecutionException e )
675                 {
676                     if ( exceptionMessage == null )
677                     {
678                         exceptionMessage = e.getMessage();
679                     }
680                 }
681             }
682 
683             if ( exceptionMessage != null )
684             {
685                 // Fail no matter what as long as any provider failed
686                 result.setResult( ProviderConfiguration.TESTS_FAILED_EXIT_CODE );
687                 result.setException( exceptionMessage );
688             }
689 
690             if ( getOriginalSystemProperties() != null && forkConfiguration != null && !forkConfiguration.isForking() )
691             {
692                 // restore system properties, only makes sense when not forking..
693                 System.setProperties( getOriginalSystemProperties() );
694             }
695 
696             if ( !getSummaryFile().getParentFile().isDirectory() )
697             {
698                 getSummaryFile().getParentFile().mkdirs();
699             }
700 
701             try
702             {
703                 String encoding;
704                 if ( StringUtils.isEmpty( this.encoding ) )
705                 {
706                     getLog().warn(
707                         "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
708                             + ", i.e. build is platform dependent!" );
709                     encoding = ReaderFactory.FILE_ENCODING;
710                 }
711                 else
712                 {
713                     encoding = this.encoding;
714                 }
715 
716                 FileOutputStream fileOutputStream = new FileOutputStream( getSummaryFile() );
717                 BufferedOutputStream bufferedOutputStream = new BufferedOutputStream( fileOutputStream );
718                 Writer writer = new OutputStreamWriter( bufferedOutputStream, encoding );
719                 FailsafeSummaryXpp3Writer xpp3Writer = new FailsafeSummaryXpp3Writer();
720                 xpp3Writer.write( writer, result );
721                 writer.close();
722                 bufferedOutputStream.close();
723                 fileOutputStream.close();
724             }
725             catch ( IOException e )
726             {
727                 throw new MojoExecutionException( e.getMessage(), e );
728             }
729         }
730     }
731 
732 
733     protected boolean verifyParameters()
734         throws MojoFailureException
735     {
736         if ( isSkip() || isSkipTests() || isSkipITs() || isSkipExec() )
737         {
738             getLog().info( "Tests are skipped." );
739             return false;
740         }
741 
742         if ( !getTestClassesDirectory().exists() )
743         {
744             if ( getFailIfNoTests() != null && getFailIfNoTests().booleanValue() )
745             {
746                 throw new MojoFailureException( "No tests to run!" );
747             }
748             getLog().info( "No tests to run." );
749             return false;
750         }
751 
752         ensureWorkingDirectoryExists();
753 
754         ensureParallelRunningCompatibility();
755 
756         warnIfUselessUseSystemClassLoaderParameter();
757 
758         return true;
759     }
760 
761     protected String getPluginName()
762     {
763         return "failsafe";
764     }
765 
766     protected String[] getDefaultIncludes()
767     {
768         return new String[]{ "**/IT*.java", "**/*IT.java", "**/*ITCase.java" };
769     }
770 
771     public boolean isSkipTests()
772     {
773         return skipTests;
774     }
775 
776     public void setSkipTests( boolean skipTests )
777     {
778         this.skipTests = skipTests;
779     }
780 
781     public boolean isSkipITs()
782     {
783         return skipITs;
784     }
785 
786     public void setSkipITs( boolean skipITs )
787     {
788         this.skipITs = skipITs;
789     }
790 
791     public boolean isSkipExec()
792     {
793         return skipExec;
794     }
795 
796     public void setSkipExec( boolean skipExec )
797     {
798         this.skipExec = skipExec;
799     }
800 
801     public boolean isSkip()
802     {
803         return skip;
804     }
805 
806     public void setSkip( boolean skip )
807     {
808         this.skip = skip;
809     }
810 
811     public File getBasedir()
812     {
813         return basedir;
814     }
815 
816     public void setBasedir( File basedir )
817     {
818         this.basedir = basedir;
819     }
820 
821     public File getTestClassesDirectory()
822     {
823         return testClassesDirectory;
824     }
825 
826     public void setTestClassesDirectory( File testClassesDirectory )
827     {
828         this.testClassesDirectory = testClassesDirectory;
829     }
830 
831     public File getClassesDirectory()
832     {
833         return classesDirectory;
834     }
835 
836     public void setClassesDirectory( File classesDirectory )
837     {
838         this.classesDirectory = classesDirectory;
839     }
840 
841     public MavenProject getProject()
842     {
843         return project;
844     }
845 
846     public void setProject( MavenProject project )
847     {
848         this.project = project;
849     }
850 
851     public List getClasspathDependencyExcludes()
852     {
853         return classpathDependencyExcludes;
854     }
855 
856     public void setClasspathDependencyExcludes( List classpathDependencyExcludes )
857     {
858         this.classpathDependencyExcludes = classpathDependencyExcludes;
859     }
860 
861     public String getClasspathDependencyScopeExclude()
862     {
863         return classpathDependencyScopeExclude;
864     }
865 
866     public void setClasspathDependencyScopeExclude( String classpathDependencyScopeExclude )
867     {
868         this.classpathDependencyScopeExclude = classpathDependencyScopeExclude;
869     }
870 
871     public List getAdditionalClasspathElements()
872     {
873         return additionalClasspathElements;
874     }
875 
876     public void setAdditionalClasspathElements( List additionalClasspathElements )
877     {
878         this.additionalClasspathElements = additionalClasspathElements;
879     }
880 
881     public File getReportsDirectory()
882     {
883         return reportsDirectory;
884     }
885 
886     public void setReportsDirectory( File reportsDirectory )
887     {
888         this.reportsDirectory = reportsDirectory;
889     }
890 
891     public File getTestSourceDirectory()
892     {
893         return testSourceDirectory;
894     }
895 
896     public void setTestSourceDirectory( File testSourceDirectory )
897     {
898         this.testSourceDirectory = testSourceDirectory;
899     }
900 
901     public String getTest()
902     {
903         return test;
904     }
905 
906     public void setTest( String test )
907     {
908         this.test = test;
909     }
910 
911     public List getIncludes()
912     {
913         return includes;
914     }
915 
916     public void setIncludes( List includes )
917     {
918         this.includes = includes;
919     }
920 
921     public List getExcludes()
922     {
923         return excludes;
924     }
925 
926     public void setExcludes( List excludes )
927     {
928         this.excludes = excludes;
929     }
930 
931     public ArtifactRepository getLocalRepository()
932     {
933         return localRepository;
934     }
935 
936     public void setLocalRepository( ArtifactRepository localRepository )
937     {
938         this.localRepository = localRepository;
939     }
940 
941     public Properties getSystemProperties()
942     {
943         return systemProperties;
944     }
945 
946     public void setSystemProperties( Properties systemProperties )
947     {
948         this.systemProperties = systemProperties;
949     }
950 
951     public Map getSystemPropertyVariables()
952     {
953         return systemPropertyVariables;
954     }
955 
956     public void setSystemPropertyVariables( Map systemPropertyVariables )
957     {
958         this.systemPropertyVariables = systemPropertyVariables;
959     }
960 
961     public Properties getProperties()
962     {
963         return properties;
964     }
965 
966     public void setProperties( Properties properties )
967     {
968         this.properties = properties;
969     }
970 
971     public Map getPluginArtifactMap()
972     {
973         return pluginArtifactMap;
974     }
975 
976     public void setPluginArtifactMap( Map pluginArtifactMap )
977     {
978         this.pluginArtifactMap = pluginArtifactMap;
979     }
980 
981     public Map getProjectArtifactMap()
982     {
983         return projectArtifactMap;
984     }
985 
986     public void setProjectArtifactMap( Map projectArtifactMap )
987     {
988         this.projectArtifactMap = projectArtifactMap;
989     }
990 
991     public File getSummaryFile()
992     {
993         return summaryFile;
994     }
995 
996     public void setSummaryFile( File summaryFile )
997     {
998         this.summaryFile = summaryFile;
999     }
1000 
1001     public boolean isPrintSummary()
1002     {
1003         return printSummary;
1004     }
1005 
1006     public void setPrintSummary( boolean printSummary )
1007     {
1008         this.printSummary = printSummary;
1009     }
1010 
1011     public String getReportFormat()
1012     {
1013         return reportFormat;
1014     }
1015 
1016     public void setReportFormat( String reportFormat )
1017     {
1018         this.reportFormat = reportFormat;
1019     }
1020 
1021     public boolean isUseFile()
1022     {
1023         return useFile;
1024     }
1025 
1026     public void setUseFile( boolean useFile )
1027     {
1028         this.useFile = useFile;
1029     }
1030 
1031     public boolean isRedirectTestOutputToFile()
1032     {
1033         return redirectTestOutputToFile;
1034     }
1035 
1036     public void setRedirectTestOutputToFile( boolean redirectTestOutputToFile )
1037     {
1038         this.redirectTestOutputToFile = redirectTestOutputToFile;
1039     }
1040 
1041     public Boolean getFailIfNoTests()
1042     {
1043         return failIfNoTests;
1044     }
1045 
1046     public void setFailIfNoTests( Boolean failIfNoTests )
1047     {
1048         this.failIfNoTests = failIfNoTests;
1049     }
1050 
1051     public String getForkMode()
1052     {
1053         return forkMode;
1054     }
1055 
1056     public void setForkMode( String forkMode )
1057     {
1058         this.forkMode = forkMode;
1059     }
1060 
1061     public String getJvm()
1062     {
1063         return jvm;
1064     }
1065 
1066     public void setJvm( String jvm )
1067     {
1068         this.jvm = jvm;
1069     }
1070 
1071     public String getArgLine()
1072     {
1073         return argLine;
1074     }
1075 
1076     public void setArgLine( String argLine )
1077     {
1078         this.argLine = argLine;
1079     }
1080 
1081     public String getDebugForkedProcess()
1082     {
1083         return debugForkedProcess;
1084     }
1085 
1086     public void setDebugForkedProcess( String debugForkedProcess )
1087     {
1088         this.debugForkedProcess = debugForkedProcess;
1089     }
1090 
1091     public int getForkedProcessTimeoutInSeconds()
1092     {
1093         return forkedProcessTimeoutInSeconds;
1094     }
1095 
1096     public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
1097     {
1098         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
1099     }
1100 
1101     public Map getEnvironmentVariables()
1102     {
1103         return environmentVariables;
1104     }
1105 
1106     public void setEnvironmentVariables( Map environmentVariables )
1107     {
1108         this.environmentVariables = environmentVariables;
1109     }
1110 
1111     public File getWorkingDirectory()
1112     {
1113         return workingDirectory;
1114     }
1115 
1116     public void setWorkingDirectory( File workingDirectory )
1117     {
1118         this.workingDirectory = workingDirectory;
1119     }
1120 
1121     public boolean isChildDelegation()
1122     {
1123         return childDelegation;
1124     }
1125 
1126     public void setChildDelegation( boolean childDelegation )
1127     {
1128         this.childDelegation = childDelegation;
1129     }
1130 
1131     public String getGroups()
1132     {
1133         return groups;
1134     }
1135 
1136     public void setGroups( String groups )
1137     {
1138         this.groups = groups;
1139     }
1140 
1141     public String getExcludedGroups()
1142     {
1143         return excludedGroups;
1144     }
1145 
1146     public void setExcludedGroups( String excludedGroups )
1147     {
1148         this.excludedGroups = excludedGroups;
1149     }
1150 
1151     public File[] getSuiteXmlFiles()
1152     {
1153         return suiteXmlFiles;
1154     }
1155 
1156     public void setSuiteXmlFiles( File[] suiteXmlFiles )
1157     {
1158         this.suiteXmlFiles = suiteXmlFiles;
1159     }
1160 
1161     public String getJunitArtifactName()
1162     {
1163         return junitArtifactName;
1164     }
1165 
1166     public void setJunitArtifactName( String junitArtifactName )
1167     {
1168         this.junitArtifactName = junitArtifactName;
1169     }
1170 
1171     public String getTestNGArtifactName()
1172     {
1173         return testNGArtifactName;
1174     }
1175 
1176     public void setTestNGArtifactName( String testNGArtifactName )
1177     {
1178         this.testNGArtifactName = testNGArtifactName;
1179     }
1180 
1181     public int getThreadCount()
1182     {
1183         return threadCount;
1184     }
1185 
1186     public void setThreadCount( int threadCount )
1187     {
1188         this.threadCount = threadCount;
1189     }
1190 
1191     public boolean getPerCoreThreadCount()
1192     {
1193         return perCoreThreadCount;
1194     }
1195 
1196     public void setPerCoreThreadCount( boolean perCoreThreadCount )
1197     {
1198         this.perCoreThreadCount = perCoreThreadCount;
1199     }
1200 
1201     public boolean getUseUnlimitedThreads()
1202     {
1203         return useUnlimitedThreads;
1204     }
1205 
1206     public void setUseUnlimitedThreads( boolean useUnlimitedThreads )
1207     {
1208         this.useUnlimitedThreads = useUnlimitedThreads;
1209     }
1210 
1211     public String getParallel()
1212     {
1213         return parallel;
1214     }
1215 
1216     public void setParallel( String parallel )
1217     {
1218         this.parallel = parallel;
1219     }
1220 
1221     public boolean isTrimStackTrace()
1222     {
1223         return trimStackTrace;
1224     }
1225 
1226     public void setTrimStackTrace( boolean trimStackTrace )
1227     {
1228         this.trimStackTrace = trimStackTrace;
1229     }
1230 
1231     public ArtifactResolver getArtifactResolver()
1232     {
1233         return artifactResolver;
1234     }
1235 
1236     public void setArtifactResolver( ArtifactResolver artifactResolver )
1237     {
1238         this.artifactResolver = artifactResolver;
1239     }
1240 
1241     public ArtifactFactory getArtifactFactory()
1242     {
1243         return artifactFactory;
1244     }
1245 
1246     public void setArtifactFactory( ArtifactFactory artifactFactory )
1247     {
1248         this.artifactFactory = artifactFactory;
1249     }
1250 
1251     public List getRemoteRepositories()
1252     {
1253         return remoteRepositories;
1254     }
1255 
1256     public void setRemoteRepositories( List remoteRepositories )
1257     {
1258         this.remoteRepositories = remoteRepositories;
1259     }
1260 
1261     public ArtifactMetadataSource getMetadataSource()
1262     {
1263         return metadataSource;
1264     }
1265 
1266     public void setMetadataSource( ArtifactMetadataSource metadataSource )
1267     {
1268         this.metadataSource = metadataSource;
1269     }
1270 
1271     public Properties getOriginalSystemProperties()
1272     {
1273         return originalSystemProperties;
1274     }
1275 
1276     public void setOriginalSystemProperties( Properties originalSystemProperties )
1277     {
1278         this.originalSystemProperties = originalSystemProperties;
1279     }
1280 
1281     public Properties getInternalSystemProperties()
1282     {
1283         return internalSystemProperties;
1284     }
1285 
1286     public void setInternalSystemProperties( Properties internalSystemProperties )
1287     {
1288         this.internalSystemProperties = internalSystemProperties;
1289     }
1290 
1291     public boolean isDisableXmlReport()
1292     {
1293         return disableXmlReport;
1294     }
1295 
1296     public void setDisableXmlReport( boolean disableXmlReport )
1297     {
1298         this.disableXmlReport = disableXmlReport;
1299     }
1300 
1301     public boolean isUseSystemClassLoader()
1302     {
1303         return useSystemClassLoader;
1304     }
1305 
1306     public void setUseSystemClassLoader( boolean useSystemClassLoader )
1307     {
1308         this.useSystemClassLoader = useSystemClassLoader;
1309     }
1310 
1311     public boolean isUseManifestOnlyJar()
1312     {
1313         return useManifestOnlyJar;
1314     }
1315 
1316     public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
1317     {
1318         this.useManifestOnlyJar = useManifestOnlyJar;
1319     }
1320 
1321     public boolean isEnableAssertions()
1322     {
1323         return enableAssertions;
1324     }
1325 
1326     public void setEnableAssertions( boolean enableAssertions )
1327     {
1328         this.enableAssertions = enableAssertions;
1329     }
1330 
1331     public MavenSession getSession()
1332     {
1333         return session;
1334     }
1335 
1336     public void setSession( MavenSession session )
1337     {
1338         this.session = session;
1339     }
1340 
1341     public String getObjectFactory()
1342     {
1343         return objectFactory;
1344     }
1345 
1346     public void setObjectFactory( String objectFactory )
1347     {
1348         this.objectFactory = objectFactory;
1349     }
1350 
1351     public ToolchainManager getToolchainManager()
1352     {
1353         return toolchainManager;
1354     }
1355 
1356     public void setToolchainManager( ToolchainManager toolchainManager )
1357     {
1358         this.toolchainManager = toolchainManager;
1359     }
1360 
1361     // the following will be refactored out once the common code is all in one place
1362 
1363     public boolean isTestFailureIgnore()
1364     {
1365         return true; // ignore
1366     }
1367 
1368     public void setTestFailureIgnore( boolean testFailureIgnore )
1369     {
1370         // ignore
1371     }
1372 
1373     public boolean isMavenParallel()
1374     {
1375         return parallelMavenExecution != null && parallelMavenExecution.booleanValue();
1376     }
1377 
1378     public String getRunOrder()
1379     {
1380         return runOrder;
1381     }
1382 
1383     public void setRunOrder( String runOrder )
1384     {
1385         this.runOrder = runOrder;
1386     }
1387 
1388     protected void addPluginSpecificChecksumItems( ChecksumCalculator checksum )
1389     {
1390         checksum.add(skipITs);
1391         checksum.add(summaryFile);
1392     }
1393 }