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 java.io.File;
23  import java.io.IOException;
24  import java.util.Arrays;
25  import java.util.Collections;
26  import java.util.List;
27  
28  import org.apache.maven.artifact.Artifact;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.MojoFailureException;
31  import org.apache.maven.plugin.surefire.AbstractSurefireMojo;
32  import org.apache.maven.plugin.surefire.booterclient.ChecksumCalculator;
33  import org.apache.maven.plugins.annotations.LifecyclePhase;
34  import org.apache.maven.plugins.annotations.Mojo;
35  import org.apache.maven.plugins.annotations.Parameter;
36  import org.apache.maven.plugins.annotations.ResolutionScope;
37  import org.apache.maven.shared.utils.ReaderFactory;
38  import org.apache.maven.shared.utils.StringUtils;
39  import org.apache.maven.surefire.suite.RunResult;
40  
41  
42  
43  
44  
45  
46  
47  
48  @Mojo( name = "integration-test", requiresProject = true, requiresDependencyResolution = ResolutionScope.TEST,
49         defaultPhase = LifecyclePhase.INTEGRATION_TEST, threadSafe = true )
50  public class IntegrationTestMojo
51      extends AbstractSurefireMojo
52  {
53  
54      private static final String FAILSAFE_IN_PROGRESS_CONTEXT_KEY = "failsafe-in-progress";
55  
56      
57  
58  
59  
60      @Parameter( defaultValue = "${project.build.outputDirectory}" )
61      private File classesDirectory;
62  
63      
64  
65  
66  
67  
68  
69      @Parameter( property = "skipITs" )
70      private boolean skipITs;
71  
72      
73  
74  
75      @Parameter( defaultValue = "${project.build.directory}/failsafe-reports" )
76      private File reportsDirectory;
77  
78      
79  
80  
81  
82  
83  
84  
85  
86  
87  
88  
89  
90  
91  
92  
93  
94  
95  
96  
97  
98      @Parameter( property = "it.test" )
99      private String test;
100 
101     
102 
103 
104     @Parameter( defaultValue = "${project.build.directory}/failsafe-reports/failsafe-summary.xml", required = true )
105     private File summaryFile;
106 
107     
108 
109 
110     @Parameter( property = "failsafe.printSummary", defaultValue = "true" )
111     private boolean printSummary;
112 
113     
114 
115 
116 
117     @Parameter( property = "failsafe.reportFormat", defaultValue = "brief" )
118     private String reportFormat;
119 
120     
121 
122 
123     @Parameter( property = "failsafe.useFile", defaultValue = "true" )
124     private boolean useFile;
125 
126     
127 
128 
129 
130 
131 
132     @Parameter( property = "it.failIfNoSpecifiedTests" )
133     private Boolean failIfNoSpecifiedTests;
134 
135     
136 
137 
138 
139 
140 
141 
142 
143     @Parameter( property = "maven.failsafe.debug" )
144     private String debugForkedProcess;
145 
146     
147 
148 
149 
150 
151 
152     @Parameter( property = "failsafe.timeout" )
153     private int forkedProcessTimeoutInSeconds;
154 
155     
156 
157 
158 
159 
160 
161 
162 
163 
164 
165     @Parameter( property = "failsafe.parallel.timeout" )
166     private double parallelTestsTimeoutInSeconds;
167 
168     
169 
170 
171 
172 
173 
174 
175 
176 
177 
178 
179     @Parameter( property = "failsafe.parallel.forcedTimeout" )
180     private double parallelTestsTimeoutForcedInSeconds;
181 
182     
183 
184 
185 
186 
187 
188 
189 
190 
191 
192 
193 
194 
195 
196 
197 
198 
199 
200 
201 
202 
203 
204 
205     @Parameter
206     private List<String> includes;
207 
208     
209 
210 
211 
212 
213 
214 
215     @Parameter( property = "failsafe.useSystemClassLoader", defaultValue = "true" )
216     private boolean useSystemClassLoader;
217 
218     
219 
220 
221 
222 
223 
224 
225 
226 
227 
228 
229     @Parameter( property = "failsafe.useManifestOnlyJar", defaultValue = "true" )
230     private boolean useManifestOnlyJar;
231 
232     
233 
234 
235     @Parameter( property = "encoding", defaultValue = "${project.reporting.outputEncoding}" )
236     private String encoding;
237 
238     
239 
240 
241 
242 
243 
244     @Parameter( property = "failsafe.rerunFailingTestsCount", defaultValue = "0" )
245     private int rerunFailingTestsCount;
246 
247     
248 
249 
250 
251 
252 
253 
254 
255 
256     @Parameter( property = "failsafe.suiteXmlFiles" )
257     private File[] suiteXmlFiles;
258 
259     
260 
261 
262 
263 
264 
265 
266 
267 
268 
269 
270 
271 
272 
273 
274 
275 
276 
277 
278 
279 
280 
281 
282 
283     @Parameter( property = "failsafe.runOrder", defaultValue = "filesystem" )
284     private String runOrder;
285 
286     
287 
288 
289 
290 
291 
292 
293     @Parameter( property = "failsafe.includesFile" )
294     private File includesFile;
295 
296     
297 
298 
299 
300 
301 
302 
303     @Parameter( property = "failsafe.excludesFile" )
304     private File excludesFile;
305 
306     
307 
308 
309 
310 
311 
312 
313 
314 
315 
316 
317     @Parameter( property = "failsafe.skipAfterFailureCount", defaultValue = "0" )
318     private int skipAfterFailureCount;
319 
320     
321 
322 
323 
324 
325 
326 
327 
328 
329 
330     @Parameter( property = "failsafe.shutdown", defaultValue = "testset" )
331     private String shutdown;
332 
333     protected int getRerunFailingTestsCount()
334     {
335         return rerunFailingTestsCount;
336     }
337 
338     @SuppressWarnings( "unchecked" )
339     protected void handleSummary( RunResult summary, Exception firstForkException )
340         throws MojoExecutionException, MojoFailureException
341     {
342         File summaryFile = getSummaryFile();
343         if ( !summaryFile.getParentFile().isDirectory() )
344         {
345             
346             summaryFile.getParentFile().mkdirs();
347         }
348 
349         try
350         {
351             Object token = getPluginContext().get( FAILSAFE_IN_PROGRESS_CONTEXT_KEY );
352             summary.writeSummary( summaryFile, token != null, getEncodingOrDefault() );
353         }
354         catch ( IOException e )
355         {
356             throw new MojoExecutionException( e.getMessage(), e );
357         }
358 
359         getPluginContext().put( FAILSAFE_IN_PROGRESS_CONTEXT_KEY, FAILSAFE_IN_PROGRESS_CONTEXT_KEY );
360     }
361 
362     private String getEncodingOrDefault()
363     {
364         if ( StringUtils.isEmpty( encoding ) )
365         {
366             getLog().warn( "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
367                            + ", i.e. build is platform dependent! The file encoding for reports output files "
368                                + "should be provided by the POM property ${project.reporting.outputEncoding}." );
369             return ReaderFactory.FILE_ENCODING;
370         }
371         else
372         {
373             return encoding;
374         }
375     }
376 
377     @SuppressWarnings( "deprecation" )
378     protected boolean isSkipExecution()
379     {
380         return isSkip() || isSkipTests() || isSkipITs() || isSkipExec();
381     }
382 
383     protected String getPluginName()
384     {
385         return "failsafe";
386     }
387 
388     protected String[] getDefaultIncludes()
389     {
390         return new String[]{ "**/IT*.java", "**/*IT.java", "**/*ITCase.java" };
391     }
392 
393     public boolean isSkipTests()
394     {
395         return skipTests;
396     }
397 
398     public void setSkipTests( boolean skipTests )
399     {
400         this.skipTests = skipTests;
401     }
402 
403     public boolean isSkipITs()
404     {
405         return skipITs;
406     }
407 
408     public void setSkipITs( boolean skipITs )
409     {
410         this.skipITs = skipITs;
411     }
412 
413     @SuppressWarnings( "deprecation" )
414     @Deprecated
415     public boolean isSkipExec()
416     {
417         return skipExec;
418     }
419 
420     @SuppressWarnings( "deprecation" )
421     @Deprecated
422     public void setSkipExec( boolean skipExec )
423     {
424         this.skipExec = skipExec;
425     }
426 
427     public boolean isSkip()
428     {
429         return skip;
430     }
431 
432     public void setSkip( boolean skip )
433     {
434         this.skip = skip;
435     }
436 
437     public File getBasedir()
438     {
439         return basedir;
440     }
441 
442     public void setBasedir( File basedir )
443     {
444         this.basedir = basedir;
445     }
446 
447     public File getTestClassesDirectory()
448     {
449         return testClassesDirectory;
450     }
451 
452     public void setTestClassesDirectory( File testClassesDirectory )
453     {
454         this.testClassesDirectory = testClassesDirectory;
455     }
456 
457     
458 
459 
460 
461 
462     public File getClassesDirectory()
463     {
464         Artifact artifact = getProject().getArtifact();
465         File artifactFile = artifact.getFile();
466 
467         boolean useArtifactFile = artifactFile != null && artifactFile.isFile()
468             && artifactFile.getName().toLowerCase().endsWith( ".jar" );
469 
470         return useArtifactFile ? artifactFile : classesDirectory;
471     }
472 
473     public void setClassesDirectory( File classesDirectory )
474     {
475         this.classesDirectory = classesDirectory;
476     }
477 
478     public File getReportsDirectory()
479     {
480         return reportsDirectory;
481     }
482 
483     public void setReportsDirectory( File reportsDirectory )
484     {
485         this.reportsDirectory = reportsDirectory;
486     }
487 
488     public String getTest()
489     {
490         return test;
491     }
492 
493     public void setTest( String test )
494     {
495         this.test = test;
496     }
497 
498     public File getSummaryFile()
499     {
500         return summaryFile;
501     }
502 
503     public void setSummaryFile( File summaryFile )
504     {
505         this.summaryFile = summaryFile;
506     }
507 
508     public boolean isPrintSummary()
509     {
510         return printSummary;
511     }
512 
513     public void setPrintSummary( boolean printSummary )
514     {
515         this.printSummary = printSummary;
516     }
517 
518     public String getReportFormat()
519     {
520         return reportFormat;
521     }
522 
523     public void setReportFormat( String reportFormat )
524     {
525         this.reportFormat = reportFormat;
526     }
527 
528     public boolean isUseFile()
529     {
530         return useFile;
531     }
532 
533     public void setUseFile( boolean useFile )
534     {
535         this.useFile = useFile;
536     }
537 
538     public String getDebugForkedProcess()
539     {
540         return debugForkedProcess;
541     }
542 
543     public void setDebugForkedProcess( String debugForkedProcess )
544     {
545         this.debugForkedProcess = debugForkedProcess;
546     }
547 
548     public int getForkedProcessTimeoutInSeconds()
549     {
550         return forkedProcessTimeoutInSeconds;
551     }
552 
553     public void setForkedProcessTimeoutInSeconds( int forkedProcessTimeoutInSeconds )
554     {
555         this.forkedProcessTimeoutInSeconds = forkedProcessTimeoutInSeconds;
556     }
557 
558     public double getParallelTestsTimeoutInSeconds()
559     {
560         return parallelTestsTimeoutInSeconds;
561     }
562 
563     public void setParallelTestsTimeoutInSeconds( double parallelTestsTimeoutInSeconds )
564     {
565         this.parallelTestsTimeoutInSeconds = parallelTestsTimeoutInSeconds;
566     }
567 
568     public double getParallelTestsTimeoutForcedInSeconds()
569     {
570         return parallelTestsTimeoutForcedInSeconds;
571     }
572 
573     public void setParallelTestsTimeoutForcedInSeconds( double parallelTestsTimeoutForcedInSeconds )
574     {
575         this.parallelTestsTimeoutForcedInSeconds = parallelTestsTimeoutForcedInSeconds;
576     }
577 
578     public boolean isUseSystemClassLoader()
579     {
580         return useSystemClassLoader;
581     }
582 
583     public void setUseSystemClassLoader( boolean useSystemClassLoader )
584     {
585         this.useSystemClassLoader = useSystemClassLoader;
586     }
587 
588     public boolean isUseManifestOnlyJar()
589     {
590         return useManifestOnlyJar;
591     }
592 
593     public void setUseManifestOnlyJar( boolean useManifestOnlyJar )
594     {
595         this.useManifestOnlyJar = useManifestOnlyJar;
596     }
597 
598     
599 
600     public boolean isTestFailureIgnore()
601     {
602         return true; 
603     }
604 
605     public void setTestFailureIgnore( boolean testFailureIgnore )
606     {
607         
608     }
609 
610     protected void addPluginSpecificChecksumItems( ChecksumCalculator checksum )
611     {
612         checksum.add( skipITs );
613         checksum.add( summaryFile );
614     }
615 
616     public Boolean getFailIfNoSpecifiedTests()
617     {
618         return failIfNoSpecifiedTests;
619     }
620 
621     public void setFailIfNoSpecifiedTests( boolean failIfNoSpecifiedTests )
622     {
623         this.failIfNoSpecifiedTests = failIfNoSpecifiedTests;
624     }
625 
626     public int getSkipAfterFailureCount()
627     {
628         return skipAfterFailureCount;
629     }
630 
631     public String getShutdown()
632     {
633         return shutdown;
634     }
635 
636     @Override
637     public List<String> getIncludes()
638     {
639         return includes;
640     }
641 
642     @Override
643     public void setIncludes( List<String> includes )
644     {
645         this.includes = includes;
646     }
647 
648     public File[] getSuiteXmlFiles()
649     {
650         return suiteXmlFiles.clone();
651     }
652 
653     @SuppressWarnings( "UnusedDeclaration" )
654     public void setSuiteXmlFiles( File[] suiteXmlFiles )
655     {
656         this.suiteXmlFiles = suiteXmlFiles.clone();
657     }
658 
659     public String getRunOrder()
660     {
661         return runOrder;
662     }
663 
664     @SuppressWarnings( "UnusedDeclaration" )
665     public void setRunOrder( String runOrder )
666     {
667         this.runOrder = runOrder;
668     }
669 
670     @Override
671     public File getIncludesFile()
672     {
673         return includesFile;
674     }
675 
676     @Override
677     public File getExcludesFile()
678     {
679         return excludesFile;
680     }
681 
682     @Override
683     protected final List<File> suiteXmlFiles()
684     {
685         return hasSuiteXmlFiles() ? Arrays.asList( suiteXmlFiles ) : Collections.<File>emptyList();
686     }
687 
688     @Override
689     protected final boolean hasSuiteXmlFiles()
690     {
691         return suiteXmlFiles != null && suiteXmlFiles.length != 0;
692     }
693 }