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.execution.MavenSession;
23 import org.apache.maven.plugin.AbstractMojo;
24 import org.apache.maven.plugin.MojoExecutionException;
25 import org.apache.maven.plugin.MojoFailureException;
26 import org.apache.maven.plugin.failsafe.util.FailsafeSummaryXmlUtils;
27 import org.apache.maven.plugin.surefire.SurefireHelper;
28 import org.apache.maven.plugin.surefire.SurefireReportParameters;
29 import org.apache.maven.plugin.surefire.log.PluginConsoleLogger;
30 import org.apache.maven.plugins.annotations.Component;
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.surefire.api.cli.CommandLineOption;
35 import org.apache.maven.surefire.api.suite.RunResult;
36 import org.codehaus.plexus.logging.Logger;
37
38 import java.io.File;
39 import java.util.Collection;
40
41 import static org.apache.maven.plugin.surefire.SurefireHelper.reportExecution;
42 import static org.apache.maven.surefire.shared.utils.StringUtils.capitalizeFirstLetter;
43 import static org.apache.maven.surefire.api.suite.RunResult.noTestsRun;
44
45
46
47
48
49
50
51 @SuppressWarnings( "unused" )
52 @Mojo( name = "verify", defaultPhase = LifecyclePhase.VERIFY, requiresProject = true, threadSafe = true )
53 public class VerifyMojo
54 extends AbstractMojo
55 implements SurefireReportParameters
56 {
57
58
59
60
61
62
63
64 @Parameter( property = "skipTests" )
65 private boolean skipTests;
66
67
68
69
70
71
72
73 @Parameter( property = "skipITs" )
74 private boolean skipITs;
75
76
77
78
79
80
81
82 @Deprecated
83 @Parameter( property = "maven.test.skip.exec" )
84 private boolean skipExec;
85
86
87
88
89
90
91 @Parameter( property = "maven.test.skip", defaultValue = "false" )
92 private boolean skip;
93
94
95
96
97
98 @Parameter( property = "maven.test.failure.ignore", defaultValue = "false" )
99 private boolean testFailureIgnore;
100
101
102
103
104
105 @Parameter( defaultValue = "${basedir}" )
106 private File basedir;
107
108
109
110
111
112 @Parameter( defaultValue = "${project.build.testOutputDirectory}" )
113 private File testClassesDirectory;
114
115
116
117
118 @Parameter( defaultValue = "${project.build.directory}/failsafe-reports" )
119 private File reportsDirectory;
120
121
122
123
124 @Parameter( defaultValue = "${project.build.directory}/failsafe-reports/failsafe-summary.xml", required = true )
125 private File summaryFile;
126
127
128
129
130
131 @Parameter
132 private File[] summaryFiles;
133
134
135
136
137
138
139 @Parameter( property = "failIfNoTests", defaultValue = "false" )
140 private boolean failIfNoTests;
141
142
143
144
145
146
147
148 @Parameter( property = "failsafe.failOnFlakeCount", defaultValue = "0" )
149 private int failOnFlakeCount;
150
151
152
153
154
155
156
157 @Parameter( property = "encoding", defaultValue = "${project.reporting.outputEncoding}" )
158 private String encoding;
159
160
161
162
163 @Parameter( defaultValue = "${session}", readonly = true )
164 private MavenSession session;
165
166 @Component
167 private Logger logger;
168
169 private Collection<CommandLineOption> cli;
170
171 private volatile PluginConsoleLogger consoleLogger;
172
173 @Override
174 public void execute()
175 throws MojoExecutionException, MojoFailureException
176 {
177 cli = commandLineOptions();
178 if ( verifyParameters() )
179 {
180 logDebugOrCliShowErrors( capitalizeFirstLetter( getPluginName() )
181 + " report directory: " + getReportsDirectory() );
182
183 RunResult summary;
184 try
185 {
186 summary = existsSummaryFile() ? readSummary( summaryFile ) : noTestsRun();
187
188 if ( existsSummaryFiles() )
189 {
190 for ( final File summaryFile : summaryFiles )
191 {
192 summary = summary.aggregate( readSummary( summaryFile ) );
193 }
194 }
195 }
196 catch ( Exception e )
197 {
198 throw new MojoExecutionException( e.getMessage(), e );
199 }
200
201 reportExecution( this, summary, getConsoleLogger(), null );
202 }
203 }
204
205 private PluginConsoleLogger getConsoleLogger()
206 {
207 if ( consoleLogger == null )
208 {
209 synchronized ( this )
210 {
211 if ( consoleLogger == null )
212 {
213 consoleLogger = new PluginConsoleLogger( logger );
214 }
215 }
216 }
217 return consoleLogger;
218 }
219
220 private RunResult readSummary( File summaryFile ) throws Exception
221 {
222 return FailsafeSummaryXmlUtils.toRunResult( summaryFile );
223 }
224
225 protected boolean verifyParameters()
226 throws MojoFailureException
227 {
228 if ( isSkip() || isSkipTests() || isSkipITs() || isSkipExec() )
229 {
230 getConsoleLogger().info( "Tests are skipped." );
231 return false;
232 }
233
234 if ( !getTestClassesDirectory().exists() )
235 {
236 if ( getFailIfNoTests() )
237 {
238 throw new MojoFailureException( "No tests to run!" );
239 }
240 }
241
242 if ( !existsSummary() )
243 {
244 getConsoleLogger().info( "No tests to run." );
245 return false;
246 }
247
248 if ( failOnFlakeCount < 0 )
249 {
250 throw new MojoFailureException( "Parameter \"failOnFlakeCount\" should not be negative." );
251 }
252
253 return true;
254 }
255
256 protected String getPluginName()
257 {
258 return "failsafe";
259 }
260
261 protected String[] getDefaultIncludes()
262 {
263 return null;
264 }
265
266 @Override
267 public boolean isSkipTests()
268 {
269 return skipTests;
270 }
271
272 @Override
273 public void setSkipTests( boolean skipTests )
274 {
275 this.skipTests = skipTests;
276 }
277
278 public boolean isSkipITs()
279 {
280 return skipITs;
281 }
282
283 public void setSkipITs( boolean skipITs )
284 {
285 this.skipITs = skipITs;
286 }
287
288 @Override
289 @Deprecated
290 public boolean isSkipExec()
291 {
292 return skipExec;
293 }
294
295 @Override
296 @Deprecated
297 public void setSkipExec( boolean skipExec )
298 {
299 this.skipExec = skipExec;
300 }
301
302 @Override
303 public boolean isSkip()
304 {
305 return skip;
306 }
307
308 @Override
309 public void setSkip( boolean skip )
310 {
311 this.skip = skip;
312 }
313
314 @Override
315 public boolean isTestFailureIgnore()
316 {
317 return testFailureIgnore;
318 }
319
320 @Override
321 public void setTestFailureIgnore( boolean testFailureIgnore )
322 {
323 this.testFailureIgnore = testFailureIgnore;
324 }
325
326 @Override
327 public File getBasedir()
328 {
329 return basedir;
330 }
331
332 @Override
333 public void setBasedir( File basedir )
334 {
335 this.basedir = basedir;
336 }
337
338 @Override
339 public File getTestClassesDirectory()
340 {
341 return testClassesDirectory;
342 }
343
344 @Override
345 public void setTestClassesDirectory( File testClassesDirectory )
346 {
347 this.testClassesDirectory = testClassesDirectory;
348 }
349
350 @Override
351 public File getReportsDirectory()
352 {
353 return reportsDirectory;
354 }
355
356 @Override
357 public void setReportsDirectory( File reportsDirectory )
358 {
359 this.reportsDirectory = reportsDirectory;
360 }
361
362 @Override
363 public boolean getFailIfNoTests()
364 {
365 return failIfNoTests;
366 }
367
368 @Override
369 public void setFailIfNoTests( boolean failIfNoTests )
370 {
371 this.failIfNoTests = failIfNoTests;
372 }
373
374 @Override
375 public int getFailOnFlakeCount()
376 {
377 return failOnFlakeCount;
378 }
379
380 @Override
381 public void setFailOnFlakeCount( int failOnFlakeCount )
382 {
383 this.failOnFlakeCount = failOnFlakeCount;
384 }
385
386 private boolean existsSummaryFile()
387 {
388 return summaryFile != null && summaryFile.isFile();
389 }
390
391 private boolean existsSummaryFiles()
392 {
393 return summaryFiles != null && summaryFiles.length != 0;
394 }
395
396 private boolean existsSummary()
397 {
398 return existsSummaryFile() || existsSummaryFiles();
399 }
400
401 private Collection<CommandLineOption> commandLineOptions()
402 {
403 return SurefireHelper.commandLineOptions( session, getConsoleLogger() );
404 }
405
406 private void logDebugOrCliShowErrors( String s )
407 {
408 SurefireHelper.logDebugOrCliShowErrors( s, getConsoleLogger(), cli );
409 }
410
411 }