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