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.Artifact;
23  import org.apache.maven.plugin.MojoExecutionException;
24  import org.apache.maven.plugin.MojoFailureException;
25  import org.apache.maven.plugin.surefire.AbstractSurefireMojo;
26  import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
27  import org.apache.maven.plugins.annotations.LifecyclePhase;
28  import org.apache.maven.plugins.annotations.Mojo;
29  import org.apache.maven.plugins.annotations.Parameter;
30  import org.apache.maven.plugins.annotations.ResolutionScope;
31  import org.apache.maven.surefire.suite.RunResult;
32  
33  import java.io.File;
34  import java.io.IOException;
35  import java.nio.charset.Charset;
36  import java.util.Arrays;
37  import java.util.Collections;
38  import java.util.List;
39  import java.util.Locale;
40  import java.util.Map;
41  
42  import static org.apache.maven.plugin.failsafe.util.FailsafeSummaryXmlUtils.writeSummary;
43  
44  /**
45   * Run integration tests using Surefire.
46   *
47   * @author Jason van Zyl
48   * @author Stephen Connolly
49   */
50  @Mojo( name = "integration-test", requiresProject = true, requiresDependencyResolution = ResolutionScope.TEST,
51               defaultPhase = LifecyclePhase.INTEGRATION_TEST, threadSafe = true )
52  public class IntegrationTestMojo
53          extends AbstractSurefireMojo
54  {
55  
56      private static final String FAILSAFE_IN_PROGRESS_CONTEXT_KEY = "failsafe-in-progress";
57  
58      /**
59       * The path representing project <em>JAR</em> file, if exists; Otherwise the directory containing generated
60       * classes of the project being tested. This will be included after the test classes in the test classpath.
61       * Defaults to built artifact <em>JAR</em> file or <code>${project.build.outputDirectory}</code>.
62       */
63      @Parameter
64      private File classesDirectory;
65  
66      @Parameter( readonly = true, defaultValue = "${project.build.outputDirectory}" )
67      private File defaultClassesDirectory;
68  
69      /**
70       * Set this to "true" to skip running integration tests, but still compile them. Its use is NOT RECOMMENDED, but
71       * quite convenient on occasion.
72       *
73       * @since 2.4.3-alpha-2
74       */
75      @Parameter( property = "skipITs" )
76      private boolean skipITs;
77  
78      /**
79       * Base directory where all reports are written to.
80       */
81      @Parameter( defaultValue = "${project.build.directory}/failsafe-reports" )
82      private File reportsDirectory;
83  
84      @SuppressWarnings( "checkstyle:linelength" )
85      /**
86       * Specify this parameter to run individual tests by file name, overriding parameter {@code includes} and
87       * {@code excludes}. Each pattern you specify here will be used to create an include pattern formatted like
88       * <code>**{@literal /}${it.test}.java</code>, so you can just type {@code -Dit.test=MyIT} to run
89       * a single test file called "foo/MyIT.java". The test patterns prefixed with a <em>!</em> will be excluded.
90       * <br>
91       * This parameter overrides the parameter {@code includes} and {@code excludes}, and the TestNG parameter
92       * {@code suiteXmlFiles}.
93       * <br>
94       * Since 2.7.3 You can execute a limited number of methods in the test with adding <i>#myMethod</i> or
95       * <i>#my*ethod</i>. E.g. type {@code -Dit.test=MyIT#myMethod} <b>supported for junit 4.x and TestNg.</b>
96       * <br>
97       * Since 2.19 a complex syntax is supported in one parameter (JUnit 4, JUnit 4.7+, TestNG):
98       * <pre><code>"-Dit.test=???IT, !Unstable*, pkg{@literal /}**{@literal /}Ci*leIT.java, *IT#test*One+testTwo?????, #fast*+slowTest"</code></pre>
99       * or e.g.
100      * <br>
101      * <pre><code>"-Dit.test=Basic*, !%regex[.*.Unstable.*], !%regex[.*.MyIT.class#one.*|two.*], %regex[#fast.*|slow.*]"</code></pre>
102      * <br>
103      * The Parameterized JUnit runner {@code describes} test methods using an index in brackets, so the non-regex
104      * method pattern would become: {@code #testMethod[*]}. If using <code>@Parameters(name="{index}: fib({0})={1}")</code>
105      * and selecting the index e.g. 5 in pattern, the non-regex method pattern would become {@code #testMethod[5:*]}.
106      */
107     @Parameter( property = "it.test" )
108     private String test;
109 
110     /**
111      * The summary file to write integration test results to.
112      */
113     @Parameter( defaultValue = "${project.build.directory}/failsafe-reports/failsafe-summary.xml", required = true )
114     private File summaryFile;
115 
116     /**
117      * Option to print summary of test suites or just print the test cases that have errors.
118      */
119     @Parameter( property = "failsafe.printSummary", defaultValue = "true" )
120     private boolean printSummary;
121 
122     /**
123      * Selects the formatting for the test report to be generated. Can be set as "brief" or "plain".
124      * Only applies to the output format of the output files  (target/surefire-reports/testName.txt)
125      */
126     @Parameter( property = "failsafe.reportFormat", defaultValue = "brief" )
127     private String reportFormat;
128 
129     /**
130      * Option to generate a file test report or just output the test report to the console.
131      */
132     @Parameter( property = "failsafe.useFile", defaultValue = "true" )
133     private boolean useFile;
134 
135     /**
136      * Set this to "true" to cause a failure if none of the tests specified in -Dtest=... are run. Defaults to
137      * "true".
138      *
139      * @since 2.12
140      */
141     @Parameter( property = "it.failIfNoSpecifiedTests" )
142     private Boolean failIfNoSpecifiedTests;
143 
144     /**
145      * Attach a debugger to the forked JVM. If set to "true", the process will suspend and wait for a debugger to attach
146      * on port 5005. If set to some other string, that string will be appended to the argLine, allowing you to configure
147      * arbitrary debugging ability options (without overwriting the other options specified through the {@code argLine}
148      * parameter).
149      *
150      * @since 2.4
151      */
152     @Parameter( property = "maven.failsafe.debug" )
153     private String debugForkedProcess;
154 
155     /**
156      * Kill the forked test process after a certain number of seconds. If set to 0, wait forever for the process, never
157      * timing out.
158      *
159      * @since 2.4
160      */
161     @Parameter( property = "failsafe.timeout" )
162     private int forkedProcessTimeoutInSeconds;
163 
164     /**
165      * Forked process is normally terminated without any significant delay after given tests have completed.
166      * If the particular tests started non-daemon Thread(s), the process hangs instead of been properly terminated
167      * by {@code System.exit()}. Use this parameter in order to determine the timeout of terminating the process.
168      * <a href="http://maven.apache.org/surefire/maven-failsafe-plugin/examples/shutdown.html">see the documentation:
169      * http://maven.apache.org/surefire/maven-failsafe-plugin/examples/shutdown.html</a>;
170      *
171      * @since 2.20
172      */
173     @Parameter( property = "failsafe.exitTimeout", defaultValue = "30" )
174     private int forkedProcessExitTimeoutInSeconds;
175 
176     /**
177      * Stop executing queued parallel JUnit tests after a certain number of seconds.
178      * <br>
179      * Example values: "3.5", "4"<br>
180      * <br>
181      * If set to 0, wait forever, never timing out.
182      * Makes sense with specified {@code parallel} different from "none".
183      *
184      * @since 2.16
185      */
186     @Parameter( property = "failsafe.parallel.timeout" )
187     private double parallelTestsTimeoutInSeconds;
188 
189     /**
190      * Stop executing queued parallel JUnit tests
191      * and <i>interrupt</i> currently running tests after a certain number of seconds.
192      * <br>
193      * Example values: "3.5", "4"<br>
194      * <br>
195      * If set to 0, wait forever, never timing out.
196      * Makes sense with specified {@code parallel} different from "none".
197      *
198      * @since 2.16
199      */
200     @Parameter( property = "failsafe.parallel.forcedTimeout" )
201     private double parallelTestsTimeoutForcedInSeconds;
202 
203     @SuppressWarnings( "checkstyle:linelength" )
204     /**
205      * A list of {@literal <include>} elements specifying the test filter (by pattern) of tests which should be
206      * included in testing. If it is not specified and the {@code test} parameter is unspecified as well, the default
207      * includes is
208      * <pre><code>
209      * {@literal <includes>}
210      *     {@literal <include>}**{@literal /}IT*.java{@literal </include>}
211      *     {@literal <include>}**{@literal /}*IT.java{@literal </include>}
212      *     {@literal <include>}**{@literal /}*ITCase.java{@literal </include>}
213      * {@literal </includes>}
214      * </code></pre>
215      * <br>
216      * Each include item may also contain a comma-separated sublist of items, which will be treated as multiple
217      * {@literal <include>} entries.<br>
218      * Since 2.19 a complex syntax is supported in one parameter (JUnit 4, JUnit 4.7+, TestNG):
219      * <pre><code>
220      * {@literal <include>}%regex[.*[Cat|Dog].*], Basic????, !Unstable*{@literal </include>}
221      * {@literal <include>}%regex[.*[Cat|Dog].*], !%regex[pkg.*Slow.*.class], pkg{@literal /}**{@literal /}*Fast*.java{@literal </include>}
222      * </code></pre>
223      * <br>
224      * This parameter is ignored if the TestNG {@code suiteXmlFiles} parameter is specified.<br>
225      * <br>
226      * <b>Notice that</b> these values are relative to the directory containing generated test classes of the project
227      * being tested. This directory is declared by the parameter {@code testClassesDirectory} which defaults
228      * to the POM property <code>${project.build.testOutputDirectory}</code>, typically
229      * <code>{@literal src/test/java}</code> unless overridden.
230      */
231     @Parameter
232     private List<String> includes;
233 
234     /**
235      * Option to pass dependencies to the system's classloader instead of using an isolated class loader when forking.
236      * Prevents problems with JDKs which implement the service provider lookup mechanism by using the system's
237      * classloader.
238      *
239      * @since 2.3
240      */
241     @Parameter( property = "failsafe.useSystemClassLoader", defaultValue = "true" )
242     private boolean useSystemClassLoader;
243 
244     /**
245      * By default, Surefire forks your tests using a manifest-only JAR; set this parameter to "false" to force it to
246      * launch your tests with a plain old Java classpath. (See the
247      * <a href="http://maven.apache.org/plugins/maven-failsafe-plugin/examples/class-loading.html">
248      * http://maven.apache.org/plugins/maven-failsafe-plugin/examples/class-loading.html</a>;
249      * for a more detailed explanation of manifest-only JARs and their benefits.)
250      * <br>
251      * Beware, setting this to "false" may cause your tests to fail on Windows if your classpath is too long.
252      *
253      * @since 2.4.3
254      */
255     @Parameter( property = "failsafe.useManifestOnlyJar", defaultValue = "true" )
256     private boolean useManifestOnlyJar;
257 
258     /**
259      * The character encoding scheme to be applied.
260      * Deprecated since 2.20.1 and used encoding UTF-8 in <tt>failsafe-summary.xml</tt>.
261      *
262      * @deprecated since of 2.20.1
263      */
264     @Parameter( property = "encoding", defaultValue = "${project.reporting.outputEncoding}" )
265     private String encoding;
266 
267     /**
268      * (JUnit 4+ providers)
269      * The number of times each failing test will be rerun. If set larger than 0, rerun failing tests immediately after
270      * they fail. If a failing test passes in any of those reruns, it will be marked as pass and reported as a "flake".
271      * However, all the failing attempts will be recorded.
272      */
273     @Parameter( property = "failsafe.rerunFailingTestsCount", defaultValue = "0" )
274     private int rerunFailingTestsCount;
275 
276     /**
277      * (TestNG) List of &lt;suiteXmlFile&gt; elements specifying TestNG suite xml file locations. Note that
278      * {@code suiteXmlFiles} is incompatible with several other parameters of this plugin, like
279      * {@code includes} and {@code excludes}.<br>
280      * This parameter is ignored if the {@code test} parameter is specified (allowing you to run a single test
281      * instead of an entire suite).
282      *
283      * @since 2.2
284      */
285     @Parameter( property = "failsafe.suiteXmlFiles" )
286     private File[] suiteXmlFiles;
287 
288     /**
289      * Defines the order the tests will be run in. Supported values are {@code alphabetical},
290      * {@code reversealphabetical}, {@code random}, {@code hourly} (alphabetical on even hours, reverse alphabetical
291      * on odd hours), {@code failedfirst}, {@code balanced} and {@code filesystem}.
292      * <br>
293      * <br>
294      * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during a
295      * multi-module build.
296      * <br>
297      * <br>
298      * Failed first will run tests that failed on previous run first, as well as new tests for this run.
299      * <br>
300      * <br>
301      * Balanced is only relevant with parallel=classes, and will try to optimize the run-order of the tests reducing the
302      * overall execution time. Initially a statistics file is created and every next test run will reorder classes.
303      * <br>
304      * <br>
305      * Note that the statistics are stored in a file named <b>.surefire-XXXXXXXXX</b> beside <i>pom.xml</i> and
306      * should not be checked into version control. The "XXXXX" is the SHA1 checksum of the entire surefire
307      * configuration, so different configurations will have different statistics files, meaning if you change any
308      * configuration settings you will re-run once before new statistics data can be established.
309      *
310      * @since 2.7
311      */
312     @Parameter( property = "failsafe.runOrder", defaultValue = "filesystem" )
313     private String runOrder;
314 
315     /**
316      * A file containing include patterns, each in a next line. Blank lines, or lines starting with # are ignored.
317      * If {@code includes} are also specified, these patterns are appended. Example with path, simple and regex
318      * includes:
319      * <pre><code>
320      * *{@literal /}it{@literal /}*
321      * **{@literal /}NotIncludedByDefault.java
322      * %regex[.*IT.*|.*Not.*]
323      * </code></pre>
324      */
325     @Parameter( property = "failsafe.includesFile" )
326     private File includesFile;
327 
328     /**
329      * A file containing exclude patterns, each in a next line. Blank lines, or lines starting with # are ignored.
330      * If {@code excludes} are also specified, these patterns are appended.
331      * Example with path, simple and regex excludes:
332      * <pre><code>
333      * *{@literal /}it{@literal /}*
334      * **{@literal /}DontRunIT.*
335      * %regex[.*IT.*|.*Not.*]
336      * </code></pre>
337      */
338     @Parameter( property = "failsafe.excludesFile" )
339     private File excludesFile;
340 
341     /**
342      * Set to error/failure count in order to skip remaining tests.
343      * Due to race conditions in parallel/forked execution this may not be fully guaranteed.<br>
344      * Enable with system property {@code -Dfailsafe.skipAfterFailureCount=1} or any number greater than zero.
345      * Defaults to "0".<br>
346      * See the prerequisites and limitations in documentation:<br>
347      * <a href="http://maven.apache.org/plugins/maven-failsafe-plugin/examples/skip-after-failure.html">
348      * http://maven.apache.org/plugins/maven-failsafe-plugin/examples/skip-after-failure.html</a>;
349      *
350      * @since 2.19
351      */
352     @Parameter( property = "failsafe.skipAfterFailureCount", defaultValue = "0" )
353     private int skipAfterFailureCount;
354 
355     /**
356      * After the plugin process is shutdown by sending <i>SIGTERM signal (CTRL+C)</i>, <i>SHUTDOWN command</i> is
357      * received by every forked JVM.
358      * <br>
359      * By default ({@code shutdown=testset}) forked JVM would not continue with new test which means that
360      * the current test may still continue to run.
361      * <br>
362      * The parameter can be configured with other two values {@code exit} and {@code kill}.
363      * <br>
364      * Using {@code exit} forked JVM executes {@code System.exit(1)} after the plugin process has received
365      * <i>SIGTERM signal</i>.
366      * <br>
367      * Using {@code kill} the JVM executes {@code Runtime.halt(1)} and kills itself.
368      *
369      * @since 2.19
370      */
371     @Parameter( property = "failsafe.shutdown", defaultValue = "testset" )
372     private String shutdown;
373 
374     @Override
375     protected int getRerunFailingTestsCount()
376     {
377         return rerunFailingTestsCount;
378     }
379 
380     @Override
381     @SuppressWarnings( "unchecked" )
382     protected void handleSummary( RunResult summary, Exception firstForkException )
383             throws MojoExecutionException, MojoFailureException
384     {
385         File summaryFile = getSummaryFile();
386         if ( !summaryFile.getParentFile().isDirectory() )
387         {
388             //noinspection ResultOfMethodCallIgnored
389             summaryFile.getParentFile().mkdirs();
390         }
391 
392         try
393         {
394             Object token = getPluginContext().get( FAILSAFE_IN_PROGRESS_CONTEXT_KEY );
395             writeSummary( summary, summaryFile, token != null );
396         }
397         catch ( Exception e )
398         {
399             throw new MojoExecutionException( e.getMessage(), e );
400         }
401 
402         getPluginContext().put( FAILSAFE_IN_PROGRESS_CONTEXT_KEY, FAILSAFE_IN_PROGRESS_CONTEXT_KEY );
403     }
404 
405     private boolean isJarArtifact( File artifactFile )
406     {
407         return artifactFile != null && artifactFile.isFile() && artifactFile.getName().toLowerCase().endsWith( ".jar" );
408     }
409 
410     private static File toAbsoluteCanonical( File f )
411     {
412         try
413         {
414             return f == null ? null : f.getAbsoluteFile().getCanonicalFile();
415         }
416         catch ( IOException e )
417         {
418             throw new IllegalStateException( e.getLocalizedMessage(), e );
419         }
420     }
421 
422     @Override
423     @SuppressWarnings( "deprecation" )
424     protected boolean isSkipExecution()
425     {
426         return isSkip() || isSkipTests() || isSkipITs() || isSkipExec();
427     }
428 
429     @Override
430     protected String getPluginName()
431     {
432         return "failsafe";
433     }
434 
435     @Override
436     protected String[] getDefaultIncludes()
437     {
438         return new String[]{ "**/IT*.java", "**/*IT.java", "**/*ITCase.java" };
439     }
440 
441     @Override
442     protected String getReportSchemaLocation()
443     {
444         return "https://maven.apache.org/surefire/maven-failsafe-plugin/xsd/failsafe-test-report.xsd";
445     }
446 
447     @Override
448     protected Artifact getMojoArtifact()
449     {
450         final Map<String, Artifact> pluginArtifactMap = getPluginArtifactMap();
451         return pluginArtifactMap.get( "org.apache.maven.plugins:maven-failsafe-plugin" );
452     }
453 
454     @Override
455     public boolean isSkipTests()
456     {
457         return skipTests;
458     }
459 
460     @Override
461     public void setSkipTests( boolean skipTests )
462     {
463         this.skipTests = skipTests;
464     }
465 
466     public boolean isSkipITs()
467     {
468         return skipITs;
469     }
470 
471     public void setSkipITs( boolean skipITs )
472     {
473         this.skipITs = skipITs;
474     }
475 
476     @Override
477     @SuppressWarnings( "deprecation" )
478     @Deprecated
479     public boolean isSkipExec()
480     {
481         return skipExec;
482     }
483 
484     @Override
485     @SuppressWarnings( "deprecation" )
486     @Deprecated
487     public void setSkipExec( boolean skipExec )
488     {
489         this.skipExec = skipExec;
490     }
491 
492     @Override
493     public boolean isSkip()
494     {
495         return skip;
496     }
497 
498     @Override
499     public void setSkip( boolean skip )
500     {
501         this.skip = skip;
502     }
503 
504     @Override
505     public File getBasedir()
506     {
507         return basedir;
508     }
509 
510     @Override
511     public void setBasedir( File basedir )
512     {
513         this.basedir = basedir;
514     }
515 
516     @Override
517     public File getTestClassesDirectory()
518     {
519         return testClassesDirectory;
520     }
521 
522     @Override
523     public void setTestClassesDirectory( File testClassesDirectory )
524     {
525         this.testClassesDirectory = testClassesDirectory;
526     }
527 
528     /**
529      * @return Output directory, or artifact file if artifact type is "jar". If not forking the JVM, parameter
530      * {@link #useSystemClassLoader} is ignored and the {@link org.apache.maven.surefire.booter.IsolatedClassLoader} is
531      * used instead. See the resolution of {@link #getClassLoaderConfiguration() ClassLoaderConfiguration}.
532      */
533     @Override
534     public File getClassesDirectory()
535     {
536         File artifact = getProject().getArtifact().getFile();
537         boolean isDefaultClsDir = classesDirectory == null;
538         return isDefaultClsDir ? ( isJarArtifact( artifact ) ? artifact : defaultClassesDirectory ) : classesDirectory;
539     }
540 
541     @Override
542     public void setClassesDirectory( File classesDirectory )
543     {
544         this.classesDirectory = toAbsoluteCanonical( classesDirectory );
545     }
546 
547     public void setDefaultClassesDirectory( File defaultClassesDirectory )
548     {
549         this.defaultClassesDirectory = toAbsoluteCanonical( defaultClassesDirectory );
550     }
551 
552     @Override
553     public File getReportsDirectory()
554     {
555         return reportsDirectory;
556     }
557 
558     @Override
559     public void setReportsDirectory( File reportsDirectory )
560     {
561         this.reportsDirectory = reportsDirectory;
562     }
563 
564     @Override
565     public String getTest()
566     {
567         return test;
568     }
569 
570     @Override
571     public void setTest( String test )
572     {
573         this.test = test;
574     }
575 
576     public File getSummaryFile()
577     {
578         return summaryFile;
579     }
580 
581     public void setSummaryFile( File summaryFile )
582     {
583         this.summaryFile = summaryFile;
584     }
585 
586     @Override
587     public boolean isPrintSummary()
588     {
589         return printSummary;
590     }
591 
592     @Override
593     public void setPrintSummary( boolean printSummary )
594     {
595         this.printSummary = printSummary;
596     }
597 
598     @Override
599     public String getReportFormat()
600     {
601         return reportFormat;
602     }
603 
604     @Override
605     public void setReportFormat( String reportFormat )
606     {
607         this.reportFormat = reportFormat;
608     }
609 
610     @Override
611     public boolean isUseFile()
612     {
613         return useFile;
614     }
615 
616     @Override
617     public void setUseFile( boolean useFile )
618     {
619         this.useFile = useFile;
620     }
621 
622     @Override
623     public String getDebugForkedProcess()
624     {
625         return debugForkedProcess;
626     }
627 
628     @Override
629     public void setDebugForkedProcess( String debugForkedProcess )
630     {
631         this.debugForkedProcess = debugForkedProcess;
632     }
633 
634     @Override
635     public int getForkedProcessTimeoutInSeconds()
636     {
637         return forkedProcessTimeoutInSeconds;
638     }
639 
640     @Override
641     public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
642     {
643         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
644     }
645 
646     @Override
647     public int getForkedProcessExitTimeoutInSeconds()
648     {
649         return forkedProcessExitTimeoutInSeconds;
650     }
651 
652     @Override
653     public void setForkedProcessExitTimeoutInSeconds( int forkedProcessExitTimeoutInSeconds )
654     {
655         this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds;
656     }
657 
658     @Override
659     public double getParallelTestsTimeoutInSeconds()
660     {
661         return parallelTestsTimeoutInSeconds;
662     }
663 
664     @Override
665     public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
666     {
667         this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds;
668     }
669 
670     @Override
671     public double getParallelTestsTimeoutForcedInSeconds()
672     {
673         return parallelTestsTimeoutForcedInSeconds;
674     }
675 
676     @Override
677     public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
678     {
679         this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds;
680     }
681 
682     @Override
683     public boolean isUseSystemClassLoader()
684     {
685         return useSystemClassLoader;
686     }
687 
688     @Override
689     public void setUseSystemClassLoader( boolean useSystemClassLoader )
690     {
691         this.useSystemClassLoader = useSystemClassLoader;
692     }
693 
694     @Override
695     public boolean isUseManifestOnlyJar()
696     {
697         return useManifestOnlyJar;
698     }
699 
700     @Override
701     public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
702     {
703         this.useManifestOnlyJar = useManifestOnlyJar;
704     }
705 
706     // the following will be refactored out once the common code is all in one place
707 
708     public boolean isTestFailureIgnore()
709     {
710         return true; // ignore
711     }
712 
713     public void setTestFailureIgnore( boolean testFailureIgnore )
714     {
715         // ignore
716     }
717 
718     @Override
719     protected void addPluginSpecificChecksumItems( ChecksumCalculator checksum )
720     {
721         checksum.add( skipITs );
722         checksum.add( summaryFile );
723     }
724 
725     @Override
726     public Boolean getFailIfNoSpecifiedTests()
727     {
728         return failIfNoSpecifiedTests;
729     }
730 
731     @Override
732     public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
733     {
734         this.failIfNoSpecifiedTests = failIfNoSpecifiedTests;
735     }
736 
737     @Override
738     public int getSkipAfterFailureCount()
739     {
740         return skipAfterFailureCount;
741     }
742 
743     @Override
744     public String getShutdown()
745     {
746         return shutdown;
747     }
748 
749     @Override
750     public List<String> getIncludes()
751     {
752         return includes;
753     }
754 
755     @Override
756     public void setIncludes( List<String> includes )
757     {
758         this.includes = includes;
759     }
760 
761     @Override
762     public File[] getSuiteXmlFiles()
763     {
764         return suiteXmlFiles.clone();
765     }
766 
767     @Override
768     @SuppressWarnings( "UnusedDeclaration" )
769     public void setSuiteXmlFiles( File[] suiteXmlFiles )
770     {
771         this.suiteXmlFiles = suiteXmlFiles.clone();
772     }
773 
774     @Override
775     public String getRunOrder()
776     {
777         return runOrder;
778     }
779 
780     @Override
781     @SuppressWarnings( "UnusedDeclaration" )
782     public void setRunOrder( String runOrder )
783     {
784         this.runOrder = runOrder;
785     }
786 
787     @Override
788     public File getIncludesFile()
789     {
790         return includesFile;
791     }
792 
793     @Override
794     public File getExcludesFile()
795     {
796         return excludesFile;
797     }
798 
799     @Override
800     protected final List<File> suiteXmlFiles()
801     {
802         return hasSuiteXmlFiles() ? Arrays.asList( suiteXmlFiles ) : Collections.<File>emptyList();
803     }
804 
805     @Override
806     protected final boolean hasSuiteXmlFiles()
807     {
808         return suiteXmlFiles != null && suiteXmlFiles.length != 0;
809     }
810 
811     static Charset toCharset( String encoding )
812     {
813         return Charset.forName( Charset.isSupported( encoding ) ? encoding : encoding.toUpperCase( Locale.ROOT ) );
814     }
815 }