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 <suiteXmlFile> 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 * A file containing include patterns, each in a next line. Blank lines, or lines starting with # are ignored. 373 * If {@code includes} are also specified, these patterns are appended. Example with path, simple and regex 374 * includes: 375 * <pre><code> 376 * *{@literal /}it{@literal /}* 377 * **{@literal /}NotIncludedByDefault.java 378 * %regex[.*IT.*|.*Not.*] 379 * </code></pre> 380 * <br> 381 * Since 3.0.0-M6, method filtering support is provided in the inclusions file as well, example: 382 * <pre><code> 383 * pkg.SomeIT#testMethod 384 * </code></pre> 385 * 386 * @since 2.13 387 */ 388 @Parameter(property = "failsafe.includesFile") 389 private File includesFile; 390 391 /** 392 * A file containing exclude patterns, each in a next line. Blank lines, or lines starting with # are ignored. 393 * If {@code excludes} are also specified, these patterns are appended. 394 * Example with path, simple and regex excludes: 395 * <pre><code> 396 * *{@literal /}it{@literal /}* 397 * **{@literal /}DontRunIT.* 398 * %regex[.*IT.*|.*Not.*] 399 * </code></pre> 400 * <br> 401 * Since 3.0.0-M6, method filtering support is provided in the exclusions file as well, example: 402 * <pre><code> 403 * pkg.SomeIT#testMethod 404 * </code></pre> 405 * 406 * @since 2.13 407 */ 408 @Parameter(property = "failsafe.excludesFile") 409 private File excludesFile; 410 411 /** 412 * Set to error/failure count in order to skip remaining tests. 413 * Due to race conditions in parallel/forked execution this may not be fully guaranteed.<br> 414 * Enable with system property {@code -Dfailsafe.skipAfterFailureCount=1} or any number greater than zero. 415 * Defaults to "0".<br> 416 * See the prerequisites and limitations in documentation:<br> 417 * <a href="http://maven.apache.org/plugins/maven-failsafe-plugin/examples/skip-after-failure.html"> 418 * http://maven.apache.org/plugins/maven-failsafe-plugin/examples/skip-after-failure.html</a> 419 * 420 * @since 2.19 421 */ 422 @Parameter(property = "failsafe.skipAfterFailureCount", defaultValue = "0") 423 private int skipAfterFailureCount; 424 425 /** 426 * After the plugin process is shutdown by sending <i>SIGTERM signal (CTRL+C)</i>, <i>SHUTDOWN command</i> is 427 * received by every forked JVM. 428 * <br> 429 * The value is set to ({@code shutdown=exit}) by default (changed in version 3.0.0-M4). 430 * <br> 431 * The parameter can be configured with other two values {@code testset} and {@code kill}. 432 * <br> 433 * With({@code shutdown=testset}) the test set may still continue to run in forked JVM. 434 * <br> 435 * Using {@code exit} forked JVM executes {@code System.exit(1)} after the plugin process has received 436 * <i>SIGTERM signal</i>. 437 * <br> 438 * Using {@code kill} the JVM executes {@code Runtime.halt(1)} and kills itself. 439 * 440 * @since 2.19 441 */ 442 @Parameter(property = "failsafe.shutdown", defaultValue = "exit") 443 private String shutdown; 444 445 /** 446 * When {@code true}, uses the modulepath when executing with JDK 9+ and <i>module-info.java</i> is 447 * present. When {@code false}, always uses the classpath. 448 * <br> 449 * Defaults to {@code true}. 450 * 451 * @since 3.0.0-M2 452 */ 453 @Parameter(property = "failsafe.useModulePath", defaultValue = "true") 454 private boolean useModulePath; 455 456 /** 457 * This parameter configures the forked node. Currently, you can select the communication protocol, i.e. process 458 * pipes or TCP/IP sockets. 459 * The plugin uses process pipes by default which will be turned to TCP/IP in the version 3.0.0. 460 * Alternatively, you can implement your own factory and SPI. 461 * <br> 462 * See the documentation for more details:<br> 463 * <a href="https://maven.apache.org/plugins/maven-surefire-plugin/examples/process-communication.html"> 464 * https://maven.apache.org/plugins/maven-surefire-plugin/examples/process-communication.html</a> 465 * 466 * @since 3.0.0-M5 467 */ 468 @Parameter(property = "failsafe.forkNode") 469 private ForkNodeFactory forkNode; 470 471 /** 472 * You can selectively exclude individual environment variables by enumerating their keys. 473 * <br> 474 * The environment is a system-dependent mapping from keys to values which is inherited from the Maven process 475 * to the forked Surefire processes. The keys must literally (case sensitive) match in order to exclude 476 * their environment variable. 477 * <br> 478 * Example to exclude three environment variables: 479 * <br> 480 * <i>mvn test -Dfailsafe.excludedEnvironmentVariables=ACME1,ACME2,ACME3</i> 481 * 482 * @since 3.0.0-M4 483 */ 484 @Parameter(property = "failsafe.excludedEnvironmentVariables") 485 private String[] excludedEnvironmentVariables; 486 487 /** 488 * Since 3.0.0-M4 the process checkers are disabled. 489 * You can enable them namely by setting {@code ping} and {@code native} or {@code all} in this parameter. 490 * <br> 491 * The checker is useful in situations when you kill the build on a CI system and you want the Surefire forked JVM 492 * to kill the tests asap and free all handlers on the file system been previously used by the JVM and by the tests. 493 * 494 * <br> 495 * 496 * The {@code ping} should be safely used together with ZGC or Shenandoah Garbage Collector. 497 * Due to the {@code ping} relies on timing of the PING (triggered every 30 seconds), slow GCs may pause 498 * the timers and pretend that the parent process of the forked JVM does not exist. 499 * 500 * <br> 501 * 502 * The {@code native} is very fast checker. 503 * It is useful mechanism on Unix based systems, Linux distributions and Alpine/BusyBox Linux. 504 * See the JIRA <a href="https://issues.apache.org/jira/browse/SUREFIRE-1631">SUREFIRE-1631</a> for Windows issues. 505 * 506 * <br> 507 * 508 * Another useful configuration parameter is {@code forkedProcessTimeoutInSeconds}. 509 * <br> 510 * See the Frequently Asked Questions page with more details:<br> 511 * <a href="http://maven.apache.org/surefire/maven-surefire-plugin/faq.html#kill-jvm"> 512 * http://maven.apache.org/surefire/maven-surefire-plugin/faq.html#kill-jvm</a> 513 * <br> 514 * <a href="http://maven.apache.org/surefire/maven-failsafe-plugin/faq.html#kill-jvm"> 515 * http://maven.apache.org/surefire/maven-failsafe-plugin/faq.html#kill-jvm</a> 516 * 517 * <br> 518 * 519 * Example of use: 520 * <br> 521 * <i>mvn test -Dfailsafe.enableProcessChecker=all</i> 522 * 523 * @since 3.0.0-M4 524 */ 525 @Parameter(property = "failsafe.enableProcessChecker") 526 private String enableProcessChecker; 527 528 /** 529 * Properties file being used as system properties passed to the provider. 530 * 531 * @see AbstractSurefireMojo#systemPropertyVariables {@code systemPropertyVariables} for how the effective provider properties are calculated 532 */ 533 @Parameter(property = "failsafe.systemPropertiesFile") 534 private File systemPropertiesFile; 535 536 /** 537 * Provide the ID/s of an JUnit engine to be included in the test run. 538 * 539 * @since 3.0.0-M6 540 */ 541 @Parameter(property = "failsafe.includeJUnit5Engines") 542 private String[] includeJUnit5Engines; 543 544 /** 545 * Provide the ID/s of an JUnit engine to be excluded in the test run. 546 * 547 * @since 3.0.0-M6 548 */ 549 @Parameter(property = "failsafe.excludeJUnit5Engines") 550 private String[] excludeJUnit5Engines; 551 552 @Override 553 protected int getRerunFailingTestsCount() { 554 return rerunFailingTestsCount; 555 } 556 557 @Override 558 @SuppressWarnings("unchecked") 559 protected void handleSummary(RunResult summary, Exception firstForkException) 560 throws MojoExecutionException, MojoFailureException { 561 try { 562 if (!summary.isNoTestsRun()) { 563 Object token = getPluginContext().get(FAILSAFE_IN_PROGRESS_CONTEXT_KEY); 564 writeSummary(summary, getSummaryFile(), token != null); 565 } 566 } catch (Exception e) { 567 throw new MojoExecutionException(e.getMessage(), e); 568 } 569 570 getPluginContext().put(FAILSAFE_IN_PROGRESS_CONTEXT_KEY, FAILSAFE_IN_PROGRESS_CONTEXT_KEY); 571 } 572 573 private boolean isJarArtifact(File artifactFile) { 574 return artifactFile != null 575 && artifactFile.isFile() 576 && artifactFile.getName().toLowerCase().endsWith(".jar"); 577 } 578 579 private static File toAbsoluteCanonical(File f) { 580 try { 581 return f == null ? null : f.getAbsoluteFile().getCanonicalFile(); 582 } catch (IOException e) { 583 throw new IllegalStateException(e.getLocalizedMessage(), e); 584 } 585 } 586 587 @Override 588 @SuppressWarnings("deprecation") 589 protected boolean isSkipExecution() { 590 return isSkip() || isSkipTests() || isSkipITs() || isSkipExec(); 591 } 592 593 @Override 594 protected String getPluginName() { 595 return "failsafe"; 596 } 597 598 @Override 599 protected String[] getDefaultIncludes() { 600 return new String[] {"**/IT*.java", "**/*IT.java", "**/*ITCase.java"}; 601 } 602 603 @Override 604 protected String getReportSchemaLocation() { 605 return "https://maven.apache.org/surefire/maven-failsafe-plugin/xsd/failsafe-test-report.xsd"; 606 } 607 608 @Override 609 public boolean isSkipTests() { 610 return skipTests; 611 } 612 613 @Override 614 @Deprecated 615 public void setSkipTests(boolean skipTests) { 616 this.skipTests = skipTests; 617 } 618 619 public boolean isSkipITs() { 620 return skipITs; 621 } 622 623 public void setSkipITs(boolean skipITs) { 624 this.skipITs = skipITs; 625 } 626 627 @Override 628 @Deprecated 629 public boolean isSkipExec() { 630 return skipExec; 631 } 632 633 @Override 634 @Deprecated 635 public void setSkipExec(boolean skipExec) { 636 this.skipExec = skipExec; 637 } 638 639 @Override 640 public boolean isSkip() { 641 return skip; 642 } 643 644 @Override 645 public void setSkip(boolean skip) { 646 this.skip = skip; 647 } 648 649 @Override 650 public File getBasedir() { 651 return basedir; 652 } 653 654 @Override 655 public void setBasedir(File basedir) { 656 this.basedir = basedir; 657 } 658 659 @Override 660 public File getTestClassesDirectory() { 661 return testClassesDirectory; 662 } 663 664 @Override 665 public void setTestClassesDirectory(File testClassesDirectory) { 666 this.testClassesDirectory = testClassesDirectory; 667 } 668 669 /** 670 * @return Output directory, or artifact file if artifact type is "jar". If not forking the JVM, parameter 671 * {@link #useSystemClassLoader} is ignored and the {@link org.apache.maven.surefire.booter.IsolatedClassLoader} is 672 * used instead. See the resolution of {@link #getClassLoaderConfiguration() ClassLoaderConfiguration}. 673 */ 674 @Override 675 public File getMainBuildPath() { 676 File artifact = getProject().getArtifact().getFile(); 677 boolean isDefaultClsDir = classesDirectory == null; 678 return isDefaultClsDir ? (isJarArtifact(artifact) ? artifact : defaultClassesDirectory) : classesDirectory; 679 } 680 681 @Override 682 public void setMainBuildPath(File mainBuildPath) { 683 classesDirectory = toAbsoluteCanonical(mainBuildPath); 684 } 685 686 public void setDefaultClassesDirectory(File defaultClassesDirectory) { 687 this.defaultClassesDirectory = toAbsoluteCanonical(defaultClassesDirectory); 688 } 689 690 @Override 691 public File getReportsDirectory() { 692 return reportsDirectory; 693 } 694 695 @Override 696 public void setReportsDirectory(File reportsDirectory) { 697 this.reportsDirectory = reportsDirectory; 698 } 699 700 @Override 701 public String getTest() { 702 return test; 703 } 704 705 @Override 706 public void setTest(String test) { 707 this.test = test; 708 } 709 710 public File getSummaryFile() { 711 return summaryFile; 712 } 713 714 public void setSummaryFile(File summaryFile) { 715 this.summaryFile = summaryFile; 716 } 717 718 @Override 719 public boolean isPrintSummary() { 720 return printSummary; 721 } 722 723 @Override 724 public void setPrintSummary(boolean printSummary) { 725 this.printSummary = printSummary; 726 } 727 728 @Override 729 public String getReportFormat() { 730 return reportFormat; 731 } 732 733 @Override 734 public void setReportFormat(String reportFormat) { 735 this.reportFormat = reportFormat; 736 } 737 738 @Override 739 public boolean isUseFile() { 740 return useFile; 741 } 742 743 @Override 744 public void setUseFile(boolean useFile) { 745 this.useFile = useFile; 746 } 747 748 @Override 749 public String getDebugForkedProcess() { 750 return debugForkedProcess; 751 } 752 753 @Override 754 public void setDebugForkedProcess(String debugForkedProcess) { 755 this.debugForkedProcess = debugForkedProcess; 756 } 757 758 @Override 759 public int getForkedProcessTimeoutInSeconds() { 760 return forkedProcessTimeoutInSeconds; 761 } 762 763 @Override 764 public void setForkedProcessTimeoutInSeconds(int forkedProcessTimeoutInSeconds) { 765 this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds; 766 } 767 768 @Override 769 public int getForkedProcessExitTimeoutInSeconds() { 770 return forkedProcessExitTimeoutInSeconds; 771 } 772 773 @Override 774 public void setForkedProcessExitTimeoutInSeconds(int forkedProcessExitTimeoutInSeconds) { 775 this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds; 776 } 777 778 @Override 779 public double getParallelTestsTimeoutInSeconds() { 780 return parallelTestsTimeoutInSeconds; 781 } 782 783 @Override 784 public void setParallelTestsTimeoutInSeconds(double parallelTestsTimeoutInSeconds) { 785 this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds; 786 } 787 788 @Override 789 public double getParallelTestsTimeoutForcedInSeconds() { 790 return parallelTestsTimeoutForcedInSeconds; 791 } 792 793 @Override 794 public void setParallelTestsTimeoutForcedInSeconds(double parallelTestsTimeoutForcedInSeconds) { 795 this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds; 796 } 797 798 @Override 799 public boolean isUseSystemClassLoader() { 800 return useSystemClassLoader; 801 } 802 803 @Override 804 public void setUseSystemClassLoader(boolean useSystemClassLoader) { 805 this.useSystemClassLoader = useSystemClassLoader; 806 } 807 808 @Override 809 public boolean isUseManifestOnlyJar() { 810 return useManifestOnlyJar; 811 } 812 813 @Override 814 public void setUseManifestOnlyJar(boolean useManifestOnlyJar) { 815 this.useManifestOnlyJar = useManifestOnlyJar; 816 } 817 818 @Override 819 public String getEncoding() { 820 return encoding; 821 } 822 823 @Override 824 public void setEncoding(String encoding) { 825 this.encoding = encoding; 826 } 827 828 // the following will be refactored out once the common code is all in one place 829 830 public boolean isTestFailureIgnore() { 831 return true; // ignore 832 } 833 834 public void setTestFailureIgnore(boolean testFailureIgnore) { 835 // ignore 836 } 837 838 @Override 839 protected void addPluginSpecificChecksumItems(ChecksumCalculator checksum) { 840 checksum.add(skipITs); 841 checksum.add(summaryFile); 842 } 843 844 @Override 845 public File getSystemPropertiesFile() { 846 return systemPropertiesFile; 847 } 848 849 @Override 850 public void setSystemPropertiesFile(File systemPropertiesFile) { 851 this.systemPropertiesFile = systemPropertiesFile; 852 } 853 854 @Override 855 @SuppressWarnings("deprecation") 856 public boolean getFailIfNoSpecifiedTests() { 857 if (!failIfNoSpecifiedTestsDeprecated) { 858 getConsoleLogger() 859 .warning("Use " + getPluginName() 860 + ".failIfNoSpecifiedTests property instead of obsolete it.failIfNoSpecifiedTests."); 861 } 862 // since both have default "true", assuming that any "false" is set by user on purpose 863 return failIfNoSpecifiedTests && failIfNoSpecifiedTestsDeprecated; 864 } 865 866 @Override 867 public void setFailIfNoSpecifiedTests(boolean failIfNoSpecifiedTests) { 868 this.failIfNoSpecifiedTests = failIfNoSpecifiedTests; 869 } 870 871 @Override 872 public int getSkipAfterFailureCount() { 873 return skipAfterFailureCount; 874 } 875 876 @Override 877 public String getShutdown() { 878 return shutdown; 879 } 880 881 @Override 882 public List<String> getIncludes() { 883 return includes; 884 } 885 886 @Override 887 public void setIncludes(List<String> includes) { 888 this.includes = includes; 889 } 890 891 @Override 892 public List<String> getExcludes() { 893 return excludes; 894 } 895 896 @Override 897 public void setExcludes(List<String> excludes) { 898 this.excludes = excludes; 899 } 900 901 @Override 902 public File[] getSuiteXmlFiles() { 903 return suiteXmlFiles.clone(); 904 } 905 906 @Override 907 @SuppressWarnings("UnusedDeclaration") 908 public void setSuiteXmlFiles(File[] suiteXmlFiles) { 909 this.suiteXmlFiles = suiteXmlFiles.clone(); 910 } 911 912 @Override 913 public String getRunOrder() { 914 return runOrder; 915 } 916 917 @Override 918 @SuppressWarnings("UnusedDeclaration") 919 public void setRunOrder(String runOrder) { 920 this.runOrder = runOrder; 921 } 922 923 @Override 924 public Long getRunOrderRandomSeed() { 925 return runOrderRandomSeed; 926 } 927 928 @Override 929 public void setRunOrderRandomSeed(Long runOrderRandomSeed) { 930 this.runOrderRandomSeed = runOrderRandomSeed; 931 } 932 933 @Override 934 public File getIncludesFile() { 935 return includesFile; 936 } 937 938 @Override 939 public File getExcludesFile() { 940 return excludesFile; 941 } 942 943 @Override 944 protected boolean useModulePath() { 945 return useModulePath; 946 } 947 948 @Override 949 protected void setUseModulePath(boolean useModulePath) { 950 this.useModulePath = useModulePath; 951 } 952 953 @Override 954 protected final List<File> suiteXmlFiles() { 955 return hasSuiteXmlFiles() ? Arrays.asList(suiteXmlFiles) : Collections.<File>emptyList(); 956 } 957 958 @Override 959 protected final boolean hasSuiteXmlFiles() { 960 return suiteXmlFiles != null && suiteXmlFiles.length != 0; 961 } 962 963 @Override 964 protected final ForkNodeFactory getForkNode() { 965 return forkNode; 966 } 967 968 @Override 969 protected final String[] getExcludedEnvironmentVariables() { 970 return excludedEnvironmentVariables == null ? new String[0] : excludedEnvironmentVariables; 971 } 972 973 void setExcludedEnvironmentVariables(String[] excludedEnvironmentVariables) { 974 this.excludedEnvironmentVariables = excludedEnvironmentVariables; 975 } 976 977 @Override 978 protected final String getEnableProcessChecker() { 979 return enableProcessChecker; 980 } 981 982 public String[] getIncludeJUnit5Engines() { 983 return includeJUnit5Engines; 984 } 985 986 @SuppressWarnings("UnusedDeclaration") 987 public void setIncludeJUnit5Engines(String[] includeJUnit5Engines) { 988 this.includeJUnit5Engines = includeJUnit5Engines; 989 } 990 991 public String[] getExcludeJUnit5Engines() { 992 return excludeJUnit5Engines; 993 } 994 995 @SuppressWarnings("UnusedDeclaration") 996 public void setExcludeJUnit5Engines(String[] excludeJUnit5Engines) { 997 this.excludeJUnit5Engines = excludeJUnit5Engines; 998 } 999 }