View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one
3    * or more contributor license agreements.  See the NOTICE file
4    * distributed with this work for additional information
5    * regarding copyright ownership.  The ASF licenses this file
6    * to you under the Apache License, Version 2.0 (the
7    * "License"); you may not use this file except in compliance
8    * with the License.  You may obtain a copy of the License at
9    *
10   *   http://www.apache.org/licenses/LICENSE-2.0
11   *
12   * Unless required by applicable law or agreed to in writing,
13   * software distributed under the License is distributed on an
14   * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15   * KIND, either express or implied.  See the License for the
16   * specific language governing permissions and limitations
17   * under the License.
18   */
19  package org.apache.maven.plugins.invoker;
20  
21  import java.io.File;
22  import java.io.IOException;
23  import java.io.Reader;
24  
25  import org.apache.maven.plugin.AbstractMojo;
26  import org.apache.maven.plugin.MojoExecutionException;
27  import org.apache.maven.plugin.MojoFailureException;
28  import org.apache.maven.plugins.annotations.LifecyclePhase;
29  import org.apache.maven.plugins.annotations.Mojo;
30  import org.apache.maven.plugins.annotations.Parameter;
31  import org.apache.maven.plugins.invoker.model.io.xpp3.BuildJobXpp3Reader;
32  import org.codehaus.plexus.util.ReaderFactory;
33  import org.codehaus.plexus.util.xml.pull.XmlPullParserException;
34  
35  /**
36   * Checks the results of maven-invoker-plugin based integration tests and fails the build if any tests failed.
37   *
38   * @author Olivier Lamy
39   * @since 1.4
40   */
41  @Mojo(name = "verify", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
42  public class VerifyMojo extends AbstractMojo {
43  
44      /**
45       * Flag used to suppress certain invocations. This is useful in tailoring the build using profiles.
46       *
47       * @since 1.1
48       */
49      @Parameter(property = "invoker.skip", defaultValue = "false")
50      private boolean skipInvocation;
51  
52      /**
53       * Base directory where all build reports are read from.
54       *
55       * @since 1.4
56       */
57      @Parameter(property = "invoker.reportsDirectory", defaultValue = "${project.build.directory}/invoker-reports")
58      private File reportsDirectory;
59  
60      /**
61       * A flag controlling whether failures of the sub builds should fail the main build, too. If set to
62       * <code>true</code>, the main build will proceed even if one or more sub builds failed.
63       *
64       * @since 1.3
65       */
66      @Parameter(property = "maven.test.failure.ignore", defaultValue = "false")
67      private boolean ignoreFailures;
68  
69      /**
70       * Flag used to suppress the summary output notifying of successes and failures. If set to <code>true</code>, the
71       * only indication of the build's success or failure will be the effect it has on the main build (if it fails, the
72       * main build should fail as well).
73       */
74      @Parameter(defaultValue = "false")
75      private boolean suppressSummaries;
76  
77      /**
78       * Set this to <code>true</code> to cause a failure if there are no projects to invoke.
79       *
80       * @since 1.9
81       */
82      @Parameter(property = "invoker.failIfNoProjects")
83      private Boolean failIfNoProjects;
84  
85      /**
86       * Set to <code>true</code> to output build.log to mojo log in case of failed jobs.
87       *
88       * @since 3.2.2
89       */
90      @Parameter(property = "invoker.streamLogsOnFailures", defaultValue = "false")
91      private boolean streamLogsOnFailures;
92  
93      /**
94       * Invokes Maven on the configured test projects.
95       *
96       * @throws org.apache.maven.plugin.MojoExecutionException If the goal encountered severe errors.
97       * @throws org.apache.maven.plugin.MojoFailureException If any of the Maven builds failed.
98       */
99      public void execute() throws MojoExecutionException, MojoFailureException {
100         if (skipInvocation) {
101             getLog().info("Skipping invocation per configuration."
102                     + " If this is incorrect, ensure the skipInvocation parameter is not set to true.");
103             return;
104         }
105 
106         File[] reportFiles = ReportUtils.getReportFiles(reportsDirectory);
107         if (reportFiles.length <= 0) {
108             if (Boolean.TRUE.equals(failIfNoProjects)) {
109                 throw new MojoFailureException("No projects to invoke!");
110             }
111             getLog().info("No invoker report files found, nothing to check.");
112             return;
113         }
114 
115         BuildJobXpp3Reader reader = new BuildJobXpp3Reader();
116 
117         InvokerSession invokerSession = new InvokerSession();
118 
119         for (File reportFile : reportFiles) {
120             try (Reader xmlReader = ReaderFactory.newXmlReader(reportFile)) {
121                 invokerSession.addJob(reader.read(xmlReader));
122             } catch (XmlPullParserException e) {
123                 throw new MojoExecutionException("Failed to parse report file: " + reportFile, e);
124             } catch (IOException e) {
125                 throw new MojoExecutionException("Failed to read report file: " + reportFile, e);
126             }
127         }
128 
129         if (streamLogsOnFailures) {
130             invokerSession.logFailedBuildLog(getLog(), ignoreFailures);
131         }
132 
133         if (!suppressSummaries) {
134             invokerSession.logSummary(getLog(), ignoreFailures);
135         }
136 
137         invokerSession.handleFailures(getLog(), ignoreFailures);
138     }
139 }