View Javadoc
1   package org.apache.maven.plugin.failsafe;
2   
3   /*
4    * Licensed to the Apache Software Foundation (ASF) under one
5    * or more contributor license agreements.  See the NOTICE file
6    * distributed with this work for additional information
7    * regarding copyright ownership.  The ASF licenses this file
8    * to you under the Apache License, Version 2.0 (the
9    * "License"); you may not use this file except in compliance
10   * with the License.  You may obtain a copy of the License at
11   *
12   *     http://www.apache.org/licenses/LICENSE-2.0
13   *
14   * Unless required by applicable law or agreed to in writing,
15   * software distributed under the License is distributed on an
16   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
17   * KIND, either express or implied.  See the License for the
18   * specific language governing permissions and limitations
19   * under the License.
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.cli.CommandLineOption;
35  import org.apache.maven.surefire.suite.RunResult;
36  
37  import java.io.File;
38  import java.util.Collection;
39  
40  import static org.apache.maven.plugin.surefire.SurefireHelper.reportExecution;
41  import static org.apache.maven.shared.utils.StringUtils.capitalizeFirstLetter;
42  import static org.apache.maven.surefire.suite.RunResult.noTestsRun;
43  
44  /**
45   * Verify integration tests ran using Surefire.
46   *
47   * @author Stephen Connolly
48   * @author Jason van Zyl
49   */
50  @SuppressWarnings( "unused" )
51  @Mojo( name = "verify", defaultPhase = LifecyclePhase.VERIFY, requiresProject = true, threadSafe = true )
52  public class VerifyMojo
53          extends AbstractMojo
54          implements SurefireReportParameters
55  {
56  
57      /**
58       * Set this to 'true' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite
59       * convenient on occasion.
60       *
61       * @since 2.4
62       */
63      @Parameter( property = "skipTests" )
64      private boolean skipTests;
65  
66      /**
67       * Set this to 'true' to skip running integration tests, but still compile them. Its use is NOT RECOMMENDED, but
68       * quite convenient on occasion.
69       *
70       * @since 2.4.3-alpha-2
71       */
72      @Parameter( property = "skipITs" )
73      private boolean skipITs;
74  
75      /**
76       * This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
77       *
78       * @since 2.3
79       * @deprecated Use -DskipTests instead.
80       */
81      @Deprecated
82      @Parameter( property = "maven.test.skip.exec" )
83      private boolean skipExec;
84  
85      /**
86       * Set this to 'true' to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you
87       * enable it using the "maven.test.skip" property, because maven.test.skip disables both running the
88       * tests and compiling the tests.  Consider using the skipTests parameter instead.
89       */
90      @Parameter( property = "maven.test.skip", defaultValue = "false" )
91      private boolean skip;
92  
93      /**
94       * Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on
95       * occasion.
96       */
97      @Parameter( property = "maven.test.failure.ignore", defaultValue = "false" )
98      private boolean testFailureIgnore;
99  
100     /**
101      * The base directory of the project being tested. This can be obtained in your unit test by
102      * System.getProperty("basedir").
103      */
104     @Parameter( defaultValue = "${basedir}" )
105     private File basedir;
106 
107     /**
108      * The directory containing generated test classes of the project being tested.
109      * This will be included at the beginning the test classpath.
110      */
111     @Parameter( defaultValue = "${project.build.testOutputDirectory}" )
112     private File testClassesDirectory;
113 
114     /**
115      * Base directory where all reports are written to.
116      */
117     @Parameter( defaultValue = "${project.build.directory}/failsafe-reports" )
118     private File reportsDirectory;
119 
120     /**
121      * The summary file to read integration test results from.
122      */
123     @Parameter( defaultValue = "${project.build.directory}/failsafe-reports/failsafe-summary.xml", required = true )
124     private File summaryFile;
125 
126     /**
127      * Additional summary files to read integration test results from.
128      * @since 2.6
129      */
130     @Parameter
131     private File[] summaryFiles;
132 
133     /**
134      * Set this to "true" to cause a failure if there are no tests to run.
135      *
136      * @since 2.4
137      */
138     @Parameter( property = "failIfNoTests" )
139     private Boolean failIfNoTests;
140 
141     /**
142      * The character encoding scheme to be applied.
143      * Deprecated since 2.20.1 and used encoding UTF-8 in <tt>failsafe-summary.xml</tt>.
144      *
145      * @deprecated since of 2.20.1
146      */
147     @Parameter( property = "encoding", defaultValue = "${project.reporting.outputEncoding}" )
148     private String encoding;
149 
150     /**
151      * The current build session instance.
152      */
153     @Component
154     private MavenSession session;
155 
156     private Collection<CommandLineOption> cli;
157 
158     private volatile PluginConsoleLogger consoleLogger;
159 
160     @Override
161     public void execute()
162             throws MojoExecutionException, MojoFailureException
163     {
164         cli = commandLineOptions();
165         if ( verifyParameters() )
166         {
167             logDebugOrCliShowErrors( capitalizeFirstLetter( getPluginName() )
168                                              + " report directory: " + getReportsDirectory() );
169 
170             RunResult summary;
171             try
172             {
173                 summary = existsSummaryFile() ? readSummary( summaryFile ) : noTestsRun();
174 
175                 if ( existsSummaryFiles() )
176                 {
177                     for ( final File summaryFile : summaryFiles )
178                     {
179                         summary = summary.aggregate( readSummary( summaryFile ) );
180                     }
181                 }
182             }
183             catch ( Exception e )
184             {
185                 throw new MojoExecutionException( e.getMessage(), e );
186             }
187 
188             reportExecution( this, summary, getConsoleLogger(), null );
189         }
190     }
191 
192     private PluginConsoleLogger getConsoleLogger()
193     {
194         if ( consoleLogger == null )
195         {
196             synchronized ( this )
197             {
198                 if ( consoleLogger == null )
199                 {
200                     consoleLogger = new PluginConsoleLogger( getLog() );
201                 }
202             }
203         }
204         return consoleLogger;
205     }
206 
207     private RunResult readSummary( File summaryFile ) throws Exception
208     {
209         return FailsafeSummaryXmlUtils.toRunResult( summaryFile );
210     }
211 
212     protected boolean verifyParameters()
213             throws MojoFailureException
214     {
215         if ( isSkip() || isSkipTests() || isSkipITs() || isSkipExec() )
216         {
217             getConsoleLogger().info( "Tests are skipped." );
218             return false;
219         }
220 
221         if ( !getTestClassesDirectory().exists() )
222         {
223             if ( getFailIfNoTests() != null && getFailIfNoTests() )
224             {
225                 throw new MojoFailureException( "No tests to run!" );
226             }
227         }
228 
229         if ( !existsSummary() )
230         {
231             getConsoleLogger().info( "No tests to run." );
232             return false;
233         }
234 
235         return true;
236     }
237 
238     protected String getPluginName()
239     {
240         return "failsafe";
241     }
242 
243     protected String[] getDefaultIncludes()
244     {
245         return null;
246     }
247 
248     @Override
249     public boolean isSkipTests()
250     {
251         return skipTests;
252     }
253 
254     @Override
255     public void setSkipTests( boolean skipTests )
256     {
257         this.skipTests = skipTests;
258     }
259 
260     public boolean isSkipITs()
261     {
262         return skipITs;
263     }
264 
265     public void setSkipITs( boolean skipITs )
266     {
267         this.skipITs = skipITs;
268     }
269 
270     @Override
271     @Deprecated
272     public boolean isSkipExec()
273     {
274         return skipExec;
275     }
276 
277     @Override
278     @Deprecated
279     public void setSkipExec( boolean skipExec )
280     {
281         this.skipExec = skipExec;
282     }
283 
284     @Override
285     public boolean isSkip()
286     {
287         return skip;
288     }
289 
290     @Override
291     public void setSkip( boolean skip )
292     {
293         this.skip = skip;
294     }
295 
296     @Override
297     public boolean isTestFailureIgnore()
298     {
299         return testFailureIgnore;
300     }
301 
302     @Override
303     public void setTestFailureIgnore( boolean testFailureIgnore )
304     {
305         this.testFailureIgnore = testFailureIgnore;
306     }
307 
308     @Override
309     public File getBasedir()
310     {
311         return basedir;
312     }
313 
314     @Override
315     public void setBasedir( File basedir )
316     {
317         this.basedir = basedir;
318     }
319 
320     @Override
321     public File getTestClassesDirectory()
322     {
323         return testClassesDirectory;
324     }
325 
326     @Override
327     public void setTestClassesDirectory( File testClassesDirectory )
328     {
329         this.testClassesDirectory = testClassesDirectory;
330     }
331 
332     @Override
333     public File getReportsDirectory()
334     {
335         return reportsDirectory;
336     }
337 
338     @Override
339     public void setReportsDirectory( File reportsDirectory )
340     {
341         this.reportsDirectory = reportsDirectory;
342     }
343 
344     @Override
345     public Boolean getFailIfNoTests()
346     {
347         return failIfNoTests;
348     }
349 
350     @Override
351     public void setFailIfNoTests( boolean failIfNoTests )
352     {
353         this.failIfNoTests = failIfNoTests;
354     }
355 
356     private boolean existsSummaryFile()
357     {
358         return summaryFile != null && summaryFile.isFile();
359     }
360 
361     private boolean existsSummaryFiles()
362     {
363         return summaryFiles != null && summaryFiles.length != 0;
364     }
365 
366     private boolean existsSummary()
367     {
368         return existsSummaryFile() || existsSummaryFiles();
369     }
370 
371     private Collection<CommandLineOption> commandLineOptions()
372     {
373         return SurefireHelper.commandLineOptions( session, getConsoleLogger() );
374     }
375 
376     private void logDebugOrCliShowErrors( String s )
377     {
378         SurefireHelper.logDebugOrCliShowErrors( s, getConsoleLogger(), cli );
379     }
380 
381 }