KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > mavenplugins > testsuite > ResultsSummaryMojo


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
20 package org.apache.geronimo.mavenplugins.testsuite;
21
22 import java.io.File JavaDoc;
23 import java.io.FileInputStream JavaDoc;
24 import java.io.FileOutputStream JavaDoc;
25 import java.io.IOException JavaDoc;
26 import java.text.NumberFormat JavaDoc;
27 import java.util.ArrayList JavaDoc;
28 import java.util.Iterator JavaDoc;
29
30 import org.w3c.dom.Document JavaDoc;
31 import org.w3c.dom.Element JavaDoc;
32 import org.w3c.dom.Node JavaDoc;
33 import org.w3c.dom.NodeList JavaDoc;
34 import org.w3c.dom.Text JavaDoc;
35 import org.w3c.tidy.Tidy;
36 import org.xml.sax.ErrorHandler JavaDoc;
37 import org.xml.sax.InputSource JavaDoc;
38 import org.xml.sax.SAXException JavaDoc;
39 import org.xml.sax.SAXParseException JavaDoc;
40
41 import javax.xml.transform.Transformer JavaDoc;
42 import javax.xml.transform.TransformerFactory JavaDoc;
43 import javax.xml.transform.TransformerException JavaDoc;
44 import javax.xml.transform.TransformerConfigurationException JavaDoc;
45 import javax.xml.transform.dom.DOMSource JavaDoc;
46 import javax.xml.transform.stream.StreamResult JavaDoc;
47
48
49 import org.apache.geronimo.genesis.MojoSupport;
50 import org.apache.geronimo.genesis.ant.AntHelper;
51
52 import org.apache.maven.model.DistributionManagement;
53 import org.apache.maven.project.MavenProject;
54 import org.apache.maven.plugin.MojoExecutionException;
55 import org.apache.maven.plugin.MojoFailureException;
56 import org.apache.maven.settings.Settings;
57 import org.apache.maven.settings.Server;
58
59 import org.codehaus.plexus.util.FileUtils;
60
61 import org.apache.tools.ant.Project;
62 import org.apache.tools.ant.taskdefs.Property;
63 import org.apache.tools.ant.taskdefs.XmlProperty;
64 import org.apache.tools.ant.taskdefs.optional.ssh.Scp;
65
66 /**
67  * Download the ResultsSummary.html file from the site url.
68  * Update it with success rate (in percentage) of the results from each of the top level testsuites.
69  * Upload the file back again.
70  *
71  * @goal summarize
72  *
73  * @version $Rev: 485709 $ $Date: 2006-12-11 10:26:58 -0500 (Mon, 11 Dec 2006) $
74  */

75 public class ResultsSummaryMojo
76 extends MojoSupport
77 {
78     /**
79      * @component
80      */

81     protected AntHelper ant;
82
83     /**
84      * @parameter default-value="${project.build.directory}"
85      * @read-only
86      */

87     private File JavaDoc targetDirectory;
88
89     /**
90     * The maven project.
91     *
92     * @parameter expression="${project}"
93     * @required
94     * @readonly
95     */

96     protected MavenProject project = null;
97
98     /**
99     * The build settings.
100     *
101     * @parameter expression="${settings}" default-value="${settings}
102     * @required
103     * @readonly
104     */

105     protected Settings settings;
106
107     /**
108      * The username
109      *
110      * @parameter expression="${username}"
111      */

112     private String JavaDoc username;
113
114     /**
115      * The password
116      *
117      * @parameter expression="${password}"
118      */

119     private String JavaDoc password;
120
121
122     /**
123      * The passphrase
124      *
125      * @parameter expression="${passphrase}"
126      */

127     private String JavaDoc passphrase;
128
129     /**
130      * The keyfile
131      *
132      * @parameter expression="${keyfile}"
133      */

134     private String JavaDoc keyFile;
135
136     /**
137      * The passphrase
138      *
139      * @parameter expression="${buildNumber}"
140      */

141     private String JavaDoc buildNumber;
142
143     /**
144      * show results for only these many tests.
145      *
146      * @parameter expression="${numberShown}" default-value="8"
147      */

148     private int numberShown;
149
150
151     private NumberFormat JavaDoc numberFormat = NumberFormat.getInstance();
152
153     private static final int PCENT = 100;
154
155     private final String JavaDoc resultsFileName = "ResultsSummary.html";
156
157     private Server server = null;
158
159     private Scp scp;
160
161     protected MavenProject getProject()
162     {
163         return project;
164     }
165
166     protected void init() throws MojoExecutionException, MojoFailureException {
167         super.init();
168
169         ant.setProject(getProject());
170
171         scp = (Scp)ant.createTask("scp");
172
173
174         String JavaDoc siteId = project.getDistributionManagement().getSite().getId();
175         server = settings.getServer(siteId);
176
177         scp.setKeyfile(getKeyFile());
178
179         scp.setPassword(getPassword());
180         scp.setPassphrase(getPassphrase());
181         scp.setTrust(true);
182     }
183
184     private String JavaDoc getKeyFile() {
185        if (keyFile != null) {
186            return keyFile;
187        }
188        else if (server != null && server.getPrivateKey() != null) {
189            return server.getPrivateKey();
190        }
191
192        return "/home/" + getUsername() + "/.ssh/id_dsa";
193     }
194
195     private String JavaDoc getUsername() {
196        if (username != null) {
197            return username;
198        }
199        else if (server != null && server.getUsername() != null) {
200            return server.getUsername();
201        }
202
203        return System.getProperty("user.name");
204     }
205
206     private String JavaDoc getPassword() {
207         if (password != null) {
208             return password;
209         }
210         else if (server != null && server.getPassword() != null) {
211             return server.getPassword();
212         }
213
214         return " ";
215     }
216
217     private String JavaDoc getPassphrase() {
218         if (passphrase != null) {
219             return passphrase;
220         }
221         else if (server != null && server.getPassphrase() != null) {
222             return server.getPassphrase();
223         }
224
225         return " ";
226     }
227
228
229
230     /**
231      * called by execute from super
232      */

233     protected void doExecute() throws Exception JavaDoc {
234
235         File JavaDoc currentSiteDirectory = new File JavaDoc(targetDirectory, "/site");
236         if ( !currentSiteDirectory.exists() )
237         {
238             log.warn("No site directory here");
239             return;
240         }
241
242
243         // Download ResultsSummary.html and parse it.
244
File JavaDoc resultsFile = null;
245         try
246         {
247             downloadHTML();
248             resultsFile = new File JavaDoc(targetDirectory, resultsFileName);
249         }
250         catch ( Exception JavaDoc e )
251         {
252             log.warn("Download failed. " + e.getMessage());
253         }
254
255         Tidy tidy = new Tidy();
256         tidy.setQuiet(true);
257         tidy.setShowWarnings(false);
258
259
260
261         if ( resultsFile == null || !resultsFile.exists() )
262         {
263             log.info( resultsFileName + " could not be downloaded. Using the template to create anew");
264             resultsFile = new File JavaDoc(project.getBasedir(), "src/main/resources/" + resultsFileName);
265         }
266
267         FileInputStream JavaDoc is = new FileInputStream JavaDoc( resultsFile );
268         Document JavaDoc document = tidy.parseDOM(is, null);
269         is.close();
270
271         File JavaDoc reportsDir = new File JavaDoc(targetDirectory, "surefire-reports");
272         if ( !reportsDir.exists() )
273         {
274             log.warn("No surefire-reports directory here");
275             return;
276         }
277
278         ArrayList JavaDoc files = (ArrayList JavaDoc) FileUtils.getFiles(reportsDir, "TEST-*.xml", null, true);
279         if ( files.size() > 0 )
280         {
281             document = insertNewColumn(document);
282             if ( document == null )
283             {
284                 throw new MojoFailureException("Main table cannot be found in the " + resultsFileName + ". The file may be corrupted");
285             }
286         }
287
288         for ( Iterator JavaDoc itr=files.iterator(); itr.hasNext(); )
289         {
290             File JavaDoc file = (File JavaDoc) itr.next();
291             log.debug("working on " + file.getAbsolutePath() );
292             document = processFile(document, file);
293         }
294
295
296         // Use a Transformer for output
297
TransformerFactory JavaDoc tFactory = TransformerFactory.newInstance();
298         Transformer JavaDoc transformer = tFactory.newTransformer();
299
300         // write the document back into a temporary file.
301
File JavaDoc tempFile = new File JavaDoc(targetDirectory, "ResultsSummary-2.html");
302         FileOutputStream JavaDoc os = new FileOutputStream JavaDoc( tempFile );
303         DOMSource JavaDoc source = new DOMSource JavaDoc(document);
304         StreamResult JavaDoc result = new StreamResult JavaDoc(os);
305         transformer.transform(source, result);
306
307         os.flush();
308         os.close();
309
310         // tidy the document and create/replace ResultsSummary.html in the target directory
311
resultsFile = new File JavaDoc(targetDirectory, resultsFileName);
312         is = new FileInputStream JavaDoc( tempFile );
313         os = new FileOutputStream JavaDoc( resultsFile );
314         tidy.parse(is, os);
315         is.close();
316         os.close();
317
318         // delete the temp file.
319
tempFile.delete();
320
321         try
322         {
323             uploadHTML(resultsFile);
324         }
325         catch ( Exception JavaDoc e )
326         {
327             log.warn("Upload failed. " + e.getMessage());
328         }
329     }
330
331
332     private String JavaDoc getRemoteUri()
333     {
334         String JavaDoc siteUri = project.getDistributionManagement().getSite().getUrl();
335
336         // chop off the protocol
337
int index = siteUri.indexOf("://");
338         siteUri = siteUri.substring(index + 3);
339         log.debug("siteUri uri is " + siteUri);
340
341         // chop off the buildNumber directory at the end. This is used to deploy site files.
342
index = siteUri.lastIndexOf("/");
343         siteUri = siteUri.substring(0, index);
344         log.debug("siteUri uri is " + siteUri);
345
346         // insert : between the host and path
347
index = siteUri.indexOf("/");
348         String JavaDoc remoteUri = siteUri.substring(0, index) + ":" + siteUri.substring(index);
349         log.debug("siteUri uri is " + remoteUri);
350
351
352         // construct the uri using username
353
remoteUri = getUsername() + ":" + getPassword() + "@" + remoteUri;
354         log.info("Remote uri is " + remoteUri);
355
356         return remoteUri;
357
358     }
359
360
361     /**
362      * Download the html from the remote site where it is has been deployed.
363      */

364     private void downloadHTML()
365     {
366         String JavaDoc remoteUri = getRemoteUri() + "/" + resultsFileName;
367
368         scp.setFile(remoteUri);
369         scp.setTodir(targetDirectory.getAbsolutePath());
370
371         scp.execute();
372     }
373
374
375     /**
376      * Upload the html to the remote site where it will be deployed.
377      */

378     private void uploadHTML(File JavaDoc resultsFile)
379     {
380         String JavaDoc remoteUri = getRemoteUri();
381
382         scp.setFile( resultsFile.getAbsolutePath() );
383         scp.setTodir(remoteUri);
384
385         scp.execute();
386     }
387
388
389     /**
390      * Append a new column for the latest build. Put the build number in the column header
391      */

392     private Document JavaDoc insertNewColumn(Document JavaDoc document)
393     {
394         Element JavaDoc table = getElementById(document.getDocumentElement(), "table", "mainTable");
395         if ( table == null )
396         {
397             log.info("table is null");
398             return null;
399         }
400
401         Element JavaDoc thead = getElementById(table, "thead", "mainTableHead");
402         Element JavaDoc tr = (Element JavaDoc) thead.getFirstChild();
403
404         Element JavaDoc td= document.createElement("TD");
405         td.setAttribute("class", "servers");
406
407         Element JavaDoc anchor = document.createElement("a");
408         anchor.setAttribute("href", "./" + buildNumber + "/surefire-report.html");
409         Text JavaDoc text = document.createTextNode(buildNumber);
410         anchor.appendChild(text);
411
412         td.appendChild(anchor);
413         tr.appendChild(td);
414
415         // increment the cols attribute for the table
416
int cols = tr.getChildNodes().getLength();
417
418         // check for number of columns to be shown.
419
// Don't take the suite names column into count.
420
if ( cols > (numberShown + 1) )
421         {
422             cols = cleanup(table);
423         }
424
425         table.setAttribute("cols", String.valueOf(cols) );
426
427
428         return document;
429     }
430
431
432     private Document JavaDoc processFile(Document JavaDoc document, File JavaDoc file)
433     {
434         String JavaDoc pcent = getResultsFromFile(file);
435
436         // strip off TEST- and .xml from the filename to get the suitename
437
String JavaDoc fileName = FileUtils.basename(file.getName());
438         fileName = fileName.substring(fileName.indexOf("-") + 1);
439         fileName = fileName.substring(0, fileName.length()-1);
440         document = insertColumn(document, pcent, fileName);
441
442         return document;
443     }
444
445
446     /**
447      * Load the surefire-report xml file as an ANT xml property and get the values of the results
448      * compute percentage
449      */

450     private String JavaDoc getResultsFromFile(File JavaDoc xmlFile)
451     {
452         String JavaDoc prefix = String.valueOf(System.currentTimeMillis());
453         loadXMLProperty(xmlFile, prefix);
454
455         String JavaDoc tests = ant.getAnt().getProperty(prefix + ".testsuite.tests");
456         String JavaDoc errors = ant.getAnt().getProperty(prefix + ".testsuite.errors");
457         String JavaDoc failures = ant.getAnt().getProperty(prefix + ".testsuite.failures");
458         String JavaDoc skipped = ant.getAnt().getProperty(prefix + ".testsuite.skipped");
459
460         log.debug("tests: " + tests + "; errors:" + errors + "; failures:" + failures + "; skipped:" + skipped);
461
462         int testsNum = Integer.parseInt(tests);
463         int errorsNum = Integer.parseInt(errors);
464         int failuresNum = Integer.parseInt(failures);
465         int skippedNum = Integer.parseInt(skipped);
466
467         String JavaDoc pcent = computePercentage(testsNum, errorsNum, failuresNum, skippedNum);
468         return pcent;
469     }
470
471
472     /**
473      * http://ant.apache.org/manual/CoreTasks/xmlproperty.html
474      */

475     private void loadXMLProperty(File JavaDoc src, String JavaDoc prefix)
476     {
477         XmlProperty xmlProperty = (XmlProperty)ant.createTask("xmlproperty");
478         xmlProperty.setFile(src);
479         if ( prefix != null )
480         {
481             xmlProperty.setPrefix(prefix);
482         }
483         xmlProperty.setCollapseAttributes(true);
484         xmlProperty.execute();
485         log.debug("Loaded xml file as ant property with prefix " + prefix);
486     }
487
488
489     /**
490      * compute percentage
491      */

492     public String JavaDoc computePercentage( int tests, int errors, int failures, int skipped )
493     {
494         float percentage;
495         if ( tests == 0 )
496         {
497             percentage = 0;
498         }
499         else
500         {
501             percentage = ( (float) ( tests - errors - failures - skipped ) / (float) tests ) * PCENT;
502         }
503
504         return numberFormat.format( percentage );
505     }
506
507
508
509     /**
510      * Insert the rest of the column. If there is no matching row for the suite name, create a new row.
511      */

512     private Document JavaDoc insertColumn(Document JavaDoc document, String JavaDoc pcent, String JavaDoc suiteName)
513     {
514         log.debug("inserting column");
515
516         Element JavaDoc table = getElementById(document.getDocumentElement(), "table", "mainTable");
517         int cols = Integer.parseInt( table.getAttribute("cols") );
518
519         Element JavaDoc tr = getElementById(table, "tr", suiteName);
520
521         if ( tr != null )
522         {
523             Element JavaDoc td = document.createElement("TD");
524             td.setAttribute("class", "cell");
525
526             Element JavaDoc anchor = document.createElement("a");
527             anchor.setAttribute("href", "./" + buildNumber + "/" + suiteName + "/surefire-report.html");
528             Text JavaDoc text = document.createTextNode(pcent + "%");
529             anchor.appendChild(text);
530
531             td.appendChild(anchor);
532             tr.appendChild(td);
533         }
534         else
535         {
536             log.debug("Creating a new row for a new suite");
537             tr = document.createElement("TR");
538             tr.setAttribute("id", suiteName);
539
540             Element JavaDoc td = document.createElement("TD");
541             td.setAttribute("class", "suite");
542             Text JavaDoc text = document.createTextNode(suiteName);
543             td.appendChild(text);
544             tr.appendChild(td);
545
546             // creating empty cells in the cols for the previous builds.
547
for ( int i=1; i<cols; i++ )
548             {
549                 td = document.createElement("TD");
550                 td.setAttribute("class", "cell");
551                 tr.appendChild(td);
552             }
553
554             Element JavaDoc anchor = document.createElement("a");
555             anchor.setAttribute("href", "./" + buildNumber + "/" + suiteName + "/surefire-report.html");
556             text = document.createTextNode(pcent + "%");
557             anchor.appendChild(text);
558             td.appendChild(anchor);
559
560             table.appendChild(tr);
561         }
562
563         log.debug("inserted column");
564
565         return document;
566
567     }
568
569
570     /**
571      * Get a child element identified by an ID
572      */

573     private Element JavaDoc getElementById(Element JavaDoc element, String JavaDoc tagName, String JavaDoc id)
574     {
575         log.debug("Searching for tag " + tagName + " with id=" + id);
576
577         Element JavaDoc foundElement = null;
578
579         NodeList JavaDoc nodeList = element.getElementsByTagName(tagName);
580
581         for ( int i=0; i<nodeList.getLength(); i++ )
582         {
583             foundElement = (Element JavaDoc) nodeList.item(i);
584             log.debug("Element is " + foundElement.getTagName() + " " + foundElement.getAttribute("id") );
585             if ( id.trim().equals(foundElement.getAttribute("id").trim()) )
586             {
587                 break;
588             }
589             else
590             {
591                 foundElement = null;
592             }
593         }
594
595         return foundElement;
596     }
597
598
599     /**
600      * Removes the oldest test column(s) from the table based on the value set in 'numberShown' variable
601      */

602     private int cleanup(Element JavaDoc table)
603     {
604         log.info("Removing oldest column");
605
606         NodeList JavaDoc nodeList = table.getElementsByTagName("tr");
607
608         int new_cols = 0;
609         for ( int i=0; i<nodeList.getLength(); i++ )
610         {
611             Element JavaDoc tr = (Element JavaDoc) nodeList.item(i);
612             Element JavaDoc suiteColumn = (Element JavaDoc) tr.getFirstChild();
613             Element JavaDoc removeMe = (Element JavaDoc) suiteColumn.getNextSibling();
614             tr.removeChild(removeMe);
615
616             // get the count from just the header row since only the header has been added yet
617
if ( i==0 )
618             {
619                 new_cols = tr.getChildNodes().getLength();
620             }
621         }
622
623         if ( new_cols > (numberShown + 1) )
624         {
625             new_cols = cleanup(table);
626         }
627
628         log.debug( String.valueOf("Returning cols: " + new_cols) );
629
630         return new_cols;
631     }
632
633 }
634
Popular Tags