1 /******************************************************************************* 2 * Copyright (c) 2000, 2009 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 *******************************************************************************/ 11 package org.eclipse.test.performance.ui; 12 13 import java.io.BufferedOutputStream; 14 import java.io.File; 15 import java.io.FileNotFoundException; 16 import java.io.FileOutputStream; 17 import java.io.IOException; 18 import java.io.OutputStream; 19 import java.io.PrintStream; 20 import java.util.ArrayList; 21 import java.util.List; 22 23 import org.eclipse.swt.SWT; 24 import org.eclipse.swt.graphics.GC; 25 import org.eclipse.swt.graphics.Image; 26 import org.eclipse.swt.graphics.ImageData; 27 import org.eclipse.swt.graphics.ImageLoader; 28 import org.eclipse.swt.widgets.Display; 29 import org.eclipse.test.internal.performance.results.db.ConfigResults; 30 import org.eclipse.test.internal.performance.results.db.DB_Results; 31 import org.eclipse.test.internal.performance.results.db.PerformanceResults; 32 import org.eclipse.test.internal.performance.results.db.ScenarioResults; 33 34 /** 35 * Class used to create scenario fingerprint. 36 */ 37 public class FingerPrint { 38 39 private static final int GRAPH_WIDTH = 1000; 40 41 String component; 42 PrintStream stream; 43 File outputDir; 44 45 public FingerPrint(String name, PrintStream ps, File outputDir) { 46 if (!name.startsWith("global")) this.component = name; 47 this.stream = ps; 48 this.outputDir = outputDir; 49 } 50 51 /** 52 * Create and save fingerprints as image and print their reference in the current stream. 53 * 54 * @param performanceResults The performance results used to print the fingerprints 55 */ 56 public void print(final PerformanceResults performanceResults) { 57 String buildName = performanceResults.getName(); 58 59 // Compute fingerprint output file name prefix 60 int currentUnderscoreIndex = buildName.indexOf('_'); 61 if (currentUnderscoreIndex != -1){ 62 buildName = buildName.substring(0, currentUnderscoreIndex); 63 } 64 StringBuffer buffer = new StringBuffer("FP_"); 65 if (this.component != null) { 66 buffer.append(this.component); 67 buffer.append('_'); 68 } 69 buffer.append(DB_Results.getDbBaselineRefVersion()); 70 buffer.append('_'); 71 buffer.append(buildName); 72 String filePrefix = buffer.toString(); 73 74 // Print the legend 75 this.stream.print("The following fingerprints show results for the most representative tests of the "); 76 if (this.component == null) { 77 this.stream.print("current build.<br>\n"); 78 } else { 79 this.stream.print(this.component); 80 this.stream.print(" component.<br>\n"); 81 } 82 this.stream.print("<table border=\"0\">\n"); 83 this.stream.print("<tr><td valign=\"top\">Select which kind of scale you want to use:</td>\n"); 84 this.stream.print("<td valign=\"top\">\n"); 85 this.stream.print(" <form>\n"); 86 this.stream.print(" <select onChange=\"toggleFingerprints();\">\n"); 87 this.stream.print(" <option>percentage</option>\n"); 88 this.stream.print(" <option>time (linear)</option>\n"); 89 this.stream.print(" <option>time (log)</option>\n"); 90 this.stream.print(" </select>\n"); 91 this.stream.print(" </form>\n"); 92 this.stream.print("</td>\n"); 93 // this.stream.print("<td valign=\"top\">\n"); 94 // this.stream.print("<a href=\"help.html\"><img hspace=\"10\" border=\"0\" src=\""+Utils.LIGHT+"\" title=\"Some tips on fingerprints\"/></a>\n"); 95 // this.stream.print("</td></tr></table>\n"); 96 this.stream.print("</tr></table>\n"); 97 this.stream.print("<img hspace=\"10\" border=\"0\" src=\""+Utils.LIGHT+"\"><a href=\""+Utils.HELP+"\">Help on fingerprints</a>\n"); 98 99 // Print script to reset dropdown list selection 100 this.stream.print("<script type=\"text/javascript\">\n"); 101 this.stream.print(" setFingerprintsType();\n"); 102 this.stream.print("</script>\n"); 103 104 // Create each fingerprint and save it 105 String[] configNames = performanceResults.getConfigNames(false/* not sorted*/); 106 String[] configBoxes = performanceResults.getConfigBoxes(false/* not sorted*/); 107 int length = configNames.length; 108 for (int c=0; c<length; c++) { 109 String configName = configNames[c]; 110 List scenarios = performanceResults.getComponentSummaryScenarios(this.component, configName); 111 if (scenarios == null) continue; 112 113 // Create BarGraph 114 // TODO use FingerPrintGraph instead 115 BarGraph barGraph = null; 116 List allResults = new ArrayList(); 117 String defaultDimName = DB_Results.getDefaultDimension().getName(); 118 for (int i=0, size=scenarios.size(); i<size; i++) { 119 ScenarioResults scenarioResults = (ScenarioResults) scenarios.get(i); 120 ConfigResults configResults = scenarioResults.getConfigResults(configName); 121 if (configResults == null || !configResults.isValid()) continue; 122 double[] results = configResults.getCurrentBuildDeltaInfo(); 123 double percent = -results[0] * 100.0; 124 if (results != null && Math.abs(percent) < 200) { 125 String name = scenarioResults.getLabel() + " (" + defaultDimName + ")"; 126 if (!configResults.getCurrentBuildName().equals(buildName)) { 127 continue; // the test didn't run on last build, skip it 128 } 129 if (!configResults.isBaselined()) { 130 name = "*" + name + " (" + configResults.getBaselineBuildName() + ")"; 131 } 132 if (barGraph == null) { 133 barGraph = new BarGraph(null); 134 } 135 barGraph.addItem(name, 136 results, 137 configName + "/" + scenarioResults.getFileName() + ".html", 138 configResults.getCurrentBuildResults().getComment(), 139 (Utils.confidenceLevel(results) & Utils.ERR) == 0); 140 141 // add results 142 allResults.add(configResults); 143 } 144 } 145 if (barGraph == null) continue; 146 147 // Save image file 148 String fileName = filePrefix + '.' + configName ; 149 File outputFile = new File(this.outputDir, fileName+".gif"); 150 save(barGraph, outputFile); 151 152 // Print image file reference in stream 153 String boxName = configBoxes[c]; 154 if (outputFile.exists()) { 155 String areas = barGraph.getAreas(); 156 if (areas == null) areas = ""; 157 this.stream.print("<h4>"); 158 this.stream.print(boxName); 159 this.stream.print("</h4>\n"); 160 this.stream.print("<?php\n"); 161 this.stream.print(" $type=$_SERVER['QUERY_STRING'];\n"); 162 this.stream.print(" if ($type==\"\" || $type==\"fp_type=0\") {\n"); 163 this.stream.print(" echo '<img src=\""); 164 this.stream.print(fileName); 165 this.stream.print(".gif\" usemap=\"#"); 166 this.stream.print(fileName); 167 this.stream.print("\" name=\""); 168 this.stream.print(configName); 169 this.stream.print("\">';\n"); 170 this.stream.print(" echo '<map name=\""); 171 this.stream.print(fileName); 172 this.stream.print("\">';\n"); 173 this.stream.print(areas); 174 this.stream.print(" echo '</map>';\n"); 175 this.stream.print(" }\n"); 176 } else { 177 this.stream.print("<br><br>There is no fingerprint for "); 178 this.stream.print(boxName); 179 this.stream.print("<br><br>\n"); 180 } 181 182 // Create, paint and print the time bars graph 183 FingerPrintGraph graph = new FingerPrintGraph(this.outputDir, fileName, GRAPH_WIDTH, allResults); 184 graph.paint(this.stream); 185 this.stream.print("?>\n"); 186 } 187 } 188 189 /* 190 * Save the computed bar graph. 191 */ 192 private void save(BarGraph barGraph, File outputFile) { 193 194 // Create and paint image 195 Display display = Display.getDefault(); 196 int height = barGraph.getHeight(); 197 Image image = new Image(display, GRAPH_WIDTH, height); 198 GC gc = new GC(image); 199 barGraph.paint(display, GRAPH_WIDTH, height, gc); 200 gc.dispose(); 201 202 saveImage(outputFile, image); 203 } 204 205 /** 206 * @param outputFile 207 * @param image 208 */ 209 private void saveImage(File outputFile, Image image) { 210 // Save image 211 ImageData data = Utils.downSample(image); 212 ImageLoader imageLoader = new ImageLoader(); 213 imageLoader.data = new ImageData[] { data }; 214 215 OutputStream out = null; 216 try { 217 out = new BufferedOutputStream(new FileOutputStream(outputFile)); 218 imageLoader.save(out, SWT.IMAGE_GIF); 219 } catch (FileNotFoundException e) { 220 e.printStackTrace(); 221 } finally { 222 image.dispose(); 223 if (out != null) { 224 try { 225 out.close(); 226 } catch (IOException e1) { 227 // silently ignored 228 } 229 } 230 } 231 } 232 } 233