View Javadoc
1   /*
2    * (C) Copyright 2006-2014 Nuxeo SA (http://nuxeo.com/) and contributors.
3    *
4    * All rights reserved. This program and the accompanying materials
5    * are made available under the terms of the GNU Lesser General Public License
6    * (LGPL) version 2.1 which accompanies this distribution, and is available at
7    * http://www.gnu.org/licenses/lgpl-2.1.html
8    *
9    * This library is distributed in the hope that it will be useful,
10   * but WITHOUT ANY WARRANTY; without even the implied warranty of
11   * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
12   * Lesser General Public License for more details.
13   *
14   * Contributors:
15   *     mguillaume, jcarsique
16   */
17  package org.nuxeo.build.maven;
18  
19  import java.io.File;
20  import java.io.FileInputStream;
21  import java.io.FileOutputStream;
22  import java.io.IOException;
23  
24  import org.apache.maven.plugin.MojoExecutionException;
25  import org.apache.maven.plugin.MojoFailureException;
26  import org.apache.maven.plugins.annotations.LifecyclePhase;
27  import org.apache.maven.plugins.annotations.Mojo;
28  import org.apache.maven.plugins.annotations.Parameter;
29  import org.apache.maven.plugins.annotations.ResolutionScope;
30  import org.apache.maven.surefire.suite.RunResult;
31  import org.apache.tools.ant.ExitStatusException;
32  import org.apache.tools.ant.taskdefs.optional.testing.BuildTimeoutException;
33  import org.codehaus.plexus.util.IOUtil;
34  import org.codehaus.plexus.util.StringUtils;
35  
36  /**
37   * Wrap the Ant executions to catch their build result and store a Surefire/Failsafe compliant summary file. Typical
38   * usage is the execution of Ant commands performing some tests.
39   *
40   * @see VerifyMojo
41   */
42  @Mojo(name = "integration-test", defaultPhase = LifecyclePhase.INTEGRATION_TEST, threadSafe = true, //
43  requiresProject = true, requiresDependencyResolution = ResolutionScope.TEST)
44  public class IntegrationTestMojo extends AntBuildMojo {
45  
46      private static final String FAILSAFE_IN_PROGRESS_CONTEXT_KEY = "failsafe-in-progress";
47  
48      /**
49       * That property is ignored.
50       *
51       * @deprecated Since 2.0. Now never fail during integration-test and rely on verify for exception raise.
52       */
53      @Deprecated
54      @Parameter(defaultValue = "true", property = "maven.test.failure.ignore")
55      protected boolean testFailureIgnore;
56  
57      /**
58       * The summary file to write integration test results to.
59       */
60      @Parameter(defaultValue = "${project.build.directory}/nxtools-reports/nxtools-summary.xml", required = true)
61      protected File summaryFile;
62  
63      /**
64       * Set this to {@code true} to skip running integration tests.
65       *
66       * @since 2.0
67       */
68      @Parameter(property = "skipITs")
69      protected boolean skipITs;
70  
71      /**
72       * The character encoding scheme to be applied. Defaults to {@link AntBuildMojo#getEncoding()} if not defined.
73       *
74       * @since 2.0
75       * @see AntBuildMojo#encoding
76       */
77      @Parameter(defaultValue = "${project.reporting.outputEncoding}")
78      protected String reportingEncoding;
79  
80      @Override
81      public String getEncoding() {
82          if (StringUtils.isEmpty(reportingEncoding)) {
83              reportingEncoding = super.getEncoding();
84          }
85          return reportingEncoding;
86      }
87  
88      @Override
89      public void execute() throws MojoExecutionException, MojoFailureException {
90          if (skipITs) {
91              getLog().info("Tests are skipped.");
92              return;
93          }
94          RunResult result = RunResult.noTestsRun();
95          boolean failFast = failOnError;
96          // Ensure exception raise from AntBuildMojo#execute
97          failOnError = true;
98          File[] testBuildFiles = getBuildFiles();
99          for (File file : testBuildFiles) {
100             buildFiles = null;
101             buildFile = file;
102             try {
103                 super.execute();
104                 result = result.aggregate(new RunResult(1, 0, 0, 0));
105             } catch (MojoFailureException | MojoExecutionException e) {
106                 if (e.getCause() instanceof ExitStatusException) {
107                     ExitStatusException exit = (ExitStatusException) e.getCause();
108                     getLog().debug("Result: " + exit.getStatus());
109                     getLog().debug(exit.getMessage());
110                     result = result.aggregate(new RunResult(1, 1, 0, 0));
111                 } else {
112                     Throwable cause = e.getCause();
113                     if (cause == null) {
114                         cause = e;
115                     }
116                     getLog().error(cause.getMessage(), cause);
117                     result = result.aggregate(new RunResult(1, 0, 1, 0, cause.getMessage(),
118                             cause instanceof BuildTimeoutException));
119                 }
120                 if (failFast) {
121                     break;
122                 }
123             }
124         }
125         writeSummary(result);
126     }
127 
128     /**
129      * @since 2.0.5
130      */
131     protected void writeSummary(RunResult summary) throws MojoExecutionException {
132         if (!summaryFile.getParentFile().isDirectory()) {
133             summaryFile.getParentFile().mkdirs();
134         }
135         FileOutputStream fout = null;
136         FileInputStream fin = null;
137         try {
138             Object token = getPluginContext().get(FAILSAFE_IN_PROGRESS_CONTEXT_KEY);
139             summary.writeSummary(summaryFile, token != null, getEncoding());
140         } catch (IOException e) {
141             throw new MojoExecutionException(e.getMessage(), e);
142         } finally {
143             IOUtil.close(fin);
144             IOUtil.close(fout);
145         }
146         getPluginContext().put(FAILSAFE_IN_PROGRESS_CONTEXT_KEY, FAILSAFE_IN_PROGRESS_CONTEXT_KEY);
147     }
148 
149 }