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