1 package org.apache.maven.plugin.failsafe;
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22 import org.apache.maven.plugin.MojoExecutionException;
23 import org.apache.maven.plugin.MojoFailureException;
24 import org.apache.maven.plugin.surefire.AbstractSurefireMojo;
25 import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
26 import org.apache.maven.plugins.annotations.LifecyclePhase;
27 import org.apache.maven.plugins.annotations.Mojo;
28 import org.apache.maven.plugins.annotations.Parameter;
29 import org.apache.maven.plugins.annotations.ResolutionScope;
30 import org.apache.maven.surefire.suite.RunResult;
31
32 import java.io.File;
33 import java.io.IOException;
34 import java.util.Arrays;
35 import java.util.Collections;
36 import java.util.List;
37
38 import static org.apache.maven.plugin.failsafe.util.FailsafeSummaryXmlUtils.writeSummary;
39
40
41
42
43
44
45
46 @Mojo( name = "integration-test", requiresProject = true, requiresDependencyResolution = ResolutionScope.TEST,
47 defaultPhase = LifecyclePhase.INTEGRATION_TEST, threadSafe = true )
48 public class IntegrationTestMojo
49 extends AbstractSurefireMojo
50 {
51
52 private static final String FAILSAFE_IN_PROGRESS_CONTEXT_KEY = "failsafe-in-progress";
53
54
55
56
57
58
59 @Parameter
60 private File classesDirectory;
61
62 @Parameter( defaultValue = "${project.build.outputDirectory}", readonly = true, required = true )
63 private File defaultClassesDirectory;
64
65
66
67
68
69
70
71 @Parameter( property = "skipITs" )
72 private boolean skipITs;
73
74
75
76
77 @Parameter( defaultValue = "${project.build.directory}/failsafe-reports" )
78 private File reportsDirectory;
79
80 @SuppressWarnings( "checkstyle:linelength" )
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103 @Parameter( property = "it.test" )
104 private String test;
105
106
107
108
109 @Parameter( defaultValue = "${project.build.directory}/failsafe-reports/failsafe-summary.xml", required = true )
110 private File summaryFile;
111
112
113
114
115 @Parameter( property = "failsafe.printSummary", defaultValue = "true" )
116 private boolean printSummary;
117
118
119
120
121
122 @Parameter( property = "failsafe.reportFormat", defaultValue = "brief" )
123 private String reportFormat;
124
125
126
127
128 @Parameter( property = "failsafe.useFile", defaultValue = "true" )
129 private boolean useFile;
130
131
132
133
134
135
136
137 @Parameter( property = "it.failIfNoSpecifiedTests" )
138 private Boolean failIfNoSpecifiedTests;
139
140
141
142
143
144
145
146
147
148 @Parameter( property = "maven.failsafe.debug" )
149 private String debugForkedProcess;
150
151
152
153
154
155
156
157 @Parameter( property = "failsafe.timeout" )
158 private int forkedProcessTimeoutInSeconds;
159
160
161
162
163
164
165
166
167
168
169 @Parameter( property = "failsafe.exitTimeout", defaultValue = "30" )
170 private int forkedProcessExitTimeoutInSeconds;
171
172
173
174
175
176
177
178
179
180
181
182 @Parameter( property = "failsafe.parallel.timeout" )
183 private double parallelTestsTimeoutInSeconds;
184
185
186
187
188
189
190
191
192
193
194
195
196 @Parameter( property = "failsafe.parallel.forcedTimeout" )
197 private double parallelTestsTimeoutForcedInSeconds;
198
199 @SuppressWarnings( "checkstyle:linelength" )
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227 @Parameter
228 private List<String> includes;
229
230
231
232
233
234
235
236
237 @Parameter( property = "failsafe.useSystemClassLoader", defaultValue = "true" )
238 private boolean useSystemClassLoader;
239
240
241
242
243
244
245
246
247
248
249
250
251 @Parameter( property = "failsafe.useManifestOnlyJar", defaultValue = "true" )
252 private boolean useManifestOnlyJar;
253
254
255
256
257
258
259
260
261 @Parameter( property = "encoding", defaultValue = "${project.reporting.outputEncoding}" )
262 private String encoding;
263
264
265
266
267
268
269
270 @Parameter( property = "failsafe.rerunFailingTestsCount", defaultValue = "0" )
271 private int rerunFailingTestsCount;
272
273
274
275
276
277
278
279
280
281
282 @Parameter( property = "failsafe.suiteXmlFiles" )
283 private File[] suiteXmlFiles;
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309 @Parameter( property = "failsafe.runOrder", defaultValue = "filesystem" )
310 private String runOrder;
311
312
313
314
315
316
317
318
319
320
321
322
323
324 @Parameter( property = "failsafe.includesFile" )
325 private File includesFile;
326
327
328
329
330
331
332
333
334
335
336
337
338
339 @Parameter( property = "failsafe.excludesFile" )
340 private File excludesFile;
341
342
343
344
345
346
347
348
349
350
351
352
353 @Parameter( property = "failsafe.skipAfterFailureCount", defaultValue = "0" )
354 private int skipAfterFailureCount;
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373 @Parameter( property = "failsafe.shutdown", defaultValue = "exit" )
374 private String shutdown;
375
376
377
378
379
380
381
382
383
384 @Parameter( property = "failsafe.useModulePath", defaultValue = "true" )
385 private boolean useModulePath;
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400 @Parameter( property = "failsafe.excludedEnvironmentVariables" )
401 private String[] excludedEnvironmentVariables;
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441 @Parameter( property = "failsafe.enableProcessChecker" )
442 private String enableProcessChecker;
443
444 @Override
445 protected int getRerunFailingTestsCount()
446 {
447 return rerunFailingTestsCount;
448 }
449
450 @Override
451 @SuppressWarnings( "unchecked" )
452 protected void handleSummary( RunResult summary, Exception firstForkException )
453 throws MojoExecutionException, MojoFailureException
454 {
455 File summaryFile = getSummaryFile();
456 if ( !summaryFile.getParentFile().isDirectory() )
457 {
458
459 summaryFile.getParentFile().mkdirs();
460 }
461
462 try
463 {
464 Object token = getPluginContext().get( FAILSAFE_IN_PROGRESS_CONTEXT_KEY );
465 writeSummary( summary, summaryFile, token != null );
466 }
467 catch ( Exception e )
468 {
469 throw new MojoExecutionException( e.getMessage(), e );
470 }
471
472 getPluginContext().put( FAILSAFE_IN_PROGRESS_CONTEXT_KEY, FAILSAFE_IN_PROGRESS_CONTEXT_KEY );
473 }
474
475 private boolean isJarArtifact( File artifactFile )
476 {
477 return artifactFile != null && artifactFile.isFile() && artifactFile.getName().toLowerCase().endsWith( ".jar" );
478 }
479
480 private static File toAbsoluteCanonical( File f )
481 {
482 try
483 {
484 return f == null ? null : f.getAbsoluteFile().getCanonicalFile();
485 }
486 catch ( IOException e )
487 {
488 throw new IllegalStateException( e.getLocalizedMessage(), e );
489 }
490 }
491
492 @Override
493 @SuppressWarnings( "deprecation" )
494 protected boolean isSkipExecution()
495 {
496 return isSkip() || isSkipTests() || isSkipITs() || isSkipExec();
497 }
498
499 @Override
500 protected String getPluginName()
501 {
502 return "failsafe";
503 }
504
505 @Override
506 protected String[] getDefaultIncludes()
507 {
508 return new String[]{ "**/IT*.java", "**/*IT.java", "**/*ITCase.java" };
509 }
510
511 @Override
512 protected String getReportSchemaLocation()
513 {
514 return "https://maven.apache.org/surefire/maven-failsafe-plugin/xsd/failsafe-test-report-3.0.xsd";
515 }
516
517 @Override
518 public boolean isSkipTests()
519 {
520 return skipTests;
521 }
522
523 @Override
524 @Deprecated
525 public void setSkipTests( boolean skipTests )
526 {
527 this.skipTests = skipTests;
528 }
529
530 public boolean isSkipITs()
531 {
532 return skipITs;
533 }
534
535 public void setSkipITs( boolean skipITs )
536 {
537 this.skipITs = skipITs;
538 }
539
540 @Override
541 @SuppressWarnings( "deprecation" )
542 @Deprecated
543 public boolean isSkipExec()
544 {
545 return skipExec;
546 }
547
548 @Override
549 @SuppressWarnings( "deprecation" )
550 @Deprecated
551 public void setSkipExec( boolean skipExec )
552 {
553 this.skipExec = skipExec;
554 }
555
556 @Override
557 public boolean isSkip()
558 {
559 return skip;
560 }
561
562 @Override
563 public void setSkip( boolean skip )
564 {
565 this.skip = skip;
566 }
567
568 @Override
569 public File getBasedir()
570 {
571 return basedir;
572 }
573
574 @Override
575 public void setBasedir( File basedir )
576 {
577 this.basedir = basedir;
578 }
579
580 @Override
581 public File getTestClassesDirectory()
582 {
583 return testClassesDirectory;
584 }
585
586 @Override
587 public void setTestClassesDirectory( File testClassesDirectory )
588 {
589 this.testClassesDirectory = testClassesDirectory;
590 }
591
592
593
594
595
596
597 @Override
598 public File getClassesDirectory()
599 {
600 File artifact = getProject().getArtifact().getFile();
601 boolean isDefaultClsDir = classesDirectory == null;
602 return isDefaultClsDir ? ( isJarArtifact( artifact ) ? artifact : defaultClassesDirectory ) : classesDirectory;
603 }
604
605 @Override
606 public void setClassesDirectory( File classesDirectory )
607 {
608 this.classesDirectory = toAbsoluteCanonical( classesDirectory );
609 }
610
611 public void setDefaultClassesDirectory( File defaultClassesDirectory )
612 {
613 this.defaultClassesDirectory = toAbsoluteCanonical( defaultClassesDirectory );
614 }
615
616 @Override
617 public File getReportsDirectory()
618 {
619 return reportsDirectory;
620 }
621
622 @Override
623 public void setReportsDirectory( File reportsDirectory )
624 {
625 this.reportsDirectory = reportsDirectory;
626 }
627
628 @Override
629 public String getTest()
630 {
631 return test;
632 }
633
634 @Override
635 public void setTest( String test )
636 {
637 this.test = test;
638 }
639
640 public File getSummaryFile()
641 {
642 return summaryFile;
643 }
644
645 public void setSummaryFile( File summaryFile )
646 {
647 this.summaryFile = summaryFile;
648 }
649
650 @Override
651 public boolean isPrintSummary()
652 {
653 return printSummary;
654 }
655
656 @Override
657 public void setPrintSummary( boolean printSummary )
658 {
659 this.printSummary = printSummary;
660 }
661
662 @Override
663 public String getReportFormat()
664 {
665 return reportFormat;
666 }
667
668 @Override
669 public void setReportFormat( String reportFormat )
670 {
671 this.reportFormat = reportFormat;
672 }
673
674 @Override
675 public boolean isUseFile()
676 {
677 return useFile;
678 }
679
680 @Override
681 public void setUseFile( boolean useFile )
682 {
683 this.useFile = useFile;
684 }
685
686 @Override
687 public String getDebugForkedProcess()
688 {
689 return debugForkedProcess;
690 }
691
692 @Override
693 public void setDebugForkedProcess( String debugForkedProcess )
694 {
695 this.debugForkedProcess = debugForkedProcess;
696 }
697
698 @Override
699 public int getForkedProcessTimeoutInSeconds()
700 {
701 return forkedProcessTimeoutInSeconds;
702 }
703
704 @Override
705 public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
706 {
707 this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
708 }
709
710 @Override
711 public int getForkedProcessExitTimeoutInSeconds()
712 {
713 return forkedProcessExitTimeoutInSeconds;
714 }
715
716 @Override
717 public void setForkedProcessExitTimeoutInSeconds( int forkedProcessExitTimeoutInSeconds )
718 {
719 this.forkedProcessExitTimeoutInSeconds = forkedProcessExitTimeoutInSeconds;
720 }
721
722 @Override
723 public double getParallelTestsTimeoutInSeconds()
724 {
725 return parallelTestsTimeoutInSeconds;
726 }
727
728 @Override
729 public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
730 {
731 this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds;
732 }
733
734 @Override
735 public double getParallelTestsTimeoutForcedInSeconds()
736 {
737 return parallelTestsTimeoutForcedInSeconds;
738 }
739
740 @Override
741 public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
742 {
743 this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds;
744 }
745
746 @Override
747 public boolean isUseSystemClassLoader()
748 {
749 return useSystemClassLoader;
750 }
751
752 @Override
753 public void setUseSystemClassLoader( boolean useSystemClassLoader )
754 {
755 this.useSystemClassLoader = useSystemClassLoader;
756 }
757
758 @Override
759 public boolean isUseManifestOnlyJar()
760 {
761 return useManifestOnlyJar;
762 }
763
764 @Override
765 public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
766 {
767 this.useManifestOnlyJar = useManifestOnlyJar;
768 }
769
770 @Override
771 public String getEncoding()
772 {
773 return encoding;
774 }
775
776 @Override
777 public void setEncoding( String encoding )
778 {
779 this.encoding = encoding;
780 }
781
782
783
784 public boolean isTestFailureIgnore()
785 {
786 return true;
787 }
788
789 public void setTestFailureIgnore( boolean testFailureIgnore )
790 {
791
792 }
793
794 @Override
795 protected void addPluginSpecificChecksumItems( ChecksumCalculator checksum )
796 {
797 checksum.add( skipITs );
798 checksum.add( summaryFile );
799 }
800
801 @Override
802 public Boolean getFailIfNoSpecifiedTests()
803 {
804 return failIfNoSpecifiedTests;
805 }
806
807 @Override
808 public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
809 {
810 this.failIfNoSpecifiedTests = failIfNoSpecifiedTests;
811 }
812
813 @Override
814 public int getSkipAfterFailureCount()
815 {
816 return skipAfterFailureCount;
817 }
818
819 @Override
820 public String getShutdown()
821 {
822 return shutdown;
823 }
824
825 @Override
826 public List<String> getIncludes()
827 {
828 return includes;
829 }
830
831 @Override
832 public void setIncludes( List<String> includes )
833 {
834 this.includes = includes;
835 }
836
837 @Override
838 public File[] getSuiteXmlFiles()
839 {
840 return suiteXmlFiles.clone();
841 }
842
843 @Override
844 @SuppressWarnings( "UnusedDeclaration" )
845 public void setSuiteXmlFiles( File[] suiteXmlFiles )
846 {
847 this.suiteXmlFiles = suiteXmlFiles.clone();
848 }
849
850 @Override
851 public String getRunOrder()
852 {
853 return runOrder;
854 }
855
856 @Override
857 @SuppressWarnings( "UnusedDeclaration" )
858 public void setRunOrder( String runOrder )
859 {
860 this.runOrder = runOrder;
861 }
862
863 @Override
864 public File getIncludesFile()
865 {
866 return includesFile;
867 }
868
869 @Override
870 public File getExcludesFile()
871 {
872 return excludesFile;
873 }
874
875 @Override
876 protected boolean useModulePath()
877 {
878 return useModulePath;
879 }
880
881 @Override
882 protected void setUseModulePath( boolean useModulePath )
883 {
884 this.useModulePath = useModulePath;
885 }
886
887 @Override
888 protected final List<File> suiteXmlFiles()
889 {
890 return hasSuiteXmlFiles() ? Arrays.asList( suiteXmlFiles ) : Collections.<File>emptyList();
891 }
892
893 @Override
894 protected final boolean hasSuiteXmlFiles()
895 {
896 return suiteXmlFiles != null && suiteXmlFiles.length != 0;
897 }
898
899 @Override
900 protected final String[] getExcludedEnvironmentVariables()
901 {
902 return excludedEnvironmentVariables == null ? new String[0] : excludedEnvironmentVariables;
903 }
904
905 void setExcludedEnvironmentVariables( String[] excludedEnvironmentVariables )
906 {
907 this.excludedEnvironmentVariables = excludedEnvironmentVariables;
908 }
909
910 @Override
911 protected final String getEnableProcessChecker()
912 {
913 return enableProcessChecker;
914 }
915 }