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 }