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: 524717 $ $Date: 2007-04-01 23:39:19 -0400 (Sun, 01 Apr 2007) $ 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 = Float.parseFloat(parent_time) + Float.parseFloat(time); 182 183 writeParentXML(testsNum,skippedNum,errorsNum,failuresNum,timeNum,artifactName,parentSurefireXMLFile); 184 } 185 } 186 187 /** 188 * http://ant.apache.org/manual/CoreTasks/xmlproperty.html 189 */ 190 private void loadXMLProperty(File src, String prefix) 191 { 192 XmlProperty xmlProperty = (XmlProperty)ant.createTask("xmlproperty"); 193 xmlProperty.setFile(src); 194 if ( prefix != null ) 195 { 196 xmlProperty.setPrefix(prefix); 197 } 198 xmlProperty.setCollapseAttributes(true); 199 xmlProperty.execute(); 200 } 201 202 /** 203 * (over)writes the surefire xml file in the parent's surefire-reports dir 204 */ 205 private void writeParentXML(int testsNum,int skippedNum,int errorsNum, 206 int failuresNum, float timeNum, 207 String artifactName, File parentSurefireXMLFile ) throws IOException { 208 209 final String header = "<?xml version=\"1.0\" encoding=\"UTF-8\" ?>"; 210 String testSuite = "<testsuite errors=\"" + errorsNum + "\" skipped=\"" + skippedNum + "\" tests=\"" + testsNum + "\" time=\"" + timeNum + "\" failures=\"" + failuresNum + "\" name=\"" + artifactName + "#.\"/>"; 211 212 String parentSurefireXMLFileName = parentSurefireXMLFile.getAbsolutePath(); 213 214 log.debug(testSuite); 215 216 FileUtils.fileWrite(parentSurefireXMLFileName, header + "\n" + testSuite); 217 218 return; 219 } 220 }