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
FingerPrint(String name, PrintStream ps, File outputDir)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 */
print(final PerformanceResults performanceResults)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 */
save(BarGraph barGraph, File outputFile)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 */
saveImage(File outputFile, Image image)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