geronimo-scm mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From pra...@apache.org
Subject svn commit: r481080 - in /geronimo/server/trunk: maven-plugins/testsuite-maven-plugin/ maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ testsuite/ testsuite/src/main/ testsuite/src/main/resources/
Date Thu, 30 Nov 2006 21:08:25 GMT
Author: prasad
Date: Thu Nov 30 13:08:22 2006
New Revision: 481080

URL: http://svn.apache.org/viewvc?view=rev&rev=481080
Log:
* introduced a 'summarize' goal that will be executed in the post-site phase.
* goal will create/update a table in a html file with the summary of results.
* table will maintain the results of 'n' most recent tests.
* test results will be deployed to a numbered directory at the site location.
* this will help in maintaining results from previous test runs.

Added:
    geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ResultsSummaryMojo.java
  (with props)
    geronimo/server/trunk/testsuite/src/main/
    geronimo/server/trunk/testsuite/src/main/resources/
    geronimo/server/trunk/testsuite/src/main/resources/ResultsSummary.html   (with props)
Modified:
    geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/pom.xml
    geronimo/server/trunk/testsuite/pom.xml

Modified: geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/pom.xml?view=diff&rev=481080&r1=481079&r2=481080
==============================================================================
--- geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/pom.xml (original)
+++ geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/pom.xml Thu Nov 30 13:08:22
2006
@@ -61,6 +61,11 @@
             <artifactId>jtidy</artifactId>
             <version>8.0-SNAPSHOT</version>
         </dependency>
+        <dependency>
+            <groupId>ant</groupId>
+            <artifactId>ant-jsch</artifactId>
+            <version>1.6.5</version>
+        </dependency>
     </dependencies>
 
     <build>

Added: geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ResultsSummaryMojo.java
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ResultsSummaryMojo.java?view=auto&rev=481080
==============================================================================
--- geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ResultsSummaryMojo.java
(added)
+++ geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ResultsSummaryMojo.java
Thu Nov 30 13:08:22 2006
@@ -0,0 +1,564 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *  http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied.  See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+package org.apache.geronimo.mavenplugins.testsuite;
+
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+import org.w3c.dom.Document;
+import org.w3c.dom.Element;
+import org.w3c.dom.Node;
+import org.w3c.dom.NodeList;
+import org.w3c.dom.Text;
+import org.w3c.tidy.Tidy;
+import org.xml.sax.ErrorHandler;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.SAXParseException;
+
+import javax.xml.transform.Transformer;
+import javax.xml.transform.TransformerFactory;
+import javax.xml.transform.TransformerException;
+import javax.xml.transform.TransformerConfigurationException;
+import javax.xml.transform.dom.DOMSource; 
+import javax.xml.transform.stream.StreamResult; 
+
+
+import org.apache.geronimo.genesis.MojoSupport;
+import org.apache.geronimo.genesis.ant.AntHelper;
+
+import org.apache.maven.model.DistributionManagement;
+import org.apache.maven.project.MavenProject;
+import org.apache.maven.plugin.MojoExecutionException;
+import org.apache.maven.plugin.MojoFailureException;
+
+import org.codehaus.plexus.util.FileUtils;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Property;
+import org.apache.tools.ant.taskdefs.XmlProperty;
+import org.apache.tools.ant.taskdefs.optional.ssh.Scp;
+
+/**
+ * Download the ResultsSummary.html file from the site url.
+ * Update it with success rate (in percentage) of the results from each of the top level
testsuites.
+ * Upload the file back again.
+ * 
+ * @goal summarize
+ *
+ * @version $Rev$ $Date$
+ */
+public class ResultsSummaryMojo
+extends MojoSupport
+{
+    /**
+     * @component
+     */
+    protected AntHelper ant;
+
+    /**
+     * @parameter default-value="${project.build.directory}"
+     * @read-only
+     */
+    private File targetDirectory;
+
+    /**
+    * The maven project.
+    *
+    * @parameter expression="${project}"
+    * @required
+    * @readonly
+    */
+    protected MavenProject project = null;
+
+    /**
+     * The username
+     * 
+     * @parameter expression="${username}" default-value="${user.name}"
+     */
+    private String username;
+
+    /**
+     * The password
+     * 
+     * @parameter expression="${password}"
+     */
+    private String password;
+
+    /**
+     * The passphrase
+     * 
+     * @parameter expression="${passphrase}" default-value=" "
+     */
+    private String passphrase;
+
+    /**
+     * The passphrase
+     * 
+     * @parameter expression="${buildNumber}"
+     */
+    private String buildNumber;
+
+    /**
+     * show results for only these many tests.
+     * 
+     * @parameter expression="${numberShown}" default-value="7"
+     */
+    private int numberShown;
+
+
+    private NumberFormat numberFormat = NumberFormat.getInstance();
+
+    private static final int PCENT = 100;
+
+    private final String resultsFileName = "ResultsSummary.html";
+
+    private Scp scp;
+
+    protected MavenProject getProject()
+    {
+        return project;
+    }
+
+    protected void init() throws MojoExecutionException, MojoFailureException {
+        super.init();
+
+        ant.setProject(getProject());
+
+        scp = (Scp)ant.createTask("scp");
+        scp.setKeyfile("/home/" + username + "/.ssh/id_dsa");
+
+        if ( password != null )
+        {
+            scp.setPassword(password);
+        }
+        else if ( passphrase != null )
+        {
+            scp.setPassphrase(passphrase);
+        }
+        scp.setTrust(true);
+    }
+
+    protected void doExecute() throws Exception {
+
+        File currentSiteDirectory = new File(targetDirectory, "/site");
+        if ( !currentSiteDirectory.exists() )
+        {
+            log.warn("No site directory here");
+            return;
+        }
+
+
+        // Download ResultsSummary.html and parse it.
+        File resultsFile = null;
+        try
+        {
+            downloadHTML();
+            resultsFile = new File(targetDirectory, resultsFileName);            
+        }
+        catch ( Exception e )
+        {
+            log.warn("Download failed. " + e.getMessage());
+        }
+
+        Tidy tidy = new Tidy();
+        tidy.setQuiet(true);
+        tidy.setShowWarnings(false);
+
+
+
+        if ( resultsFile == null || !resultsFile.exists() )
+        {
+            log.info( resultsFileName + " could not be downloaded. Using the template to
create anew");
+            resultsFile = new File(project.getBasedir(), "src/main/resources/" + resultsFileName);
+        }
+
+        FileInputStream is = new FileInputStream( resultsFile );
+        Document document = tidy.parseDOM(is, null); 
+        is.close();
+
+        File reportsDir = new File(targetDirectory, "surefire-reports");
+        if ( !reportsDir.exists() )
+        {
+            log.warn("No surefire-reports directory here");
+            return;
+        }
+
+        ArrayList files = (ArrayList) FileUtils.getFiles(reportsDir, "TEST-*.xml", null,
true);
+        if ( files.size() > 0 )
+        {
+            document = insertNewColumn(document);
+            if ( document == null )
+            {
+                throw new MojoFailureException("Main table cannot be found in the " + resultsFileName
+ ". The file may be corrupted");
+            }
+        }
+
+        for ( Iterator itr=files.iterator(); itr.hasNext(); )
+        {
+            File file = (File) itr.next();
+            log.debug("working on " + file.getAbsolutePath() );
+            document = processFile(document, file);
+        }
+
+
+        // Use a Transformer for output
+        TransformerFactory tFactory = TransformerFactory.newInstance();
+        Transformer transformer = tFactory.newTransformer();
+
+        // write the document back into a temporary file.
+        File tempFile = new File(targetDirectory, "ResultsSummary-2.html");
+        FileOutputStream os = new FileOutputStream( tempFile );
+        DOMSource source = new DOMSource(document);
+        StreamResult result = new StreamResult(os);
+        transformer.transform(source, result); 
+
+        os.flush();
+        os.close();
+
+        // tidy the document and create/replace ResultsSummary.html in the target directory
+        resultsFile = new File(targetDirectory, resultsFileName);
+        is = new FileInputStream( tempFile );
+        os = new FileOutputStream( resultsFile );
+        tidy.parse(is, os);
+        is.close();
+        os.close();
+
+        // delete the temp file.
+        tempFile.delete();
+
+        try
+        {
+            uploadHTML(resultsFile);
+        }
+        catch ( Exception e )
+        {
+            log.warn("Upload failed. " + e.getMessage());
+        }
+    }
+
+
+    private String getRemoteUri()
+    {
+        String siteUri = project.getDistributionManagement().getSite().getUrl();
+
+        // chop off the protocol
+        int index = siteUri.indexOf("://");
+        siteUri = siteUri.substring(index + 3);
+        log.debug("siteUri uri is " + siteUri);
+
+        // chop off the buildNumber directory at the end. This is used to deploy site files.
+        index = siteUri.lastIndexOf("/");
+        siteUri = siteUri.substring(0, index);
+        log.debug("siteUri uri is " + siteUri);
+
+        // insert : between the host and path
+        index = siteUri.indexOf("/");
+        String remoteUri = siteUri.substring(0, index) + ":" + siteUri.substring(index);
+        log.debug("siteUri uri is " + remoteUri);
+
+
+        // construct the uri using username
+        remoteUri = username + "@" + remoteUri;
+        log.info("Remote uri is " + remoteUri);
+
+        return remoteUri;
+
+    }
+
+
+    /**
+     * Download the html from the remote site where it is has been deployed.
+     */
+    private void downloadHTML()
+    {
+        String remoteUri = getRemoteUri() + "/" + resultsFileName;
+
+        scp.setFile(remoteUri);
+        scp.setTodir(targetDirectory.getAbsolutePath());
+
+        scp.execute();
+    }
+
+
+    /**
+     * Upload the html to the remote site where it will be deployed.
+     */
+    private void uploadHTML(File resultsFile)
+    {
+        String remoteUri = getRemoteUri();
+
+        scp.setFile( resultsFile.getAbsolutePath() );
+        scp.setTodir(remoteUri);
+
+        scp.execute();
+    }
+
+
+    /**
+     * Append a new column for the latest build. Put the build number in the column header
+     */
+    private Document insertNewColumn(Document document)
+    {
+        Element table = getElementById(document.getDocumentElement(), "table", "mainTable");
+        if ( table == null )
+        {
+            log.info("table is null");
+            return null;
+        }
+
+        Element thead = getElementById(table, "thead", "mainTableHead");
+        Element tr = (Element) thead.getFirstChild();
+
+        Element td= document.createElement("TD");
+        td.setAttribute("class", "servers");
+
+        Element anchor = document.createElement("a");
+        anchor.setAttribute("href", "./" + buildNumber + "/surefire-report.html");
+        Text text = document.createTextNode(buildNumber);
+        anchor.appendChild(text);
+
+        td.appendChild(anchor);
+        tr.appendChild(td);
+
+        // increment the cols attribute for the table
+        int cols = tr.getChildNodes().getLength();
+
+        // check for number of columns to be shown. 
+        // Don't take the suite names column into count.
+        if ( cols > (numberShown + 1) )
+        {
+            cols = cleanup(table);
+        }
+
+        table.setAttribute("cols", String.valueOf(cols) );
+
+
+        return document;
+    }
+
+
+    private Document processFile(Document document, File file)
+    {
+        String pcent = getResultsFromFile(file);
+
+        // strip off TEST- and .xml from the filename to get the suitename
+        String fileName = FileUtils.basename(file.getName());
+        fileName = fileName.substring(fileName.indexOf("-") + 1);
+        fileName = fileName.substring(0, fileName.length()-1);
+        document = insertColumn(document, pcent, fileName);
+
+        return document;
+    }
+
+
+    /**
+     * Load the surefire-report xml file as an ANT xml property and get the values of the
results
+     * compute percentage
+     */
+    private String getResultsFromFile(File xmlFile)
+    {
+        String prefix = String.valueOf(System.currentTimeMillis());
+        loadXMLProperty(xmlFile, prefix);
+
+        String tests = ant.getAnt().getProperty(prefix + ".testsuite.tests");
+        String errors = ant.getAnt().getProperty(prefix + ".testsuite.errors");
+        String failures = ant.getAnt().getProperty(prefix + ".testsuite.failures");
+        String skipped = ant.getAnt().getProperty(prefix + ".testsuite.skipped");
+
+        log.debug("tests: " + tests + "; errors:" + errors + "; failures:" + failures + ";
skipped:" + skipped);
+
+        int testsNum = Integer.parseInt(tests);
+        int errorsNum = Integer.parseInt(errors);
+        int failuresNum = Integer.parseInt(failures);
+        int skippedNum = Integer.parseInt(skipped);
+
+        String pcent = computePercentage(testsNum, errorsNum, failuresNum, skippedNum);
+        return pcent;
+    }
+
+
+    /**
+     * http://ant.apache.org/manual/CoreTasks/xmlproperty.html
+     */
+    private void loadXMLProperty(File src, String prefix)
+    {
+        XmlProperty xmlProperty = (XmlProperty)ant.createTask("xmlproperty");
+        xmlProperty.setFile(src);
+        if ( prefix != null )
+        {
+            xmlProperty.setPrefix(prefix);
+        }
+        xmlProperty.setCollapseAttributes(true);
+        xmlProperty.execute();
+        log.debug("Loaded xml file as ant property with prefix " + prefix);
+    }
+
+
+    /**
+     * compute percentage
+     */
+    public String computePercentage( int tests, int errors, int failures, int skipped )
+    {
+        float percentage;
+        if ( tests == 0 )
+        {
+            percentage = 0;
+        }
+        else
+        {
+            percentage = ( (float) ( tests - errors - failures - skipped ) / (float) tests
) * PCENT;
+        }
+
+        return numberFormat.format( percentage );
+    }
+
+
+
+    /**
+     * Insert the rest of the column. If there is no matching row for the suite name, create
a new row.
+     */
+    private Document insertColumn(Document document, String pcent, String suiteName)
+    {
+        log.debug("inserting column");
+
+        Element table = getElementById(document.getDocumentElement(), "table", "mainTable");
+        int cols = Integer.parseInt( table.getAttribute("cols") );
+
+        Element tr = getElementById(table, "tr", suiteName);
+
+        if ( tr != null )
+        {
+            Element td = document.createElement("TD");
+            td.setAttribute("class", "cell");
+
+            Element anchor = document.createElement("a");
+            anchor.setAttribute("href", "./" + buildNumber + "/" + suiteName + "/surefire-report.html");
+            Text text = document.createTextNode(pcent + "%");
+            anchor.appendChild(text);
+
+            td.appendChild(anchor);
+            tr.appendChild(td);
+        }
+        else
+        {
+            log.debug("Creating a new row for a new suite");
+            tr = document.createElement("TR");
+            tr.setAttribute("id", suiteName);
+
+            Element td = document.createElement("TD");
+            td.setAttribute("class", "suite");
+            Text text = document.createTextNode(suiteName);
+            td.appendChild(text);
+            tr.appendChild(td);
+
+            // creating empty cells in the cols for the previous builds.
+            for ( int i=1; i<cols; i++ )
+            {
+                td = document.createElement("TD");
+                td.setAttribute("class", "cell");                
+                tr.appendChild(td);
+            }
+
+            Element anchor = document.createElement("a");
+            anchor.setAttribute("href", "./" + buildNumber + "/" + suiteName + "/surefire-report.html");
+            text = document.createTextNode(pcent + "%");
+            anchor.appendChild(text);
+            td.appendChild(anchor);
+
+            table.appendChild(tr);
+        }
+
+        log.debug("inserted column");
+
+        return document;
+
+    }
+
+
+    /**
+     * Get a child element identified by an ID
+     */
+    private Element getElementById(Element element, String tagName, String id)
+    {
+        log.debug("Searching for tag " + tagName + " with id=" + id);
+
+        Element foundElement = null;
+
+        NodeList nodeList = element.getElementsByTagName(tagName);
+
+        for ( int i=0; i<nodeList.getLength(); i++ )
+        {
+            foundElement = (Element) nodeList.item(i);
+            log.debug("Element is " + foundElement.getTagName() + " " + foundElement.getAttribute("id")
);
+            if ( id.trim().equals(foundElement.getAttribute("id").trim()) )
+            {
+                break;
+            }
+            else
+            {
+                foundElement = null;
+            }
+        }
+
+        return foundElement;
+    }
+
+
+    /**
+     * Removes the oldest test column(s) from the table based on the value set in 'numberShown'
variable
+     */
+    private int cleanup(Element table)
+    {
+        log.info("Removing oldest column");
+
+        NodeList nodeList = table.getElementsByTagName("tr");
+
+        int new_cols = 0;
+        for ( int i=0; i<nodeList.getLength(); i++ )
+        {
+            Element tr = (Element) nodeList.item(i);
+            Element suiteColumn = (Element) tr.getFirstChild();
+            Element removeMe = (Element) suiteColumn.getNextSibling();
+            tr.removeChild(removeMe);
+
+            // get the count from just the header row since only the header has been added
yet
+            if ( i==0 )
+            {
+                new_cols = tr.getChildNodes().getLength();
+            }
+        }
+
+        if ( new_cols > (numberShown + 1) )
+        {
+            new_cols = cleanup(table);
+        }
+
+        log.debug( String.valueOf("Returning cols: " + new_cols) );
+
+        return new_cols;
+    }
+
+}

Propchange: geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ResultsSummaryMojo.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ResultsSummaryMojo.java
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/maven-plugins/testsuite-maven-plugin/src/main/java/org/apache/geronimo/mavenplugins/testsuite/ResultsSummaryMojo.java
------------------------------------------------------------------------------
    svn:mime-type = text/plain

Modified: geronimo/server/trunk/testsuite/pom.xml
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/testsuite/pom.xml?view=diff&rev=481080&r1=481079&r2=481080
==============================================================================
--- geronimo/server/trunk/testsuite/pom.xml (original)
+++ geronimo/server/trunk/testsuite/pom.xml Thu Nov 30 13:08:22 2006
@@ -177,6 +177,9 @@
                                 <goals>
                                     <goal>site-deploy</goal>
                                 </goals>
+                                <parameters>
+                                    <buildNumber>${buildNumber}</buildNumber>
+                                </parameters>
                             </configuration>
                         </execution>
 
@@ -224,7 +227,7 @@
     <distributionManagement>
         <site>
             <id>website</id>
-            <url>scp://people.apache.org/www/geronimo.apache.org/maven/server/testsuite</url>
+            <url>scp://people.apache.org/www/geronimo.apache.org/maven/server/testsuite/${buildNumber}</url>
         </site>
     </distributionManagement>
 
@@ -291,6 +294,23 @@
                         </plugin>
                     </plugins>
                 </pluginManagement>
+
+                <plugins>
+                    <plugin>
+                        <groupId>org.apache.geronimo.plugins</groupId>
+                        <artifactId>testsuite-maven-plugin</artifactId>
+                        <inherited>false</inherited>
+                        <executions>
+                            <execution>
+                                <id>summarize</id>
+                                <phase>post-site</phase>
+                                <goals>
+                                    <goal>summarize</goal>
+                                </goals>
+                            </execution>
+                        </executions>
+                    </plugin>
+                </plugins>
 
             </build>
         </profile>

Added: geronimo/server/trunk/testsuite/src/main/resources/ResultsSummary.html
URL: http://svn.apache.org/viewvc/geronimo/server/trunk/testsuite/src/main/resources/ResultsSummary.html?view=auto&rev=481080
==============================================================================
--- geronimo/server/trunk/testsuite/src/main/resources/ResultsSummary.html (added)
+++ geronimo/server/trunk/testsuite/src/main/resources/ResultsSummary.html Thu Nov 30 13:08:22
2006
@@ -0,0 +1,25 @@
+<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
+<html>
+<head>
+  <title>Summary of Testsuite Results</title>
+  <meta content="text/html; CHARSET=iso-8859-1" http-equiv="Content-Type">
+  <style type="text/css">
+  .servers  { background-color:aqua; text-align:center }
+  .suite    { background-color:olive;text-align:center } 
+  .cell     { text-align:center } 
+  </style>
+</head>
+<body>
+<h1>Summary of Testsuite Results</h1>
+<p>
+The success rate of the results (as a percentage) from the tests run against Geronimo for
the 7 recent builds.
+</p>
+<table cols="1" border="5" id="mainTable">
+  <thead id="mainTableHead">
+  <tr>
+    <td class="servers">Suite\Servers</td>
+  </tr>
+  </thead>
+</table>
+</body>
+</html>

Propchange: geronimo/server/trunk/testsuite/src/main/resources/ResultsSummary.html
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: geronimo/server/trunk/testsuite/src/main/resources/ResultsSummary.html
------------------------------------------------------------------------------
    svn:keywords = Date Revision

Propchange: geronimo/server/trunk/testsuite/src/main/resources/ResultsSummary.html
------------------------------------------------------------------------------
    svn:mime-type = text/html



Mime
View raw message