Bug 256349 rerun 3.5M3 with performance tests
diff --git a/bundles/org.eclipse.test.performance.ui/doc/help.html b/bundles/org.eclipse.test.performance.ui/doc/help.html
new file mode 100644
index 0000000..03eefba
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/help.html
@@ -0,0 +1,102 @@
+<html><head><meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
+<style type="text/css">p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}
+pre { font-family: "Courier New", Courier, mono; font-size: 10pt}
+h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}
+code { font-family: "Courier New", Courier, mono; font-size: 10pt}
+sup { font-family: arial,helvetica,geneva; font-size: 10px}
+h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}
+li { font-family: arial, helvetica, geneva; font-size: 10pt}
+h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}
+body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}
+.indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}
+.indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}
+</style>
+<body>
+<p>
+Since 3.5, it's possible to see results in fingerprints with three different
+kinds of scale:
+<ul>
+<li><a href="#percent">Percentage scale</a></li>
+<li><a href="#time">Time linear scale</a></li>
+<li><a href="#time">Time logarithmic scale</a></li>
+<li><a href="#tips">Tips for time scales</a></li>
+</ul>
+</p>
+<h1><a name="percent">Percentage scale</h1>
+<p>The X axis represents percentage of the variation vs. the given baseline</p>
+<p>This is the way fingerprints were displayed since the beginning:
+<p><img src="images/percentage.png">
+<ul>
+<li>Red bar means a regression, even if it's less than the 10% threshold.</li>
+<li>Green bar means an improvement</li>
+<li>Gray bar means an 'explained' regression.</li>
+</ul>
+</p>
+<h1><a name="time">Linear and logarithmic time scales</h1>
+<p>For these scales, the X axis represents the duration time of the test.<br>
+The colors meanings are the same than for the percentage scale.<br>
+These kind of graphs give a better idea of time duration for each test.</p>
+<p>Typically use linear scale if you want to see the tests relativeness for all the component tests:</p>
+<p><img src="images/linear.png">
+<p>But the logarithmic scale is more appropriate when there are a strong duration differences between tests, hence makes short duration tests easier to survey:</p>
+<p><img src="images/log.png">
+<p>Each test have two bars: the former is white and shows the baseline result, the latter is colored (red, green or gray) and shows the current build result.<br>
+The variation between the baseline and the build is displayed as a percentage on top of both bars.</p>
+<h1><a name="tips">Tips for time scales</h1>
+<p>Tips are almost the same for linear and logarithmic scales:</p>
+<table border="0">
+ <tr>
+ <td valign="top"><img src="images/light.gif"></td>
+ <td><b>Flying over a bar displays its time value<b>:</td></tr>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img src="images/help_time_baseline.png"></td>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img src="images/help_time_current.png"></td>
+ </tr>
+ <tr><td><br></td></tr>
+ <tr>
+ <td valign="top"><img src="images/light.gif"></td>
+ <td><b>For <u>linear scale only</u>, when the error on the time result is noticeable,
+ then the measurement uncertainty is shown in yellow at the end of the bar<b>:</td></tr>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img src="images/help_time_error.png"></td>
+ </tr>
+ <tr><td><br></td></tr>
+ <tr>
+ <td valign="top"><img src="images/light.gif"></td>
+ <td><b>A performance regression may sometimes have a known good reason</b>.<br>
+ In this case, the current build bar is grayed and flying over it also shows the given explanation:</td></tr>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img src="images/help_explained_regression.png"></td>
+ </tr>
+ <tr><td><br></td></tr>
+ <tr>
+ <td valign="top"><img src="images/light.gif"></td>
+ <td><b>Test result may have big error which can make the test result not fully reliable</b>.<br>
+ In this case, a warning icon is shown after the variation value and flying over it gives the offending error value:</td></tr>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img src="images/help_error_warning.png"></td>
+ </tr>
+ <tr><td><br></td></tr>
+ <tr>
+ <td valign="top"><img src="images/light.gif"></td>
+ <td><b>Test may have no result for the used baseline, hence the first available build is used as a reference</b>.<br>
+ In this case, a warning icon is shown after the scenario title and flying over it gives the build ID used to compute the variation:</td></tr>
+ </tr>
+ <tr>
+ <td></td>
+ <td><img src="images/help_no_baseline.png"></td>
+ </tr>
+</table>
+</body>
+</html>
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/help_error_warning.png b/bundles/org.eclipse.test.performance.ui/doc/images/help_error_warning.png
new file mode 100644
index 0000000..399acaf
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/help_error_warning.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/help_explained_regression.png b/bundles/org.eclipse.test.performance.ui/doc/images/help_explained_regression.png
new file mode 100644
index 0000000..a7b7c84
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/help_explained_regression.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/help_no_baseline.png b/bundles/org.eclipse.test.performance.ui/doc/images/help_no_baseline.png
new file mode 100644
index 0000000..f06762e
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/help_no_baseline.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/help_time_baseline.png b/bundles/org.eclipse.test.performance.ui/doc/images/help_time_baseline.png
new file mode 100644
index 0000000..594fdf2
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/help_time_baseline.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/help_time_current.png b/bundles/org.eclipse.test.performance.ui/doc/images/help_time_current.png
new file mode 100644
index 0000000..5e913cb
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/help_time_current.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/help_time_error.png b/bundles/org.eclipse.test.performance.ui/doc/images/help_time_error.png
new file mode 100644
index 0000000..2ce272d
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/help_time_error.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/light.gif b/bundles/org.eclipse.test.performance.ui/doc/images/light.gif
new file mode 100644
index 0000000..11af180
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/light.gif
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/linear.png b/bundles/org.eclipse.test.performance.ui/doc/images/linear.png
new file mode 100644
index 0000000..cd276a9
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/linear.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/log.png b/bundles/org.eclipse.test.performance.ui/doc/images/log.png
new file mode 100644
index 0000000..7f2e84a
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/log.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/doc/images/percentage.png b/bundles/org.eclipse.test.performance.ui/doc/images/percentage.png
new file mode 100644
index 0000000..6f965da
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/doc/images/percentage.png
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/images/light.gif b/bundles/org.eclipse.test.performance.ui/images/light.gif
new file mode 100644
index 0000000..11af180
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/images/light.gif
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/images/warning_obj.gif b/bundles/org.eclipse.test.performance.ui/images/warning_obj.gif
new file mode 100644
index 0000000..2b2e50f
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/images/warning_obj.gif
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/performanceui.jar b/bundles/org.eclipse.test.performance.ui/performanceui.jar
index 3d0f83c..0244b35 100644
--- a/bundles/org.eclipse.test.performance.ui/performanceui.jar
+++ b/bundles/org.eclipse.test.performance.ui/performanceui.jar
Binary files differ
diff --git a/bundles/org.eclipse.test.performance.ui/scripts/Fingerprints.js b/bundles/org.eclipse.test.performance.ui/scripts/Fingerprints.js
new file mode 100644
index 0000000..d1914e9
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/scripts/Fingerprints.js
@@ -0,0 +1,32 @@
+function toggleFingerprints() {
+ var formSelect=document.forms[0].elements[0];
+ var type=formSelect.selectedIndex;
+ var idx=document.URL.indexOf("php?");
+ if (idx==-1) {
+ window.open(document.URL+"?fp_type="+type, "_self");
+ } else {
+ window.open(document.URL.substring(0,idx)+"php?fp_type="+type, "_self");
+ }
+}
+
+function setFingerprintsType() {
+ var idx=document.URL.indexOf("?");
+ var type=0;
+ if (idx != -1) {
+ var typeStr=document.URL.substring(idx+1, document.URL.length);
+ idx=typeStr.indexOf("=");
+ if (idx != -1) {
+ var ch=typeStr.substring(idx+1, idx+2)
+ switch (ch) {
+ case '1':
+ type=1;
+ break;
+ case '2':
+ type=2;
+ break;
+ }
+ }
+ }
+ var formSelect=document.forms[0].elements[0];
+ formSelect.selectedIndex=type;
+}
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/BarGraph.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/BarGraph.java
index 2dc79d0..a5cf5a1 100644
--- a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/BarGraph.java
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/BarGraph.java
@@ -273,7 +273,7 @@
if (hasURL) {
if (fAreaBuffer == null)
fAreaBuffer= new StringBuffer();
- fAreaBuffer.append("<area shape=\"RECT\" coords=\"0," + y0 + ',' + width + ',' + y + "\" href=\"" + bar.url + "\">\n"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
+ fAreaBuffer.append(" echo '<area shape=\"RECT\" coords=\"0," + y0 + ',' + width + ',' + y + "\" href=\"" + bar.url + "\">';\n");
}
}
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/FingerPrint.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/FingerPrint.java
index 648e7ed..2bd8243 100644
--- a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/FingerPrint.java
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/FingerPrint.java
@@ -17,6 +17,7 @@
import java.io.IOException;
import java.io.OutputStream;
import java.io.PrintStream;
+import java.util.ArrayList;
import java.util.List;
import org.eclipse.swt.SWT;
@@ -42,7 +43,7 @@
File outputDir;
public FingerPrint(String name, PrintStream ps, File outputDir) {
- if (!name.equals("global")) this.component = name;
+ if (!name.startsWith("global")) this.component = name;
this.stream = ps;
this.outputDir = outputDir;
}
@@ -53,15 +54,9 @@
* @param performanceResults The performance results used to print the fingerprints
*/
public void print(PerformanceResults performanceResults) {
- String baselineBuildName = performanceResults.getBaselineName();
String buildName = performanceResults.getName();
// Compute fingerprint output file name prefix
- int referenceUnderscoreIndex = baselineBuildName.indexOf('_');
- String baselinePrefix = baselineBuildName;
- if (referenceUnderscoreIndex != -1) {
- baselinePrefix = baselineBuildName.substring(0, referenceUnderscoreIndex);
- }
int currentUnderscoreIndex = buildName.indexOf('_');
if (currentUnderscoreIndex != -1){
buildName = buildName.substring(0, currentUnderscoreIndex);
@@ -71,11 +66,38 @@
buffer.append(this.component);
buffer.append('_');
}
- buffer.append(baselinePrefix);
+ buffer.append(AbstractResults.VERSION_REF);
buffer.append('_');
buffer.append(buildName);
- buffer.append('.');
String filePrefix = buffer.toString();
+
+ // Print the legend
+ this.stream.print("The following fingerprints show results for the most representative tests of the ");
+ if (this.component == null) {
+ this.stream.print("current build.<br>\n");
+ } else {
+ this.stream.print(component);
+ this.stream.print(" component.<br>\n");
+ }
+ this.stream.print("<table border=\"0\">\n");
+ this.stream.print("<tr><td valign=\"top\">Select which kind of scale you want to use:</td>\n");
+ this.stream.print("<td valign=\"top\">\n");
+ this.stream.print(" <form>\n");
+ this.stream.print(" <select onChange=\"toggleFingerprints();\">\n");
+ this.stream.print(" <option>percentage</option>\n");
+ this.stream.print(" <option>time (linear)</option>\n");
+ this.stream.print(" <option>time (log)</option>\n");
+ this.stream.print(" </select>\n");
+ this.stream.print(" </form>\n");
+ this.stream.print("</td>\n");
+ this.stream.print("<td valign=\"top\">\n");
+ this.stream.print("<a href=\"help.html\"><img hspace=\"10\" border=\"0\" src=\"light.gif\" title=\"Some tips on fingerprints\"/></a>\n");
+ this.stream.print("</td></tr></table>\n");
+
+ // Print script to reset dropdown list selection
+ this.stream.print("<script type=\"text/javascript\">\n");
+ this.stream.print(" setFingerprintsType();\n");
+ this.stream.print("</script>\n");
// Create each fingerprint and save it
String[] configNames = performanceResults.getConfigNames(false/* not sorted*/);
@@ -87,8 +109,9 @@
if (scenarios == null) continue;
// Create BarGraph
-// BarGraph barGraph = new BarGraph(null);
+ // TODO use FingerPrintGraph instead
BarGraph barGraph = null;
+ List allResults = new ArrayList();
String defaultDimName = AbstractResults.DEFAULT_DIM.getName();
for (int i=0, size=scenarios.size(); i<size; i++) {
ScenarioResults scenarioResults = (ScenarioResults) scenarios.get(i);
@@ -112,12 +135,15 @@
configName + "/" + scenarioResults.getFileName() + ".html",
configResults.getCurrentBuildResults().getComment(),
(Utils.confidenceLevel(results) & Utils.ERR) == 0);
+
+ // add results
+ allResults.add(configResults);
}
}
if (barGraph == null) continue;
// Save image file
- String fileName = filePrefix + configName ;
+ String fileName = filePrefix + '.' + configName ;
File outputFile = new File(this.outputDir, fileName+".gif");
save(barGraph, outputFile);
@@ -128,21 +154,33 @@
if (areas == null) areas = "";
this.stream.print("<h4>");
this.stream.print(boxName);
- this.stream.print("</h4>");
- this.stream.print("<img src=\"");
+ this.stream.print("</h4>\n");
+ this.stream.print("<?php\n");
+ this.stream.print(" $type=$_SERVER['QUERY_STRING'];\n");
+ this.stream.print(" if ($type==\"\" || $type==\"fp_type=0\") {\n");
+ this.stream.print(" echo '<img src=\"");
this.stream.print(fileName);
this.stream.print(".gif\" usemap=\"#");
this.stream.print(fileName);
- this.stream.print("\"><map name=\"");
+ this.stream.print("\" name=\"");
+ this.stream.print(configName);
+ this.stream.print("\">';\n");
+ this.stream.print(" echo '<map name=\"");
this.stream.print(fileName);
- this.stream.print("\">");
+ this.stream.print("\">';\n");
this.stream.print(areas);
- this.stream.print("</map>\n");
+ this.stream.print(" echo '</map>';\n");
+ this.stream.print(" }\n");
} else {
this.stream.print("<br><br>There is no fingerprint for ");
this.stream.print(boxName);
this.stream.print("<br><br>\n");
}
+
+ // Create, paint and print the time bars graph
+ FingerPrintGraph graph = new FingerPrintGraph(this.outputDir, fileName, GRAPH_WIDTH, allResults);
+ graph.paint(this.stream);
+ this.stream.print("?>\n");
}
}
@@ -159,6 +197,14 @@
barGraph.paint(display, GRAPH_WIDTH, height, gc);
gc.dispose();
+ saveImage(outputFile, image);
+}
+
+/**
+ * @param outputFile
+ * @param image
+ */
+private void saveImage(File outputFile, Image image) {
// Save image
ImageData data = Utils.downSample(image);
ImageLoader imageLoader = new ImageLoader();
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/FingerPrintGraph.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/FingerPrintGraph.java
new file mode 100644
index 0000000..87fea0b
--- /dev/null
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/FingerPrintGraph.java
@@ -0,0 +1,671 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2008 IBM Corporation and others.
+ * All rights reserved. This program and the accompanying materials
+ * are made available under the terms of the Eclipse Public License v1.0
+ * which accompanies this distribution, and is available at
+ * http://www.eclipse.org/legal/epl-v10.html
+ *
+ * Contributors:
+ * IBM Corporation - initial API and implementation
+ *******************************************************************************/
+package org.eclipse.test.performance.ui;
+
+import java.io.File;
+import java.io.PrintStream;
+import java.text.NumberFormat;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+
+import org.eclipse.swt.SWT;
+import org.eclipse.swt.graphics.Color;
+import org.eclipse.swt.graphics.Font;
+import org.eclipse.swt.graphics.FontData;
+import org.eclipse.swt.graphics.GC;
+import org.eclipse.swt.graphics.Image;
+import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.Point;
+import org.eclipse.swt.graphics.Rectangle;
+import org.eclipse.swt.graphics.Resource;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.test.internal.performance.results.AbstractResults;
+import org.eclipse.test.internal.performance.results.BuildResults;
+import org.eclipse.test.internal.performance.results.ConfigResults;
+import org.eclipse.test.internal.performance.results.ScenarioResults;
+
+/**
+ * Abstract class to build graph with bars
+ */
+public class FingerPrintGraph {
+
+ // Dimensions
+ static final String DEFAULT_DIM_NAME = AbstractResults.DEFAULT_DIM.getName();
+
+ // Sizes
+ static final int MARGIN= 5; // margin on all four sides
+ static final int BAR_HEIGHT= 6; // height of bar
+ static final int GAP= 10; // gap between bars
+ static final int TGAP= 5; // gap between lines and labels
+ static final int LINE_HEIGHT = 2*BAR_HEIGHT + GAP;
+
+ // fraction of width reserved for bar graph
+ static final double RATIO= 0.6;
+
+ // Formatting constants
+ static final NumberFormat NUMBER_FORMAT;
+ static {
+ NUMBER_FORMAT = NumberFormat.getInstance();
+ NUMBER_FORMAT.setMaximumFractionDigits(1);
+ }
+
+ // Graphic constants
+ static final Display DEFAULT_DISPLAY = Display.getDefault();
+ static final Color BLACK= DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_BLACK);
+ static final Color BLUE= DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_BLUE);
+ static final Color GREEN= DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_GREEN);
+ static final Color RED = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_RED);
+ static final Color GRAY = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_GRAY);
+ static final Color DARK_GRAY = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_DARK_GRAY);
+ static final Color YELLOW = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_YELLOW);
+ static final Color WHITE = DEFAULT_DISPLAY.getSystemColor(SWT.COLOR_WHITE);
+
+ // Bar graph kinds
+ static final int NO_TIME = 0; // i.e. percentage
+ static final int TIME_LINEAR = 1;
+ static final int TIME_LOG = 2;
+ static final int[] SUPPORTED_GRAPHS = {
+// NO_TIME,
+ TIME_LINEAR,
+ TIME_LOG,
+ };
+
+ // Graphic fields
+ GC gc;
+ Image image;
+ int imageWidth;
+ int imageHeight;
+ int graphWidth;
+ int graphHeight;
+ Map resources = new HashMap();
+
+ // Data fields
+ int count = 0;
+ ConfigResults[] results = new ConfigResults[10];
+ BarGraphArea[] areas;
+
+ // Values
+ double maxValue = 0.0;
+ double minValue = Double.MAX_VALUE;
+
+ // File info
+ File outputDir;
+ String imageName;
+
+ /*
+ * Member class defining a bar graph area.
+ * This area applies to a configuration results and is made of several zones.
+ */
+ class BarGraphArea {
+ List zones;
+ private ConfigResults configResults;
+
+ /*
+ * Member class defining a zone inside a bar graph area.
+ * Typically made of a rectangle and an associated text used as tooltip.
+ */
+ class AreaZone {
+ Rectangle zone;
+ String title;
+
+ AreaZone(Rectangle zone, String tooltip) {
+ super();
+ this.zone = zone;
+ this.title = tooltip;
+ }
+
+ void print(String url, PrintStream stream) {
+ stream.print(" echo '<area shape=\"RECT\"");
+ if (this.title != null) {
+ stream.print(" title=\""+this.title+"\"");
+ }
+ stream.print("coords=\"");
+ stream.print(this.zone.x);
+ stream.print(',');
+ stream.print(this.zone.y);
+ stream.print(',');
+ stream.print(this.zone.x+this.zone.width);
+ stream.print(',');
+ stream.print(this.zone.y+this.zone.height);
+ stream.print('"');
+ if (url != null) {
+ stream.print(" href=\"");
+ stream.print(url);
+ stream.print('"');
+ }
+ stream.print(">';\n");
+ }
+ }
+
+ BarGraphArea(ConfigResults results) {
+ this.configResults = results;
+ this.zones = new ArrayList();
+ }
+
+ void print(PrintStream stream) {
+ String url = this.configResults.getName() + "/" + ((ScenarioResults) this.configResults.getParent()).getFileName() + ".html";
+ int size = this.zones.size();
+ for (int i=0; i<size; i++) {
+ AreaZone zone = (AreaZone) this.zones.get(i);
+ zone.print(url, stream);
+ }
+ }
+
+ void addArea(Rectangle rec, String tooltip) {
+ AreaZone zone = new AreaZone(rec, tooltip);
+ this.zones.add(zone);
+ }
+
+ }
+
+
+FingerPrintGraph(File dir, String fileName, int width, List results) {
+ super();
+ this.imageWidth = width;
+ this.count = results.size();
+ this.results = new ConfigResults[this.count];
+ results.toArray(this.results);
+ this.outputDir = dir;
+ this.imageName = fileName;
+}
+
+/**
+ */
+void drawBars(int kind) {
+
+ // Get/Set graphical resources
+ Font italicFont = (Font) this.resources.get("italicFont");
+ if (italicFont == null) {
+ String fontDataName = this.gc.getFont().getFontData()[0].toString();
+ FontData fdItalic = new FontData(fontDataName);
+ fdItalic.setStyle(SWT.ITALIC);
+ italicFont = new Font(DEFAULT_DISPLAY, fdItalic);
+ this.resources.put("italicFont", italicFont);
+ }
+ Color blueref = (Color) this.resources.get("blueref");
+ if (blueref == null) {
+ blueref = new Color(DEFAULT_DISPLAY, 200, 200, 255);
+ this.resources.put("blueref", blueref);
+ }
+ Color lightyellow= (Color) this.resources.get("lightyellow");
+ if (lightyellow == null) {
+ lightyellow = new Color(DEFAULT_DISPLAY, 255, 255, 160);
+ this.resources.put("lightyellow", lightyellow);
+ }
+ Color darkyellow= (Color) this.resources.get("darkyellow");
+ if (darkyellow == null) {
+ darkyellow = new Color(DEFAULT_DISPLAY, 160, 160, 0);
+ this.resources.put("darkyellow", darkyellow);
+ }
+ Color lightgreen= (Color) this.resources.get("lightgreen");
+ if (lightgreen == null) {
+ lightgreen = new Color(DEFAULT_DISPLAY, 160, 255, 160);
+ this.resources.put("lightgreen", lightgreen);
+ }
+ Color lightred = (Color) this.resources.get("lightred");
+ if (lightred == null) {
+ lightred = new Color(DEFAULT_DISPLAY, 255, 160, 160);
+ this.resources.put("lightred", lightred);
+ }
+
+ // Build each scenario bar graph
+ this.areas = new BarGraphArea[this.count];
+ double max = kind == TIME_LOG ? Math.log(this.maxValue) : this.maxValue;
+ for (int i=0, y=MARGIN; i < this.count; i++, y+=LINE_HEIGHT) {
+
+ // get builds info
+ ConfigResults configResults = this.results[i];
+ this.areas[i] = new BarGraphArea(configResults);
+ BarGraphArea graphArea = this.areas[i];
+ BuildResults currentBuildResults = configResults.getCurrentBuildResults();
+ double currentValue = currentBuildResults.getValue();
+ double currentError = currentBuildResults.getError();
+ double error = configResults.getError();
+ boolean singleTest = Double.isNaN(error);
+ boolean isSignificant = singleTest || error < Utils.STANDARD_ERROR_THRESHOLD;
+ boolean isCommented = currentBuildResults.getComment() != null;
+ BuildResults baselineBuildResults = configResults.getBaselineBuildResults();
+ double baselineValue = baselineBuildResults.getValue();
+ double baselineError = baselineBuildResults.getError();
+
+ // draw baseline build bar
+ Color whiteref = (Color) this.resources.get("whiteref");
+ if (whiteref == null) {
+ whiteref = new Color(DEFAULT_DISPLAY, 240, 240, 248);
+ this.resources.put("whiteref", whiteref);
+ }
+ this.gc.setBackground(whiteref);
+ double baselineGraphValue = kind == TIME_LOG ? Math.log(baselineValue) : baselineValue;
+ int baselineBarLength= (int) (baselineGraphValue / max * this.graphWidth);
+ int baselineErrorLength= (int) (baselineError / max * this.graphWidth / 2);
+ int labelxpos = MARGIN + baselineBarLength;
+ if (kind == TIME_LOG || baselineErrorLength <= 1) {
+ this.gc.fillRectangle(MARGIN, y + (GAP/2), baselineBarLength, BAR_HEIGHT);
+ Rectangle rec = new Rectangle(MARGIN, y + (GAP/2), baselineBarLength, BAR_HEIGHT);
+ this.gc.drawRectangle(rec);
+ graphArea.addArea(rec, "Time for baseline build "+baselineBuildResults.getName()+": "+AbstractResults.timeString((long)baselineValue));
+ } else {
+ int wr = baselineBarLength - baselineErrorLength;
+ Rectangle recValue = new Rectangle(MARGIN, y + (GAP/2), wr, BAR_HEIGHT);
+ this.gc.fillRectangle(recValue);
+ this.gc.setBackground(YELLOW);
+ Rectangle recError = new Rectangle(MARGIN+wr, y + (GAP/2), baselineErrorLength*2, BAR_HEIGHT);
+ this.gc.fillRectangle(recError);
+ Rectangle rec = new Rectangle(MARGIN, y + (GAP/2), baselineBarLength+baselineErrorLength, BAR_HEIGHT);
+ this.gc.drawRectangle(rec);
+ StringBuffer tooltip = new StringBuffer("Time for baseline build ");
+ tooltip.append(baselineBuildResults.getName());
+ tooltip.append(": ");
+ tooltip.append(AbstractResults.timeString((long)baselineValue));
+ tooltip.append(" [±");
+ tooltip.append(AbstractResults.timeString((long)baselineError));
+ tooltip.append(']');
+ graphArea.addArea(rec, tooltip.toString());
+ labelxpos += baselineErrorLength;
+ }
+
+ // set current build bar color
+ if (baselineValue < currentValue) {
+ if (isCommented) {
+ this.gc.setBackground(GRAY);
+ } else {
+ this.gc.setBackground(RED);
+ }
+ } else {
+ this.gc.setBackground(GREEN);
+ }
+
+ // draw current build bar
+ double currentGraphValue = kind == TIME_LOG ? Math.log(currentValue) : currentValue;
+ int currentBarLength= (int) (currentGraphValue / max * this.graphWidth);
+ int currentErrorLength= (int) (currentError / max * this.graphWidth / 2);
+ if (kind == TIME_LOG || currentErrorLength <= 1) {
+ this.gc.fillRectangle(MARGIN, y + (GAP/2) + BAR_HEIGHT, currentBarLength, BAR_HEIGHT);
+ Rectangle rec = new Rectangle(MARGIN, y + (GAP/2) + BAR_HEIGHT, currentBarLength, BAR_HEIGHT);
+ this.gc.drawRectangle(rec);
+ String tooltip = "Time for current build "+currentBuildResults.getName()+": "+AbstractResults.timeString((long)currentValue);
+ if (isCommented) {
+ tooltip += ". " + currentBuildResults.getComment();
+ }
+ graphArea.addArea(rec, tooltip);
+ if (labelxpos < (MARGIN+currentBarLength)) {
+ labelxpos = MARGIN + currentBarLength;
+ }
+ } else {
+ int wr = currentBarLength - currentErrorLength;
+ Rectangle recValue = new Rectangle(MARGIN, y + (GAP/2) + BAR_HEIGHT, wr, BAR_HEIGHT);
+ this.gc.fillRectangle(recValue);
+ this.gc.setBackground(YELLOW);
+ Rectangle recError = new Rectangle(MARGIN+wr, y + (GAP/2) + BAR_HEIGHT, currentErrorLength*2, BAR_HEIGHT);
+ this.gc.fillRectangle(recError);
+ Rectangle rec = new Rectangle(MARGIN, y + (GAP/2) + BAR_HEIGHT, currentBarLength+currentErrorLength, BAR_HEIGHT);
+ this.gc.drawRectangle(rec);
+ StringBuffer tooltip = new StringBuffer("Time for current build ");
+ tooltip.append(currentBuildResults.getName());
+ tooltip.append(": ");
+ tooltip.append(AbstractResults.timeString((long)currentValue));
+ tooltip.append(" [±");
+ tooltip.append(AbstractResults.timeString((long)currentError));
+ tooltip.append(']');
+ if (isCommented) {
+ tooltip.append(". ");
+ tooltip.append(currentBuildResults.getComment());
+ }
+ graphArea.addArea(rec, tooltip.toString());
+ if (labelxpos < (MARGIN+currentBarLength+currentErrorLength)) {
+ labelxpos = MARGIN + currentBarLength+currentErrorLength;
+ }
+ }
+
+ // set delta value style and color
+ boolean hasFailure = currentBuildResults.getFailure() != null;
+ if (hasFailure) {
+ if (isCommented) {
+ this.gc.setForeground(DARK_GRAY);
+ } else {
+ this.gc.setForeground(RED);
+ }
+ } else {
+ this.gc.setForeground(BLACK);
+ }
+
+ // draw delta value
+ double delta = -configResults.getDelta();
+ String label = delta > 0 ? "+" : "";
+ label += NUMBER_FORMAT.format(delta*100) + "%";
+ Point labelExtent= this.gc.stringExtent(label);
+ int labelvpos= y + (LINE_HEIGHT - labelExtent.y) / 2;
+ this.gc.drawString(label, labelxpos+TGAP, labelvpos, true);
+ this.gc.setForeground(BLACK);
+ this.gc.setFont(null);
+ int titleStart = (int) (RATIO * this.imageWidth);
+ if (singleTest || !isSignificant) {
+ String deltaTooltip = null;
+ if (singleTest) {
+ deltaTooltip = "This test performed only one iteration; hence its reliability cannot be assessed";
+ } else if (!isSignificant) {
+ deltaTooltip = "This test has a bad reliability: error is "+NUMBER_FORMAT.format(error*100)+"% (> 3%)!";
+ }
+ Image warning = (Image) this.resources.get("warning");
+ int xi = labelxpos+TGAP+labelExtent.x;
+ this.gc.drawImage(warning, xi, labelvpos);
+ ImageData imageData = warning.getImageData();
+ // Set zones
+ // - first one is between end of bar and warning image beginning
+ Rectangle deltaZone = new Rectangle(labelxpos, labelvpos-2, xi-labelxpos, labelExtent.y+4);
+ graphArea.addArea(deltaZone, null);
+ // - second one is the warning image
+ Rectangle warningZone = new Rectangle(xi, labelvpos, imageData.width, imageData.height);
+ graphArea.addArea(warningZone, deltaTooltip);
+ // - last one is between end of the warning image and the scenario title beginning
+ int warningImageEnd = xi+imageData.width;
+ Rectangle emptyZone = new Rectangle(warningImageEnd, labelvpos, titleStart-warningImageEnd, imageData.height);
+ graphArea.addArea(emptyZone, deltaTooltip);
+ } else {
+ // No tooltip => delta zone is between end of bar and the scenario title beginning
+ Rectangle deltaZone = new Rectangle(labelxpos, labelvpos-2, titleStart-labelxpos, labelExtent.y+4);
+ graphArea.addArea(deltaZone, null);
+ }
+
+ // set title style
+ Color oldfg= this.gc.getForeground();
+ this.gc.setForeground(BLUE);
+
+ // draw scenario title
+ int x= titleStart;
+ ScenarioResults scenarioResults = (ScenarioResults) configResults.getParent();
+ String title = scenarioResults.getLabel() + " (" + DEFAULT_DIM_NAME + ")";
+ Point e= this.gc.stringExtent(title);
+ this.gc.drawLine(x, labelvpos + e.y - 1, x + e.x, labelvpos + e.y - 1);
+ this.gc.drawString(title, x, labelvpos, true);
+ this.gc.setForeground(oldfg);
+ this.gc.setFont(null);
+ Rectangle titleZone = new Rectangle(x, labelvpos, e.x, e.y);
+ graphArea.addArea(titleZone, null/*no tooltip*/);
+ if (!configResults.isBaselined()) {
+ Image warning = (Image) this.resources.get("warning");
+ this.gc.drawImage(warning, x+e.x, labelvpos);
+ ImageData imageData = warning.getImageData();
+ Rectangle warningZone = new Rectangle(x+e.x, labelvpos, imageData.width, imageData.height);
+ String titleTooltip = "This test has no baseline result, hence use build "+configResults.getBaselineBuildName()+" for reference!";
+ graphArea.addArea(warningZone, titleTooltip);
+ }
+ }
+}
+
+void drawLinearScale() {
+
+ // Draw scale background
+ drawScaleBackground();
+
+ // Draw scale grid lines
+ int gridValue = 100;
+ int n = (int) (this.maxValue / gridValue);
+ while (n > 10) {
+ switch (gridValue) {
+ case 100:
+ gridValue = 200;
+ break;
+ case 200:
+ gridValue = 500;
+ break;
+ case 500:
+ gridValue = 1000;
+ break;
+ default:
+ gridValue += 1000;
+ break;
+ }
+ n = (int) (this.maxValue / gridValue);
+ }
+ int gridWidth = (int) (this.graphWidth * gridValue / this.maxValue);
+ int x = MARGIN;
+ long value = 0; // TODO use minValue instead
+ while (x < this.graphWidth) {
+
+ // draw line
+ this.gc.setForeground(GRAY);
+ if (x > 0) {
+ this.gc.setLineStyle(SWT.LINE_DOT);
+ this.gc.drawLine(x, MARGIN, x, this.graphHeight + TGAP);
+ }
+
+ // draw value
+ this.gc.setForeground(BLACK);
+ String val= AbstractResults.timeString(value);
+ Point point= this.gc.stringExtent(val);
+ this.gc.drawString(val, x - point.x / 2, this.graphHeight + TGAP, true);
+
+ // compute next grid position
+ x += gridWidth;
+ value += gridValue; // value is expressed in seconds
+ }
+ this.gc.setLineStyle(SWT.LINE_SOLID);
+ this.gc.drawLine(0, this.graphHeight, this.graphWidth, this.graphHeight);
+}
+
+void drawLogarithmScale() {
+
+ // Draw scale background
+ drawScaleBackground();
+
+ // Draw scale grid lines
+ double max = Math.log(this.maxValue);
+ int gridValue = 100;
+ int x = MARGIN;
+ long value = 0; // TODO use minValue instead
+ while (x < this.graphWidth) {
+
+ // draw line
+ this.gc.setForeground(GRAY);
+ if (x > MARGIN) {
+ this.gc.setLineStyle(SWT.LINE_DOT);
+ this.gc.drawLine(x, MARGIN, x, this.graphHeight + TGAP);
+ }
+
+ // draw value
+ this.gc.setForeground(BLACK);
+ String str = AbstractResults.timeString(value);
+ Point point= this.gc.stringExtent(str);
+ this.gc.drawString(str, x - point.x / 2, this.graphHeight + TGAP, true);
+
+ // compute next grid position
+ value += gridValue;
+ int v = (int) (value / 100);
+ int c = 1;
+ while (v > 10) {
+ v = v / 10;
+ c *= 10;
+ }
+ switch (v) {
+ case 3:
+ gridValue = 200*c;
+ break;
+ case 5:
+ gridValue = 500*c;
+ break;
+ case 10:
+ gridValue = 1000*c;
+ break;
+ }
+ x = MARGIN + (int) (this.graphWidth * Math.log(value) / max);
+ }
+ this.gc.setLineStyle(SWT.LINE_SOLID);
+ this.gc.drawLine(0, this.graphHeight, this.graphWidth, this.graphHeight);
+}
+
+/**
+ * Draw the scale depending on the bar time graph kind.
+ */
+void drawScale(int kind) {
+ switch (kind) {
+ case TIME_LINEAR:
+ drawLinearScale();
+ break;
+ case TIME_LOG:
+ drawLogarithmScale();
+ break;
+ }
+}
+
+private void drawScaleBackground() {
+
+ // Draw striped background
+ Color lightblue = (Color) this.resources.get("lightblue");
+ if (lightblue == null) {
+ lightblue = new Color(DEFAULT_DISPLAY, 237, 243, 254);
+ this.resources.put("lightblue", lightblue);
+ }
+ this.gc.setBackground(lightblue);
+ for (int i= 0; i<this.count; i++) {
+ if (i % 2 == 0) {
+ this.gc.fillRectangle(0, MARGIN + i * LINE_HEIGHT, this.imageWidth, LINE_HEIGHT);
+ }
+ }
+
+ // Draw bottom vertical line
+ int yy= MARGIN + this.count * LINE_HEIGHT;
+ this.gc.drawLine(MARGIN, MARGIN, MARGIN, yy + TGAP);
+}
+
+String getImageName(int kind) {
+ switch (kind) {
+ case TIME_LINEAR:
+ return this.imageName+"_linear";
+ case TIME_LOG:
+ return this.imageName+"_log";
+ }
+ return this.imageName;
+}
+
+void paint(int kind) {
+
+ // Set image
+ this.graphHeight = MARGIN + this.count * LINE_HEIGHT;
+ this.imageHeight = this.graphHeight + GAP + 16 + MARGIN;
+ this.image = new Image(DEFAULT_DISPLAY, this.imageWidth, this.imageHeight);
+ this.gc = new GC(this.image);
+
+ // draw white background
+ this.gc.setBackground(WHITE);
+ this.gc.fillRectangle(0, 0, this.imageWidth, this.imageHeight);
+
+ // Set widths and heights
+ int width= (int) (RATIO * this.imageWidth); // width for results bar
+ this.graphWidth= width - this.gc.stringExtent("-999.9%").x - TGAP - MARGIN; // reserve space //$NON-NLS-1$
+
+ // Get warning image width
+ Image warning = (Image) this.resources.get("warning");
+ if (warning == null) {
+ warning = new Image(this.gc.getDevice(), new File(this.outputDir, Utils.WARNING_OBJ).toString());
+ this.resources.put("warning", warning);
+ }
+ this.graphWidth -= warning.getImageData().width;
+
+ // Set maximum of values
+ for (int i= 0; i<this.count; i++) {
+ BuildResults baselineBuildResults = this.results[i].getBaselineBuildResults();
+ double value = baselineBuildResults.getValue();
+// double error = baselineBuildResults.getError();
+// value += error;
+ if (value > this.maxValue) {
+ this.maxValue = value;
+ }
+ if (value < this.minValue) {
+ this.minValue = value;
+ }
+ BuildResults currentBuildResults = this.results[i].getCurrentBuildResults();
+ value = currentBuildResults.getValue();
+// error = currentBuildResults.getError();
+// value += error;
+ if (value > this.maxValue) {
+ this.maxValue = value;
+ }
+ if (value < this.minValue) {
+ this.minValue = value;
+ }
+ }
+ this.minValue = 0; // do not use minValue for now...
+
+ // Draw the scale
+ drawScale(kind);
+
+ // Draw the bars
+ drawBars(kind);
+
+ // Dispose
+ this.gc.dispose();
+}
+
+/**
+ * Create, paint and save all supported bar graphs and add the corresponding
+ * image and map references in the given stream.
+ *
+ * @param stream
+ */
+final public void paint(PrintStream stream) {
+
+ // Paint supported graphs
+ int length = SUPPORTED_GRAPHS.length;
+ for (int i=0; i<length; i++) {
+ int kind = SUPPORTED_GRAPHS[i];
+ paint(kind);
+ save(kind, stream);
+ }
+
+ // Dispose created graphic resources
+ Iterator iterator = this.resources.values().iterator();
+ while (iterator.hasNext()) {
+ Resource resource = (Resource) iterator.next();
+ resource.dispose();
+ }
+ this.resources.clear();
+}
+
+void print(int kind, PrintStream stream) {
+ String imgName = getImageName(kind);
+ stream.print(" if ($type==\"fp_type="+kind+"\") {\n");
+ stream.print(" echo '<img src=\"");
+ stream.print(imgName);
+ stream.print(".gif\" usemap=\"#");
+ stream.print(imgName);
+ stream.print("\" name=\"");
+ stream.print(imgName.substring(imgName.lastIndexOf('.')));
+ stream.print("\">';\n");
+ stream.print(" echo '<map name=\"");
+ stream.print(imgName);
+ stream.print("\">';\n");
+ if (this.areas != null) {
+ for (int i=0; i<this.count; i++) {
+ this.areas[i].print(stream);
+ }
+ }
+ stream.print(" echo '</map>';\n");
+ stream.print(" }\n");
+}
+
+void save(int kind, PrintStream stream) {
+ File file = new File(this.outputDir, getImageName(kind)+".gif");
+ Utils.saveImage(file, this.image);
+ if (file.exists()) {
+ print(kind, stream);
+ } else {
+ stream.print("<br><br>There is no fingerprint for ");
+ stream.print(imageName);
+ stream.print(" (kind=");
+ stream.print(kind);
+ stream.print(")<br><br>\n");
+ }
+}
+}
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/Main.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/Main.java
index c57b2db..88410b3 100644
--- a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/Main.java
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/Main.java
@@ -165,14 +165,6 @@
private boolean print = false;
/**
- * Tells whether the generation is done for a PHP server or not.
- * This field is set to <code>false</code> if <b>-nophp</b> argument is specified.
- * <p>
- * Default is <code>true</code> which means that the generation is done for the build server.
- */
-private boolean use_php = true; // PerformanceTestPlugin.getDBLocation().startsWith("net://");
-
-/**
* Tells what should be the failure percentage threshold.
* <p>
* Default is 10%.
@@ -418,12 +410,6 @@
i++;
continue;
}
- if (arg.equals("-nophp")) {
- this.use_php = false;
- buffer.append(" ").append(arg).append('\n');
- i++;
- continue;
- }
if (arg.equals("-failure.threshold")) {
String value = args[i + 1];
try {
@@ -476,28 +462,49 @@
if (this.print) System.out.print(".");
File outputFile = new File(this.outputDir, component + ".php");
PrintStream stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
- stream.println(Utils.HTML_OPEN);
- stream.println("<link href=\"ToolTip.css\" rel=\"stylesheet\" type=\"text/css\"><script src=\"ToolTip.js\"></script>");
- stream.println(Utils.HTML_DEFAULT_CSS);
- stream.println("<body>");
-
- String baselineName = performanceResults.getBaselineName();
- String currentName = performanceResults.getName();
- boolean isGlobal = component.equals("global");
- StringBuffer title = new StringBuffer("<h3>Performance of ");
- if (!isGlobal) {
- title.append(component);
- title.append(": ");
+
+ // Print header
+ boolean isGlobal = component.startsWith("global");
+ if (isGlobal) {
+ File globalFile = new File(this.outputDir, "global.php");
+ PrintStream gStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(globalFile)));
+ gStream.print(Utils.HTML_OPEN);
+ gStream.print("</head>\n");
+ gStream.print("<body>\n");
+ gStream.print("<?php\n");
+ gStream.print(" include(\"global_fp.php\");\n");
+ gStream.print("?>\n");
+ gStream.print("<table border=0 cellpadding=2 cellspacing=5 width=\"100%\">\n");
+ gStream.print("<tbody><tr> <td colspan=3 align=\"left\" bgcolor=\"#0080c0\" valign=\"top\"><b><font color=\"#ffffff\" face=\"Arial,Helvetica\">\n");
+ gStream.print("Detailed performance data grouped by scenario prefix</font></b></td></tr></tbody></table>\n");
+ gStream.print("<a href=\"org.eclipse.ant.php?\">org.eclipse.ant*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.compare.php?\">org.eclipse.compare*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.core.php?\">org.eclipse.core*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.jdt.core.php?\">org.eclipse.jdt.core*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.jdt.debug.php?\">org.eclipse.jdt.debug*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.jdt.text.php?\">org.eclipse.jdt.text*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.jdt.ui.php?\">org.eclipse.jdt.ui*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.jface.php?\">org.eclipse.jface*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.osgi.php?\">org.eclipse.osgi*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.pde.ui.php?\">org.eclipse.pde.ui*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.swt.php?\">org.eclipse.swt*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.team.php?\">org.eclipse.team*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.ua.php?\">org.eclipse.ua*</a><br>\n");
+ gStream.print("<a href=\"org.eclipse.ui.php?\">org.eclipse.ui*</a><br><p><br><br>\n");
+ gStream.print("</body>\n");
+ gStream.print(Utils.HTML_CLOSE);
+ gStream.close();
+ } else {
+ stream.print(Utils.HTML_OPEN);
}
- title.append(currentName);
- title.append(" relative to ");
- int index = baselineName.indexOf('_');
- title.append(baselineName.substring(0, index));
- title.append(" (");
- index = baselineName.lastIndexOf('_');
- title.append(baselineName.substring(index+1, baselineName.length()));
- title.append(")</h3>");
- stream.println(title.toString());
+ stream.print("<link href=\"ToolTip.css\" rel=\"stylesheet\" type=\"text/css\">\n");
+ stream.print("<script src=\"ToolTip.js\"></script>\n");
+ stream.print("<script src=\"Fingerprints.js\"></script>\n");
+ stream.print(Utils.HTML_DEFAULT_CSS);
+
+ // Print title
+ stream.print("<body>");
+ printComponentTitle(performanceResults, component, isGlobal, stream);
// print the html representation of fingerprint for each config
if (genFingerPrints || genAll) {
@@ -510,27 +517,7 @@
}
// print scenario status table
- if (isGlobal) {
- if (!this.use_php) {
- stream.println("<table border=0 cellpadding=2 cellspacing=5 width=\"100%\">");
- stream.println("<tbody><tr> <td colspan=3 align=\"left\" bgcolor=\"#0080c0\" valign=\"top\"><b><font color=\"#ffffff\" face=\"Arial,Helvetica\">");
- stream.println("Detailed performance data grouped by scenario prefix</font></b></td></tr></tbody></table>");
- stream.println("<a href=\"org.eclipse.ant.php?\">org.eclipse.ant*</a><br>");
- stream.println("<a href=\"org.eclipse.compare.php?\">org.eclipse.compare*</a><br>");
- stream.println("<a href=\"org.eclipse.core.php?\">org.eclipse.core*</a><br>");
- stream.println("<a href=\"org.eclipse.jdt.core.php?\">org.eclipse.jdt.core*</a><br>");
- stream.println("<a href=\"org.eclipse.jdt.debug.php?\">org.eclipse.jdt.debug*</a><br>");
- stream.println("<a href=\"org.eclipse.jdt.text.php?\">org.eclipse.jdt.text*</a><br>");
- stream.println("<a href=\"org.eclipse.jdt.ui.php?\">org.eclipse.jdt.ui*</a><br>");
- stream.println("<a href=\"org.eclipse.jface.php?\">org.eclipse.jface*</a><br>");
- stream.println("<a href=\"org.eclipse.osgi.php?\">org.eclipse.osgi*</a><br>");
- stream.println("<a href=\"org.eclipse.pde.ui.php?\">org.eclipse.pde.ui*</a><br>");
- stream.println("<a href=\"org.eclipse.swt.php?\">org.eclipse.swt*</a><br>");
- stream.println("<a href=\"org.eclipse.team.php?\">org.eclipse.team*</a><br>");
- stream.println("<a href=\"org.eclipse.ua.php?\">org.eclipse.ua*</a><br>");
- stream.println("<a href=\"org.eclipse.ui.php?\">org.eclipse.ui*</a><br><p><br><br>");
- }
- } else if (component.length() > 0) {
+ if (!isGlobal) {
// print the component scenario status table beneath the fingerprint
ScenarioStatusTable sst = new ScenarioStatusTable(component, stream);
try {
@@ -540,10 +527,43 @@
}
}
- stream.println(Utils.HTML_CLOSE);
+ stream.print(Utils.HTML_CLOSE);
stream.close();
}
+private void printComponentTitle(PerformanceResults performanceResults, String component, boolean isGlobal, PrintStream stream) {
+ String baselineName = performanceResults.getBaselineName();
+ String currentName = performanceResults.getName();
+
+ // Print title line
+ stream.print("<h3>Performance of ");
+ if (!isGlobal) {
+ stream.print(component);
+ stream.print(": ");
+ }
+ stream.print(currentName);
+ stream.print(" relative to ");
+ int index = baselineName.indexOf('_');
+ stream.print(baselineName.substring(0, index));
+ stream.print(" (");
+ index = baselineName.lastIndexOf('_');
+ stream.print(baselineName.substring(index+1, baselineName.length()));
+ stream.print(")</h3>\n");
+
+ // Print reference to global results
+ if (!isGlobal) {
+ stream.print("<?php\n");
+ stream.print(" $type=$_SERVER['QUERY_STRING'];\n");
+ stream.print(" if ($type==\"\") {\n");
+ stream.print(" $type=\"fp_type=0\";\n");
+ stream.print(" }\n");
+ stream.print(" $href=\"<a href=\\\"performance.php?\";\n");
+ stream.print(" $href=$href . $type . \"\\\">Back to global results</a><br><br>\";\n");
+ stream.print(" echo $href;\n");
+ stream.print("?>\n");
+ }
+}
+
/*
* Print summary of coefficient of variation for each scenario of the given pattern
* both for baseline and current builds.
@@ -566,7 +586,7 @@
if (scenarioName == null) continue;
ScenarioResults scenarioResults = performanceResults.getScenarioResults(scenarioName);
if (scenarioResults != null) {
- stream.println("<tr>");
+ stream.print("<tr>\n");
for (int j=0; j<2; j++) {
for (int c=0; c<configsLength; c++) {
printSummaryScenarioLine(j, configs[c], scenarioResults, stream);
@@ -574,13 +594,13 @@
}
stream.print("<td>");
stream.print(scenarioName);
- stream.println("</td></tr>");
+ stream.print("</td></tr>\n");
}
}
} catch (Exception e) {
e.printStackTrace();
} finally {
- stream.println("</table></body></html>");
+ stream.print("</table></body></html>\n");
stream.flush();
stream.close();
}
@@ -591,31 +611,31 @@
* Print summary presentation (eg. file start and text presenting the purpose of this file contents)..
*/
private void printSummaryPresentation(PrintStream stream) {
- stream.println(Utils.HTML_OPEN);
+ stream.print(Utils.HTML_OPEN);
stream.print(Utils.HTML_DEFAULT_CSS);
- stream.println("<title>Summary of Elapsed Process Variation Coefficients</title></head>");
- stream.println("<body><h3>Summary of Elapsed Process Variation Coefficients</h3>\n");
- stream.println("<p> This table provides a bird's eye view of variability in elapsed process times\n");
+ stream.print("<title>Summary of Elapsed Process Variation Coefficients</title></head>\n");
+ stream.print("<body><h3>Summary of Elapsed Process Variation Coefficients</h3>\n");
+ stream.print("<p> This table provides a bird's eye view of variability in elapsed process times\n");
stream.print("for baseline and current build stream performance scenarios.");
stream.print(" This summary is provided to facilitate the identification of scenarios that should be examined due to high variability.");
- stream.println("The variability for each scenario is expressed as a <a href=\"http://en.wikipedia.org/wiki/Coefficient_of_variation\">coefficient\n");
- stream.println("of variation</a> (CV). The CV is calculated by dividing the <b>standard deviation\n");
- stream.println("of the elapse process time over builds</b> by the <b>average elapsed process\n");
- stream.println("time over builds</b> and multiplying by 100.\n");
- stream.println("</p><p>High CV values may be indicative of any of the following:<br></p>\n");
- stream.println("<ol><li> an unstable performance test. </li>\n");
- stream.println("<ul><li>may be evidenced by an erratic elapsed process line graph.<br><br></li></ul>\n");
- stream.println("<li>performance regressions or improvements at some time in the course of builds.</li>\n");
- stream.println("<ul><li>may be evidenced by plateaus in elapsed process line graphs.<br><br></li></ul>\n");
- stream.println("<li>unstable testing hardware.\n");
+ stream.print("The variability for each scenario is expressed as a <a href=\"http://en.wikipedia.org/wiki/Coefficient_of_variation\">coefficient\n");
+ stream.print("of variation</a> (CV). The CV is calculated by dividing the <b>standard deviation\n");
+ stream.print("of the elapse process time over builds</b> by the <b>average elapsed process\n");
+ stream.print("time over builds</b> and multiplying by 100.\n");
+ stream.print("</p><p>High CV values may be indicative of any of the following:<br></p>\n");
+ stream.print("<ol><li> an unstable performance test. </li>\n");
+ stream.print("<ul><li>may be evidenced by an erratic elapsed process line graph.<br><br></li></ul>\n");
+ stream.print("<li>performance regressions or improvements at some time in the course of builds.</li>\n");
+ stream.print("<ul><li>may be evidenced by plateaus in elapsed process line graphs.<br><br></li></ul>\n");
+ stream.print("<li>unstable testing hardware.\n");
stream.print("<ul><li>consistent higher CV values for one test configuration as compared to others across");
- stream.println(" scenarios may be related to hardward problems.</li></ul></li></ol>\n");
- stream.println("<p> Scenarios are listed in alphabetical order in the far right column. A scenario's\n");
- stream.println("variation coefficients (CVs) are in columns to the left for baseline and current\n");
- stream.println("build streams for each test configuration. Scenarios with CVs > 10% are highlighted\n");
- stream.println("in yellow (10%<CV><CV<20%) and orange(CV>20%). </p>\n");
- stream.println("<p> Each CV value links to the scenario's detailed results to allow viewers to\n");
- stream.println("investigate the variability.</p>\n");
+ stream.print(" scenarios may be related to hardward problems.</li></ul></li></ol>\n");
+ stream.print("<p> Scenarios are listed in alphabetical order in the far right column. A scenario's\n");
+ stream.print("variation coefficients (CVs) are in columns to the left for baseline and current\n");
+ stream.print("build streams for each test configuration. Scenarios with CVs > 10% are highlighted\n");
+ stream.print("in yellow (10%<CV><CV<20%) and orange(CV>20%). </p>\n");
+ stream.print("<p> Each CV value links to the scenario's detailed results to allow viewers to\n");
+ stream.print("investigate the variability.</p>\n");
}
/*
@@ -628,7 +648,7 @@
stream.print(length);
stream.print("\"><b>Baseline CVs</b></td><td colspan=\"");
stream.print(length);
- stream.println("\"><b>Current Build Stream CVs</b></td><td rowspan=\"2\"><b>Scenario Name</b></td></tr>");
+ stream.print("\"><b>Current Build Stream CVs</b></td><td rowspan=\"2\"><b>Scenario Name</b></td></tr>\n");
stream.print("<tr>");
for (int n=0; n<2; n++) {
for (int c=0; c<length; c++) {
@@ -637,7 +657,7 @@
stream.print("</td>");
}
}
- stream.println("</tr>\n");
+ stream.print("</tr>\n");
}
/*
@@ -766,15 +786,43 @@
// Copy images and scripts to output dir
Bundle bundle = UiPlugin.getDefault().getBundle();
URL images = bundle.getEntry("images");
- URL scripts = bundle.getEntry("scripts");
if (images != null) {
images = FileLocator.resolve(images);
Utils.copyImages(new File(images.getPath()), this.outputDir);
}
+ URL scripts = bundle.getEntry("scripts");
if (scripts != null) {
scripts = FileLocator.resolve(scripts);
Utils.copyScripts(new File(scripts.getPath()), this.outputDir);
}
+ URL doc = bundle.getEntry("doc");
+ if (doc != null) {
+ doc = FileLocator.resolve(doc);
+ File docDir = new File(doc.getPath());
+ FileFilter filter = new FileFilter() {
+ public boolean accept(File pathname) {
+ return !pathname.getName().equals("CVS");
+ }
+ };
+ File[] docFiles = docDir.listFiles(filter);
+ for (int i=0; i<docFiles.length; i++) {
+ File file = docFiles[i];
+ if (file.isDirectory()) {
+ File subdir = new File(this.outputDir, file.getName());
+ subdir.mkdir();
+ File[] subdirFiles = file.listFiles(filter);
+ for (int j=0; j<subdirFiles.length; j++) {
+ if (subdirFiles[i].isDirectory()) {
+ // expect only one sub-directory
+ } else {
+ AbstractResults.copyFile(subdirFiles[j], new File(subdir, subdirFiles[j].getName()));
+ }
+ }
+ } else {
+ AbstractResults.copyFile(file, new File(this.outputDir, file.getName()));
+ }
+ }
+ }
// Print HTML pages and all linked files
if (this.print) {
@@ -782,7 +830,7 @@
System.out.print(" - components main page");
}
long start = System.currentTimeMillis();
- printComponent(performanceResults, "global");
+ printComponent(performanceResults, "global_fp");
Iterator components = performanceResults.getComponents().iterator();
while (components.hasNext()) {
printComponent(performanceResults, (String) components.next());
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/RawDataTable.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/RawDataTable.java
index c18861e..bac35c3 100644
--- a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/RawDataTable.java
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/RawDataTable.java
@@ -54,7 +54,7 @@
stream.print("<table border=\"1\">");
printSummary();
printDetails();
- stream.println("</table>");
+ stream.print("</table>\n");
}
/*
@@ -77,7 +77,7 @@
private void printDetails() {
stream.print("<tr><td><b>Build ID</b></td>");
printColumnHeaders();
- stream.println("</tr>");
+ stream.print("</tr>\n");
List builds = this.configResults.getBuildsMatchingPrefixes(this.buildPrefixes);
Collections.reverse(builds);
@@ -98,7 +98,7 @@
stream.print("</td>");
}
if (debug) System.out.println();
- stream.println("</tr>");
+ stream.print("</tr>\n");
}
if (debug) System.out.println("\n");
}
@@ -109,7 +109,7 @@
private void printSummary() {
stream.print("<tr><td><b>Stats</b></td>");
printColumnHeaders();
- stream.println("</tr>");
+ stream.print("</tr>\n");
int length = this.dimensions.length;
double[][] dimStats = new double[2][];
@@ -124,23 +124,23 @@
stream.print((int)dimStats[i][0]);
stream.print("</td>");
}
- stream.println("</tr>");
+ stream.print("</tr>\n");
stream.print("<tr><td>MEAN</td>");
printRowDoubles(dimStats, 1);
- stream.println("</tr>");
+ stream.print("</tr>\n");
stream.print("<tr><td>STD DEV</td>");
printRowDoubles(dimStats, 2);
- stream.println("</tr>");
+ stream.print("</tr>\n");
stream.print("<tr><td>COEF. VAR</td>");
printRowDoubles(dimStats, 3);
- stream.println("</tr>");
+ stream.print("</tr>\n");
// Blank line
stream.print("<tr>");
for (int i=0; i<length+1; i++){
stream.print("<td> </td>");
}
- stream.println("</tr>");
+ stream.print("</tr>\n");
}
/*
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ScenarioData.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ScenarioData.java
index 8ac9846..8ee20a4 100644
--- a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ScenarioData.java
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ScenarioData.java
@@ -211,39 +211,39 @@
if (stream == null) {
stream = System.out;
}
- stream.println(Utils.HTML_OPEN);
- stream.println(Utils.HTML_DEFAULT_CSS);
+ stream.print(Utils.HTML_OPEN);
+ stream.print(Utils.HTML_DEFAULT_CSS);
- stream.println("<title>" + scenarioResults.getName() + "(" + configBox + ")" + "</title></head>"); //$NON-NLS-1$
- stream.println("<h4>Scenario: " + scenarioResults.getName() + " (" + configBox + ")</h4><br>"); //$NON-NLS-1$ //$NON-NLS-2$
+ stream.print("<title>" + scenarioResults.getName() + "(" + configBox + ")" + "</title></head>\n"); //$NON-NLS-1$
+ stream.print("<h4>Scenario: " + scenarioResults.getName() + " (" + configBox + ")</h4><br>\n"); //$NON-NLS-1$ //$NON-NLS-2$
String failureMessage = Utils.failureMessage(configResults.getCurrentBuildDeltaInfo(), true);
if (failureMessage != null){
- stream.println("<table><tr><td><b>"+failureMessage+"</td></tr></table>\n");
+ stream.print("<table><tr><td><b>"+failureMessage+"</td></tr></table>\n");
}
BuildResults currentBuildResults = configResults.getCurrentBuildResults();
String comment = currentBuildResults.getComment();
if (comment != null) {
- stream.println("<p><b>Note:</b><br>\n");
- stream.println(comment + "</p>");
+ stream.print("<p><b>Note:</b><br>\n");
+ stream.print(comment + "</p>\n");
}
// Print link to raw data.
String rawDataFile = "raw/" + scenarioFileName+".html";
- stream.println("<br><br><b><a href=\""+rawDataFile+"\">Raw data and Stats</a></b><br><br>\n");
- stream.println("<b>Click measurement name to view line graph of measured values over builds.</b><br><br>\n");
+ stream.print("<br><br><b><a href=\""+rawDataFile+"\">Raw data and Stats</a></b><br><br>\n");
+ stream.print("<b>Click measurement name to view line graph of measured values over builds.</b><br><br>\n");
try {
// Print build result table
- stream.println("<table border=\"1\">"); //$NON-NLS-1$
+ stream.print("<table border=\"1\">\n"); //$NON-NLS-1$
stream.print("<tr><td><b>Build Id</b></td>"); //$NON-NLS-1$
Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
int dimLength = dimensions.length;
for (int d=0; d<dimLength; d++) {
stream.print("<td><a href=\"#" + dimensions[d].getShortName() + "\"><b>" + dimensions[d].getName() + "</b></a></td>");
}
- stream.println("</tr>\n");
+ stream.print("</tr>\n");
// Write build lines
printTableLine(stream, currentBuildResults);
@@ -253,12 +253,12 @@
printDifferenceLine(stream, configResults);
// End of table
- stream.println("</table>");
- stream.println("*Delta values in red and green indicate degradation > 10% and improvement > 10%,respectively.<br><br>");
- stream.println("<br><hr>\n\n");
+ stream.print("</table>\n");
+ stream.print("*Delta values in red and green indicate degradation > 10% and improvement > 10%,respectively.<br><br>\n");
+ stream.print("<br><hr>\n\n");
// print text legend.
- stream.println("Black and yellow points plot values measured in integration and last seven nightly builds.<br>\n" + "Magenta points plot the repeated baseline measurement over time.<br>\n"
+ stream.print("Black and yellow points plot values measured in integration and last seven nightly builds.<br>\n" + "Magenta points plot the repeated baseline measurement over time.<br>\n"
+ "Boxed points represent previous releases, milestone builds, current reference and current build.<br><br>\n"
+ "Hover over any point for build id and value.\n");
@@ -270,18 +270,18 @@
String imgFileName = scenarioFileName + "_" + dimShortName;
File imgFile = createFile(outputDir, "graphs", imgFileName, "gif");
saveGraph(lineGraph, imgFile);
- stream.println("<br><a name=\"" + dimShortName + "\"></a>");
- stream.println("<br><b>" + dimensions[d].getName() + "</b><br>");
- stream.println(dimensions[d].getDescription() + "<br><br>\n");
+ stream.print("<br><a name=\"" + dimShortName + "\"></a>\n");
+ stream.print("<br><b>" + dimensions[d].getName() + "</b><br>\n");
+ stream.print(dimensions[d].getDescription() + "<br><br>\n");
stream.print("<img src=\"graphs/");
stream.print(imgFile.getName());
stream.print("\" usemap=\"#" + lineGraph.fTitle + "\">");
stream.print("<map name=\"" + lineGraph.fTitle + "\">");
stream.print(lineGraph.getAreas());
- stream.println("</map>");
+ stream.print("</map>\n");
}
- stream.println("<br><br></body>");
- stream.println(Utils.HTML_CLOSE);
+ stream.print("<br><br></body>\n");
+ stream.print(Utils.HTML_CLOSE);
if (stream != System.out)
stream.close();
@@ -309,7 +309,7 @@
stream.print("<td>");
stream.print(displayValue);
if (stddev < 0) {
- stream.println(" [n/a]");
+ stream.print(" [n/a]\n");
} else if (stddev > 0) {
stream.print(" [");
stream.print(dimensions[d].getDisplayValue(stddev));
@@ -317,7 +317,7 @@
}
stream.print( "</td>");
}
- stream.println("</tr>");
+ stream.print("</tr>\n");
}
/*
@@ -380,21 +380,21 @@
if (stream == null) stream = System.out;
RawDataTable currentResultsTable = new RawDataTable(configResults, this.buildIDStreamPatterns, stream);
RawDataTable baselineResultsTable = new RawDataTable(configResults, this.baselinePrefix, stream);
- stream.println(Utils.HTML_OPEN);
- stream.println(Utils.HTML_DEFAULT_CSS);
- stream.println("<title>" + scenarioName + "(" + configBox + ")" + " - Details</title></head>"); //$NON-NLS-1$
- stream.println("<h4>Scenario: " + scenarioName + " (" + configBox + ")</h4>"); //$NON-NLS-1$
- stream.println("<a href=\"../"+scenarioFileName+".html\">VIEW GRAPH</a><br><br>"); //$NON-NLS-1$
- stream.println("<table><td><b>Current Stream Test Runs</b></td><td><b>Baseline Test Runs</b></td></tr>\n");
- stream.println("<tr valign=\"top\">");
+ stream.print(Utils.HTML_OPEN);
+ stream.print(Utils.HTML_DEFAULT_CSS);
+ stream.print("<title>" + scenarioName + "(" + configBox + ")" + " - Details</title></head>\n"); //$NON-NLS-1$
+ stream.print("<h4>Scenario: " + scenarioName + " (" + configBox + ")</h4>\n"); //$NON-NLS-1$
+ stream.print("<a href=\"../"+scenarioFileName+".html\">VIEW GRAPH</a><br><br>\n"); //$NON-NLS-1$
+ stream.print("<table><td><b>Current Stream Test Runs</b></td><td><b>Baseline Test Runs</b></td></tr>\n");
+ stream.print("<tr valign=\"top\">\n");
stream.print("<td>");
currentResultsTable.print();
- stream.println("</td>");
+ stream.print("</td>\n");
stream.print("<td>");
baselineResultsTable.print();
- stream.println("</td>");
- stream.println("</tr>");
- stream.println("</table>");
+ stream.print("</td>\n");
+ stream.print("</tr>\n");
+ stream.print("</table>\n");
stream.close();
}
}
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ScenarioStatusTable.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ScenarioStatusTable.java
index 45494d2..ec257e2 100644
--- a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ScenarioStatusTable.java
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/ScenarioStatusTable.java
@@ -49,7 +49,7 @@
this.jsIdCount = 0;
for (int i=0; i<size; i++) {
ScenarioResults scenarioResults = (ScenarioResults) scenarios.get(i);
- this.stream.println("<tr>");
+ this.stream.print("<tr>\n");
this.stream.print("<td>");
boolean hasSummary = scenarioResults.hasSummary();
if (hasSummary) this.stream.print("<b>");
@@ -65,25 +65,25 @@
this.stream.print(scenarioResults.getShortName());
}
if (hasSummary) this.stream.print("</b>");
- this.stream.println();
+ this.stream.print("\n");
String[] configs = performanceResults.getConfigNames(true/*sort*/);
int length = configs.length;
for (int j=0; j<length; j++) {
printConfigStats(scenarioResults, configs[j]);
}
}
- this.stream.println("</table>");
+ this.stream.print("</table>\n");
}
/*
* Print the table columns title.
*/
private void printColumnsTitle(int size, PerformanceResults performanceResults) {
- this.stream.println("<table border=\"1\">");
- this.stream.println("<tr>");
+ this.stream.print("<table border=\"1\">\n");
+ this.stream.print("<tr>\n");
this.stream.print("<td><h4>All ");
this.stream.print(size);
- this.stream.println(" scenarios</h4></td>");
+ this.stream.print(" scenarios</h4></td>\n");
String[] configNames = performanceResults.getConfigNames(true/*sort*/);
String[] configBoxes = performanceResults.getConfigBoxes(true/*sort*/);
int length = configNames.length;
@@ -113,7 +113,7 @@
}
this.stream.print("<td><h5>");
this.stream.print(columnTitle);
- this.stream.println("</h5>");
+ this.stream.print("</h5>\n");
}
}
@@ -140,10 +140,10 @@
this.stream.print(configResults.getName());
this.stream.print('/');
this.stream.print(scenarioResults.getFileName());
- this.stream.println(".html\">");
+ this.stream.print(".html\">\n");
this.stream.print("<img hspace=\"10\" border=\"0\" src=\"");
this.stream.print(image);
- this.stream.println("\"/></a>");
+ this.stream.print("\"/></a>\n");
} else {
// create message with tooltip text including deviation with error plus failure message
this.jsIdCount+=1;
@@ -155,62 +155,63 @@
this.stream.print(configResults.getName());
this.stream.print('/');
this.stream.print(scenarioResults.getFileName());
- this.stream.println(".html\">");
+ this.stream.print(".html\">\n");
this.stream.print("<img hspace=\"10\" border=\"0\" src=\"");
this.stream.print(image);
- this.stream.println("\"/>");
+ this.stream.print("\"/>\n");
this.stream.print("<span class=\"hidden_tooltip\" id=\"toolTip");
this.stream.print(jsIdCount);
this.stream.print("\">");
this.stream.print(failure);
- this.stream.println("</span></a>");
+ this.stream.print("</span></a>\n");
}
String result = Utils.failureMessage(deviation, false);
- this.stream.println(result);
+ this.stream.print(result);
+ this.stream.print("\n");
}
/*
* Print the status table explanationtitle.
*/
private void printTitle() {
- this.stream.println("<br><h4>Scenario Status</h4>");
- this.stream.println("The following table gives a complete but compact view of performance results for the component.<br>");
- this.stream.println("Each line of the table shows the results for one scenario on all machines.<br><br>");
- this.stream.println("The name of the scenario is in <b>bold</b> when its results are also displayed in the fingerprints<br>");
- this.stream.println("and starts with an '*' when the scenario has no results in the last baseline run.<br><br>");
- this.stream.println("Here are information displayed for each test (ie. in each cell):");
- this.stream.println("<ul>");
- this.stream.println("<li>an icon showing whether the test fails or passes and whether it's reliable or not.<br>");
- this.stream.println("The legend for this icon is:");
- this.stream.println("<ul>");
+ this.stream.print("<br><h4>Scenario Status</h4>\n");
+ this.stream.print("The following table gives a complete but compact view of performance results for the component.<br>\n");
+ this.stream.print("Each line of the table shows the results for one scenario on all machines.<br><br>\n");
+ this.stream.print("The name of the scenario is in <b>bold</b> when its results are also displayed in the fingerprints<br>\n");
+ this.stream.print("and starts with an '*' when the scenario has no results in the last baseline run.<br><br>\n");
+ this.stream.print("Here are information displayed for each test (ie. in each cell):\n");
+ this.stream.print("<ul>\n");
+ this.stream.print("<li>an icon showing whether the test fails or passes and whether it's reliable or not.<br>\n");
+ this.stream.print("The legend for this icon is:\n");
+ this.stream.print("<ul>\n");
this.stream.print("<li>Green (<img src=\"");
this.stream.print(Utils.OK_IMAGE);
this.stream.print("\">): mark a <b>successful result</b>, which means this test has neither significant performance regression nor significant standard error</li>");
this.stream.print("<li>Red (<img src=\"");
this.stream.print(Utils.FAIL_IMAGE);
- this.stream.println("\">): mark a <b>failing result</b>, which means this test shows a significant performance regression (more than 10%)</li>");
+ this.stream.print("\">): mark a <b>failing result</b>, which means this test shows a significant performance regression (more than 10%)</li>\n");
this.stream.print("<li>Gray (<img src=\"");
this.stream.print(Utils.FAIL_IMAGE_EXPLAINED);
- this.stream.println("\">): mark a <b>failing result</b> (see above) with a comment explaining this degradation.</li>");
+ this.stream.print("\">): mark a <b>failing result</b> (see above) with a comment explaining this degradation.</li>\n");
this.stream.print("<li>Yellow (<img src=\"");
this.stream.print(Utils.FAIL_IMAGE_WARN);
this.stream.print("\"> or <img src=\"");
this.stream.print(Utils.OK_IMAGE_WARN);
this.stream.print("\">): mark a <b>failing or successful result</b> with a significant standard error (more than ");
this.stream.print(Utils.STANDARD_ERROR_THRESHOLD_STRING);
- this.stream.println(")</li>");
+ this.stream.print(")</li>\n");
this.stream.print("<li>Black (<img src=\"");
this.stream.print(Utils.UNKNOWN_IMAGE);
this.stream.print("\">): mark an <b>undefined result</b>, which means that deviation on this test is not a number (<code>NaN</code>) or is infinite (happens when the reference value is equals to 0!)</li>");
- this.stream.println("<li>\"n/a\": mark a test for with <b>no</b> performance results</li>");
- this.stream.println("</ul></li>");
- this.stream.println("<li>the value of the deviation from the baseline as a percentage (ie. formula is: <code>(build_test_time - baseline_test_time) / baseline_test_time</code>)</li>");
- this.stream.println("<li>the value of the standard error of this deviation as a percentage (ie. formula is: <code>sqrt(build_test_stddev^2 / N + baseline_test_stddev^2 / N) / baseline_test_time</code>)<br>");
- this.stream.println("When test only has one measure, the standard error cannot be computed and is replaced with a '<font color=\"#CCCC00\">[n/a]</font>'.</li>");
- this.stream.println("</ul>");
- this.stream.println("<u>Hints</u>:<ul>");
- this.stream.println("<li>fly over image of failing tests to see the complete error message</li>");
- this.stream.println("<li>to look at the complete and detailed test results, click on its image</li>");
- this.stream.println("</ul>");
+ this.stream.print("<li>\"n/a\": mark a test for with <b>no</b> performance results</li>\n");
+ this.stream.print("</ul></li>\n");
+ this.stream.print("<li>the value of the deviation from the baseline as a percentage (ie. formula is: <code>(build_test_time - baseline_test_time) / baseline_test_time</code>)</li>\n");
+ this.stream.print("<li>the value of the standard error of this deviation as a percentage (ie. formula is: <code>sqrt(build_test_stddev^2 / N + baseline_test_stddev^2 / N) / baseline_test_time</code>)<br>\n");
+ this.stream.print("When test only has one measure, the standard error cannot be computed and is replaced with a '<font color=\"#CCCC00\">[n/a]</font>'.</li>\n");
+ this.stream.print("</ul>\n");
+ this.stream.print("<u>Hints</u>:<ul>\n");
+ this.stream.print("<li>fly over image of failing tests to see the complete error message</li>\n");
+ this.stream.print("<li>to look at the complete and detailed test results, click on its image</li>\n");
+ this.stream.print("</ul>\n");
}
}
diff --git a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/Utils.java b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/Utils.java
index 7055465..94fe523 100644
--- a/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/Utils.java
+++ b/bundles/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/Utils.java
@@ -10,15 +10,22 @@
*******************************************************************************/
package org.eclipse.test.performance.ui;
+import java.io.BufferedOutputStream;
import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
import java.util.Arrays;
import java.util.Calendar;
import java.util.HashMap;
+import org.eclipse.swt.SWT;
import org.eclipse.swt.graphics.Image;
import org.eclipse.swt.graphics.ImageData;
+import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.graphics.PaletteData;
import org.eclipse.swt.graphics.RGB;
import org.eclipse.test.internal.performance.PerformanceTestPlugin;
@@ -53,6 +60,8 @@
public final static String FAIL_IMAGE="FAIL.gif";
public final static String FAIL_IMAGE_WARN="FAIL_caution.gif";
public final static String FAIL_IMAGE_EXPLAINED="FAIL_greyed.gif";
+ public final static String LIGHT="light.gif";
+ public final static String WARNING_OBJ="warning_obj.gif";
public final static int OK = 0;
public final static int NAN = 0x1;
public final static int ERR = 0x2;
@@ -61,24 +70,24 @@
* Return <html><head><meta http-equiv="Content-Type"
* content="text/html; charset=iso-8859-1">
*/
- public static String HTML_OPEN = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">";
+ public final static String HTML_OPEN = "<html><head><meta http-equiv=\"Content-Type\" content=\"text/html; charset=iso-8859-1\">\n";
/**
* Return "</html>".
*/
- public static String HTML_CLOSE = "</html>";
+ public final static String HTML_CLOSE = "</html>\n";
/**
* Default style-sheet used on eclipse.org
*/
- public static String HTML_DEFAULT_CSS = "<style type=\"text/css\">" + "p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}\n"
+ public final static String HTML_DEFAULT_CSS = "<style type=\"text/css\">" + "p, table, td, th { font-family: arial, helvetica, geneva; font-size: 10pt}\n"
+ "pre { font-family: \"Courier New\", Courier, mono; font-size: 10pt}\n" + "h2 { font-family: arial, helvetica, geneva; font-size: 18pt; font-weight: bold ; line-height: 14px}\n"
+ "code { font-family: \"Courier New\", Courier, mono; font-size: 10pt}\n" + "sup { font-family: arial,helvetica,geneva; font-size: 10px}\n"
+ "h3 { font-family: arial, helvetica, geneva; font-size: 14pt; font-weight: bold}\n" + "li { font-family: arial, helvetica, geneva; font-size: 10pt}\n"
+ "h1 { font-family: arial, helvetica, geneva; font-size: 28px; font-weight: bold}\n"
+ "body { font-family: arial, helvetica, geneva; font-size: 10pt; clip: rect( ); margin-top: 5mm; margin-left: 3mm}\n"
+ ".indextop { font-size: x-large;; font-family: Verdana, Arial, Helvetica, sans-serif; font-weight: bold}\n"
- + ".indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}\n" + "</style>";
+ + ".indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}\n" + "</style>\n\n";
/**
* Creates a Variations object using build id pattern, config and jvm.
@@ -106,6 +115,8 @@
AbstractResults.copyFile(new File(images, OK_IMAGE), new File(output, OK_IMAGE));
AbstractResults.copyFile(new File(images, OK_IMAGE_WARN), new File(output, OK_IMAGE_WARN));
AbstractResults.copyFile(new File(images, UNKNOWN_IMAGE), new File(output, UNKNOWN_IMAGE));
+ AbstractResults.copyFile(new File(images, LIGHT), new File(output, LIGHT));
+ AbstractResults.copyFile(new File(images, WARNING_OBJ), new File(output, WARNING_OBJ));
}
/**
@@ -114,6 +125,24 @@
public static void copyScripts(File scripts, File output) {
AbstractResults.copyFile(new File(scripts, "ToolTip.css"), new File(output, "ToolTip.css"));
AbstractResults.copyFile(new File(scripts, "ToolTip.js"), new File(output, "ToolTip.js"));
+ AbstractResults.copyFile(new File(scripts, "Fingerprints.js"), new File(output, "Fingerprints.js"));
+ }
+
+ /**
+ * Copy all doc files.
+ */
+ public static void copyDoc(File docDir, File output) {
+ File[] docFiles = docDir.listFiles();
+ for (int i=0; i<docFiles.length; i++) {
+ File file = docFiles[i];
+ if (file.isDirectory()) {
+ File subdir = new File(output, file.getName());
+ subdir.mkdir();
+ copyDoc(file, subdir);
+ } else {
+ AbstractResults.copyFile(file, new File(output, file.getName()));
+ }
+ }
}
/**
@@ -361,4 +390,31 @@
return image;
}
+/**
+ * @param outputFile
+ * @param image
+ */
+public static void saveImage(File outputFile, Image image) {
+ // Save image
+ ImageData data = downSample(image);
+ ImageLoader imageLoader = new ImageLoader();
+ imageLoader.data = new ImageData[] { data };
+
+ OutputStream out = null;
+ try {
+ out = new BufferedOutputStream(new FileOutputStream(outputFile));
+ imageLoader.save(out, SWT.IMAGE_GIF);
+ } catch (FileNotFoundException e) {
+ e.printStackTrace();
+ } finally {
+ image.dispose();
+ if (out != null) {
+ try {
+ out.close();
+ } catch (IOException e1) {
+ // silently ignored
+ }
+ }
+ }
+}
}
\ No newline at end of file