perf_34x - 186549+201920
diff --git a/bundles/org.eclipse.test.performance.ui/META-INF/MANIFEST.MF b/bundles/org.eclipse.test.performance.ui/META-INF/MANIFEST.MF
index 1af5e3f..90da67c 100644
--- a/bundles/org.eclipse.test.performance.ui/META-INF/MANIFEST.MF
+++ b/bundles/org.eclipse.test.performance.ui/META-INF/MANIFEST.MF
@@ -12,6 +12,7 @@
org.eclipse.test.performance,
org.eclipse.swt,
org.apache.derby;resolution:=optional,
+ Cloudscape;resolution:=optional,
org.junit
Bundle-RequiredExecutionEnvironment: J2SE-1.4
Export-Package: org.eclipse.test.performance.ui
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 7760695..9e8eddc 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 054f65a..3ada494 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;
}
@@ -74,8 +75,35 @@
buffer.append(baselinePrefix);
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,17 +115,18 @@
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);
ConfigResults configResults = scenarioResults.getConfigResults(configName);
if (configResults == null || !configResults.isValid()) continue;
- double[] results = configResults.getCurrentBuildDeviation();
+ double[] results = configResults.getCurrentBuildDeltaInfo();
double percent = -results[0] * 100.0;
if (results != null && Math.abs(percent) < 200) {
- String defaultDimensionName = AbstractResults.SUPPORTED_DIMS[0].getName();
- String name = scenarioResults.getLabel() + " (" + defaultDimensionName + ")";
+ String name = scenarioResults.getLabel() + " (" + defaultDimName + ")";
if (!configResults.getCurrentBuildName().equals(buildName)) {
continue; // the test didn't run on last build, skip it
}
@@ -109,15 +138,18 @@
}
barGraph.addItem(name,
results,
- configName + "/" + scenarioResults.getFileName() + ".html#" + defaultDimensionName,
+ configName + "/" + scenarioResults.getFileName() + ".html",
configResults.getCurrentBuildResults().getComment(),
(Utils.confidenceLevel(results) & Utils.ERR) == 0);
+
+ // add results
+ allResults.add(configResults);
}
}
- if (barGraph == null) continue;
+ 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 +160,32 @@
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(" if ($QUERY_STRING==\"\" || $QUERY_STRING==\"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 +202,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..36d4d8c
--- /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 ($QUERY_STRING==\"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 c9992d8..90258e3 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
@@ -18,7 +18,6 @@
import org.eclipse.core.runtime.FileLocator;
import org.eclipse.equinox.app.IApplication;
import org.eclipse.equinox.app.IApplicationContext;
-import org.eclipse.test.internal.performance.PerformanceTestPlugin;
import org.eclipse.test.internal.performance.results.AbstractResults;
import org.eclipse.test.internal.performance.results.ConfigResults;
import org.eclipse.test.internal.performance.results.DB_Results;
@@ -36,7 +35,7 @@
/**
* Prefix of baseline builds displayed in data graphs.
- * This field is set using <b>-baselinePrefix</b> argument.
+ * This field is set using <b>-baseline.prefix</b> argument.
* <p>
* Example:
* <pre>-baseline.prefix 3.2_200606291905</pre>
@@ -165,6 +164,13 @@
*/
private boolean print = false;
+/**
+ * Tells what should be the failure percentage threshold.
+ * <p>
+ * Default is 10%.
+ */
+private int failure_threshold = 10; // PerformanceTestPlugin.getDBLocation().startsWith("net://");
+
/*
* Parse the command arguments and create corresponding performance
* results object.
@@ -197,7 +203,7 @@
if (arg.equals("-baseline")) {
baseline = args[i + 1];
if (baseline.startsWith("-")) {
- System.out.println("Missing value for -baseline parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
buffer.append(" -baseline = "+baseline+'\n');
@@ -207,20 +213,20 @@
if (arg.equals("-baseline.prefix")) {
this.baselinePrefix = args[i + 1];
if (this.baselinePrefix.startsWith("-")) {
- System.out.println("Missing value for -baseline.prefix parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
- buffer.append(" -baselinePrefix = "+this.baselinePrefix+'\n');
+ buffer.append(" ").append(arg).append(" = ").append(this.baselinePrefix).append('\n');
i++;
continue;
}
if (arg.equals("-current.prefix")) {
String idPrefixList = args[i + 1];
if (idPrefixList.startsWith("-")) {
- System.out.println("Missing value for -current.prefix parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
- buffer.append(" -current.prefix = ");
+ buffer.append(" ").append(arg).append(" = ");
String[] ids = idPrefixList.split(",");
this.currentBuildPrefixes = new ArrayList();
for (int j = 0; j < ids.length; j++) {
@@ -233,10 +239,10 @@
}
if (arg.equals("-highlight") || arg.equals("-highlight.latest")) {
if (args[i + 1].startsWith("-")) {
- System.out.println("Missing value for -highlight parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
- buffer.append(" "+arg+" = ");
+ buffer.append(" ").append(arg).append(" = ");
String[] ids = args[i + 1].split(",");
this.pointsOfInterest = new ArrayList();
for (int j = 0; j < ids.length; j++) {
@@ -250,27 +256,27 @@
if (arg.equals("-current")) {
currentBuildId = args[i + 1];
if (currentBuildId.startsWith("-")) {
- System.out.println("Missing value for -current parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
- buffer.append(" -current = "+currentBuildId+'\n');
+ buffer.append(" ").append(arg).append(" = ").append(currentBuildId).append('\n');
i++;
continue;
}
if (arg.equals("-jvm")) {
jvm = args[i + 1];
if (jvm.startsWith("-")) {
- System.out.println("Missing value for -jvm parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
- buffer.append(" -jvm = "+jvm+'\n');
+ buffer.append(" ").append(arg).append(" = ").append(jvm).append('\n');
i++;
continue;
}
if (arg.equals("-output")) {
String dir = args[++i];
if (dir.startsWith("-")) {
- System.out.println("Missing value for -output parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
this.outputDir = new File(dir);
@@ -278,13 +284,13 @@
System.err.println("Cannot create directory "+dir+" to write results in!");
System.exit(2);
}
- buffer.append(" -output = "+dir+'\n');
+ buffer.append(" ").append(arg).append(" = ").append(dir).append('\n');
continue;
}
if (arg.equals("-dataDir")) {
String dir = args[++i];
if (dir.startsWith("-")) {
- System.out.println("Missing value for -output parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
this.dataDir = new File(dir);
@@ -292,18 +298,18 @@
System.err.println("Cannot create directory "+dir+" to save data locally!");
System.exit(2);
}
- buffer.append(" -dataDir = "+dir+'\n');
+ buffer.append(" ").append(arg).append(" = ").append(dir).append('\n');
continue;
}
if (arg.equals("-config")) {
String configs = args[i + 1];
if (configs.startsWith("-")) {
- System.out.println("Missing value for -config parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
String[] names = configs.split(",");
int length = names.length;
- buffer.append(" -config = ");
+ buffer.append(" ").append(arg).append(" = ");
for (int j=0; j<length; j++) {
if (j>0) buffer.append(',');
buffer.append(names[j]);
@@ -347,7 +353,7 @@
if (arg.equals("-config.properties")) {
String configProperties = args[i + 1];
if (configProperties.startsWith("-")) {
- System.out.println("Missing value for -config.properties parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
if (this.configDescriptors == null) {
@@ -356,7 +362,7 @@
}
int length = this.configDescriptors.length;
StringTokenizer tokenizer = new StringTokenizer(configProperties, ";");
- buffer.append(" -config.properties = ");
+ buffer.append(" ").append(arg).append(" = ");
while (tokenizer.hasMoreTokens()) {
String labelDescriptor = tokenizer.nextToken();
String[] elements = labelDescriptor.trim().split(",");
@@ -377,47 +383,73 @@
if (arg.equals("-scenario.filter") || arg.equals("-scenario.pattern")) {
this.scenarioPattern= args[i + 1];
if (this.scenarioPattern.startsWith("-")) {
- System.out.println("Missing value for -baseline parameter");
+ System.out.println("Missing value for "+arg+" parameter");
printUsage();
}
- buffer.append(" "+arg+" = "+this.scenarioPattern+'\n');
+ buffer.append(" ").append(arg).append(" = ").append(this.scenarioPattern).append('\n');
i++;
continue;
}
if (arg.equals("-fingerprints")) {
this.genFingerPrints = true;
this.genAll = false;
- buffer.append(" -fingerprints\n");
+ buffer.append(" ").append(arg).append('\n');
i++;
continue;
}
if (arg.equals("-data")) {
this.genData = true;
this.genAll = false;
- buffer.append(" -data\n");
+ buffer.append(" ").append(arg).append('\n');
i++;
continue;
}
if (arg.equals("-print")) {
this.print = true;
- buffer.append(" -print\n");
+ buffer.append(" ").append(arg).append('\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-failure.threshold")) {
+ String value = args[i + 1];
+ try {
+ this.failure_threshold = Integer.parseInt(value);
+ if (this.failure_threshold < 0) {
+ System.out.println("Value for "+arg+" parameter must be positive.");
+ printUsage();
+ }
+ }
+ catch (NumberFormatException nfe) {
+ System.out.println("Invalid value for "+arg+" parameter");
+ printUsage();
+ }
+ buffer.append(" ").append(arg).append(" = ").append(value).append('\n');
i++;
continue;
}
i++;
}
if (this.print) System.out.println(buffer.toString());
+
+ // Stop if some mandatory parameters are missing
if (baseline == null || this.outputDir == null || this.configDescriptors == null || jvm == null || currentBuildId == null) {
printUsage();
}
+
+ // Init baseline prefix if not set
if (this.baselinePrefix == null) {
// Assume that baseline name format is *always* x.y_yyyyMMddhhmm_yyyyMMddhhmm
this.baselinePrefix = baseline.substring(0, baseline.lastIndexOf('_'));
}
+ // Init currnt build prefixes if not set
if (this.currentBuildPrefixes == null) {
this.currentBuildPrefixes = new ArrayList();
- this.currentBuildPrefixes.add("N");
+ if (currentBuildId.charAt(0) == 'M') {
+ this.currentBuildPrefixes.add("M");
+ } else {
+ this.currentBuildPrefixes.add("N");
+ }
this.currentBuildPrefixes.add("I");
}
return new PerformanceResults(currentBuildId, baseline, this.print);
@@ -430,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) {
@@ -464,27 +517,7 @@
}
// print scenario status table
- if (isGlobal) {
- if (!PerformanceTestPlugin.getDBLocation().startsWith("net://")) {
- 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 {
@@ -494,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=$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.
@@ -510,7 +576,7 @@
try {
stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
printSummaryPresentation(stream);
- List scenarioNames = DB_Results.getScenariosNames();
+ List scenarioNames = DB_Results.getScenarios();
int size = scenarioNames.size();
printSummaryColumnsTitle(stream, performanceResults);
String[] configs = performanceResults.getConfigNames(true/*sorted*/);
@@ -520,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);
@@ -528,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();
}
@@ -545,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");
}
/*
@@ -582,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++) {
@@ -591,7 +657,7 @@
stream.print("</td>");
}
}
- stream.println("</tr>\n");
+ stream.print("</tr>\n");
}
/*
@@ -605,13 +671,12 @@
}
String url = config + "/" + scenarioResults.getFileName()+".html";
double[] stats = null;
- int dim_id = AbstractResults.SUPPORTED_DIMS[0].getId();
if (i==0) { // baseline results
List baselinePrefixes = new ArrayList();
baselinePrefixes.add(this.baselinePrefix);
- stats = configResults.getStatistics(baselinePrefixes, dim_id);
+ stats = configResults.getStatistics(baselinePrefixes);
} else {
- stats = configResults.getStatistics(this.currentBuildPrefixes, dim_id);
+ stats = configResults.getStatistics(this.currentBuildPrefixes);
}
double variation = stats[3];
if (variation > 10 && variation < 20) {
@@ -683,7 +748,13 @@
" Optional. Generates table of scenario reference and current data with line graphs.\n\n" +
"[-print]\n" +
- " Optional. Display output in the console while generating.\n"
+ " Optional. Display output in the console while generating.\n" +
+
+ "[-nophp]\n" +
+ " Optional. Generate files for non-php server.\n" +
+
+ "[-failure.threshold]\n" +
+ " Optional. Set the failure percentage threshold (default is 10%).\n"
);
System.exit(1);
@@ -706,67 +777,89 @@
// Parse arguments and read DB info
PerformanceResults performanceResults = parse(context.getArguments().get("application.args"));
- performanceResults.read(this.configDescriptors, this.scenarioPattern, this.dataDir);
+ performanceResults.read(this.configDescriptors, this.scenarioPattern, this.dataDir, this.failure_threshold);
// Print whole scenarios summary
+ if (this.print) System.out.println();
printSummary(performanceResults);
// 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) {
System.out.println("Print performance results HTML pages:");
- System.out.print(" - all components");
+ 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());
}
- if (this.print) System.out.println("done in "+(System.currentTimeMillis()-start)+"ms");
+ if (this.print) {
+ String duration = AbstractResults.timeString(System.currentTimeMillis()-start);
+ System.out.println(" done in "+duration);
+ }
// Print the scenarios data
if (genData || genAll) {
start = System.currentTimeMillis();
- if (this.print) System.out.print(" - all scenarios data...");
+ if (this.print) System.out.println(" - all scenarios data:");
ScenarioData data = new ScenarioData(this.baselinePrefix, this.pointsOfInterest, this.currentBuildPrefixes, this.outputDir);
try {
- data.print(performanceResults);
+ data.print(performanceResults, this.print);
} catch (Exception ex) {
ex.printStackTrace();
}
- if (this.print) System.out.println("done in "+(System.currentTimeMillis()-start)+"ms");
+ if (this.print) {
+ String duration = AbstractResults.timeString(System.currentTimeMillis()-start);
+ System.out.println(" => done in "+duration);
+ }
}
if (this.print) {
long time = System.currentTimeMillis();
System.out.println("End of generation: "+new SimpleDateFormat("H:mm:ss").format(new Date(time)));
- long ms = System.currentTimeMillis() - begin;
- int sec = (int) (ms / 1000L);
- if ((ms - (sec*1000)) >= 500) sec++;
- if (sec < 60) {
- System.out.println("=> done in "+sec+" second"+(sec==1?"":"s"));
- } else if (sec < 3600) {
- int m = sec / 60;
- int s = sec % 60;
- System.out.println("=> done in "+m+" minute"+(m==1?"":"s")+" and "+s+" second"+(s==1?"":"s"));
- } else {
- int h = sec / 3600;
- int m = (sec-h*3600) / 60;
- int s = (sec-h*3600) % 60;
- System.out.println("=> done in "+h+" hour"+(h==1?"":"s")+", "+m+" minute"+(m==1?"":"s")+" and "+s+" second"+(s==1?"":"s"));
- }
+ String duration = AbstractResults.timeString(System.currentTimeMillis()-begin);
+ System.out.println("=> done in "+duration);
}
return null;
}
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 d41a12a..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
@@ -30,7 +30,6 @@
import org.eclipse.swt.graphics.ImageLoader;
import org.eclipse.swt.widgets.Display;
import org.eclipse.test.internal.performance.data.Dim;
-import org.eclipse.test.internal.performance.data.DimensionMessages;
import org.eclipse.test.internal.performance.results.AbstractResults;
import org.eclipse.test.internal.performance.results.BuildResults;
import org.eclipse.test.internal.performance.results.ComponentResults;
@@ -66,211 +65,19 @@
this.rootDir = outputDir;
}
-/**
- * Print the scenario all builds data from the given performance results.
- *
- * @param performanceResults The needed information to generate scenario data
- */
-public void print(PerformanceResults performanceResults) {
- String[] configNames = performanceResults.getConfigNames(false/*not sorted*/);
- String[] configBoxes = performanceResults.getConfigBoxes(false/*not sorted*/);
- int length = configNames.length;
- for (int i=0; i<length; i++) {
- File outputDir = new File(this.rootDir, configNames[i]);
- outputDir.mkdir();
- Iterator components = performanceResults.getResults();
- while (components.hasNext()) {
- ComponentResults componentResults = (ComponentResults) components.next();
- printSummary(configNames[i], configBoxes[i], componentResults, outputDir);
- printDetails(configNames[i], configBoxes[i], componentResults, outputDir);
- }
- }
-}
-
/*
- * Print the summary file of the builds data.
+ * Create a file handle verifying that its name does not go over
+ * the maximum authorized length.
*/
-private void printSummary(String configName, String configBox, ComponentResults componentResults, File outputDir) {
- Iterator scenarios = componentResults.getResults();
- while (scenarios.hasNext()) {
- List highlightedPoints = new ArrayList();
- ScenarioResults scenarioResults = (ScenarioResults) scenarios.next();
- ConfigResults configResults = scenarioResults.getConfigResults(configName);
- if (configResults == null || !configResults.isValid()) continue;
-
- // get latest points of interest matching
- if (this.pointsOfInterest != null) {
- Iterator buildPrefixes = this.pointsOfInterest.iterator();
- while (buildPrefixes.hasNext()) {
- String buildPrefix = (String) buildPrefixes.next();
- List builds = configResults.getBuilds(buildPrefix);
- if (buildPrefix.indexOf('*') <0 && buildPrefix.indexOf('?') < 0) {
- if (builds.size() > 0) {
- highlightedPoints.add(builds.get(builds.size()-1));
- }
- } else {
- highlightedPoints.addAll(builds);
- }
- }
- }
-
- String scenarioFileName = scenarioResults.getFileName();
- File outFile = new File(outputDir, scenarioFileName + ".html");
- PrintStream stream = null;
- try {
- stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outFile)));
- } catch (FileNotFoundException e) {
- System.err.println("can't create output file" + outFile); //$NON-NLS-1$
- }
- if (stream == null) {
- stream = System.out;
- }
- stream.println(Utils.HTML_OPEN);
- stream.println(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$
-
- String failureMessage = Utils.failureMessage(configResults.getCurrentBuildDeviation(), true);
- if (failureMessage != null){
- stream.println("<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>");
- }
-
- // Print link to raw data.
- String rawDataFile = scenarioFileName+"_raw.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");
-
- try {
- // Print build result table
- stream.println("<table border=\"1\">"); //$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++) {
- String dimName = dimensions[d].getName();
- stream.print("<td><a href=\"#" + configName + "_" + scenarioFileName + "_" + dimName + "\"><b>" + dimName + "</b></a></td>");
- }
- stream.println("</tr>\n");
-
- // Write build lines
- printTableLine(stream, currentBuildResults);
- printTableLine(stream, configResults.getBaselineBuildResults());
-
- // Write difference line
- 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");
-
- // 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"
- + "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");
-
- // print image maps of historical
- for (int d=0; d<dimLength; d++) {
- String dimName = dimensions[d].getName();
- int dim_id = dimensions[d].getId();
- TimeLineGraph lineGraph = getLineGraph(scenarioResults, configResults, dimensions[d], highlightedPoints, this.buildIDStreamPatterns);
-
- File graphsDir = new File(outputDir, "graphs");
- graphsDir.mkdir();
- File imgFile = new File(graphsDir, scenarioFileName + "_" + dimName + ".gif");
- saveGraph(lineGraph, imgFile);
- stream.println("<br><a name=\"" + configName + "_" + scenarioFileName + "_" + dimName + "\"></a>");
- stream.println("<br><b>" + dimName + "</b><br>");
- stream.println(DimensionMessages.getDescription(dim_id) + "<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.println("<br><br></body>");
- stream.println(Utils.HTML_CLOSE);
- if (stream != System.out)
- stream.close();
-
- } catch (AssertionFailedError e) {
- e.printStackTrace();
- continue;
+private File createFile(File outputDir, String subdir, String name, String extension) {
+ File dir = outputDir;
+ if (subdir != null) {
+ dir = new File(outputDir, subdir);
+ if (!dir.exists()) {
+ dir.mkdir();
}
}
-}
-
-/*
- * Print the data for a build results.
- */
-private void printTableLine(PrintStream stream, BuildResults buildResults) {
- stream.print("<tr><td>");
- stream.print(buildResults.getName());
- if (buildResults.isBaseline()) stream.print(" (reference)");
- stream.print("</td>");
- Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
- int dimLength = dimensions.length;
- for (int d=0; d<dimLength; d++) {
- int dim_id = dimensions[d].getId();
- double stddev = buildResults.getDeviation(dim_id);
- String displayValue = dimensions[d].getDisplayValue(buildResults.getValue(dim_id));
- stream.print("<td>");
- stream.print(displayValue);
- if (stddev < 0) {
- stream.println(" [n/a]");
- } else if (stddev > 0) {
- stream.print(" [");
- stream.print(dimensions[d].getDisplayValue(stddev));
- stream.print("]");
- }
- stream.print( "</td>");
- }
- stream.println("</tr>");
-}
-
-/*
- * Print the line showing the difference between current and baseline builds.
- */
-private void printDifferenceLine(PrintStream stream, ConfigResults configResults) {
- stream.print("<tr><td>*Delta</td>");
- Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
- int dimLength = dimensions.length;
- for (int d=0; d<dimLength; d++) {
- Dim currentDim = dimensions[d];
- int dim_id = currentDim.getId();
- BuildResults currentBuild = configResults.getCurrentBuildResults();
- BuildResults baselineBuild = configResults.getBaselineBuildResults();
-
- double baselineValue = baselineBuild.getValue(dim_id);
- double diffValue = currentBuild.getValue(dim_id) - baselineValue;
- double diffPercentage = baselineValue == 0 ? 0 : Math.round(diffValue / baselineValue * 1000) / 10.0;
- String diffDisplayValue = currentDim.getDisplayValue(diffValue);
- // green
- String fontColor = "";
- if ((diffPercentage < -10 && !currentDim.largerIsBetter()) || (diffPercentage > 10 && currentDim.largerIsBetter()))
- fontColor = "#006600";
- if ((diffPercentage < -10 && currentDim.largerIsBetter()) || (diffPercentage > 10 && !currentDim.largerIsBetter()))
- fontColor = "#FF0000";
-
- diffPercentage = Math.abs(diffPercentage);
- String percentage = (diffPercentage == 0) ? "" : "<br>" + diffPercentage + " %";
-
- if (diffPercentage > 10 || diffPercentage < -10) {
- stream.print("<td><FONT COLOR=\"" + fontColor + "\"><b>" + diffDisplayValue + percentage + "</b></FONT></td>");
- } else {
- stream.print("<td>" + diffDisplayValue + percentage + "</td>");
- }
- }
- stream.print("</tr></font>");
+ return new File(dir, name + '.' + extension);
}
/*
@@ -337,6 +144,221 @@
return graph;
}
+/**
+ * Print the scenario all builds data from the given performance results.
+ *
+ * @param performanceResults The needed information to generate scenario data
+ */
+public void print(PerformanceResults performanceResults, boolean print) {
+ String[] configNames = performanceResults.getConfigNames(false/*not sorted*/);
+ String[] configBoxes = performanceResults.getConfigBoxes(false/*not sorted*/);
+ int length = configNames.length;
+ for (int i=0; i<length; i++) {
+ String configName = configNames[i];
+ long start = System.currentTimeMillis();
+ if (print) System.out.print(" + "+configName);
+ File outputDir = new File(this.rootDir, configName);
+ outputDir.mkdir();
+ Iterator components = performanceResults.getResults();
+ while (components.hasNext()) {
+ if (print) System.out.print(".");
+ ComponentResults componentResults = (ComponentResults) components.next();
+ printSummary(configName, configBoxes[i], componentResults, outputDir);
+ printDetails(configName, configBoxes[i], componentResults, outputDir);
+ }
+ if (print) {
+ String duration = AbstractResults.timeString(System.currentTimeMillis()-start);
+ System.out.println(" done in "+duration);
+ }
+ }
+}
+
+/*
+ * Print the summary file of the builds data.
+ */
+private void printSummary(String configName, String configBox, ComponentResults componentResults, File outputDir) {
+ Iterator scenarios = componentResults.getResults();
+ while (scenarios.hasNext()) {
+ List highlightedPoints = new ArrayList();
+ ScenarioResults scenarioResults = (ScenarioResults) scenarios.next();
+ ConfigResults configResults = scenarioResults.getConfigResults(configName);
+ if (configResults == null || !configResults.isValid()) continue;
+
+ // get latest points of interest matching
+ if (this.pointsOfInterest != null) {
+ Iterator buildPrefixes = this.pointsOfInterest.iterator();
+ while (buildPrefixes.hasNext()) {
+ String buildPrefix = (String) buildPrefixes.next();
+ List builds = configResults.getBuilds(buildPrefix);
+ if (buildPrefix.indexOf('*') <0 && buildPrefix.indexOf('?') < 0) {
+ if (builds.size() > 0) {
+ highlightedPoints.add(builds.get(builds.size()-1));
+ }
+ } else {
+ highlightedPoints.addAll(builds);
+ }
+ }
+ }
+
+ String scenarioFileName = scenarioResults.getFileName();
+ File outputFile = new File(outputDir, scenarioFileName+".html");
+ PrintStream stream = null;
+ try {
+ stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
+ } catch (FileNotFoundException e) {
+ System.err.println("can't create output file" + outputFile); //$NON-NLS-1$
+ }
+ if (stream == null) {
+ stream = System.out;
+ }
+ stream.print(Utils.HTML_OPEN);
+ stream.print(Utils.HTML_DEFAULT_CSS);
+
+ 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.print("<table><tr><td><b>"+failureMessage+"</td></tr></table>\n");
+ }
+
+ BuildResults currentBuildResults = configResults.getCurrentBuildResults();
+ String comment = currentBuildResults.getComment();
+ if (comment != null) {
+ stream.print("<p><b>Note:</b><br>\n");
+ stream.print(comment + "</p>\n");
+ }
+
+ // Print link to raw data.
+ String rawDataFile = "raw/" + scenarioFileName+".html";
+ 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.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.print("</tr>\n");
+
+ // Write build lines
+ printTableLine(stream, currentBuildResults);
+ printTableLine(stream, configResults.getBaselineBuildResults());
+
+ // Write difference line
+ printDifferenceLine(stream, configResults);
+
+ // End of table
+ 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.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");
+
+ // print image maps of historical
+ for (int d=0; d<dimLength; d++) {
+ TimeLineGraph lineGraph = getLineGraph(scenarioResults, configResults, dimensions[d], highlightedPoints, this.buildIDStreamPatterns);
+
+ String dimShortName = dimensions[d].getShortName();
+ String imgFileName = scenarioFileName + "_" + dimShortName;
+ File imgFile = createFile(outputDir, "graphs", imgFileName, "gif");
+ saveGraph(lineGraph, imgFile);
+ 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.print("</map>\n");
+ }
+ stream.print("<br><br></body>\n");
+ stream.print(Utils.HTML_CLOSE);
+ if (stream != System.out)
+ stream.close();
+
+ } catch (AssertionFailedError e) {
+ e.printStackTrace();
+ continue;
+ }
+ }
+}
+
+/*
+ * Print the data for a build results.
+ */
+private void printTableLine(PrintStream stream, BuildResults buildResults) {
+ stream.print("<tr><td>");
+ stream.print(buildResults.getName());
+ if (buildResults.isBaseline()) stream.print(" (reference)");
+ stream.print("</td>");
+ Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
+ int dimLength = dimensions.length;
+ for (int d=0; d<dimLength; d++) {
+ int dim_id = dimensions[d].getId();
+ double stddev = buildResults.getDeviation(dim_id);
+ String displayValue = dimensions[d].getDisplayValue(buildResults.getValue(dim_id));
+ stream.print("<td>");
+ stream.print(displayValue);
+ if (stddev < 0) {
+ stream.print(" [n/a]\n");
+ } else if (stddev > 0) {
+ stream.print(" [");
+ stream.print(dimensions[d].getDisplayValue(stddev));
+ stream.print("]");
+ }
+ stream.print( "</td>");
+ }
+ stream.print("</tr>\n");
+}
+
+/*
+ * Print the line showing the difference between current and baseline builds.
+ */
+private void printDifferenceLine(PrintStream stream, ConfigResults configResults) {
+ stream.print("<tr><td>*Delta</td>");
+ Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
+ int dimLength = dimensions.length;
+ for (int d=0; d<dimLength; d++) {
+ Dim currentDim = dimensions[d];
+ int dim_id = currentDim.getId();
+ BuildResults currentBuild = configResults.getCurrentBuildResults();
+ BuildResults baselineBuild = configResults.getBaselineBuildResults();
+
+ // Compute difference values
+ double baselineValue = baselineBuild.getValue(dim_id);
+ double diffValue = baselineValue - currentBuild.getValue(dim_id);
+ double diffPercentage = baselineValue == 0 ? 0 : Math.round(diffValue / baselineValue * 1000) / 10.0;
+ String diffDisplayValue = currentDim.getDisplayValue(diffValue);
+
+ // Set colors
+ String fontColor = "";
+ if (diffPercentage > 10) {
+ fontColor = "#006600"; // green
+ }
+ if (diffPercentage < -10) {
+ fontColor = "#FF0000"; // red
+ }
+
+ // Print line
+ String percentage = (diffPercentage == 0) ? "" : "<br>" + diffPercentage + " %";
+ if (diffPercentage > 10 || diffPercentage < -10) {
+ stream.print("<td><FONT COLOR=\"" + fontColor + "\"><b>" + diffDisplayValue + percentage + "</b></FONT></td>");
+ } else {
+ stream.print("<td>" + diffDisplayValue + percentage + "</td>");
+ }
+ }
+ stream.print("</tr></font>");
+}
+
/*
* Print details file of the scenario builds data.
*/
@@ -348,31 +370,31 @@
if (configResults == null || !configResults.isValid()) continue;
String scenarioName= scenarioResults.getName();
String scenarioFileName = scenarioResults.getFileName();
- File outFile = new File(outputDir, scenarioFileName + "_raw.html");
+ File outputFile = createFile(outputDir, "raw", scenarioFileName, "html");
PrintStream stream = null;
try {
- stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outFile)));
+ stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
} catch (FileNotFoundException e) {
- System.err.println("can't create output file" + outFile); //$NON-NLS-1$
+ System.err.println("can't create output file" + outputFile); //$NON-NLS-1$
}
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 3ddf979..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");
}
}
@@ -128,7 +128,7 @@
}
BuildResults currentBuildResults = configResults.getCurrentBuildResults();
String failure = currentBuildResults.getFailure();
- double[] deviation = configResults.getCurrentBuildDeviation();
+ double[] deviation = configResults.getCurrentBuildDeltaInfo();
int confidence = Utils.confidenceLevel(deviation);
boolean hasFailure = failure != null;
String comment = currentBuildResults.getComment();
@@ -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 795b63e..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,12 +10,11 @@
*******************************************************************************/
package org.eclipse.test.performance.ui;
+import java.io.BufferedOutputStream;
import java.io.File;
-import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
-import java.io.InputStream;
import java.io.OutputStream;
import java.text.DecimalFormat;
import java.text.NumberFormat;
@@ -23,12 +22,15 @@
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;
import org.eclipse.test.internal.performance.db.Variations;
+import org.eclipse.test.internal.performance.results.AbstractResults;
public class Utils {
@@ -58,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;
@@ -66,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.
@@ -102,41 +106,43 @@
}
/**
- * Utility method to copy a file.
- *
- * @param src the source file.
- * @param dest the destination.
+ * Copy all image files.
*/
- private static void copyFile(File src, File dest) {
-
- try {
- InputStream in = new FileInputStream(src);
- OutputStream out = new FileOutputStream(dest);
- byte[] buf = new byte[1024];
- int len;
- while ((len = in.read(buf)) > 0) {
- out.write(buf, 0, len);
- }
- in.close();
- out.close();
-
- } catch (FileNotFoundException e) {
- e.printStackTrace();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
public static void copyImages(File images, File output) {
- copyFile(new File(images, FAIL_IMAGE), new File(output, FAIL_IMAGE));
- copyFile(new File(images, FAIL_IMAGE_EXPLAINED), new File(output, FAIL_IMAGE_EXPLAINED));
- copyFile(new File(images, FAIL_IMAGE_WARN), new File(output, FAIL_IMAGE_WARN));
- copyFile(new File(images, OK_IMAGE), new File(output, OK_IMAGE));
- copyFile(new File(images, OK_IMAGE_WARN), new File(output, OK_IMAGE_WARN));
- copyFile(new File(images, UNKNOWN_IMAGE), new File(output, UNKNOWN_IMAGE));
+ AbstractResults.copyFile(new File(images, FAIL_IMAGE), new File(output, FAIL_IMAGE));
+ AbstractResults.copyFile(new File(images, FAIL_IMAGE_EXPLAINED), new File(output, FAIL_IMAGE_EXPLAINED));
+ AbstractResults.copyFile(new File(images, FAIL_IMAGE_WARN), new File(output, FAIL_IMAGE_WARN));
+ 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));
}
+
+ /**
+ * Copy all scripts files.
+ */
public static void copyScripts(File scripts, File output) {
- copyFile(new File(scripts, "ToolTip.css"), new File(output, "ToolTip.css"));
- copyFile(new File(scripts, "ToolTip.js"), new File(output, "ToolTip.js"));
+ 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()));
+ }
+ }
}
/**
@@ -384,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