001 /**
002 * Licensed to the Apache Software Foundation (ASF) under one
003 * or more contributor license agreements. See the NOTICE file
004 * distributed with this work for additional information
005 * regarding copyright ownership. The ASF licenses this file
006 * to you under the Apache License, Version 2.0 (the
007 * "License"); you may not use this file except in compliance
008 * with the License. You may obtain a copy of the License at
009 *
010 * http://www.apache.org/licenses/LICENSE-2.0
011 *
012 * Unless required by applicable law or agreed to in writing,
013 * software distributed under the License is distributed on an
014 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
015 * KIND, either express or implied. See the License for the
016 * specific language governing permissions and limitations
017 * under the License.
018 */
019
020 package org.apache.geronimo.mavenplugins.testsuite;
021
022 import java.io.File;
023 import java.io.IOException;
024
025 import java.util.ArrayList;
026
027 import org.codehaus.mojo.pluginsupport.MojoSupport;
028 import org.codehaus.mojo.pluginsupport.ant.AntHelper;
029
030 import org.apache.maven.project.MavenProject;
031
032 import org.apache.maven.plugin.MojoExecutionException;
033 import org.apache.maven.plugin.MojoFailureException;
034 import org.codehaus.plexus.util.FileUtils;
035
036 import org.apache.tools.ant.Project;
037 import org.apache.tools.ant.taskdefs.Property;
038 import org.apache.tools.ant.taskdefs.XmlProperty;
039
040 /**
041 * Create a surefire xml file by concatenating the surefire xmls of the child poms that are invoked using maven-maven-plugin:invoke
042 *
043 * @goal generate-surefire-xml
044 *
045 * @version $Rev: 706640 $ $Date: 2008-10-21 14:44:05 +0000 (Tue, 21 Oct 2008) $
046 */
047 public class SurefireXMLGeneratorMojo
048 extends MojoSupport
049 {
050 /**
051 * @component
052 */
053 protected AntHelper ant;
054
055 /**
056 * @parameter default-value="${project.build.directory}"
057 * @read-only
058 */
059 private File currentBuildDirectory;
060
061 private File currentReportsDirectory;
062
063 /**
064 * @parameter default-value="${project.basedir}"
065 * @read-only
066 */
067 private File currentBaseDirectory;
068
069 /**
070 * @parameter default-value="${project.parent.basedir}/target"
071 * @read-only
072 */
073 private File parentBuildDirectory;
074
075 private File parentReportsDirectory;
076
077 /**
078 * Sometimes it is necessary to generate the surefire xml in a grand parent project because
079 * the current pom was not invoked by the maven-maven-plugin by a parent project.
080 * Such a parent project whose packaging is set to pom will not transfer the surefire data to it's parent.
081 * So we will directly write to the grandparent's surefire-reports dir.
082 *
083 * @parameter default-value="false"
084 */
085 private boolean grandParent;
086
087 //
088 // MojoSupport Hooks
089 //
090
091 /**
092 * The maven project.
093 *
094 * @parameter expression="${project}"
095 * @required
096 * @readonly
097 */
098 protected MavenProject project = null;
099
100 protected MavenProject getProject()
101 {
102 return project;
103 }
104
105 protected void init() throws MojoExecutionException, MojoFailureException {
106 super.init();
107
108 ant.setProject(getProject());
109
110 currentReportsDirectory = new File(currentBuildDirectory, "surefire-reports");
111 if (grandParent) {
112 log.debug(getProject().getParent().getParent().getArtifactId() + " -- " + getProject().getParent().getParent().getBasedir().getAbsolutePath());
113 parentBuildDirectory = new File(getProject().getParent().getParent().getBasedir(), "target");
114 }
115 parentReportsDirectory = new File(parentBuildDirectory, "surefire-reports");
116 log.info("Updating directory: " + parentReportsDirectory.getAbsolutePath() );
117 }
118
119 protected void doExecute() throws Exception {
120 if ( !currentReportsDirectory.exists() )
121 {
122 log.info("No surefire-reports directory here");
123 return;
124 }
125
126 String parent_tests = "0";
127 String parent_skipped = "0";
128 String parent_errors = "0";
129 String parent_failures = "0";
130 String parent_time = "0";
131
132 String artifactName = FileUtils.filename(currentBaseDirectory.getAbsolutePath());
133 if ( !parentReportsDirectory.exists() )
134 {
135 parentReportsDirectory.mkdirs();
136 }
137 File parentSurefireXMLFile = new File(parentReportsDirectory, "TEST-" + artifactName + ".xml");
138 if ( parentSurefireXMLFile.exists() )
139 {
140 parentSurefireXMLFile.delete();
141 }
142
143 if (grandParent) {
144 artifactName = project.getParent().getBasedir().getName() + "@" + artifactName;
145 }
146
147 ArrayList xmlFiles = (ArrayList) FileUtils.getFiles(currentReportsDirectory, "TEST*.xml", null);
148 for ( int i=0; i < xmlFiles.size(); i++ )
149 {
150 File xmlFile = (File) xmlFiles.get(i);
151 log.info("Loading surefire xml for xmlproperty: " + xmlFile.getAbsolutePath());
152
153 String prefix = String.valueOf(System.currentTimeMillis());
154 loadXMLProperty(xmlFile, prefix);
155
156 String tests = ant.getAnt().getProperty(prefix + ".testsuite.tests");
157 String skipped = ant.getAnt().getProperty(prefix + ".testsuite.skipped");
158 String errors = ant.getAnt().getProperty(prefix + ".testsuite.errors");
159 String failures = ant.getAnt().getProperty(prefix + ".testsuite.failures");
160 String time = ant.getAnt().getProperty(prefix + ".testsuite.time");
161 log.debug("tests=" + tests + "; skipped=" + skipped + ", errors=" + errors + ", failures=" + failures + ", time=" + time);
162
163 if ( parentSurefireXMLFile.exists() )
164 {
165 log.info("Loading parent surefire xml for xmlproperty: " + parentSurefireXMLFile.getAbsolutePath() );
166 String parentPrefix = "parent" + prefix;
167 loadXMLProperty(parentSurefireXMLFile, parentPrefix);
168
169 parent_tests = ant.getAnt().getProperty(parentPrefix + ".testsuite.tests");
170 parent_skipped = ant.getAnt().getProperty(parentPrefix + ".testsuite.skipped");
171 parent_errors = ant.getAnt().getProperty(parentPrefix + ".testsuite.errors");
172 parent_failures = ant.getAnt().getProperty(parentPrefix + ".testsuite.failures");
173 parent_time = ant.getAnt().getProperty(parentPrefix + ".testsuite.time");
174 log.debug("tests=" + parent_tests + "; skipped=" + parent_skipped + ", errors=" + parent_errors + ", failures=" + parent_failures + ", time=" + parent_time);
175 }
176
177 int testsNum = Integer.parseInt(parent_tests) + Integer.parseInt(tests);
178 int skippedNum = Integer.parseInt(parent_skipped) + Integer.parseInt(skipped);
179 int errorsNum = Integer.parseInt(parent_errors) + Integer.parseInt(errors);
180 int failuresNum = Integer.parseInt(parent_failures) + Integer.parseInt(failures);
181 float timeNum = getTime(parent_time) + getTime(time);
182
183 writeParentXML(testsNum,skippedNum,errorsNum,failuresNum,timeNum,artifactName,parentSurefireXMLFile);
184 }
185 }
186
187 private float getTime(String time) {
188 time = time.replaceAll(",","");
189 return Float.parseFloat(time);
190 }
191
192 /**
193 * http://ant.apache.org/manual/CoreTasks/xmlproperty.html
194 */
195 private void loadXMLProperty(File src, String prefix)
196 {
197 XmlProperty xmlProperty = (XmlProperty)ant.createTask("xmlproperty");
198 xmlProperty.setFile(src);
199 if ( prefix != null )
200 {
201 xmlProperty.setPrefix(prefix);
202 }
203 xmlProperty.setCollapseAttributes(true);
204 xmlProperty.execute();
205 }
206
207 /**
208 * (over)writes the surefire xml file in the parent's surefire-reports dir
209 */
210 private void writeParentXML(int testsNum,int skippedNum,int errorsNum,
211 int failuresNum, float timeNum,
212 String artifactName, File parentSurefireXMLFile ) throws IOException {
213
214 final String header = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>";
215 String testSuite = "<testsuite errors=\"" + errorsNum + "\" skipped=\"" + skippedNum + "\" tests=\"" + testsNum + "\" time=\"" + timeNum + "\" failures=\"" + failuresNum + "\" name=\"" + artifactName + "#.\"/>";
216
217 String parentSurefireXMLFileName = parentSurefireXMLFile.getAbsolutePath();
218
219 log.debug(testSuite);
220
221 FileUtils.fileWrite(parentSurefireXMLFileName, header + "\n" + testSuite);
222
223 return;
224 }
225 }