1 19 20 package org.apache.geronimo.mavenplugins.testsuite; 21 22 import java.io.File ; 23 import java.io.FileInputStream ; 24 import java.io.FileOutputStream ; 25 import java.io.IOException ; 26 import java.text.NumberFormat ; 27 import java.util.ArrayList ; 28 import java.util.Iterator ; 29 30 import org.w3c.dom.Document ; 31 import org.w3c.dom.Element ; 32 import org.w3c.dom.Node ; 33 import org.w3c.dom.NodeList ; 34 import org.w3c.dom.Text ; 35 import org.w3c.tidy.Tidy; 36 import org.xml.sax.ErrorHandler ; 37 import org.xml.sax.InputSource ; 38 import org.xml.sax.SAXException ; 39 import org.xml.sax.SAXParseException ; 40 41 import javax.xml.transform.Transformer ; 42 import javax.xml.transform.TransformerFactory ; 43 import javax.xml.transform.TransformerException ; 44 import javax.xml.transform.TransformerConfigurationException ; 45 import javax.xml.transform.dom.DOMSource ; 46 import javax.xml.transform.stream.StreamResult ; 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 75 public class ResultsSummaryMojo 76 extends MojoSupport 77 { 78 81 protected AntHelper ant; 82 83 87 private File targetDirectory; 88 89 96 protected MavenProject project = null; 97 98 105 protected Settings settings; 106 107 112 private String username; 113 114 119 private String password; 120 121 122 127 private String passphrase; 128 129 134 private String keyFile; 135 136 141 private String buildNumber; 142 143 148 private int numberShown; 149 150 151 private NumberFormat numberFormat = NumberFormat.getInstance(); 152 153 private static final int PCENT = 100; 154 155 private final String 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 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 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 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 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 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 233 protected void doExecute() throws Exception { 234 235 File currentSiteDirectory = new File (targetDirectory, "/site"); 236 if ( !currentSiteDirectory.exists() ) 237 { 238 log.warn("No site directory here"); 239 return; 240 } 241 242 243 File resultsFile = null; 245 try 246 { 247 downloadHTML(); 248 resultsFile = new File (targetDirectory, resultsFileName); 249 } 250 catch ( Exception 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 (project.getBasedir(), "src/main/resources/" + resultsFileName); 265 } 266 267 FileInputStream is = new FileInputStream ( resultsFile ); 268 Document document = tidy.parseDOM(is, null); 269 is.close(); 270 271 File reportsDir = new File (targetDirectory, "surefire-reports"); 272 if ( !reportsDir.exists() ) 273 { 274 log.warn("No surefire-reports directory here"); 275 return; 276 } 277 278 ArrayList files = (ArrayList ) 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 itr=files.iterator(); itr.hasNext(); ) 289 { 290 File file = (File ) itr.next(); 291 log.debug("working on " + file.getAbsolutePath() ); 292 document = processFile(document, file); 293 } 294 295 296 TransformerFactory tFactory = TransformerFactory.newInstance(); 298 Transformer transformer = tFactory.newTransformer(); 299 300 File tempFile = new File (targetDirectory, "ResultsSummary-2.html"); 302 FileOutputStream os = new FileOutputStream ( tempFile ); 303 DOMSource source = new DOMSource (document); 304 StreamResult result = new StreamResult (os); 305 transformer.transform(source, result); 306 307 os.flush(); 308 os.close(); 309 310 resultsFile = new File (targetDirectory, resultsFileName); 312 is = new FileInputStream ( tempFile ); 313 os = new FileOutputStream ( resultsFile ); 314 tidy.parse(is, os); 315 is.close(); 316 os.close(); 317 318 tempFile.delete(); 320 321 try 322 { 323 uploadHTML(resultsFile); 324 } 325 catch ( Exception e ) 326 { 327 log.warn("Upload failed. " + e.getMessage()); 328 } 329 } 330 331 332 private String getRemoteUri() 333 { 334 String siteUri = project.getDistributionManagement().getSite().getUrl(); 335 336 int index = siteUri.indexOf("://"); 338 siteUri = siteUri.substring(index + 3); 339 log.debug("siteUri uri is " + siteUri); 340 341 index = siteUri.lastIndexOf("/"); 343 siteUri = siteUri.substring(0, index); 344 log.debug("siteUri uri is " + siteUri); 345 346 index = siteUri.indexOf("/"); 348 String remoteUri = siteUri.substring(0, index) + ":" + siteUri.substring(index); 349 log.debug("siteUri uri is " + remoteUri); 350 351 352 remoteUri = getUsername() + ":" + getPassword() + "@" + remoteUri; 354 log.info("Remote uri is " + remoteUri); 355 356 return remoteUri; 357 358 } 359 360 361 364 private void downloadHTML() 365 { 366 String remoteUri = getRemoteUri() + "/" + resultsFileName; 367 368 scp.setFile(remoteUri); 369 scp.setTodir(targetDirectory.getAbsolutePath()); 370 371 scp.execute(); 372 } 373 374 375 378 private void uploadHTML(File resultsFile) 379 { 380 String remoteUri = getRemoteUri(); 381 382 scp.setFile( resultsFile.getAbsolutePath() ); 383 scp.setTodir(remoteUri); 384 385 scp.execute(); 386 } 387 388 389 392 private Document insertNewColumn(Document document) 393 { 394 Element table = getElementById(document.getDocumentElement(), "table", "mainTable"); 395 if ( table == null ) 396 { 397 log.info("table is null"); 398 return null; 399 } 400 401 Element thead = getElementById(table, "thead", "mainTableHead"); 402 Element tr = (Element ) thead.getFirstChild(); 403 404 Element td= document.createElement("TD"); 405 td.setAttribute("class", "servers"); 406 407 Element anchor = document.createElement("a"); 408 anchor.setAttribute("href", "./" + buildNumber + "/surefire-report.html"); 409 Text text = document.createTextNode(buildNumber); 410 anchor.appendChild(text); 411 412 td.appendChild(anchor); 413 tr.appendChild(td); 414 415 int cols = tr.getChildNodes().getLength(); 417 418 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 processFile(Document document, File file) 433 { 434 String pcent = getResultsFromFile(file); 435 436 String 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 450 private String getResultsFromFile(File xmlFile) 451 { 452 String prefix = String.valueOf(System.currentTimeMillis()); 453 loadXMLProperty(xmlFile, prefix); 454 455 String tests = ant.getAnt().getProperty(prefix + ".testsuite.tests"); 456 String errors = ant.getAnt().getProperty(prefix + ".testsuite.errors"); 457 String failures = ant.getAnt().getProperty(prefix + ".testsuite.failures"); 458 String 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 pcent = computePercentage(testsNum, errorsNum, failuresNum, skippedNum); 468 return pcent; 469 } 470 471 472 475 private void loadXMLProperty(File src, String 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 492 public String 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 512 private Document insertColumn(Document document, String pcent, String suiteName) 513 { 514 log.debug("inserting column"); 515 516 Element table = getElementById(document.getDocumentElement(), "table", "mainTable"); 517 int cols = Integer.parseInt( table.getAttribute("cols") ); 518 519 Element tr = getElementById(table, "tr", suiteName); 520 521 if ( tr != null ) 522 { 523 Element td = document.createElement("TD"); 524 td.setAttribute("class", "cell"); 525 526 Element anchor = document.createElement("a"); 527 anchor.setAttribute("href", "./" + buildNumber + "/" + suiteName + "/surefire-report.html"); 528 Text 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 td = document.createElement("TD"); 541 td.setAttribute("class", "suite"); 542 Text text = document.createTextNode(suiteName); 543 td.appendChild(text); 544 tr.appendChild(td); 545 546 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 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 573 private Element getElementById(Element element, String tagName, String id) 574 { 575 log.debug("Searching for tag " + tagName + " with id=" + id); 576 577 Element foundElement = null; 578 579 NodeList nodeList = element.getElementsByTagName(tagName); 580 581 for ( int i=0; i<nodeList.getLength(); i++ ) 582 { 583 foundElement = (Element ) 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 602 private int cleanup(Element table) 603 { 604 log.info("Removing oldest column"); 605 606 NodeList nodeList = table.getElementsByTagName("tr"); 607 608 int new_cols = 0; 609 for ( int i=0; i<nodeList.getLength(); i++ ) 610 { 611 Element tr = (Element ) nodeList.item(i); 612 Element suiteColumn = (Element ) tr.getFirstChild(); 613 Element removeMe = (Element ) suiteColumn.getNextSibling(); 614 tr.removeChild(removeMe); 615 616 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 |