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 java.io.BufferedInputStream;
23  import java.io.File;
24  import java.io.FileInputStream;
25  import java.io.IOException;
26  import java.io.InputStreamReader;
27  import java.io.Reader;
28  import org.apache.maven.plugin.AbstractMojo;
29  import org.apache.maven.plugin.MojoExecutionException;
30  import org.apache.maven.plugin.MojoFailureException;
31  import org.apache.maven.plugin.surefire.SurefireHelper;
32  import org.apache.maven.plugin.surefire.SurefireReportParameters;
33  import org.apache.maven.surefire.failsafe.model.FailsafeSummary;
34  import org.apache.maven.surefire.failsafe.model.io.xpp3.FailsafeSummaryXpp3Reader;
35  import org.codehaus.plexus.util.IOUtil;
36  import org.codehaus.plexus.util.ReaderFactory;
37  import org.codehaus.plexus.util.StringUtils;
38  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
39  
40  /**
41   * Verify integration tests ran using Surefire.
42   *
43   * @author Stephen Connolly
44   * @author Jason van Zyl
45   * @requiresProject true
46   * @goal verify
47   * @phase verify
48   * @threadSafe
49   */
50  public class VerifyMojo
51      extends AbstractMojo
52      implements SurefireReportParameters
53  {
54  
55      /**
56       * Set this to 'true' to skip running tests, but still compile them. Its use is NOT RECOMMENDED, but quite
57       * convenient on occasion.
58       *
59       * @parameter expression="${skipTests}"
60       * @since 2.4
61       */
62      private boolean skipTests;
63  
64      /**
65       * Set this to 'true' to skip running integration tests, but still compile them. Its use is NOT RECOMMENDED, but quite
66       * convenient on occasion.
67       *
68       * @parameter expression="${skipITs}"
69       * @since 2.4.3-alpha-2
70       */
71      private boolean skipITs;
72  
73      /**
74       * This old parameter is just like skipTests, but bound to the old property maven.test.skip.exec.
75       *
76       * @parameter expression="${maven.test.skip.exec}"
77       * @since 2.3
78       * @deprecated Use -DskipTests instead.
79       */
80      private boolean skipExec;
81  
82      /**
83       * Set this to 'true' to bypass unit tests entirely. Its use is NOT RECOMMENDED, especially if you
84       * enable it using the "maven.test.skip" property, because maven.test.skip disables both running the
85       * tests and compiling the tests.  Consider using the skipTests parameter instead.
86       *
87       * @parameter default-value="false" expression="${maven.test.skip}"
88       */
89      private boolean skip;
90  
91      /**
92       * Set this to true to ignore a failure during testing. Its use is NOT RECOMMENDED, but quite convenient on
93       * occasion.
94       *
95       * @parameter default-value="false" expression="${maven.test.failure.ignore}"
96       */
97      private boolean testFailureIgnore;
98  
99      /**
100      * The base directory of the project being tested. This can be obtained in your unit test by
101      * System.getProperty("basedir").
102      *
103      * @parameter default-value="${basedir}"
104      */
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 default-value="${project.build.testOutputDirectory}"
112      */
113     private File testClassesDirectory;
114 
115     /**
116      * Base directory where all reports are written to.
117      *
118      * @parameter default-value="${project.build.directory}/failsafe-reports"
119      */
120     private File reportsDirectory;
121 
122     /**
123      * The summary file to read integration test results from.
124      *
125      * @parameter expression="${project.build.directory}/failsafe-reports/failsafe-summary.xml"
126      * @required
127      */
128     private File summaryFile;
129 
130     /**
131      * Additional summary files to read integration test results from.
132      *
133      * @parameter
134      * @since 2.6
135      */
136     private File[] summaryFiles;
137 
138     /**
139      * Set this to "true" to cause a failure if there are no tests to run.
140      *
141      * @parameter expression="${failIfNoTests}"
142      * @since 2.4
143      */
144     private Boolean failIfNoTests;
145 
146     /**
147      * The character encoding scheme to be applied.
148      *
149      * @parameter expression="${encoding}" default-value="${project.reporting.outputEncoding}"
150      */
151     private String encoding;
152 
153 
154     public void execute()
155         throws MojoExecutionException, MojoFailureException
156     {
157         if ( verifyParameters() )
158         {
159             getLog().info(
160                 StringUtils.capitalizeFirstLetter( getPluginName() ) + " report directory: " + getReportsDirectory() );
161 
162             int result;
163             try
164             {
165                 String encoding;
166                 if ( StringUtils.isEmpty( this.encoding ) )
167                 {
168                     getLog().warn(
169                         "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
170                             + ", i.e. build is platform dependent!" );
171                     encoding = ReaderFactory.FILE_ENCODING;
172                 }
173                 else
174                 {
175                     encoding = this.encoding;
176                 }
177 
178                 final FailsafeSummary summary;
179                 if ( !summaryFile.isFile() && summaryFiles != null )
180                 {
181                     summary = new FailsafeSummary();
182                 }
183                 else
184                 {                    
185                     summary = readSummary( encoding, summaryFile );
186                 }
187                 if ( summaryFiles != null )
188                 {
189                     for ( int i = 0; i < summaryFiles.length; i++ )
190                     {
191                         summary.merge( readSummary( encoding, summaryFiles[i] ) );
192                     }
193                 }
194                 result = summary.getResult();
195             }
196             catch ( IOException e )
197             {
198                 throw new MojoExecutionException( e.getMessage(), e );
199             }
200             catch ( XmlPullParserException e )
201             {
202                 throw new MojoExecutionException( e.getMessage(), e );
203             }
204 
205             SurefireHelper.reportExecution( this, result, getLog() );
206         }
207     }
208 
209     private FailsafeSummary readSummary( String encoding, File summaryFile )
210             throws IOException, XmlPullParserException
211     {
212         FileInputStream fileInputStream = null;
213         BufferedInputStream bufferedInputStream = null;
214         Reader reader = null;
215         try
216         {
217             fileInputStream = new FileInputStream( summaryFile );
218             bufferedInputStream = new BufferedInputStream( fileInputStream );
219             reader = new InputStreamReader( bufferedInputStream, encoding );
220             FailsafeSummaryXpp3Reader xpp3Reader = new FailsafeSummaryXpp3Reader();
221             return xpp3Reader.read( reader );
222         }
223         finally
224         {
225             IOUtil.close( reader );
226             IOUtil.close( bufferedInputStream );
227             IOUtil.close( fileInputStream );
228         }
229     }
230 
231     protected boolean verifyParameters()
232         throws MojoFailureException
233     {
234         if ( isSkip() || isSkipTests() || isSkipITs() || isSkipExec() )
235         {
236             getLog().info( "Tests are skipped." );
237             return false;
238         }
239 
240         if ( !getTestClassesDirectory().exists() )
241         {
242             if ( getFailIfNoTests() != null && getFailIfNoTests().booleanValue() )
243             {
244                 throw new MojoFailureException( "No tests to run!" );
245             }
246             getLog().info( "No tests to run." );
247             return false;
248         }
249 
250         return true;
251     }
252 
253     protected String getPluginName()
254     {
255         return "failsafe";
256     }
257 
258     protected String[] getDefaultIncludes()
259     {
260         return null;
261     }
262 
263     public boolean isSkipTests()
264     {
265         return skipTests;
266     }
267 
268     public void setSkipTests( boolean skipTests )
269     {
270         this.skipTests = skipTests;
271     }
272 
273     public boolean isSkipITs()
274     {
275         return skipITs;
276     }
277 
278     public void setSkipITs( boolean skipITs )
279     {
280         this.skipITs = skipITs;
281     }
282 
283     public boolean isSkipExec()
284     {
285         return skipExec;
286     }
287 
288     public void setSkipExec( boolean skipExec )
289     {
290         this.skipExec = skipExec;
291     }
292 
293     public boolean isSkip()
294     {
295         return skip;
296     }
297 
298     public void setSkip( boolean skip )
299     {
300         this.skip = skip;
301     }
302 
303     public boolean isTestFailureIgnore()
304     {
305         return testFailureIgnore;
306     }
307 
308     public void setTestFailureIgnore( boolean testFailureIgnore )
309     {
310         this.testFailureIgnore = testFailureIgnore;
311     }
312 
313     public File getBasedir()
314     {
315         return basedir;
316     }
317 
318     public void setBasedir( File basedir )
319     {
320         this.basedir = basedir;
321     }
322 
323     public File getTestClassesDirectory()
324     {
325         return testClassesDirectory;
326     }
327 
328     public void setTestClassesDirectory( File testClassesDirectory )
329     {
330         this.testClassesDirectory = testClassesDirectory;
331     }
332 
333     public File getReportsDirectory()
334     {
335         return reportsDirectory;
336     }
337 
338     public void setReportsDirectory( File reportsDirectory )
339     {
340         this.reportsDirectory = reportsDirectory;
341     }
342 
343     public Boolean getFailIfNoTests()
344     {
345         return failIfNoTests;
346     }
347 
348     public void setFailIfNoTests( Boolean failIfNoTests )
349     {
350         this.failIfNoTests = failIfNoTests;
351     }
352 
353 }