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.xmlsummary.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 javax.xml.bind.JAXBException;
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.shared.utils.StringUtils.capitalizeFirstLetter;
43  import static org.apache.maven.surefire.suite.RunResult.noTestsRun;
44  
45  /**
46   * Verify integration tests ran using Surefire.
47   *
48   * @author Stephen Connolly
49   * @author Jason van Zyl
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       * Set this to 'true' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite
60       * convenient on occasion.
61       *
62       * @since 2.4
63       */
64      @Parameter( property = "skipTests" )
65      private boolean skipTests;
66  
67      /**
68       * Set this to 'true' to skip running integration tests, but still compile them. Its use is NOT RECOMMENDED, but
69       * quite convenient on occasion.
70       *
71       * @since 2.4.3-alpha-2
72       */
73      @Parameter( property = "skipITs" )
74      private boolean skipITs;
75  
76      /**
77       * This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
78       *
79       * @since 2.3
80       * @deprecated Use -DskipTests instead.
81       */
82      @Deprecated
83      @Parameter( property = "maven.test.skip.exec" )
84      private boolean skipExec;
85  
86      /**
87       * Set this to 'true' to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you
88       * enable it using the "maven.test.skip" property, because maven.test.skip disables both running the
89       * tests and compiling the tests.  Consider using the skipTests parameter instead.
90       */
91      @Parameter( property = "maven.test.skip", defaultValue = "false" )
92      private boolean skip;
93  
94      /**
95       * Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on
96       * occasion.
97       */
98      @Parameter( property = "maven.test.failure.ignore", defaultValue = "false" )
99      private boolean testFailureIgnore;
100 
101     /**
102      * The base directory of the project being tested. This can be obtained in your unit test by
103      * System.getProperty("basedir").
104      */
105     @Parameter( defaultValue = "${basedir}" )
106     private File basedir;
107 
108     /**
109      * The directory containing generated test classes of the project being tested.
110      * This will be included at the beginning the test classpath.
111      */
112     @Parameter( defaultValue = "${project.build.testOutputDirectory}" )
113     private File testClassesDirectory;
114 
115     /**
116      * Base directory where all reports are written to.
117      */
118     @Parameter( defaultValue = "${project.build.directory}/failsafe-reports" )
119     private File reportsDirectory;
120 
121     /**
122      * The summary file to read integration test results from.
123      *
124      * @noinspection UnusedDeclaration
125      */
126     @Parameter( defaultValue = "${project.build.directory}/failsafe-reports/failsafe-summary.xml", required = true )
127     private File summaryFile;
128 
129     /**
130      * Additional summary files to read integration test results from.
131      *
132      * @noinspection UnusedDeclaration, MismatchedReadAndWriteOfArray
133      * @since 2.6
134      */
135     @Parameter
136     private File[] summaryFiles;
137 
138     /**
139      * Set this to "true" to cause a failure if there are no tests to run.
140      *
141      * @since 2.4
142      */
143     @Parameter( property = "failIfNoTests" )
144     private Boolean failIfNoTests;
145 
146     /**
147      * The character encoding scheme to be applied.
148      *
149      * @noinspection UnusedDeclaration
150      */
151     @Parameter( property = "encoding", defaultValue = "${project.reporting.outputEncoding}" )
152     private String encoding;
153 
154     /**
155      * The current build session instance.
156      */
157     @Component
158     private MavenSession session;
159 
160     private Collection<CommandLineOption> cli;
161 
162     private volatile PluginConsoleLogger consoleLogger;
163 
164     public void execute()
165             throws MojoExecutionException, MojoFailureException
166     {
167         cli = commandLineOptions();
168         if ( verifyParameters() )
169         {
170             logDebugOrCliShowErrors( capitalizeFirstLetter( getPluginName() )
171                                              + " report directory: " + getReportsDirectory() );
172 
173             RunResult summary;
174             try
175             {
176                 summary = existsSummaryFile() ? readSummary( summaryFile ) : noTestsRun();
177 
178                 if ( existsSummaryFiles() )
179                 {
180                     for ( final File summaryFile : summaryFiles )
181                     {
182                         summary = summary.aggregate( readSummary( summaryFile ) );
183                     }
184                 }
185             }
186             catch ( JAXBException e )
187             {
188                 throw new MojoExecutionException( e.getMessage(), e );
189             }
190 
191             reportExecution( this, summary, getConsoleLogger(), null );
192         }
193     }
194 
195     private PluginConsoleLogger getConsoleLogger()
196     {
197         if ( consoleLogger == null )
198         {
199             synchronized ( this )
200             {
201                 if ( consoleLogger == null )
202                 {
203                     consoleLogger = new PluginConsoleLogger( getLog() );
204                 }
205             }
206         }
207         return consoleLogger;
208     }
209 
210     private RunResult readSummary( File summaryFile ) throws JAXBException
211     {
212         return FailsafeSummaryXmlUtils.toRunResult( summaryFile );
213     }
214 
215     protected boolean verifyParameters()
216             throws MojoFailureException
217     {
218         if ( isSkip() || isSkipTests() || isSkipITs() || isSkipExec() )
219         {
220             getConsoleLogger().info( "Tests are skipped." );
221             return false;
222         }
223 
224         if ( !getTestClassesDirectory().exists() )
225         {
226             if ( getFailIfNoTests() != null && getFailIfNoTests() )
227             {
228                 throw new MojoFailureException( "No tests to run!" );
229             }
230         }
231 
232         if ( !existsSummary() )
233         {
234             getConsoleLogger().info( "No tests to run." );
235             return false;
236         }
237 
238         return true;
239     }
240 
241     protected String getPluginName()
242     {
243         return "failsafe";
244     }
245 
246     protected String[] getDefaultIncludes()
247     {
248         return null;
249     }
250 
251     public boolean isSkipTests()
252     {
253         return skipTests;
254     }
255 
256     public void setSkipTests( boolean skipTests )
257     {
258         this.skipTests = skipTests;
259     }
260 
261     public boolean isSkipITs()
262     {
263         return skipITs;
264     }
265 
266     public void setSkipITs( boolean skipITs )
267     {
268         this.skipITs = skipITs;
269     }
270 
271     @Deprecated
272     public boolean isSkipExec()
273     {
274         return skipExec;
275     }
276 
277     @Deprecated
278     public void setSkipExec( boolean skipExec )
279     {
280         this.skipExec = skipExec;
281     }
282 
283     public boolean isSkip()
284     {
285         return skip;
286     }
287 
288     public void setSkip( boolean skip )
289     {
290         this.skip = skip;
291     }
292 
293     public boolean isTestFailureIgnore()
294     {
295         return testFailureIgnore;
296     }
297 
298     public void setTestFailureIgnore( boolean testFailureIgnore )
299     {
300         this.testFailureIgnore = testFailureIgnore;
301     }
302 
303     public File getBasedir()
304     {
305         return basedir;
306     }
307 
308     public void setBasedir( File basedir )
309     {
310         this.basedir = basedir;
311     }
312 
313     public File getTestClassesDirectory()
314     {
315         return testClassesDirectory;
316     }
317 
318     public void setTestClassesDirectory( File testClassesDirectory )
319     {
320         this.testClassesDirectory = testClassesDirectory;
321     }
322 
323     public File getReportsDirectory()
324     {
325         return reportsDirectory;
326     }
327 
328     public void setReportsDirectory( File reportsDirectory )
329     {
330         this.reportsDirectory = reportsDirectory;
331     }
332 
333     public Boolean getFailIfNoTests()
334     {
335         return failIfNoTests;
336     }
337 
338     public void setFailIfNoTests( boolean failIfNoTests )
339     {
340         this.failIfNoTests = failIfNoTests;
341     }
342 
343     private boolean existsSummaryFile()
344     {
345         return summaryFile != null && summaryFile.isFile();
346     }
347 
348     private boolean existsSummaryFiles()
349     {
350         return summaryFiles != null && summaryFiles.length != 0;
351     }
352 
353     private boolean existsSummary()
354     {
355         return existsSummaryFile() || existsSummaryFiles();
356     }
357 
358     private Collection<CommandLineOption> commandLineOptions()
359     {
360         return SurefireHelper.commandLineOptions( session, getConsoleLogger() );
361     }
362 
363     private void logDebugOrCliShowErrors( String s )
364     {
365         SurefireHelper.logDebugOrCliShowErrors( s, getConsoleLogger(), cli );
366     }
367 
368 }