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 @Parameter(property = "failsafe.systemPropertiesFile") 529 private File systemPropertiesFile; 530 531 /** 532 * Provide the ID/s of an JUnit engine to be included in the test run. 533 * 534 * @since 3.0.0-M6 535 */ 536 @Parameter(property = "failsafe.includeJUnit5Engines") 537 private String[] includeJUnit5Engines; 538 539 /** 540 * Provide the ID/s of an JUnit engine to be excluded in the test run. 541 * 542 * @since 3.0.0-M6 543 */ 544 @Parameter(property = "failsafe.excludeJUnit5Engines") 545 private String[] excludeJUnit5Engines; 546 547 @Override 548 protected int getRerunFailingTestsCount() { 549 return rerunFailingTestsCount; 550 } 551 552 @Override 553 @SuppressWarnings("unchecked") 554 protected void handleSummary(RunResult summary, Exception firstForkException) 555 throws MojoExecutionException, MojoFailureException { 556 try { 557 if (!summary.isNoTestsRun()) { 558 Object token = getPluginContext().get(FAILSAFE_IN_PROGRESS_CONTEXT_KEY); 559 writeSummary(summary, getSummaryFile(), token != null); 560 } 561 } catch (Exception e) { 562 throw new MojoExecutionException(e.getMessage(), e); 563 } 564 565 getPluginContext().put(FAILSAFE_IN_PROGRESS_CONTEXT_KEY, FAILSAFE_IN_PROGRESS_CONTEXT_KEY); 566 } 567 568 private boolean isJarArtifact(File artifactFile) { 569 return artifactFile != null 570 && artifactFile.isFile() 571 && artifactFile.getName().toLowerCase().endsWith(".jar"); 572 } 573 574 private static File toAbsoluteCanonical(File f) { 575 try { 576 return f == null ? null : f.getAbsoluteFile().getCanonicalFile(); 577 } catch (IOException e) { 578 throw new IllegalStateException(e.getLocalizedMessage(), e); 579 } 580 } 581 582 @Override 583 @SuppressWarnings("deprecation") 584 protected boolean isSkipExecution() { 585 return isSkip() || isSkipTests() || isSkipITs() || isSkipExec(); 586 } 587 588 @Override 589 protected String getPluginName() { 590 return "failsafe"; 591 } 592 593 @Override 594 protected String[] getDefaultIncludes() { 595 return new String[] {"**/IT*.java", "**/*IT.java", "**/*ITCase.java"}; 596 } 597 598 @Override 599 protected String getReportSchemaLocation() { 600 return "https://maven.apache.org/surefire/maven-failsafe-plugin/xsd/failsafe-test-report.xsd"; 601 } 602 603 @Override 604 public boolean isSkipTests() { 605 return skipTests; 606 } 607 608 @Override 609 @Deprecated 610 public void setSkipTests(boolean skipTests) { 611 this.skipTests = skipTests; 612 } 613 614 public boolean isSkipITs() { 615 return skipITs; 616 } 617 618 public void setSkipITs(boolean skipITs) { 619 this.skipITs = skipITs; 620 } 621 622 @Override 623 @Deprecated 624 public boolean isSkipExec() { 625 return skipExec; 626 } 627 628 @Override 629 @Deprecated 630 public void setSkipExec(boolean skipExec) { 631 this.skipExec = skipExec; 632 } 633 634 @Override 635 public boolean isSkip() { 636 return skip; 637 } 638 639 @Override 640 public void setSkip(boolean skip) { 641 this.skip = skip; 642 } 643 644 @Override 645 public File getBasedir() { 646 return basedir; 647 } 648 649 @Override 650 public void setBasedir(File basedir) { 651 this.basedir = basedir; 652 } 653 654 @Override 655 public File getTestClassesDirectory() { 656 return testClassesDirectory; 657 } 658 659 @Override 660 public void setTestClassesDirectory(File testClassesDirectory) { 661 this.testClassesDirectory = testClassesDirectory; 662 } 663 664 /** 665 * @return Output directory, or artifact file if artifact type is "jar". If not forking the JVM, parameter 666 * {@link #useSystemClassLoader} is ignored and the {@link org.apache.maven.surefire.booter.IsolatedClassLoader} is 667 * used instead. See the resolution of {@link #getClassLoaderConfiguration() ClassLoaderConfiguration}. 668 */ 669 @Override 670 public File getMainBuildPath() { 671 File artifact = getProject().getArtifact().getFile(); 672 boolean isDefaultClsDir = classesDirectory == null; 673 return isDefaultClsDir ? (isJarArtifact(artifact) ? artifact : defaultClassesDirectory) : classesDirectory; 674 } 675 676 @Override 677 public void setMainBuildPath(File mainBuildPath) { 678 classesDirectory = toAbsoluteCanonical(mainBuildPath); 679 } 680 681 public void setDefaultClassesDirectory(File defaultClassesDirectory) { 682 this.defaultClassesDirectory = toAbsoluteCanonical(defaultClassesDirectory); 683 } 684 685 @Override 686 public File getReportsDirectory() { 687 return reportsDirectory; 688 } 689 690 @Override 691 public void setReportsDirectory(File reportsDirectory) { 692 this.reportsDirectory = reportsDirectory; 693 } 694 695 @Override 696 public String getTest() { 697 return test; 698 } 699 700 @Override 701 public void setTest(String test) { 702 this.test = test; 703 } 704 705 public File getSummaryFile() { 706 return summaryFile; 707 } 708 709 public void setSummaryFile(File summaryFile) { 710 this.summaryFile = summaryFile; 711 } 712 713 @Override 714 public boolean isPrintSummary() { 715 return printSummary; 716 } 717 718 @Override 719 public void setPrintSummary(boolean printSummary) { 720 this.printSummary = printSummary; 721 } 722 723 @Override 724 public String getReportFormat() { 725 return reportFormat; 726 } 727 728 @Override 729 public void setReportFormat(String reportFormat) { 730 this.reportFormat = reportFormat; 731 } 732 733 @Override 734 public boolean isUseFile() { 735 return useFile; 736 } 737 738 @Override 739 public void setUseFile(boolean useFile) { 740 this.useFile = useFile; 741 } 742 743 @Override 744 public String getDebugForkedProcess() { 745 return debugForkedProcess; 746 } 747 748 @Override 749 public void setDebugForkedProcess(String debugForkedProcess) { 750 this.debugForkedProcess = debugForkedProcess; 751 } 752 753 @Override 754 public int getForkedProcessTimeoutInSeconds() { 755 return forkedProcessTimeoutInSeconds; 756 } 757 758 @Override 759 public void setForkedProcessTimeoutInSeconds(int forkedProcessTimeoutInSeconds) { 760 this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds; 761 } 762 763 @Override 764 public int getForkedProcessExitTimeoutInSeconds() { 765 return forkedProcessExitTimeoutInSeconds; 766 } 767 768 @Override 769 public void setForkedProcessExitTimeoutInSeconds(int forkedProcessExitTimeoutInSeconds) { 770 this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds; 771 } 772 773 @Override 774 public double getParallelTestsTimeoutInSeconds() { 775 return parallelTestsTimeoutInSeconds; 776 } 777 778 @Override 779 public void setParallelTestsTimeoutInSeconds(double parallelTestsTimeoutInSeconds) { 780 this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds; 781 } 782 783 @Override 784 public double getParallelTestsTimeoutForcedInSeconds() { 785 return parallelTestsTimeoutForcedInSeconds; 786 } 787 788 @Override 789 public void setParallelTestsTimeoutForcedInSeconds(double parallelTestsTimeoutForcedInSeconds) { 790 this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds; 791 } 792 793 @Override 794 public boolean isUseSystemClassLoader() { 795 return useSystemClassLoader; 796 } 797 798 @Override 799 public void setUseSystemClassLoader(boolean useSystemClassLoader) { 800 this.useSystemClassLoader = useSystemClassLoader; 801 } 802 803 @Override 804 public boolean isUseManifestOnlyJar() { 805 return useManifestOnlyJar; 806 } 807 808 @Override 809 public void setUseManifestOnlyJar(boolean useManifestOnlyJar) { 810 this.useManifestOnlyJar = useManifestOnlyJar; 811 } 812 813 @Override 814 public String getEncoding() { 815 return encoding; 816 } 817 818 @Override 819 public void setEncoding(String encoding) { 820 this.encoding = encoding; 821 } 822 823 // the following will be refactored out once the common code is all in one place 824 825 public boolean isTestFailureIgnore() { 826 return true; // ignore 827 } 828 829 public void setTestFailureIgnore(boolean testFailureIgnore) { 830 // ignore 831 } 832 833 @Override 834 protected void addPluginSpecificChecksumItems(ChecksumCalculator checksum) { 835 checksum.add(skipITs); 836 checksum.add(summaryFile); 837 } 838 839 @Override 840 public File getSystemPropertiesFile() { 841 return systemPropertiesFile; 842 } 843 844 @Override 845 public void setSystemPropertiesFile(File systemPropertiesFile) { 846 this.systemPropertiesFile = systemPropertiesFile; 847 } 848 849 @Override 850 @SuppressWarnings("deprecation") 851 public boolean getFailIfNoSpecifiedTests() { 852 if (!failIfNoSpecifiedTestsDeprecated) { 853 getConsoleLogger() 854 .warning("Use " + getPluginName() 855 + ".failIfNoSpecifiedTests property instead of obsolete it.failIfNoSpecifiedTests."); 856 } 857 // since both have default "true", assuming that any "false" is set by user on purpose 858 return failIfNoSpecifiedTests && failIfNoSpecifiedTestsDeprecated; 859 } 860 861 @Override 862 public void setFailIfNoSpecifiedTests(boolean failIfNoSpecifiedTests) { 863 this.failIfNoSpecifiedTests = failIfNoSpecifiedTests; 864 } 865 866 @Override 867 public int getSkipAfterFailureCount() { 868 return skipAfterFailureCount; 869 } 870 871 @Override 872 public String getShutdown() { 873 return shutdown; 874 } 875 876 @Override 877 public List<String> getIncludes() { 878 return includes; 879 } 880 881 @Override 882 public void setIncludes(List<String> includes) { 883 this.includes = includes; 884 } 885 886 @Override 887 public List<String> getExcludes() { 888 return excludes; 889 } 890 891 @Override 892 public void setExcludes(List<String> excludes) { 893 this.excludes = excludes; 894 } 895 896 @Override 897 public File[] getSuiteXmlFiles() { 898 return suiteXmlFiles.clone(); 899 } 900 901 @Override 902 @SuppressWarnings("UnusedDeclaration") 903 public void setSuiteXmlFiles(File[] suiteXmlFiles) { 904 this.suiteXmlFiles = suiteXmlFiles.clone(); 905 } 906 907 @Override 908 public String getRunOrder() { 909 return runOrder; 910 } 911 912 @Override 913 @SuppressWarnings("UnusedDeclaration") 914 public void setRunOrder(String runOrder) { 915 this.runOrder = runOrder; 916 } 917 918 @Override 919 public Long getRunOrderRandomSeed() { 920 return runOrderRandomSeed; 921 } 922 923 @Override 924 public void setRunOrderRandomSeed(Long runOrderRandomSeed) { 925 this.runOrderRandomSeed = runOrderRandomSeed; 926 } 927 928 @Override 929 public File getIncludesFile() { 930 return includesFile; 931 } 932 933 @Override 934 public File getExcludesFile() { 935 return excludesFile; 936 } 937 938 @Override 939 protected boolean useModulePath() { 940 return useModulePath; 941 } 942 943 @Override 944 protected void setUseModulePath(boolean useModulePath) { 945 this.useModulePath = useModulePath; 946 } 947 948 @Override 949 protected final List<File> suiteXmlFiles() { 950 return hasSuiteXmlFiles() ? Arrays.asList(suiteXmlFiles) : Collections.<File>emptyList(); 951 } 952 953 @Override 954 protected final boolean hasSuiteXmlFiles() { 955 return suiteXmlFiles != null && suiteXmlFiles.length != 0; 956 } 957 958 @Override 959 protected final ForkNodeFactory getForkNode() { 960 return forkNode; 961 } 962 963 @Override 964 protected final String[] getExcludedEnvironmentVariables() { 965 return excludedEnvironmentVariables == null ? new String[0] : excludedEnvironmentVariables; 966 } 967 968 void setExcludedEnvironmentVariables(String[] excludedEnvironmentVariables) { 969 this.excludedEnvironmentVariables = excludedEnvironmentVariables; 970 } 971 972 @Override 973 protected final String getEnableProcessChecker() { 974 return enableProcessChecker; 975 } 976 977 public String[] getIncludeJUnit5Engines() { 978 return includeJUnit5Engines; 979 } 980 981 @SuppressWarnings("UnusedDeclaration") 982 public void setIncludeJUnit5Engines(String[] includeJUnit5Engines) { 983 this.includeJUnit5Engines = includeJUnit5Engines; 984 } 985 986 public String[] getExcludeJUnit5Engines() { 987 return excludeJUnit5Engines; 988 } 989 990 @SuppressWarnings("UnusedDeclaration") 991 public void setExcludeJUnit5Engines(String[] excludeJUnit5Engines) { 992 this.excludeJUnit5Engines = excludeJUnit5Engines; 993 } 994 }