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