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      * @noinspection UnusedDeclaration
128      */
129     private File summaryFile;
130 
131     /**
132      * Additional summary files to read integration test results from.
133      *
134      * @parameter
135      * @since 2.6
136      * @noinspection UnusedDeclaration, MismatchedReadAndWriteOfArray
137      */
138     private File[] summaryFiles;
139 
140     /**
141      * Set this to "true" to cause a failure if there are no tests to run.
142      *
143      * @parameter expression="${failIfNoTests}"
144      * @since 2.4
145      */
146     private Boolean failIfNoTests;
147 
148     /**
149      * The character encoding scheme to be applied.
150      *
151      * @parameter expression="${encoding}" default-value="${project.reporting.outputEncoding}"
152      * @noinspection UnusedDeclaration
153      */
154     private String encoding;
155 
156 
157     public void execute()
158         throws MojoExecutionException, MojoFailureException
159     {
160         if ( verifyParameters() )
161         {
162             getLog().info(
163                 StringUtils.capitalizeFirstLetter( getPluginName() ) + " report directory: " + getReportsDirectory() );
164 
165             int result;
166             try
167             {
168                 String encoding;
169                 if ( StringUtils.isEmpty( this.encoding ) )
170                 {
171                     getLog().warn(
172                         "File encoding has not been set, using platform encoding " + ReaderFactory.FILE_ENCODING
173                             + ", i.e. build is platform dependent!" );
174                     encoding = ReaderFactory.FILE_ENCODING;
175                 }
176                 else
177                 {
178                     encoding = this.encoding;
179                 }
180 
181                 final FailsafeSummary summary;
182                 if ( !summaryFile.isFile() && summaryFiles != null )
183                 {
184                     summary = new FailsafeSummary();
185                 }
186                 else
187                 {
188                     summary = readSummary( encoding, summaryFile );
189                 }
190                 if ( summaryFiles != null )
191                 {
192                     for ( int i = 0; i < summaryFiles.length; i++ )
193                     {
194                         summary.merge( readSummary( encoding, summaryFiles[i] ) );
195                     }
196                 }
197                 result = summary.getResult();
198             }
199             catch ( IOException e )
200             {
201                 throw new MojoExecutionException( e.getMessage(), e );
202             }
203             catch ( XmlPullParserException e )
204             {
205                 throw new MojoExecutionException( e.getMessage(), e );
206             }
207 
208             SurefireHelper.reportExecution( this, result, getLog() );
209         }
210     }
211 
212     private FailsafeSummary readSummary( String encoding, File summaryFile )
213         throws IOException, XmlPullParserException
214     {
215         FileInputStream fileInputStream = null;
216         BufferedInputStream bufferedInputStream = null;
217         Reader reader = null;
218         try
219         {
220             fileInputStream = new FileInputStream( summaryFile );
221             bufferedInputStream = new BufferedInputStream( fileInputStream );
222             reader = new InputStreamReader( bufferedInputStream, encoding );
223             FailsafeSummaryXpp3Reader xpp3Reader = new FailsafeSummaryXpp3Reader();
224             return xpp3Reader.read( reader );
225         }
226         finally
227         {
228             IOUtil.close( reader );
229             IOUtil.close( bufferedInputStream );
230             IOUtil.close( fileInputStream );
231         }
232     }
233 
234     protected boolean verifyParameters()
235         throws MojoFailureException
236     {
237         if ( isSkip() || isSkipTests() || isSkipITs() || isSkipExec() )
238         {
239             getLog().info( "Tests are skipped." );
240             return false;
241         }
242 
243         if ( !getTestClassesDirectory().exists() )
244         {
245             if ( getFailIfNoTests() != null && getFailIfNoTests().booleanValue() )
246             {
247                 throw new MojoFailureException( "No tests to run!" );
248             }
249             getLog().info( "No tests to run." );
250             return false;
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     public boolean isSkipTests()
267     {
268         return skipTests;
269     }
270 
271     public void setSkipTests( boolean skipTests )
272     {
273         this.skipTests = skipTests;
274     }
275 
276     public boolean isSkipITs()
277     {
278         return skipITs;
279     }
280 
281     public void setSkipITs( boolean skipITs )
282     {
283         this.skipITs = skipITs;
284     }
285 
286     public boolean isSkipExec()
287     {
288         return skipExec;
289     }
290 
291     public void setSkipExec( boolean skipExec )
292     {
293         this.skipExec = skipExec;
294     }
295 
296     public boolean isSkip()
297     {
298         return skip;
299     }
300 
301     public void setSkip( boolean skip )
302     {
303         this.skip = skip;
304     }
305 
306     public boolean isTestFailureIgnore()
307     {
308         return testFailureIgnore;
309     }
310 
311     public void setTestFailureIgnore( boolean testFailureIgnore )
312     {
313         this.testFailureIgnore = testFailureIgnore;
314     }
315 
316     public File getBasedir()
317     {
318         return basedir;
319     }
320 
321     public void setBasedir( File basedir )
322     {
323         this.basedir = basedir;
324     }
325 
326     public File getTestClassesDirectory()
327     {
328         return testClassesDirectory;
329     }
330 
331     public void setTestClassesDirectory( File testClassesDirectory )
332     {
333         this.testClassesDirectory = testClassesDirectory;
334     }
335 
336     public File getReportsDirectory()
337     {
338         return reportsDirectory;
339     }
340 
341     public void setReportsDirectory( File reportsDirectory )
342     {
343         this.reportsDirectory = reportsDirectory;
344     }
345 
346     public Boolean getFailIfNoTests()
347     {
348         return failIfNoTests;
349     }
350 
351     public void setFailIfNoTests( Boolean failIfNoTests )
352     {
353         this.failIfNoTests = failIfNoTests;
354     }
355 
356 }