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