View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugin.failsafe;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.util.Arrays;
24  import java.util.Collections;
25  import java.util.List;
26  
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.booterclient.ChecksumCalculator;
31  import org.apache.maven.plugins.annotations.LifecyclePhase;
32  import org.apache.maven.plugins.annotations.Mojo;
33  import org.apache.maven.plugins.annotations.Parameter;
34  import org.apache.maven.plugins.annotations.ResolutionScope;
35  import org.apache.maven.surefire.api.suite.RunResult;
36  import org.apache.maven.surefire.extensions.ForkNodeFactory;
37  
38  import static org.apache.maven.plugin.failsafe.util.FailsafeSummaryXmlUtils.writeSummary;
39  
40  /**
41   * Run integration tests using Surefire.
42   *
43   * @author Jason van Zyl
44   * @author Stephen Connolly
45   */
46  @Mojo(
47          name = "integration-test",
48          requiresProject = true,
49          requiresDependencyResolution = ResolutionScope.TEST,
50          defaultPhase = LifecyclePhase.INTEGRATION_TEST,
51          threadSafe = true)
52  public class IntegrationTestMojo extends AbstractSurefireMojo {
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(defaultValue = "${project.build.outputDirectory}", readonly = true, required = true)
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 "false" to prevent a failure if none of the tests specified in -Dit.test=... are run. Defaults to
135      * "true".
136      *
137      * @since 2.12
138      * @deprecated Since 3.0.0-M8, use "failsafe.failIfNoSpecifiedTests" instead.
139      */
140     @Deprecated
141     @Parameter(property = "it.failIfNoSpecifiedTests", defaultValue = "true")
142     private boolean failIfNoSpecifiedTestsDeprecated;
143 
144     /**
145      * Set this to "false" to prevent a failure if none of the tests specified in -Dit.test=... are run. Defaults to
146      * "true".
147      * Replacing "it.failIfNoSpecifiedTests" to be consistent with surefire plugin.
148      *
149      * @since 3.0.0-M8
150      */
151     @Parameter(property = "failsafe.failIfNoSpecifiedTests", defaultValue = "true")
152     private boolean failIfNoSpecifiedTests;
153 
154     /**
155      * Attach a debugger to the forked JVM. If set to "true", the process will suspend and wait for a debugger to attach
156      * on port 5005. If set to some other string, that string will be appended to the argLine, allowing you to configure
157      * arbitrary debugging ability options (without overwriting the other options specified through the {@code argLine}
158      * parameter).
159      *
160      * @since 2.4
161      */
162     @Parameter(property = "maven.failsafe.debug")
163     private String debugForkedProcess;
164 
165     /**
166      * Kill the forked test process after a certain number of seconds. If set to 0, wait forever for the process, never
167      * timing out.
168      *
169      * @since 2.4
170      */
171     @Parameter(property = "failsafe.timeout")
172     private int forkedProcessTimeoutInSeconds;
173 
174     /**
175      * Forked process is normally terminated without any significant delay after given tests have completed.
176      * If the particular tests started non-daemon Thread(s), the process hangs instead of been properly terminated
177      * by {@code System.exit()}. Use this parameter in order to determine the timeout of terminating the process.
178      * <a href="http://maven.apache.org/surefire/maven-failsafe-plugin/examples/shutdown.html">see the documentation:
179      * http://maven.apache.org/surefire/maven-failsafe-plugin/examples/shutdown.html</a>
180      *
181      * @since 2.20
182      */
183     @Parameter(property = "failsafe.exitTimeout", defaultValue = "30")
184     private int forkedProcessExitTimeoutInSeconds;
185 
186     /**
187      * Stop executing queued parallel JUnit tests after a certain number of seconds.
188      * <br>
189      * Example values: "3.5", "4"<br>
190      * <br>
191      * If set to 0, wait forever, never timing out.
192      * Makes sense with specified {@code parallel} different from "none".
193      *
194      * @since 2.16
195      */
196     @Parameter(property = "failsafe.parallel.timeout")
197     private double parallelTestsTimeoutInSeconds;
198 
199     /**
200      * Stop executing queued parallel JUnit tests
201      * and <i>interrupt</i> currently running tests after a certain number of seconds.
202      * <br>
203      * Example values: "3.5", "4"<br>
204      * <br>
205      * If set to 0, wait forever, never timing out.
206      * Makes sense with specified {@code parallel} different from "none".
207      *
208      * @since 2.16
209      */
210     @Parameter(property = "failsafe.parallel.forcedTimeout")
211     private double parallelTestsTimeoutForcedInSeconds;
212 
213     @SuppressWarnings("checkstyle:linelength")
214     /**
215      * A list of {@literal <include>} elements specifying the test filter (by pattern) of tests which should be
216      * included in testing. If it is not specified and the {@code test} parameter is unspecified as well, the default
217      * includes is
218      * <pre><code>
219      * {@literal <includes>}
220      *     {@literal <include>}**{@literal /}IT*.java{@literal </include>}
221      *     {@literal <include>}**{@literal /}*IT.java{@literal </include>}
222      *     {@literal <include>}**{@literal /}*ITCase.java{@literal </include>}
223      * {@literal </includes>}
224      * </code></pre>
225      * <br>
226      * Each include item may also contain a comma-separated sublist of items, which will be treated as multiple
227      * {@literal <include>} entries.<br>
228      * Since 2.19 a complex syntax is supported in one parameter (JUnit 4, JUnit 4.7+, TestNG):
229      * <pre><code>
230      * {@literal <include>}%regex[.*[Cat|Dog].*], Basic????, !Unstable*{@literal </include>}
231      * {@literal <include>}%regex[.*[Cat|Dog].*], !%regex[pkg.*Slow.*.class], pkg{@literal /}**{@literal /}*Fast*.java{@literal </include>}
232      * </code></pre>
233      * <br>
234      * This parameter is ignored if the TestNG {@code suiteXmlFiles} parameter is specified.<br>
235      * <br>
236      * <b>Notice that</b> these values are relative to the directory containing generated test classes of the project
237      * being tested. This directory is declared by the parameter {@code testClassesDirectory} which defaults
238      * to the POM property <code>${project.build.testOutputDirectory}</code>, typically
239      * <code>{@literal src/test/java}</code> unless overridden.
240      */
241     @Parameter(property = "failsafe.includes")
242     // TODO use regex for fully qualified class names in 3.0 and change the filtering abilities
243     private List<String> includes;
244 
245     /**
246      * A list of {@literal <exclude>} elements specifying the tests (by pattern) that should be excluded in testing.
247      * When not specified and when the {@code test} parameter is not specified, the default excludes will be <br>
248      * <pre><code>
249      * {@literal <excludes>}
250      *     {@literal <exclude>}**{@literal /}*$*{@literal </exclude>}
251      * {@literal </excludes>}
252      * </code></pre>
253      * (which excludes all inner classes).
254      * <br>
255      * This parameter is ignored if the TestNG {@code suiteXmlFiles} parameter is specified.
256      * <br>
257      * Each exclude item may also contain a comma-separated sub-list of items, which will be treated as multiple
258      * {@literal <exclude>} entries.<br>
259      * Since 2.19 a complex syntax is supported in one parameter (JUnit 4, JUnit 4.7+, TestNG):
260      * <pre><code>
261      * {@literal <exclude>}%regex[pkg.*Slow.*.class], Unstable*{@literal </exclude>}
262      * </code></pre>
263      * <br>
264      * <b>Notice that</b> these values are relative to the directory containing generated test classes of the project
265      * being tested. This directory is declared by the parameter {@code testClassesDirectory} which defaults
266      * to the POM property <code>${project.build.testOutputDirectory}</code>, typically
267      * <code>{@literal src/test/java}</code> unless overridden.
268      */
269     @Parameter(property = "failsafe.excludes")
270     // TODO use regex for fully qualified class names in 3.0 and change the filtering abilities
271     private List<String> excludes;
272 
273     /**
274      * Option to pass dependencies to the system's classloader instead of using an isolated class loader when forking.
275      * Prevents problems with JDKs which implement the service provider lookup mechanism by using the system's
276      * classloader.
277      *
278      * @since 2.3
279      */
280     @Parameter(property = "failsafe.useSystemClassLoader", defaultValue = "true")
281     private boolean useSystemClassLoader;
282 
283     /**
284      * By default, Surefire forks your tests using a manifest-only JAR; set this parameter to "false" to force it to
285      * launch your tests with a plain old Java classpath. (See the
286      * <a href="http://maven.apache.org/plugins/maven-failsafe-plugin/examples/class-loading.html">
287      * http://maven.apache.org/plugins/maven-failsafe-plugin/examples/class-loading.html</a>
288      * for a more detailed explanation of manifest-only JARs and their benefits.)
289      * <br>
290      * Beware, setting this to "false" may cause your tests to fail on Windows if your classpath is too long.
291      *
292      * @since 2.4.3
293      */
294     @Parameter(property = "failsafe.useManifestOnlyJar", defaultValue = "true")
295     private boolean useManifestOnlyJar;
296 
297     /**
298      * The character encoding scheme to be applied while generating test report
299      * files (see target/surefire-reports/yourTestName.txt).
300      * The report output files (*-out.txt) are still encoded with JVM's encoding used in standard out/err pipes.
301      *
302      * @since 3.0.0-M1
303      */
304     @Parameter(property = "encoding", defaultValue = "${project.reporting.outputEncoding}")
305     private String encoding;
306 
307     /**
308      * (JUnit 4+ providers and JUnit 5+ providers since 3.0.0-M4)
309      * The number of times each failing test will be rerun. If set larger than 0, rerun failing tests immediately after
310      * they fail. If a failing test passes in any of those reruns, it will be marked as pass and reported as a "flake".
311      * However, all the failing attempts will be recorded.
312      */
313     @Parameter(property = "failsafe.rerunFailingTestsCount", defaultValue = "0")
314     private int rerunFailingTestsCount;
315 
316     /**
317      * (TestNG) List of &lt;suiteXmlFile&gt; elements specifying TestNG suite xml file locations. Note that
318      * {@code suiteXmlFiles} is incompatible with several other parameters of this plugin, like
319      * {@code includes} and {@code excludes}.<br>
320      * This parameter is ignored if the {@code test} parameter is specified (allowing you to run a single test
321      * instead of an entire suite).
322      *
323      * @since 2.2
324      */
325     @Parameter(property = "failsafe.suiteXmlFiles")
326     private File[] suiteXmlFiles;
327 
328     /**
329      * Defines the order the tests will be run in. Supported values are {@code alphabetical},
330      * {@code reversealphabetical}, {@code random}, {@code hourly} (alphabetical on even hours, reverse alphabetical
331      * on odd hours), {@code failedfirst}, {@code balanced} and {@code filesystem}.
332      * <br>
333      * <br>
334      * Odd/Even for hourly is determined at the time the of scanning the classpath, meaning it could change during a
335      * multi-module build.
336      * <br>
337      * <br>
338      * Failed first will run tests that failed on previous run first, as well as new tests for this run.
339      * <br>
340      * <br>
341      * Balanced is only relevant with parallel=classes, and will try to optimize the run-order of the tests reducing the
342      * overall execution time. Initially a statistics file is created and every next test run will reorder classes.
343      * <br>
344      * <br>
345      * Note that the statistics are stored in a file named <b>.surefire-XXXXXXXXX</b> beside <i>pom.xml</i> and
346      * should not be checked into version control. The "XXXXX" is the SHA1 checksum of the entire surefire
347      * configuration, so different configurations will have different statistics files, meaning if you change any
348      * configuration settings you will re-run once before new statistics data can be established.
349      *
350      * @since 2.7
351      */
352     @Parameter(property = "failsafe.runOrder", defaultValue = "filesystem")
353     private String runOrder;
354 
355     /**
356      * Sets the random seed that will be used to order the tests if {@code failsafe.runOrder} is set to {@code random}.
357      * <br>
358      * <br>
359      * If no seeds are set and {@code failsafe.runOrder} is set to {@code random}, then the seed used will be
360      * outputted (search for "To reproduce ordering use flag -Dfailsafe.runOrder.random.seed").
361      * <br>
362      * <br>
363      * To deterministically reproduce any random test order that was run before, simply set the seed to
364      * be the same value.
365      *
366      * @since 3.0.0-M6
367      */
368     @Parameter(property = "failsafe.runOrder.random.seed")
369     private Long runOrderRandomSeed;
370 
371     /**
372      * Used to override the checksum in the name of the statistics file
373      * when {@code failsafe.runOrder} is set to "balanced".
374      *
375      * @since 3.5.5
376      */
377     @Parameter(property = "failsafe.runOrder.statisticsFile.checksum")
378     private String runOrderStatisticsFileChecksum;
379 
380     /**
381      * A file containing include patterns, each in a next line. Blank lines, or lines starting with # are ignored.
382      * If {@code includes} are also specified, these patterns are appended. Example with path, simple and regex
383      * includes:
384      * <pre><code>
385      * *{@literal /}it{@literal /}*
386      * **{@literal /}NotIncludedByDefault.java
387      * %regex[.*IT.*|.*Not.*]
388      * </code></pre>
389      * <br>
390      * Since 3.0.0-M6, method filtering support is provided in the inclusions file as well, example:
391      * <pre><code>
392      * pkg.SomeIT#testMethod
393      * </code></pre>
394      *
395      * @since 2.13
396      */
397     @Parameter(property = "failsafe.includesFile")
398     private File includesFile;
399 
400     /**
401      * A file containing exclude patterns, each in a next line. Blank lines, or lines starting with # are ignored.
402      * If {@code excludes} are also specified, these patterns are appended.
403      * Example with path, simple and regex excludes:
404      * <pre><code>
405      * *{@literal /}it{@literal /}*
406      * **{@literal /}DontRunIT.*
407      * %regex[.*IT.*|.*Not.*]
408      * </code></pre>
409      * <br>
410      * Since 3.0.0-M6, method filtering support is provided in the exclusions file as well, example:
411      * <pre><code>
412      * pkg.SomeIT#testMethod
413      * </code></pre>
414      *
415      * @since 2.13
416      */
417     @Parameter(property = "failsafe.excludesFile")
418     private File excludesFile;
419 
420     /**
421      * Set to error/failure count in order to skip remaining tests.
422      * Due to race conditions in parallel/forked execution this may not be fully guaranteed.<br>
423      * Enable with system property {@code -Dfailsafe.skipAfterFailureCount=1} or any number greater than zero.
424      * Defaults to "0".<br>
425      * See the prerequisites and limitations in documentation:<br>
426      * <a href="http://maven.apache.org/plugins/maven-failsafe-plugin/examples/skip-after-failure.html">
427      * http://maven.apache.org/plugins/maven-failsafe-plugin/examples/skip-after-failure.html</a>
428      *
429      * @since 2.19
430      */
431     @Parameter(property = "failsafe.skipAfterFailureCount", defaultValue = "0")
432     private int skipAfterFailureCount;
433 
434     /**
435      * After the plugin process is shutdown by sending <i>SIGTERM signal (CTRL+C)</i>, <i>SHUTDOWN command</i> is
436      * received by every forked JVM.
437      * <br>
438      * The value is set to ({@code shutdown=exit}) by default (changed in version 3.0.0-M4).
439      * <br>
440      * The parameter can be configured with other two values {@code testset} and {@code kill}.
441      * <br>
442      * With({@code shutdown=testset}) the test set may still continue to run in forked JVM.
443      * <br>
444      * Using {@code exit} forked JVM executes {@code System.exit(1)} after the plugin process has received
445      * <i>SIGTERM signal</i>.
446      * <br>
447      * Using {@code kill} the JVM executes {@code Runtime.halt(1)} and kills itself.
448      *
449      * @since 2.19
450      */
451     @Parameter(property = "failsafe.shutdown", defaultValue = "exit")
452     private String shutdown;
453 
454     /**
455      * When {@code true}, uses the modulepath when executing with JDK 9+ and <i>module-info.java</i> is
456      * present. When {@code false}, always uses the classpath.
457      * <br>
458      * Defaults to {@code true}.
459      *
460      * @since 3.0.0-M2
461      */
462     @Parameter(property = "failsafe.useModulePath", defaultValue = "true")
463     private boolean useModulePath;
464 
465     /**
466      * This parameter configures the forked node. Currently, you can select the communication protocol, i.e. process
467      * pipes or TCP/IP sockets.
468      * The plugin uses process pipes by default which will be turned to TCP/IP in the version 3.0.0.
469      * Alternatively, you can implement your own factory and SPI.
470      * <br>
471      * See the documentation for more details:<br>
472      * <a href="https://maven.apache.org/plugins/maven-surefire-plugin/examples/process-communication.html">
473      *     https://maven.apache.org/plugins/maven-surefire-plugin/examples/process-communication.html</a>
474      *
475      * @since 3.0.0-M5
476      */
477     @Parameter(property = "failsafe.forkNode")
478     private ForkNodeFactory forkNode;
479 
480     /**
481      * You can selectively exclude individual environment variables by enumerating their keys.
482      * <br>
483      * The environment is a system-dependent mapping from keys to values which is inherited from the Maven process
484      * to the forked Surefire processes. The keys must literally (case sensitive) match in order to exclude
485      * their environment variable.
486      * <br>
487      * Example to exclude three environment variables:
488      * <br>
489      * <i>mvn test -Dfailsafe.excludedEnvironmentVariables=ACME1,ACME2,ACME3</i>
490      *
491      * @since 3.0.0-M4
492      */
493     @Parameter(property = "failsafe.excludedEnvironmentVariables")
494     private String[] excludedEnvironmentVariables;
495 
496     /**
497      * Since 3.0.0-M4 the process checkers are disabled.
498      * You can enable them namely by setting {@code ping} and {@code native} or {@code all} in this parameter.
499      * <br>
500      * The checker is useful in situations when you kill the build on a CI system and you want the Surefire forked JVM
501      * to kill the tests asap and free all handlers on the file system been previously used by the JVM and by the tests.
502      *
503      * <br>
504      *
505      * The {@code ping} should be safely used together with ZGC or Shenandoah Garbage Collector.
506      * Due to the {@code ping} relies on timing of the PING (triggered every 30 seconds), slow GCs may pause
507      * the timers and pretend that the parent process of the forked JVM does not exist.
508      *
509      * <br>
510      *
511      * The {@code native} is very fast checker.
512      * It is useful mechanism on Unix based systems, Linux distributions and Alpine/BusyBox Linux.
513      * See the JIRA <a href="https://issues.apache.org/jira/browse/SUREFIRE-1631">SUREFIRE-1631</a> for Windows issues.
514      *
515      * <br>
516      *
517      * Another useful configuration parameter is {@code forkedProcessTimeoutInSeconds}.
518      * <br>
519      * See the Frequently Asked Questions page with more details:<br>
520      * <a href="http://maven.apache.org/surefire/maven-surefire-plugin/faq.html#kill-jvm">
521      *     http://maven.apache.org/surefire/maven-surefire-plugin/faq.html#kill-jvm</a>
522      * <br>
523      * <a href="http://maven.apache.org/surefire/maven-failsafe-plugin/faq.html#kill-jvm">
524      *     http://maven.apache.org/surefire/maven-failsafe-plugin/faq.html#kill-jvm</a>
525      *
526      * <br>
527      *
528      * Example of use:
529      * <br>
530      * <i>mvn test -Dfailsafe.enableProcessChecker=all</i>
531      *
532      * @since 3.0.0-M4
533      */
534     @Parameter(property = "failsafe.enableProcessChecker")
535     private String enableProcessChecker;
536 
537     /**
538      * Properties file being used as system properties passed to the provider.
539      *
540      * @see AbstractSurefireMojo#systemPropertyVariables {@code systemPropertyVariables} for how the effective provider properties are calculated
541      */
542     @Parameter(property = "failsafe.systemPropertiesFile")
543     private File systemPropertiesFile;
544 
545     /**
546      * Provide the ID/s of an JUnit engine to be included in the test run.
547      *
548      * @since 3.0.0-M6
549      */
550     @Parameter(property = "failsafe.includeJUnit5Engines")
551     private String[] includeJUnit5Engines;
552 
553     /**
554      * Provide the ID/s of an JUnit engine to be excluded in the test run.
555      *
556      * @since 3.0.0-M6
557      */
558     @Parameter(property = "failsafe.excludeJUnit5Engines")
559     private String[] excludeJUnit5Engines;
560 
561     @Override
562     protected int getRerunFailingTestsCount() {
563         return rerunFailingTestsCount;
564     }
565 
566     @Override
567     @SuppressWarnings("unchecked")
568     protected void handleSummary(RunResult summary, Exception firstForkException)
569             throws MojoExecutionException, MojoFailureException {
570         try {
571             if (!summary.isNoTestsRun()) {
572                 Object token = getPluginContext().get(FAILSAFE_IN_PROGRESS_CONTEXT_KEY);
573                 writeSummary(summary, getSummaryFile(), token != null);
574             }
575         } catch (Exception e) {
576             throw new MojoExecutionException(e.getMessage(), e);
577         }
578 
579         getPluginContext().put(FAILSAFE_IN_PROGRESS_CONTEXT_KEY, FAILSAFE_IN_PROGRESS_CONTEXT_KEY);
580     }
581 
582     private boolean isJarArtifact(File artifactFile) {
583         return artifactFile != null
584                 && artifactFile.isFile()
585                 && artifactFile.getName().toLowerCase().endsWith(".jar");
586     }
587 
588     private static File toAbsoluteCanonical(File f) {
589         try {
590             return f == null ? null : f.getAbsoluteFile().getCanonicalFile();
591         } catch (IOException e) {
592             throw new IllegalStateException(e.getLocalizedMessage(), e);
593         }
594     }
595 
596     @Override
597     @SuppressWarnings("deprecation")
598     protected boolean isSkipExecution() {
599         return isSkip() || isSkipTests() || isSkipITs() || isSkipExec();
600     }
601 
602     @Override
603     protected String getPluginName() {
604         return "failsafe";
605     }
606 
607     @Override
608     protected String[] getDefaultIncludes() {
609         return new String[] {"**/IT*.java", "**/*IT.java", "**/*ITCase.java"};
610     }
611 
612     @Override
613     protected String getReportSchemaLocation() {
614         return "https://maven.apache.org/surefire/maven-failsafe-plugin/xsd/failsafe-test-report.xsd";
615     }
616 
617     @Override
618     public boolean isSkipTests() {
619         return skipTests;
620     }
621 
622     @Override
623     @Deprecated
624     public void setSkipTests(boolean skipTests) {
625         this.skipTests = skipTests;
626     }
627 
628     public boolean isSkipITs() {
629         return skipITs;
630     }
631 
632     public void setSkipITs(boolean skipITs) {
633         this.skipITs = skipITs;
634     }
635 
636     @Override
637     @Deprecated
638     public boolean isSkipExec() {
639         return skipExec;
640     }
641 
642     @Override
643     @Deprecated
644     public void setSkipExec(boolean skipExec) {
645         this.skipExec = skipExec;
646     }
647 
648     @Override
649     public boolean isSkip() {
650         return skip;
651     }
652 
653     @Override
654     public void setSkip(boolean skip) {
655         this.skip = skip;
656     }
657 
658     @Override
659     public File getBasedir() {
660         return basedir;
661     }
662 
663     @Override
664     public void setBasedir(File basedir) {
665         this.basedir = basedir;
666     }
667 
668     @Override
669     public File getTestClassesDirectory() {
670         return testClassesDirectory;
671     }
672 
673     @Override
674     public void setTestClassesDirectory(File testClassesDirectory) {
675         this.testClassesDirectory = testClassesDirectory;
676     }
677 
678     /**
679      * @return Output directory, or artifact file if artifact type is "jar". If not forking the JVM, parameter
680      * {@link #useSystemClassLoader} is ignored and the {@link org.apache.maven.surefire.booter.IsolatedClassLoader} is
681      * used instead. See the resolution of {@link #getClassLoaderConfiguration() ClassLoaderConfiguration}.
682      */
683     @Override
684     public File getMainBuildPath() {
685         File artifact = getProject().getArtifact().getFile();
686         boolean isDefaultClsDir = classesDirectory == null;
687         return isDefaultClsDir ? (isJarArtifact(artifact) ? artifact : defaultClassesDirectory) : classesDirectory;
688     }
689 
690     @Override
691     public void setMainBuildPath(File mainBuildPath) {
692         classesDirectory = toAbsoluteCanonical(mainBuildPath);
693     }
694 
695     public void setDefaultClassesDirectory(File defaultClassesDirectory) {
696         this.defaultClassesDirectory = toAbsoluteCanonical(defaultClassesDirectory);
697     }
698 
699     @Override
700     public File getReportsDirectory() {
701         return reportsDirectory;
702     }
703 
704     @Override
705     public void setReportsDirectory(File reportsDirectory) {
706         this.reportsDirectory = reportsDirectory;
707     }
708 
709     @Override
710     public String getTest() {
711         return test;
712     }
713 
714     @Override
715     public void setTest(String test) {
716         this.test = test;
717     }
718 
719     public File getSummaryFile() {
720         return summaryFile;
721     }
722 
723     public void setSummaryFile(File summaryFile) {
724         this.summaryFile = summaryFile;
725     }
726 
727     @Override
728     public boolean isPrintSummary() {
729         return printSummary;
730     }
731 
732     @Override
733     public void setPrintSummary(boolean printSummary) {
734         this.printSummary = printSummary;
735     }
736 
737     @Override
738     public String getReportFormat() {
739         return reportFormat;
740     }
741 
742     @Override
743     public void setReportFormat(String reportFormat) {
744         this.reportFormat = reportFormat;
745     }
746 
747     @Override
748     public boolean isUseFile() {
749         return useFile;
750     }
751 
752     @Override
753     public void setUseFile(boolean useFile) {
754         this.useFile = useFile;
755     }
756 
757     @Override
758     public String getDebugForkedProcess() {
759         return debugForkedProcess;
760     }
761 
762     @Override
763     public void setDebugForkedProcess(String debugForkedProcess) {
764         this.debugForkedProcess = debugForkedProcess;
765     }
766 
767     @Override
768     public int getForkedProcessTimeoutInSeconds() {
769         return forkedProcessTimeoutInSeconds;
770     }
771 
772     @Override
773     public void setForkedProcessTimeoutInSeconds(int forkedProcessTimeoutInSeconds) {
774         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
775     }
776 
777     @Override
778     public int getForkedProcessExitTimeoutInSeconds() {
779         return forkedProcessExitTimeoutInSeconds;
780     }
781 
782     @Override
783     public void setForkedProcessExitTimeoutInSeconds(int forkedProcessExitTimeoutInSeconds) {
784         this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds;
785     }
786 
787     @Override
788     public double getParallelTestsTimeoutInSeconds() {
789         return parallelTestsTimeoutInSeconds;
790     }
791 
792     @Override
793     public void setParallelTestsTimeoutInSeconds(double parallelTestsTimeoutInSeconds) {
794         this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds;
795     }
796 
797     @Override
798     public double getParallelTestsTimeoutForcedInSeconds() {
799         return parallelTestsTimeoutForcedInSeconds;
800     }
801 
802     @Override
803     public void setParallelTestsTimeoutForcedInSeconds(double parallelTestsTimeoutForcedInSeconds) {
804         this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds;
805     }
806 
807     @Override
808     public boolean isUseSystemClassLoader() {
809         return useSystemClassLoader;
810     }
811 
812     @Override
813     public void setUseSystemClassLoader(boolean useSystemClassLoader) {
814         this.useSystemClassLoader = useSystemClassLoader;
815     }
816 
817     @Override
818     public boolean isUseManifestOnlyJar() {
819         return useManifestOnlyJar;
820     }
821 
822     @Override
823     public void setUseManifestOnlyJar(boolean useManifestOnlyJar) {
824         this.useManifestOnlyJar = useManifestOnlyJar;
825     }
826 
827     @Override
828     public String getEncoding() {
829         return encoding;
830     }
831 
832     @Override
833     public void setEncoding(String encoding) {
834         this.encoding = encoding;
835     }
836 
837     // the following will be refactored out once the common code is all in one place
838 
839     public boolean isTestFailureIgnore() {
840         return true; // ignore
841     }
842 
843     public void setTestFailureIgnore(boolean testFailureIgnore) {
844         // ignore
845     }
846 
847     @Override
848     protected void addPluginSpecificChecksumItems(ChecksumCalculator checksum) {
849         checksum.add(skipITs);
850         checksum.add(summaryFile);
851     }
852 
853     @Override
854     public File getSystemPropertiesFile() {
855         return systemPropertiesFile;
856     }
857 
858     @Override
859     public void setSystemPropertiesFile(File systemPropertiesFile) {
860         this.systemPropertiesFile = systemPropertiesFile;
861     }
862 
863     @Override
864     @SuppressWarnings("deprecation")
865     public boolean getFailIfNoSpecifiedTests() {
866         if (!failIfNoSpecifiedTestsDeprecated) {
867             getConsoleLogger()
868                     .warning("Use " + getPluginName()
869                             + ".failIfNoSpecifiedTests property instead of obsolete it.failIfNoSpecifiedTests.");
870         }
871         // since both have default "true", assuming that any "false" is set by user on purpose
872         return failIfNoSpecifiedTests && failIfNoSpecifiedTestsDeprecated;
873     }
874 
875     @Override
876     public void setFailIfNoSpecifiedTests(boolean failIfNoSpecifiedTests) {
877         this.failIfNoSpecifiedTests = failIfNoSpecifiedTests;
878     }
879 
880     @Override
881     public int getSkipAfterFailureCount() {
882         return skipAfterFailureCount;
883     }
884 
885     @Override
886     public String getShutdown() {
887         return shutdown;
888     }
889 
890     @Override
891     public List<String> getIncludes() {
892         return includes;
893     }
894 
895     @Override
896     public void setIncludes(List<String> includes) {
897         this.includes = includes;
898     }
899 
900     @Override
901     public List<String> getExcludes() {
902         return excludes;
903     }
904 
905     @Override
906     public void setExcludes(List<String> excludes) {
907         this.excludes = excludes;
908     }
909 
910     @Override
911     public File[] getSuiteXmlFiles() {
912         return suiteXmlFiles.clone();
913     }
914 
915     @Override
916     @SuppressWarnings("UnusedDeclaration")
917     public void setSuiteXmlFiles(File[] suiteXmlFiles) {
918         this.suiteXmlFiles = suiteXmlFiles.clone();
919     }
920 
921     @Override
922     public String getRunOrder() {
923         return runOrder;
924     }
925 
926     @Override
927     @SuppressWarnings("UnusedDeclaration")
928     public void setRunOrder(String runOrder) {
929         this.runOrder = runOrder;
930     }
931 
932     @Override
933     public Long getRunOrderRandomSeed() {
934         return runOrderRandomSeed;
935     }
936 
937     @Override
938     public void setRunOrderRandomSeed(Long runOrderRandomSeed) {
939         this.runOrderRandomSeed = runOrderRandomSeed;
940     }
941 
942     @Override
943     public String getRunOrderStatisticsFileChecksum() {
944         return runOrderStatisticsFileChecksum;
945     }
946 
947     @Override
948     public void setRunOrderStatisticsFileChecksum(String runOrderStatisticsFileChecksum) {
949         this.runOrderStatisticsFileChecksum = runOrderStatisticsFileChecksum;
950     }
951 
952     @Override
953     public File getIncludesFile() {
954         return includesFile;
955     }
956 
957     @Override
958     public File getExcludesFile() {
959         return excludesFile;
960     }
961 
962     @Override
963     protected boolean useModulePath() {
964         return useModulePath;
965     }
966 
967     @Override
968     protected void setUseModulePath(boolean useModulePath) {
969         this.useModulePath = useModulePath;
970     }
971 
972     @Override
973     protected final List<File> suiteXmlFiles() {
974         return hasSuiteXmlFiles() ? Arrays.asList(suiteXmlFiles) : Collections.<File>emptyList();
975     }
976 
977     @Override
978     protected final boolean hasSuiteXmlFiles() {
979         return suiteXmlFiles != null && suiteXmlFiles.length != 0;
980     }
981 
982     @Override
983     protected final ForkNodeFactory getForkNode() {
984         return forkNode;
985     }
986 
987     @Override
988     protected final String[] getExcludedEnvironmentVariables() {
989         return excludedEnvironmentVariables == null ? new String[0] : excludedEnvironmentVariables;
990     }
991 
992     void setExcludedEnvironmentVariables(String[] excludedEnvironmentVariables) {
993         this.excludedEnvironmentVariables = excludedEnvironmentVariables;
994     }
995 
996     @Override
997     protected final String getEnableProcessChecker() {
998         return enableProcessChecker;
999     }
1000 
1001     public String[] getIncludeJUnit5Engines() {
1002         return includeJUnit5Engines;
1003     }
1004 
1005     @SuppressWarnings("UnusedDeclaration")
1006     public void setIncludeJUnit5Engines(String[] includeJUnit5Engines) {
1007         this.includeJUnit5Engines = includeJUnit5Engines;
1008     }
1009 
1010     public String[] getExcludeJUnit5Engines() {
1011         return excludeJUnit5Engines;
1012     }
1013 
1014     @SuppressWarnings("UnusedDeclaration")
1015     public void setExcludeJUnit5Engines(String[] excludeJUnit5Engines) {
1016         this.excludeJUnit5Engines = excludeJUnit5Engines;
1017     }
1018 }