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