1/******************************************************************************* 2 * Copyright (c) 2000, 2006 IBM Corporation and others. 3 * All rights reserved. This program and the accompanying materials 4 * are made available under the terms of the Eclipse Public License v1.0 5 * which accompanies this distribution, and is available at 6 * http://www.eclipse.org/legal/epl-v10.html 7 * 8 * Contributors: 9 * IBM Corporation - initial API and implementation 10 *******************************************************************************/ 11package org.eclipse.releng.generators; 12 13import java.io.BufferedReader; 14import java.io.File; 15import java.io.FileInputStream; 16import java.io.FileNotFoundException; 17import java.io.FileOutputStream; 18import java.io.FileReader; 19import java.io.IOException; 20import java.io.InputStream; 21import java.util.Arrays; 22import java.util.StringTokenizer; 23import java.util.Vector; 24import java.util.Enumeration; 25 26import org.apache.tools.ant.Task; 27import javax.xml.parsers.DocumentBuilderFactory; 28import javax.xml.parsers.DocumentBuilder; 29import javax.xml.parsers.ParserConfigurationException; 30 31import org.w3c.dom.Document; 32import org.w3c.dom.Element; 33import org.w3c.dom.NamedNodeMap; 34import org.w3c.dom.Node; 35import org.w3c.dom.NodeList; 36import org.xml.sax.InputSource; 37import org.xml.sax.SAXException; 38 39 40/** 41 * @version 1.0 42 * @author Dean Roberts 43 */ 44public class TestResultsGenerator extends Task { 45 private static final String WARNING_SEVERITY = "WARNING"; 46 private static final String ERROR_SEVERITY = "ERROR"; 47 private static final String ForbiddenReferenceID = "ForbiddenReference"; 48 private static final String DiscouragedReferenceID = "DiscouragedReference"; 49 50 private static final int DEFAULT_READING_SIZE = 8192; 51 52 static final String elementName = "testsuite"; 53 static final String testResultsToken = "%testresults%"; 54 static final String compileLogsToken = "%compilelogs%"; 55 static final String accessesLogsToken = "%accesseslogs%"; 56 public Vector dropTokens; 57 public Vector platformSpecs; 58 public Vector differentPlatforms; 59 public String testResultsWithProblems = "\n"; 60 public String testResultsXmlUrls = "\n"; 61 62 private DocumentBuilder parser =null; 63 public ErrorTracker anErrorTracker; 64 public String testResultsTemplateString = ""; 65 public String dropTemplateString = ""; 66 67 public Vector platformDescription; 68 public Vector platformTemplateString; 69 public Vector platformDropFileName; 70 71 //Status of tests results (pending, successful, failed), used to specify the color 72 //of the test Results link on the build pages (standard, green, red), once failures 73 //are encountered, this is set to failed 74 protected String testResultsStatus = "successful"; 75 //assume tests ran. If no html files are found, this is set to false 76 private boolean testsRan = true; 77 78 // Parameters 79 // build runs JUnit automated tests 80 private boolean isBuildTested; 81 82 // buildType, I, N 83 public String buildType; 84 85 // Comma separated list of drop tokens 86 public String dropTokenList; 87 88 // Token in platform.php.template to be replaced by the desired platform ID 89 public String platformIdentifierToken; 90 91 // Location of the xml files 92 public String xmlDirectoryName; 93 94 // Location of the html files 95 public String htmlDirectoryName; 96 97 // Location of the resulting index.php file. 98 public String dropDirectoryName; 99 100 // Location and name of the template index.php file. 101 public String testResultsTemplateFileName; 102 103 // Platform specific template and output list (colon separated) in the following format: 104 // <descriptor, ie. OS name>,path to template file, path to output file 105 public String platformSpecificTemplateList=""; 106 107 // Location and name of the template drop index.php file. 108 public String dropTemplateFileName; 109 110 // Name of the generated index php file. 111 public String testResultsHtmlFileName; 112 113 // Name of the generated drop index php file; 114 public String dropHtmlFileName; 115 116 // Arbitrary path used in the index.php page to href the 117 // generated .html files. 118 public String hrefTestResultsTargetPath; 119 120 // Aritrary path used in the index.php page to reference the compileLogs 121 public String hrefCompileLogsTargetPath; 122 123 // Location of compile logs base directory 124 public String compileLogsDirectoryName; 125 126 // Location and name of test manifest file 127 public String testManifestFileName; 128 129 //Initialize the prefix to a default string 130 private String prefix = "default"; 131 private String testShortName = ""; 132 private int counter = 0; 133 //The four configurations, add new configurations to test results here + update 134 //testResults.php.template for changes 135 private String[] testsConfig = {"linux.gtk.x86.xml", 136 "linux.gtk.x86_6.0.xml", 137 "macosx.cocoa.x86_5.0.xml", 138 "win32.win32.x86.xml", 139 "win32.win32.x86_6.0.xml"}; 140 141 142 public static void main(String[] args) { 143 TestResultsGenerator test = new TestResultsGenerator(); 144 test.setDropTokenList( 145 "%sdk%,%tests%,%example%,%rcpruntime%,%rcpsdk%,%deltapack%,%icubase%,%runtime%,%platformsdk%,%jdt%,%jdtsdk%,%pde%,%pdesdk%,%cvs%,%cvssdk%,%teamextras%,%swt%,%relengtools%"); 146 test.setPlatformIdentifierToken("%platform%"); 147 test.getDropTokensFromList(test.dropTokenList); 148 test.setIsBuildTested(true); 149 test.setXmlDirectoryName("C:\\junk\\testresults\\xml"); 150 test.setHtmlDirectoryName("C:\\junk\\testresults"); 151 test.setDropDirectoryName("C:\\junk"); 152 test.setTestResultsTemplateFileName( 153 "C:\\junk\\templateFiles\\testResults.php.template"); 154 test.setPlatformSpecificTemplateList( 155 "Windows,C:\\junk\\templateFiles\\platform.php.template,winPlatform.php;Linux,C:\\junk\\templateFiles\\platform.php.template,linPlatform.php;Solaris,C:\\junk\\templateFiles\\platform.php.template,solPlatform.php;AIX,C:\\junk\\templateFiles\\platform.php.template,aixPlatform.php;Macintosh,C:\\junk\\templateFiles\\platform.php.template,macPlatform.php;Source Build,C:\\junk\\templateFiles\\sourceBuilds.php.template,sourceBuilds.php"); 156 test.setDropTemplateFileName( 157 "C:\\junk\\templateFiles\\index.php.template"); 158 test.setTestResultsHtmlFileName("testResults.php"); 159 //test.setDropHtmlFileName("index.php"); 160 test.setDropHtmlFileName("index.html"); 161 162 test.setHrefTestResultsTargetPath("testresults"); 163 test.setCompileLogsDirectoryName( 164 "C:\\junk\\compilelogs\\plugins"); 165 test.setHrefCompileLogsTargetPath("compilelogs"); 166 test.setTestManifestFileName("C:\\junk\\testManifest.xml"); 167 test.execute(); 168 } 169 170 public void execute() { 171 172 anErrorTracker = new ErrorTracker(); 173 platformDescription = new Vector(); 174 platformTemplateString = new Vector(); 175 platformDropFileName = new Vector(); 176 anErrorTracker.loadFile(testManifestFileName); 177 getDropTokensFromList(dropTokenList); 178 testResultsTemplateString = readFile(testResultsTemplateFileName); 179 dropTemplateString = readFile(dropTemplateFileName); 180 181 //Specific to the platform build-page 182 if(platformSpecificTemplateList!="") { 183 String description, platformTemplateFile, platformDropFile; 184 //Retrieve the different platforms and their info 185 getDifferentPlatformsFromList(platformSpecificTemplateList); 186 //Parses the platform info and retrieves the platform name, 187 //template file, and drop file 188 for(int i=0; i<differentPlatforms.size(); i++) { 189 getPlatformSpecsFromList(differentPlatforms.get(i).toString()); 190 description = platformSpecs.get(0).toString(); 191 platformTemplateFile = platformSpecs.get(1).toString(); 192 platformDropFile = platformSpecs.get(2).toString(); 193 platformDescription.add(description); 194 platformTemplateString.add(readFile(platformTemplateFile)); 195 platformDropFileName.add(platformDropFile); 196 197 } 198 199 } 200 201 System.out.println("Begin: Generating test results index page"); 202 System.out.println("Parsing XML files"); 203 parseXml(); 204 System.out.println("Parsing compile logs"); 205 parseCompileLogs(); 206 System.out.println("End: Generating test results index page"); 207 writeTestResultsFile(); 208 //For the platform build-page, write platform files, in addition to the index file 209 if(platformSpecificTemplateList!="") { 210 writeDropFiles(); 211 } 212 else { 213 writeDropIndexFile(); 214 } 215 } 216 217 public void parseCompileLogs() { 218 219 StringBuffer compilerString = new StringBuffer(); 220 StringBuffer accessesString = new StringBuffer(); 221 processCompileLogsDirectory( 222 compileLogsDirectoryName, 223 compilerString, 224 accessesString); 225 if (compilerString.length() == 0) { 226 compilerString.append("None"); 227 } 228 if (accessesString.length() == 0) { 229 accessesString.append("None"); 230 } 231 testResultsTemplateString = 232 replace(testResultsTemplateString, compileLogsToken, String.valueOf(compilerString)); 233 234 testResultsTemplateString = 235 replace(testResultsTemplateString, accessesLogsToken, String.valueOf(accessesString)); 236 } 237 238 private void processCompileLogsDirectory(String directoryName, StringBuffer compilerLog, StringBuffer accessesLog) { 239 File sourceDirectory = new File(directoryName); 240 if (sourceDirectory.isFile()) { 241 if (sourceDirectory.getName().endsWith(".log")) 242 readCompileLog(sourceDirectory.getAbsolutePath(), compilerLog, accessesLog); 243 if (sourceDirectory.getName().endsWith(".xml")) 244 parseCompileLog(sourceDirectory.getAbsolutePath(), compilerLog, accessesLog); 245 } 246 if (sourceDirectory.isDirectory()) { 247 File[] logFiles = sourceDirectory.listFiles(); 248 Arrays.sort(logFiles); 249 for (int j = 0; j < logFiles.length; j++) { 250 processCompileLogsDirectory(logFiles[j].getAbsolutePath(), compilerLog, accessesLog); 251 } 252 } 253 } 254 255 private void readCompileLog(String log, StringBuffer compilerLog, StringBuffer accessesLog) { 256 String fileContents = readFile(log); 257 258 int errorCount = countCompileErrors(fileContents); 259 int warningCount = countCompileWarnings(fileContents); 260 int forbiddenWarningCount = countForbiddenWarnings(fileContents); 261 int discouragedWarningCount = countDiscouragedWarnings(fileContents); 262 if (errorCount != 0) { 263 //use wildcard in place of version number on directory names 264 String logName = 265 log.substring(getCompileLogsDirectoryName().length() + 1); 266 StringBuffer stringBuffer = new StringBuffer(logName); 267 stringBuffer.replace( 268 logName.indexOf("_") + 1, 269 logName.indexOf(File.separator, logName.indexOf("_") + 1), 270 "*"); 271 logName = new String(stringBuffer); 272 273 anErrorTracker.registerError(logName); 274 } 275 formatCompileErrorRow(log, errorCount, warningCount, compilerLog); 276 formatAccessesErrorRow(log, forbiddenWarningCount, discouragedWarningCount, accessesLog); 277 } 278 279 private void parseCompileLog(String log, StringBuffer compilerLog, StringBuffer accessesLog) { 280 int errorCount = 0; 281 int warningCount = 0; 282 int forbiddenWarningCount = 0; 283 int discouragedWarningCount = 0; 284 285 File file=new File(log); 286 Document aDocument=null; 287 BufferedReader reader = null; 288 try { 289 reader = new BufferedReader(new FileReader(file)); 290 InputSource inputSource = new InputSource(reader); 291 DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance(); 292 DocumentBuilder builder = factory.newDocumentBuilder(); 293 aDocument = builder.parse(inputSource); 294 } catch (SAXException e) { 295 e.printStackTrace(); 296 } catch (IOException e) { 297 e.printStackTrace(); 298 } catch (ParserConfigurationException e) { 299 e.printStackTrace(); 300 } finally { 301 if (reader != null) { 302 try { 303 reader.close(); 304 } catch(IOException e) { 305 // ignore 306 } 307 } 308 } 309 310 if (aDocument == null) return; 311 // Get summary of problems 312 NodeList nodeList = aDocument.getElementsByTagName("problem"); 313 if (nodeList == null ||nodeList.getLength()==0) 314 return; 315 316 int length = nodeList.getLength(); 317 for (int i = 0; i < length; i++) { 318 Node problemNode = nodeList.item(i); 319 NamedNodeMap aNamedNodeMap = problemNode.getAttributes(); 320 Node severityNode = aNamedNodeMap.getNamedItem("severity"); 321 Node idNode = aNamedNodeMap.getNamedItem("id"); 322 if (severityNode != null) { 323 String severityNodeValue = severityNode.getNodeValue(); 324 if (WARNING_SEVERITY.equals(severityNodeValue)) { 325 // this is a warning 326 // need to check the id 327 String nodeValue = idNode.getNodeValue(); 328 if (ForbiddenReferenceID.equals(nodeValue)) { 329 forbiddenWarningCount++; 330 } else if (DiscouragedReferenceID.equals(nodeValue)) { 331 discouragedWarningCount++; 332 } else { 333 warningCount++; 334 } 335 } else if (ERROR_SEVERITY.equals(severityNodeValue)) { 336 // this is an error 337 errorCount++; 338 } 339 } 340 } 341 if (errorCount != 0) { 342 //use wildcard in place of version number on directory names 343 //System.out.println(log + "/n"); 344 String logName = 345 log.substring(getCompileLogsDirectoryName().length() + 1); 346 StringBuffer buffer = new StringBuffer(logName); 347 buffer.replace( 348 logName.indexOf("_") + 1, 349 logName.indexOf(File.separator, logName.indexOf("_") + 1), 350 "*"); 351 logName = new String(buffer); 352 353 anErrorTracker.registerError(logName); 354 } 355 String logName = log.replaceAll(".xml", ".html"); 356 formatCompileErrorRow( 357 logName, 358 errorCount, 359 warningCount, 360 compilerLog); 361 formatAccessesErrorRow( 362 logName, 363 forbiddenWarningCount, 364 discouragedWarningCount, 365 accessesLog); 366 } 367 368 public static byte[] getFileByteContent(String fileName) throws IOException { 369 InputStream stream = null; 370 try { 371 File file = new File(fileName); 372 stream = new FileInputStream(file); 373 return getInputStreamAsByteArray(stream, (int) file.length()); 374 } finally { 375 if (stream != null) { 376 try { 377 stream.close(); 378 } catch (IOException e) { 379 // ignore 380 } 381 } 382 } 383 } 384 385 /** 386 * Returns the given input stream's contents as a byte array. 387 * If a length is specified (ie. if length != -1), only length bytes 388 * are returned. Otherwise all bytes in the stream are returned. 389 * Note this doesn't close the stream. 390 * @throws IOException if a problem occured reading the stream. 391 */ 392 public static byte[] getInputStreamAsByteArray(InputStream stream, int length) 393 throws IOException { 394 byte[] contents; 395 if (length == -1) { 396 contents = new byte[0]; 397 int contentsLength = 0; 398 int amountRead = -1; 399 do { 400 int amountRequested = Math.max(stream.available(), DEFAULT_READING_SIZE); // read at least 8K 401 402 // resize contents if needed 403 if (contentsLength + amountRequested > contents.length) { 404 System.arraycopy( 405 contents, 406 0, 407 contents = new byte[contentsLength + amountRequested], 408 0, 409 contentsLength); 410 } 411 412 // read as many bytes as possible 413 amountRead = stream.read(contents, contentsLength, amountRequested); 414 415 if (amountRead > 0) { 416 // remember length of contents 417 contentsLength += amountRead; 418 } 419 } while (amountRead != -1); 420 421 // resize contents if necessary 422 if (contentsLength < contents.length) { 423 System.arraycopy( 424 contents, 425 0, 426 contents = new byte[contentsLength], 427 0, 428 contentsLength); 429 } 430 } else { 431 contents = new byte[length]; 432 int len = 0; 433 int readSize = 0; 434 while ((readSize != -1) && (len != length)) { 435 // See PR 1FMS89U 436 // We record first the read size. In this case len is the actual read size. 437 len += readSize; 438 readSize = stream.read(contents, len, length - len); 439 } 440 } 441 442 return contents; 443 } 444 445 public String readFile(String fileName) { 446 byte[] aByteArray = null; 447 try { 448 aByteArray = getFileByteContent(fileName); 449 } catch (IOException e) { 450 e.printStackTrace(); 451 } 452 if (aByteArray == null) { 453 return ""; 454 } 455 return new String(aByteArray); 456 } 457 458 private int countCompileErrors(String aString) { 459 return extractNumber(aString, "error"); 460 } 461 462 private int countCompileWarnings(String aString) { 463 return extractNumber(aString, "warning"); 464 } 465 466 private int countForbiddenWarnings(String aString) { 467 return extractNumber(aString, "Access restriction:"); 468 } 469 470 private int countDiscouragedWarnings(String aString) { 471 return extractNumber(aString, "Discouraged access:"); 472 } 473 474 private int extractNumber(String aString, String endToken) { 475 int endIndex = aString.lastIndexOf(endToken); 476 if (endIndex == -1) { 477 return 0; 478 } 479 480 int startIndex = endIndex; 481 while (startIndex >= 0 482 && aString.charAt(startIndex) != '(' 483 && aString.charAt(startIndex) != ',') { 484 startIndex--; 485 } 486 487 String count = aString.substring(startIndex + 1, endIndex).trim(); 488 try { 489 return Integer.parseInt(count); 490 } catch (NumberFormatException e) { 491 return 0; 492 } 493 494 } 495 496 private int missingCount = 0; 497 private String verifyAllTestsRan(String directory) { 498 Enumeration enumeration = (anErrorTracker.getTestLogs()).elements(); 499 500 String replaceString=""; 501 while (enumeration.hasMoreElements()) { 502 String testLogName = enumeration.nextElement().toString(); 503 504 if (new File(directory + File.separator + testLogName) 505 .exists()) 506 continue; 507 508 anErrorTracker.registerError(testLogName); 509 String tmp=((platformSpecificTemplateList.equals(""))?formatRow(testLogName, -1, false):formatRowReleng(testLogName, -1, false)); 510 if(missingCount==0) { 511 replaceString=replaceString+"</table></br>"+"\n"+ 512 "<table width=\"65%\" border=\"1\" bgcolor=\"#EEEEEE\" rules=\"groups\" align=\"center\">"+ 513 "<tr bgcolor=\"#9999CC\"> <th width=\"80%\" align=\"center\"> Missing Files </th><th align=\"center\"> Status </th></tr>"; 514 } 515 replaceString=replaceString+tmp; 516 testResultsWithProblems=testResultsWithProblems.concat("\n" + testLogName.substring(0,testLogName.length()-4) +" (file missing)"); 517 missingCount++; 518 } 519 return replaceString; 520 } 521 522 public void parseXml() { 523 524 File sourceDirectory = new File(xmlDirectoryName); 525 526 if (sourceDirectory.exists()) { 527 528 String replaceString = ""; 529 530 File[] xmlFileNames = sourceDirectory.listFiles(); 531 Arrays.sort(xmlFileNames) ; 532 533 File sourceDirectoryParent = sourceDirectory.getParentFile(); 534 if (sourceDirectoryParent != null) { 535 sourceDirectoryParent = sourceDirectoryParent.getParentFile(); 536 } 537 String sourceDirectoryCanonicalPath = null; 538 try { 539 sourceDirectoryCanonicalPath = sourceDirectoryParent.getCanonicalPath(); 540 } catch (IOException e) { 541 // ignore 542 } 543 for (int i = 0; i < xmlFileNames.length; i++) { 544 if (xmlFileNames[i].getPath().endsWith(".xml")) { 545 String fullName = xmlFileNames[i].getPath(); 546 int errorCount = countErrors(fullName); 547 if (errorCount != 0) { 548 String testName = 549 xmlFileNames[i].getName().substring( 550 0, 551 xmlFileNames[i].getName().length() - 4); 552 testResultsWithProblems = 553 testResultsWithProblems.concat("\n" + testName); 554 testResultsXmlUrls = 555 testResultsXmlUrls.concat("\n" + extractXmlRelativeFileName(sourceDirectoryCanonicalPath, xmlFileNames[i])); 556 anErrorTracker.registerError( 557 fullName.substring( 558 getXmlDirectoryName().length() + 1)); 559 } 560 561 562 String tmp=((platformSpecificTemplateList.equals(""))?formatRow(xmlFileNames[i].getPath(), errorCount,true):formatRowReleng(xmlFileNames[i].getPath(), errorCount,true)); 563 replaceString=replaceString+tmp; 564 565 566 } 567 } 568 //check for missing test logs 569 replaceString=replaceString+verifyAllTestsRan(xmlDirectoryName); 570 571 testResultsTemplateString = 572 replace( 573 testResultsTemplateString, 574 testResultsToken, 575 replaceString); 576 testsRan = true; 577 578 } else { 579 testsRan = false; 580 System.out.println( 581 "Test results not found in " 582 + sourceDirectory.getAbsolutePath()); 583 } 584 585 } 586 private static String extractXmlRelativeFileName(String rootCanonicalPath, File xmlFile) { 587 if (rootCanonicalPath != null) { 588 String xmlFileCanonicalPath = null; 589 try { 590 xmlFileCanonicalPath = xmlFile.getCanonicalPath(); 591 } catch (IOException e) { 592 // ignore 593 } 594 if (xmlFileCanonicalPath != null) { 595 // + 1 to remove the '\' 596 return xmlFileCanonicalPath.substring(rootCanonicalPath.length() + 1).replace('\\', '/'); 597 } 598 } 599 return ""; 600 } 601 private String replace( 602 String source, 603 String original, 604 String replacement) { 605 606 int replaceIndex = source.indexOf(original); 607 if (replaceIndex > -1) { 608 String resultString = source.substring(0, replaceIndex); 609 resultString = resultString + replacement; 610 resultString = 611 resultString 612 + source.substring(replaceIndex + original.length()); 613 return resultString; 614 } else { 615 System.out.println("Could not find token: " + original); 616 return source; 617 } 618 619 } 620 621 protected void writeDropFiles() { 622 writeDropIndexFile(); 623 //Write all the platform files 624 for(int i=0; i<platformDescription.size(); i++) { 625 writePlatformFile(platformDescription.get(i).toString(), platformTemplateString.get(i).toString(), platformDropFileName.get(i).toString()); 626 } 627 } 628 629 protected void writeDropIndexFile() { 630 631 String[] types = anErrorTracker.getTypes(); 632 for (int i = 0; i < types.length; i++) { 633 PlatformStatus[] platforms = anErrorTracker.getPlatforms(types[i]); 634 String replaceString = processDropRows(platforms); 635 dropTemplateString = 636 replace( 637 dropTemplateString, 638 dropTokens.get(i).toString(), 639 replaceString); 640 } 641 //Replace the token %testsStatus% with the status of the test results 642 dropTemplateString = replace(dropTemplateString,"%testsStatus%",testResultsStatus); 643 String outputFileName = 644 dropDirectoryName + File.separator + dropHtmlFileName; 645 writeFile(outputFileName, dropTemplateString); 646 } 647 648 //Writes the platform file (dropFileName) specific to "desiredPlatform" 649 protected void writePlatformFile(String desiredPlatform, String templateString, String dropFileName) { 650 651 String[] types = anErrorTracker.getTypes(); 652 for (int i = 0; i < types.length; i++) { 653 PlatformStatus[] platforms = anErrorTracker.getPlatforms(types[i]); 654 //Call processPlatformDropRows passing the platform's name 655 String replaceString = processPlatformDropRows(platforms, desiredPlatform); 656 templateString = 657 replace( 658 templateString, 659 dropTokens.get(i).toString(), 660 replaceString); 661 } 662 //Replace the platformIdentifierToken with the platform's name and the testsStatus 663 //token with the status of the test results 664 templateString = replace(templateString, platformIdentifierToken, desiredPlatform); 665 templateString = replace(templateString,"%testsStatus%",testResultsStatus); 666 String outputFileName = 667 dropDirectoryName + File.separator + dropFileName; 668 writeFile(outputFileName, templateString); 669 } 670 671 //Process drop rows specific to each of the platforms 672 protected String processPlatformDropRows(PlatformStatus[] platforms, String name) { 673 674 String result = ""; 675 boolean found = false; 676 for (int i = 0; i < platforms.length; i++) { 677 //If the platform description indicates the platform's name, or "All", 678 //call processDropRow 679 if(platforms[i].getName().startsWith(name.substring(0, 3)) || platforms[i].getName().equals("All")) { 680 result = result + processDropRow(platforms[i]); 681 found = true; 682 } 683 //If the platform description indicates "All Other Platforms", process 684 //the row locally 685 else if(platforms[i].getName().equals("All Other Platforms") && !found) 686 { 687 String imageName = ""; 688 689 if (platforms[i].hasErrors()) { 690 imageName = 691 "<a href=\"" + getTestResultsHtmlFileName() + "\"><img src = \"FAIL.gif\" width=19 height=23></a>"; 692 } else { 693 if (testsRan) { 694 imageName = "<img src = \"OK.gif\" width=19 height=23>"; 695 } else { 696 if (isBuildTested) { 697 imageName = 698 "<font size=\"-1\" color=\"#FF0000\">pending</font>"; 699 } else { 700 imageName = "<img src = \"OK.gif\" width=19 height=23>"; 701 } 702 } 703 } 704 705 result = result + "<tr>"; 706 result = result + "<td><div align=left>" + imageName + "</div></td>\n"; 707 result = result + "<td>All " + name + "</td>"; 708 //generate http, md5 and sha1 links by calling php functions in the template 709 result = result + "<td><?php genLinks($_SERVER[\"SERVER_NAME\"],\"@buildlabel@\",\"" + platforms[i].getFileName() +"\"); ?></td>\n"; 710 result = result + "</tr>\n"; 711 } 712 } 713 714 return result; 715 } 716 717 protected String processDropRows(PlatformStatus[] platforms) { 718 719 String result = ""; 720 for (int i = 0; i < platforms.length; i++) { 721 result = result + processDropRow(platforms[i]); 722 } 723 724 return result; 725 } 726 727 protected String processDropRow(PlatformStatus aPlatform) { 728 729 String imageName = ""; 730 731 if (aPlatform.hasErrors()) { 732 imageName = 733 "<a href=\"" + getTestResultsHtmlFileName()+ "\"><img src = \"FAIL.gif\" width=19 height=23></a>"; 734 //Failure in tests 735 testResultsStatus = "failed"; 736 } else { 737 if (testsRan) { 738 imageName = "<img src = \"OK.gif\" width=19 height=23>"; 739 } else { 740 if (isBuildTested) { 741 imageName = 742 "<font size=\"-1\" color=\"#FF0000\">pending</font>"; 743 //Tests are pending 744 testResultsStatus = "pending"; 745 } else { 746 imageName = "<img src = \"OK.gif\" width=19 height=23>"; 747 } 748 } 749 } 750 751 String result = "<tr>"; 752 753 result = result + "<td><div align=left>" + imageName + "</div></td>\n"; 754 result = result + "<td>" + aPlatform.getName() + "</td>"; 755 result = result + "<td>" + aPlatform.getFileName() + "</td>\n"; 756 result = result + "</tr>\n"; 757 758 return result; 759 } 760 761 public void writeTestResultsFile() { 762 763 String outputFileName = 764 dropDirectoryName + File.separator + testResultsHtmlFileName; 765 writeFile(outputFileName, testResultsTemplateString); 766 } 767 768 private void writeFile(String outputFileName, String contents) { 769 FileOutputStream outputStream = null; 770 try { 771 outputStream = new FileOutputStream(outputFileName); 772 outputStream.write(contents.getBytes()); 773 } catch (FileNotFoundException e) { 774 System.out.println( 775 "File not found exception writing: " + outputFileName); 776 } catch (IOException e) { 777 System.out.println("IOException writing: " + outputFileName); 778 } finally { 779 if (outputStream != null) { 780 try { 781 outputStream.close(); 782 } catch(IOException e) { 783 // ignore 784 } 785 } 786 } 787 } 788 789 public void setTestResultsHtmlFileName(String aString) { 790 testResultsHtmlFileName = aString; 791 } 792 793 public String getTestResultsHtmlFileName() { 794 return testResultsHtmlFileName; 795 } 796 797 public void setTestResultsTemplateFileName(String aString) { 798 testResultsTemplateFileName = aString; 799 } 800 801 public String getTestResultsTemplateFileName() { 802 return testResultsTemplateFileName; 803 } 804 805 public void setXmlDirectoryName(String aString) { 806 xmlDirectoryName = aString; 807 } 808 809 public String getXmlDirectoryName() { 810 return xmlDirectoryName; 811 } 812 813 public void setHtmlDirectoryName(String aString) { 814 htmlDirectoryName = aString; 815 } 816 817 public String getHtmlDirectoryName() { 818 return htmlDirectoryName; 819 } 820 821 public void setDropDirectoryName(String aString) { 822 dropDirectoryName = aString; 823 } 824 825 public String getDropDirectoryName() { 826 return dropDirectoryName; 827 } 828 829 private void formatCompileErrorRow( 830 String fileName, 831 int errorCount, 832 int warningCount, 833 StringBuffer buffer) { 834 835 if (errorCount == 0 && warningCount == 0) { 836 return; 837 } 838 839 String hrefCompileLogsTargetPath2 = getHrefCompileLogsTargetPath(); 840 int i = fileName.indexOf(hrefCompileLogsTargetPath2); 841 842 String shortName = 843 fileName.substring(i + hrefCompileLogsTargetPath2.length()); 844 845 buffer 846 .append("<tr>\n<td>\n") 847 .append("<a href=") 848 .append("\"") 849 .append(hrefCompileLogsTargetPath2) 850 .append(shortName) 851 .append("\">") 852 .append(shortName) 853 .append("</a>") 854 .append("</td>\n") 855 .append("<td align=\"center\">") 856 .append("<a href=") 857 .append("\"") 858 .append(hrefCompileLogsTargetPath2) 859 .append(shortName) 860 .append("#ERRORS") 861 .append("\">") 862 .append(errorCount) 863 .append("</a>") 864 .append("</td>\n") 865 .append("<td align=\"center\">") 866 .append("<a href=") 867 .append("\"") 868 .append(hrefCompileLogsTargetPath2) 869 .append(shortName) 870 .append("#OTHER_WARNINGS") 871 .append("\">") 872 .append(warningCount) 873 .append("</a>") 874 .append("</td>\n") 875 .append("</tr>\n"); 876 } 877 878 private void formatAccessesErrorRow( 879 String fileName, 880 int forbiddenAccessesWarningsCount, 881 int discouragedAccessesWarningsCount, 882 StringBuffer buffer) { 883 884 if (forbiddenAccessesWarningsCount == 0 && discouragedAccessesWarningsCount == 0) { 885 return; 886 } 887 888 String hrefCompileLogsTargetPath2 = getHrefCompileLogsTargetPath(); 889 int i = fileName.indexOf(hrefCompileLogsTargetPath2); 890 891 String shortName = 892 fileName.substring(i + hrefCompileLogsTargetPath2.length()); 893 894 buffer 895 .append("<tr>\n<td>\n") 896 .append("<a href=") 897 .append("\"") 898 .append(hrefCompileLogsTargetPath2) 899 .append(shortName) 900 .append("\">") 901 .append(shortName) 902 .append("</a>") 903 .append("</td>\n") 904 .append("<td align=\"center\">") 905 .append("<a href=") 906 .append("\"") 907 .append(hrefCompileLogsTargetPath2) 908 .append(shortName) 909 .append("#FORBIDDEN_WARNINGS") 910 .append("\">") 911 .append(forbiddenAccessesWarningsCount) 912 .append("</a>") 913 .append("</td>\n") 914 .append("<td align=\"center\">") 915 .append("<a href=") 916 .append("\"") 917 .append(hrefCompileLogsTargetPath2) 918 .append(shortName) 919 .append("#DISCOURAGED_WARNINGS") 920 .append("\">") 921 .append(discouragedAccessesWarningsCount) 922 .append("</a>") 923 .append("</td>\n") 924 .append("</tr>\n"); 925 } 926 927 private String formatRow(String fileName, int errorCount, boolean link) { 928 929 // replace .xml with .html 930 931 String aString = ""; 932 if (!link) { 933 return "<tr><td>" + fileName + " (missing)" + "</td><td>" + "DNF"; 934 } 935 936 if (fileName.endsWith(".xml")) { 937 938 int begin = fileName.lastIndexOf(File.separatorChar); 939 int end = fileName.lastIndexOf(".xml"); 940 941 String shortName = fileName.substring(begin + 1, end); 942 String displayName = shortName; 943 if (errorCount != 0) 944 aString = aString + "<tr><td><b>"; 945 else 946 aString = aString + "<tr><td>"; 947 948 949 if (errorCount!=0){ 950 displayName="<font color=\"#ff0000\">"+displayName+"</font>"; 951 } 952 if (errorCount==-1){ 953 aString=aString.concat(displayName); 954 }else { 955 aString=aString 956 + "<a href=" 957 + "\"" 958 + hrefTestResultsTargetPath 959 + "/" 960 + shortName 961 + ".html" 962 + "\">" 963 + displayName 964 + "</a>"; 965 } 966 if (errorCount > 0) 967 aString = aString + "</td><td><b>"; 968 else 969 aString = aString + "</td><td>"; 970 971 if (errorCount == -1) 972 aString = aString + "<font color=\"#ff0000\">DNF"; 973 974 else if (errorCount >0) 975 aString = aString + "<font color=\"#ff0000\">"+String.valueOf(errorCount); 976 else 977 aString = aString +String.valueOf(errorCount); 978 979 if (errorCount != 0) 980 aString = aString + "</font></b></td></tr>"; 981 else 982 aString = aString + "</td></tr>"; 983 } 984 985 return aString; 986 987 } 988 989 //Specific to the RelEng test results page 990 private String formatRowReleng(String fileName, int errorCount, boolean link) { 991 992 //If the file name doesn't end with any of the set test configurations, do nothing 993 boolean endsWithConfig = false; 994 int card = testsConfig.length; 995 for(int i=0; i<card; i++) { 996 if(fileName.endsWith(testsConfig[i])) 997 endsWithConfig = true; 998 } 999 if(!endsWithConfig) 1000 return ""; 1001 1002 String aString = ""; 1003 if (!link) { 1004 return "<tr><td>" + fileName + "</td><td align=\"center\">" + "DNF </tr>"; 1005 } 1006 1007 if (fileName.endsWith(".xml")) { 1008 1009 int begin = fileName.lastIndexOf(File.separatorChar); 1010 1011 //Get org.eclipse. out of the component name 1012 String shortName = fileName.substring(begin + 13, fileName.indexOf('_')); 1013 String displayName = shortName; 1014 1015 //If the short name does not start with this prefix 1016 if(!shortName.startsWith(prefix)) { 1017 //If the prefix is not yet set 1018 if(prefix=="default"){ 1019 //Set the testShortName variable to the current short name 1020 testShortName = shortName; 1021 counter=0; 1022 //Set new prefix 1023 prefix = shortName.substring(0, shortName.indexOf(".tests") + 6); 1024 aString = aString + "<tbody><tr><td><b>" + prefix + ".*" + "</b><td><td><td><td>"; 1025 aString = aString + "<tr><td><P>" + shortName; 1026 1027 //Loop until the matching string postfix(test config.) is found 1028 while(counter<card && !fileName.endsWith(testsConfig[counter])) { 1029 aString = aString + "<td align=\"center\">-</td>"; 1030 counter++; 1031 } 1032 } 1033 else { 1034 //Set new prefix 1035 prefix = shortName.substring(0, shortName.indexOf(".tests") + 6); 1036 1037 //Loop until the matching string postfix(test config.) is found 1038 while(counter<card && !fileName.endsWith(testsConfig[counter])) { 1039 aString = aString + "<td align=\"center\">-</td>"; 1040 counter++; 1041 } 1042 1043 //In this case, the new prefix should be set with the short name under it, 1044 //since this would mean that the team has more than one component test 1045 if(!shortName.endsWith("tests")) { 1046 aString = aString + "<tbody><tr><td><b>" + prefix + ".*" + "</b><td><td><td><td>"; 1047 aString = aString + "<tr><td><P>" + shortName; 1048 } 1049 //The team has only one component test 1050 else 1051 aString = aString + "<tbody><tr><td><b>" + shortName; 1052 testShortName = shortName; 1053 1054 counter = 0; 1055 } 1056 } 1057 //If the file's short name starts with the current prefix 1058 if(shortName.startsWith(prefix)) { 1059 //If the new file has a different short name than the current one 1060 if(!shortName.equals(testShortName)){ 1061 //Fill the remaining cells with '-'. These files will later be listed as 1062 //missing 1063 while(counter<card) { 1064 aString = aString + "<td align=\"center\">-</td>"; 1065 counter++; 1066 } 1067 counter = 0; 1068 //Print the component name 1069 aString = aString + "<tr><td><P>" + shortName; 1070 //Loop until the matching string postfix(test config.) is found 1071 while(counter<card && !fileName.endsWith(testsConfig[counter])) { 1072 aString = aString + "<td align=\"center\">-</td>"; 1073 counter++; 1074 } 1075 } 1076 else { 1077 //Loop until the matching string postfix(test config.) is found 1078 while(counter<card && !fileName.endsWith(testsConfig[counter])) { 1079 aString = aString + "<td align=\"center\">-</td>"; 1080 counter++; 1081 } 1082 //If the previous component has no more test files left 1083 if(counter==card) { 1084 counter = 0; 1085 //Print the new component name 1086 aString = aString + "<tr><td><P>" + shortName; 1087 //Loop until the matching string postfix(test config.) is found 1088 while(counter<card && !fileName.endsWith(testsConfig[counter])) { 1089 aString = aString + "<td align=\"center\">-</td>"; 1090 counter++; 1091 } 1092 } 1093 } 1094 1095 testShortName = shortName; 1096 1097 if (errorCount != 0) 1098 aString = aString + "<td align=\"center\"><b>"; 1099 else 1100 aString = aString + "<td align=\"center\">"; 1101 1102 //Print number of errors 1103 if (errorCount!=0){ 1104 displayName="<font color=\"#ff0000\">"+ "(" + String.valueOf(errorCount) + ")" +"</font>"; 1105 } 1106 else { 1107 displayName="(0)"; 1108 } 1109 1110 //Reference 1111 if (errorCount==-1){ 1112 aString=aString.concat(displayName); 1113 }else { 1114 aString=aString 1115 + "<a href=" 1116 + "\"" 1117 + hrefTestResultsTargetPath 1118 + "/" 1119 + fileName.substring(begin+1, fileName.length()-4) 1120 + ".html" 1121 + "\">" 1122 + displayName 1123 + "</a>"; 1124 } 1125 1126 if (errorCount == -1) 1127 aString = aString + "<font color=\"#ff0000\">DNF"; 1128 1129 if (errorCount != 0) 1130 aString = aString + "</font></b></td>"; 1131 else 1132 aString = aString + "</td>"; 1133 counter++; 1134 } 1135 } 1136 1137 return aString; 1138 } 1139 1140 private int countErrors(String fileName) { 1141 int errorCount = 0; 1142 1143 if (new File(fileName).length()==0) 1144 return -1; 1145 1146 try { 1147 DocumentBuilderFactory docBuilderFactory=DocumentBuilderFactory.newInstance(); 1148 parser=docBuilderFactory.newDocumentBuilder(); 1149 1150 Document document = parser.parse(fileName); 1151 NodeList elements = document.getElementsByTagName(elementName); 1152 1153 int elementCount = elements.getLength(); 1154 if (elementCount == 0) 1155 return -1; 1156 for (int i = 0; i < elementCount; i++) { 1157 Element element = (Element) elements.item(i); 1158 NamedNodeMap attributes = element.getAttributes(); 1159 Node aNode = attributes.getNamedItem("errors"); 1160 errorCount = 1161 errorCount + Integer.parseInt(aNode.getNodeValue()); 1162 aNode = attributes.getNamedItem("failures"); 1163 errorCount = 1164 errorCount + Integer.parseInt(aNode.getNodeValue()); 1165 1166 } 1167 1168 } catch (IOException e) { 1169 System.out.println("IOException: " + fileName); 1170 // e.printStackTrace(); 1171 return 0; 1172 } catch (SAXException e) { 1173 System.out.println("SAXException: " + fileName); 1174 // e.printStackTrace(); 1175 return 0; 1176 } catch (ParserConfigurationException e) { 1177 e.printStackTrace(); 1178 } 1179 return errorCount; 1180 } 1181 1182 1183 1184 /** 1185 * Gets the hrefTestResultsTargetPath. 1186 * @return Returns a String 1187 */ 1188 public String getHrefTestResultsTargetPath() { 1189 return hrefTestResultsTargetPath; 1190 } 1191 1192 /** 1193 * Sets the hrefTestResultsTargetPath. 1194 * @param hrefTestResultsTargetPath The hrefTestResultsTargetPath to set 1195 */ 1196 public void setHrefTestResultsTargetPath(String htmlTargetPath) { 1197 this.hrefTestResultsTargetPath = htmlTargetPath; 1198 } 1199 1200 /** 1201 * Gets the compileLogsDirectoryName. 1202 * @return Returns a String 1203 */ 1204 public String getCompileLogsDirectoryName() { 1205 return compileLogsDirectoryName; 1206 } 1207 1208 /** 1209 * Sets the compileLogsDirectoryName. 1210 * @param compileLogsDirectoryName The compileLogsDirectoryName to set 1211 */ 1212 public void setCompileLogsDirectoryName(String compileLogsDirectoryName) { 1213 this.compileLogsDirectoryName = compileLogsDirectoryName; 1214 } 1215 1216 /** 1217 * Gets the hrefCompileLogsTargetPath. 1218 * @return Returns a String 1219 */ 1220 public String getHrefCompileLogsTargetPath() { 1221 return hrefCompileLogsTargetPath; 1222 } 1223 1224 /** 1225 * Sets the hrefCompileLogsTargetPath. 1226 * @param hrefCompileLogsTargetPath The hrefCompileLogsTargetPath to set 1227 */ 1228 public void setHrefCompileLogsTargetPath(String hrefCompileLogsTargetPath) { 1229 this.hrefCompileLogsTargetPath = hrefCompileLogsTargetPath; 1230 } 1231 1232 /** 1233 * Gets the testManifestFileName. 1234 * @return Returns a String 1235 */ 1236 public String getTestManifestFileName() { 1237 return testManifestFileName; 1238 } 1239 1240 /** 1241 * Sets the testManifestFileName. 1242 * @param testManifestFileName The testManifestFileName to set 1243 */ 1244 public void setTestManifestFileName(String testManifestFileName) { 1245 this.testManifestFileName = testManifestFileName; 1246 } 1247 1248 /** 1249 * Gets the dropHtmlFileName. 1250 * @return Returns a String 1251 */ 1252 public String getDropHtmlFileName() { 1253 return dropHtmlFileName; 1254 } 1255 1256 /** 1257 * Sets the dropHtmlFileName. 1258 * @param dropHtmlFileName The dropHtmlFileName to set 1259 */ 1260 public void setDropHtmlFileName(String dropHtmlFileName) { 1261 this.dropHtmlFileName = dropHtmlFileName; 1262 } 1263 1264 /** 1265 * Gets the dropTemplateFileName. 1266 * @return Returns a String 1267 */ 1268 public String getDropTemplateFileName() { 1269 return dropTemplateFileName; 1270 } 1271 1272 /** 1273 * Sets the dropTemplateFileName. 1274 * @param dropTemplateFileName The dropTemplateFileName to set 1275 */ 1276 public void setDropTemplateFileName(String dropTemplateFileName) { 1277 this.dropTemplateFileName = dropTemplateFileName; 1278 } 1279 1280 protected void getDropTokensFromList(String list) { 1281 StringTokenizer tokenizer = new StringTokenizer(list, ","); 1282 dropTokens = new Vector(); 1283 1284 while (tokenizer.hasMoreTokens()) { 1285 dropTokens.add(tokenizer.nextToken()); 1286 } 1287 } 1288 1289 protected void getDifferentPlatformsFromList(String list) { 1290 StringTokenizer tokenizer = new StringTokenizer(list, ";"); 1291 differentPlatforms = new Vector(); 1292 1293 while (tokenizer.hasMoreTokens()) { 1294 differentPlatforms.add(tokenizer.nextToken()); 1295 } 1296 } 1297 1298 protected void getPlatformSpecsFromList(String list) { 1299 StringTokenizer tokenizer = new StringTokenizer(list, ","); 1300 platformSpecs = new Vector(); 1301 1302 while (tokenizer.hasMoreTokens()) { 1303 platformSpecs.add(tokenizer.nextToken()); 1304 } 1305 } 1306 1307 public String getDropTokenList() { 1308 return dropTokenList; 1309 } 1310 1311 public void setDropTokenList(String dropTokenList) { 1312 this.dropTokenList = dropTokenList; 1313 } 1314 1315 public boolean isBuildTested() { 1316 return isBuildTested; 1317 } 1318 1319 public void setIsBuildTested(boolean isBuildTested) { 1320 this.isBuildTested = isBuildTested; 1321 } 1322 1323 1324 /** 1325 * @return 1326 */ 1327 public boolean testsRan() { 1328 return testsRan; 1329 } 1330 1331 /** 1332 * @param b 1333 */ 1334 public void setTestsRan(boolean b) { 1335 testsRan = b; 1336 } 1337 1338 /** 1339 * @return 1340 */ 1341 public Vector getDropTokens() { 1342 return dropTokens; 1343 } 1344 1345 /** 1346 * @param vector 1347 */ 1348 public void setDropTokens(Vector vector) { 1349 dropTokens = vector; 1350 } 1351 1352 /** 1353 * @return 1354 */ 1355 public String getTestResultsWithProblems() { 1356 return testResultsWithProblems; 1357 } 1358 1359 /** 1360 * @return 1361 */ 1362 public String getTestResultsXmlUrls() { 1363 return testResultsXmlUrls; 1364 } 1365 1366 /** 1367 * @param string 1368 */ 1369 public void setTestResultsWithProblems(String string) { 1370 testResultsWithProblems = string; 1371 } 1372 1373 public String getBuildType() { 1374 return buildType; 1375 } 1376 1377 public void setBuildType(String buildType) { 1378 this.buildType = buildType; 1379 } 1380 1381 public String getPlatformSpecificTemplateList() { 1382 return platformSpecificTemplateList; 1383 } 1384 1385 public void setPlatformSpecificTemplateList(String platformSpecificTemplateList) { 1386 this.platformSpecificTemplateList = platformSpecificTemplateList; 1387 } 1388 1389 public void setPlatformIdentifierToken(String platformIdentifierToken) { 1390 this.platformIdentifierToken = platformIdentifierToken; 1391 } 1392 1393 public String getPlatformIdentifierToken() { 1394 return platformIdentifierToken; 1395 } 1396 1397} 1398