aboutsummaryrefslogtreecommitdiff
path: root/basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/GenerateResults.java
diff options
context:
space:
mode:
Diffstat (limited to 'basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/GenerateResults.java')
-rw-r--r--basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/GenerateResults.java1050
1 files changed, 1050 insertions, 0 deletions
diff --git a/basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/GenerateResults.java b/basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/GenerateResults.java
new file mode 100644
index 0000000..0a283c6
--- /dev/null
+++ b/basebuilder-3.6.2/org.eclipse.releng.basebuilder/plugins/org.eclipse.test.performance.ui/src/org/eclipse/test/performance/ui/GenerateResults.java
@@ -0,0 +1,1050 @@
+/*******************************************************************************
+ * Copyright (c) 2000, 2009 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.BufferedOutputStream;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileOutputStream;
+import java.io.PrintStream;
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Date;
+import java.util.List;
+import java.util.StringTokenizer;
+
+import org.eclipse.core.runtime.IProgressMonitor;
+import org.eclipse.core.runtime.IStatus;
+import org.eclipse.core.runtime.OperationCanceledException;
+import org.eclipse.core.runtime.Status;
+import org.eclipse.core.runtime.SubMonitor;
+import org.eclipse.swt.widgets.Display;
+import org.eclipse.test.internal.performance.results.db.ConfigResults;
+import org.eclipse.test.internal.performance.results.db.DB_Results;
+import org.eclipse.test.internal.performance.results.db.PerformanceResults;
+import org.eclipse.test.internal.performance.results.db.ScenarioResults;
+import org.eclipse.test.internal.performance.results.utils.Util;
+import org.osgi.framework.Bundle;
+
+/**
+ * Main class to generate performance results of all scenarios matching a given pattern
+ * in one HTML page per component.
+ *
+ * @see #printUsage() method to see a detailed parameters usage
+ */
+public class GenerateResults {
+
+/**
+ * Prefix of baseline builds displayed in data graphs.
+ * This field is set using <b>-baseline.prefix</b> argument.
+ * <p>
+ * Example:
+ * <pre>-baseline.prefix 3.2_200606291905</pre>
+ *
+ * @see #currentBuildPrefixes
+ */
+String baselinePrefix = null;
+
+/**
+ * Root directory where all files are generated.
+ * This field is set using <b>-output</b> argument.
+ * <p>
+ * Example:
+ * <pre>-output /releng/results/I20070615-1200/performance</pre>
+ */
+File outputDir;
+
+/**
+ * Root directory where all data are locally stored to speed-up generation.
+ * This field is set using <b>-dataDir</b> argument.
+ * <p>
+ * Example:
+ * <pre>-dataDir /tmp</pre>
+ */
+File dataDir;
+
+/**
+ * Arrays of 2 strings which contains config information: name and description.
+ * This field is set using <b>-config</b> and/or <b>-config.properties</b> arguments.
+ * <p>
+ * Example:
+ * <pre>
+ * -config eclipseperflnx3_R3.3,eclipseperfwin2_R3.3,eclipseperflnx2_R3.3,eclipseperfwin1_R3.3,eclipseperflnx1_R3.3
+ * -config.properties
+ * "eclipseperfwin1_R3.3,Win XP Sun 1.4.2_08 (2 GHz 512 MB);
+ * eclipseperflnx1_R3.3,RHEL 3.0 Sun 1.4.2_08 (2 GHz 512 MB);
+ * eclipseperfwin2_R3.3,Win XP Sun 1.4.2_08 (3 GHz 2 GB);
+ * eclipseperflnx2_R3.3,RHEL 3.0 Sun 1.4.2_08 (3 GHz 2 GB);
+ * eclipseperflnx3_R3.3,RHEL 4.0 Sun 1.4.2_08 (3 GHz 2.5 GB)"
+ * </pre>
+ * Note that:
+ * <ul>
+ * <li>if only <b>-config</b> is set, then configuration name is used for description </li>
+ * <li>if only <b>-config.properties</b> is set, then all configurations defined with this argument are generated
+ * <li>if both arguments are defined, then only configurations defined by <b>-config</b> argument are generated,
+ * <b>-config.properties</b> argument is only used to set the configuration description.</li>
+ * </ul>
+ */
+String[][] configDescriptors;
+
+/**
+ * Scenario pattern used to generate performance results.
+ * This field is set using <b>-scenarioPattern</b> argument.
+ * <p>
+ * Note that this pattern uses SQL conventions, not RegEx ones,
+ * which means that '%' is used to match several consecutive characters
+ * and '_' to match a single character.
+ * <p>
+ * Example:
+ * <pre>-scenario.pattern org.eclipse.%.test</pre>
+ */
+String scenarioPattern;
+
+/**
+ * A list of prefixes for builds displayed in data graphs.
+ * This field is set using <b>-currentPrefix</b> argument.
+ * <p>
+ * Example:
+ * <pre>-current.prefix N, I</pre>
+ *
+ * @see #baselinePrefix
+ */
+List currentBuildPrefixes;
+
+/**
+ * A list of prefixes of builds to highlight in displayed data graphs.
+ * This field is set using <b>-highlight</b> and/or <b>-highlight.latest</b> arguments.
+ * <p>
+ * Example:
+ * <pre>-higlight 3_2</pre>
+ */
+List pointsOfInterest;
+
+/**
+ * Tells whether only fingerprints has to be generated.
+ * This field is set to <code>true</code> if <b>-fingerprints</b> argument is specified.
+ * <p>
+ * Default is <code>false</code> which means that scenario data
+ * will also be generated.
+ *
+ * @see #genData
+ * @see #genAll
+ */
+boolean genFingerPrints = false;
+
+/**
+ * Tells whether only fingerprints has to be generated.
+ * This field is set to <code>true</code> if <b>-data</b> argument is specified.
+ * <p>
+ * Default is <code>false</code> which means that fingerprints
+ * will also be generated.
+ *
+ * @see #genFingerPrints
+ * @see #genAll
+ */
+boolean genData = false;
+
+/**
+ * Tells whether only fingerprints has to be generated.
+ * This field is set to <code>false</code>
+ * if <b>-fingerprints</b> or <b>-data</b> argument is specified.
+ * <p>
+ * Default is <code>true</code> which means that scenario data
+ * will also be generated.
+ *
+ * @see #genData
+ * @see #genFingerPrints
+ */
+boolean genAll = true;
+
+/**
+ * Tells whether information should be displayed in the console while generating.
+ * This field is set to <code>true</code> if <b>-print</b> argument is specified.
+ * <p>
+ * Default is <code>false</code> which means that nothing is print during the generation.
+ */
+PrintStream printStream = null;
+
+/**
+ * Tells what should be the failure percentage threshold.
+ * <p>
+ * Default is 10%.
+ */
+int failure_threshold = 10; // PerformanceTestPlugin.getDBLocation().startsWith("net://");
+
+PerformanceResults performanceResults;
+
+public GenerateResults() {
+}
+
+public GenerateResults(PerformanceResults results, String current, String baseline, boolean fingerprints, File data, File output) {
+ this.dataDir = data;
+ this.outputDir = output;
+ this.genFingerPrints = fingerprints;
+ this.genAll = !fingerprints;
+ this.performanceResults = results;
+ this.printStream = System.out;
+ setDefaults(current, baseline);
+}
+
+/*
+ * Parse the command arguments and create corresponding performance
+ * results object.
+ */
+private void parse(String[] args) {
+ StringBuffer buffer = new StringBuffer("Parameters used to generate performance results (");
+ buffer.append(new SimpleDateFormat().format(new Date(System.currentTimeMillis())));
+ buffer.append("):\n");
+ int i = 0;
+ int argsLength = args.length;
+ if (argsLength == 0) {
+ printUsage();
+ }
+
+ String currentBuildId = null;
+ String baseline = null;
+ String jvm = null;
+ this.configDescriptors = null;
+
+ while (i < argsLength) {
+ String arg = args[i];
+ if (!arg.startsWith("-")) {
+ i++;
+ continue;
+ }
+ if (argsLength == i + 1 && i != argsLength - 1) {
+ System.out.println("Missing value for last parameter");
+ printUsage();
+ }
+ if (arg.equals("-baseline")) {
+ baseline = args[i + 1];
+ if (baseline.startsWith("-")) {
+ System.out.println("Missing value for "+arg+" parameter");
+ printUsage();
+ }
+ buffer.append(" -baseline = "+baseline+'\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-baseline.prefix")) {
+ this.baselinePrefix = args[i + 1];
+ if (this.baselinePrefix.startsWith("-")) {
+ System.out.println("Missing value for "+arg+" parameter");
+ printUsage();
+ }
+ 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 "+arg+" parameter");
+ printUsage();
+ }
+ buffer.append(" ").append(arg).append(" = ");
+ String[] ids = idPrefixList.split(",");
+ this.currentBuildPrefixes = new ArrayList();
+ for (int j = 0; j < ids.length; j++) {
+ this.currentBuildPrefixes.add(ids[j]);
+ buffer.append(ids[j]);
+ }
+ buffer.append('\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-highlight") || arg.equals("-highlight.latest")) {
+ if (args[i + 1].startsWith("-")) {
+ System.out.println("Missing value for "+arg+" parameter");
+ printUsage();
+ }
+ buffer.append(" ").append(arg).append(" = ");
+ String[] ids = args[i + 1].split(",");
+ this.pointsOfInterest = new ArrayList();
+ for (int j = 0; j < ids.length; j++) {
+ this.pointsOfInterest.add(ids[j]);
+ buffer.append(ids[j]);
+ }
+ buffer.append('\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-current")) {
+ currentBuildId = args[i + 1];
+ if (currentBuildId.startsWith("-")) {
+ System.out.println("Missing value for "+arg+" parameter");
+ printUsage();
+ }
+ 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 "+arg+" parameter");
+ printUsage();
+ }
+ 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 "+arg+" parameter");
+ printUsage();
+ }
+ this.outputDir = new File(dir);
+ if (!this.outputDir.exists() && !this.outputDir.mkdirs()) {
+ System.err.println("Cannot create directory "+dir+" to write results in!");
+ System.exit(2);
+ }
+ 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 "+arg+" parameter");
+ printUsage();
+ }
+ this.dataDir = new File(dir);
+ if (!this.dataDir.exists() && !this.dataDir.mkdirs()) {
+ System.err.println("Cannot create directory "+dir+" to save data locally!");
+ System.exit(2);
+ }
+ 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 "+arg+" parameter");
+ printUsage();
+ }
+ String[] names = configs.split(",");
+ int length = names.length;
+ buffer.append(" ").append(arg).append(" = ");
+ for (int j=0; j<length; j++) {
+ if (j>0) buffer.append(',');
+ buffer.append(names[j]);
+ }
+ if (this.configDescriptors == null) {
+ this.configDescriptors = new String[length][2];
+ for (int j=0; j<length; j++) {
+ this.configDescriptors[j][0] = names[j];
+ this.configDescriptors[j][1] = names[j];
+ }
+ } else {
+ int confLength = this.configDescriptors[0].length;
+ int newLength = confLength;
+ mainLoop: for (int j=0; j<confLength; j++) {
+ for (int k=0; k<length; k++) {
+ if (this.configDescriptors[j][0].equals(names[k])) {
+ continue mainLoop;
+ }
+ }
+ this.configDescriptors[j][0] = null;
+ this.configDescriptors[j][1] = null;
+ newLength--;
+ }
+ if (newLength < confLength) {
+ String[][] newDescriptors = new String[newLength][2];
+ for (int j=0, c=0; j<newLength; j++) {
+ if (this.configDescriptors[c] != null) {
+ newDescriptors[j][0] = this.configDescriptors[c][0];
+ newDescriptors[j][1] = this.configDescriptors[c][1];
+ } else {
+ c++;
+ }
+ }
+ this.configDescriptors = newDescriptors;
+ }
+ }
+ buffer.append('\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-config.properties")) {
+ String configProperties = args[i + 1];
+ if (configProperties.startsWith("-")) {
+ System.out.println("Missing value for "+arg+" parameter");
+ printUsage();
+ }
+ if (this.configDescriptors == null) {
+ System.out.println("Missing -config parameter");
+ printUsage();
+ }
+ int length = this.configDescriptors.length;
+ StringTokenizer tokenizer = new StringTokenizer(configProperties, ";");
+ buffer.append('\t').append(arg).append(" = '").append(configProperties).append("' splitted in ").append(length).append(" configs:");
+ while (tokenizer.hasMoreTokens()) {
+ String labelDescriptor = tokenizer.nextToken();
+ String[] elements = labelDescriptor.trim().split(",");
+ for (int j=0; j<length; j++) {
+ if (elements[0].equals(this.configDescriptors[j][0])) {
+ this.configDescriptors[j][1] = elements[1];
+ buffer.append("\n\t\t+ ");
+ buffer.append(elements[0]);
+ buffer.append(" -> ");
+ buffer.append(elements[1]);
+ }
+ }
+ }
+ buffer.append('\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-scenario.filter") || arg.equals("-scenario.pattern")) {
+ this.scenarioPattern= args[i + 1];
+ if (this.scenarioPattern.startsWith("-")) {
+ System.out.println("Missing value for "+arg+" parameter");
+ printUsage();
+ }
+ buffer.append(" ").append(arg).append(" = ").append(this.scenarioPattern).append('\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-fingerprints")) {
+ this.genFingerPrints = true;
+ this.genAll = false;
+ buffer.append(" ").append(arg).append('\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-data")) {
+ this.genData = true;
+ this.genAll = false;
+ buffer.append(" ").append(arg).append('\n');
+ i++;
+ continue;
+ }
+ if (arg.equals("-print")) {
+ this.printStream = System.out; // default is to print to console
+ buffer.append(" ").append(arg);
+ i++;
+ String printFile = i==argsLength ? null : args[i];
+ if (printFile==null ||printFile.startsWith("-")) {
+ buffer.append(" (to the console)").append('\n');
+ } else {
+ try {
+ this.printStream = new PrintStream(new BufferedOutputStream(new FileOutputStream(printFile)));
+ }
+ catch (FileNotFoundException fnfe) {
+ // use the console if the output file cannot be created
+ }
+ buffer.append(" (to file: ").append(printFile).append(")\n");
+ }
+ 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.printStream != null) {
+ this.printStream.print(buffer.toString());
+ }
+
+ // Stop if some mandatory parameters are missing
+ if (this.outputDir == null || this.configDescriptors == null || jvm == null) {
+ printUsage();
+ }
+
+ // Set performance results
+ setPerformanceResults(currentBuildId, baseline);
+}
+
+/*
+ * Print component PHP file
+ */
+private void printComponent(/*PerformanceResults performanceResults, */String component) throws FileNotFoundException {
+ if (this.printStream != null) this.printStream.print(".");
+ File outputFile = new File(this.outputDir, component + ".php");
+ PrintStream stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
+
+ // 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.api.tools.php?\">org.eclipse.pde.api.tools*</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);
+ }
+ stream.print("<link href=\""+Utils.TOOLTIP_STYLE+"\" rel=\"stylesheet\" type=\"text/css\">\n");
+ stream.print("<script src=\""+Utils.TOOLTIP_SCRIPT+"\"></script>\n");
+ stream.print("<script src=\""+Utils.FINGERPRINT_SCRIPT+"\"></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
+ Display display = Display.getDefault();
+ if (this.genFingerPrints || this.genAll) {
+ final FingerPrint fingerprint = new FingerPrint(component, stream, this.outputDir);
+ display.syncExec(
+ new Runnable() {
+ public void run(){
+ try {
+ fingerprint.print(GenerateResults.this.performanceResults);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ );
+ }
+// FingerPrint fingerprint = new FingerPrint(component, stream, this.outputDir);
+// fingerprint.print(performanceResults);
+
+ // print scenario status table
+ if (!isGlobal) {
+ // print the component scenario status table beneath the fingerprint
+ final ScenarioStatusTable sst = new ScenarioStatusTable(component, stream);
+ display.syncExec(
+ new Runnable() {
+ public void run(){
+ try {
+ sst.print(GenerateResults.this.performanceResults);
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ }
+ }
+ );
+// ScenarioStatusTable sst = new ScenarioStatusTable(component, stream);
+// sst.print(performanceResults);
+ }
+
+ stream.print(Utils.HTML_CLOSE);
+ stream.close();
+}
+
+private void printComponentTitle(/*PerformanceResults performanceResults, */String component, boolean isGlobal, PrintStream stream) {
+ String baselineName = this.performanceResults.getBaselineName();
+ String currentName = this.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('_');
+ if (index > 0) {
+ stream.print(baselineName.substring(0, index));
+ stream.print(" (");
+ index = baselineName.lastIndexOf('_');
+ stream.print(baselineName.substring(index+1, baselineName.length()));
+ stream.print(')');
+ } else {
+ stream.print(baselineName);
+ }
+ stream.print("</h3>\n");
+
+ // Print reference to global results
+ if (!isGlobal) {
+ stream.print("<?php\n");
+ stream.print(" $type=$_SERVER['QUERY_STRING'];\n");
+ stream.print(" if ($type==\"\") {\n");
+ stream.print(" $type=\"fp_type=0\";\n");
+ stream.print(" }\n");
+ stream.print(" $href=\"<a href=\\\"performance.php?\";\n");
+ stream.print(" $href=$href . $type . \"\\\">Back to global results</a><br><br>\";\n");
+ stream.print(" echo $href;\n");
+ stream.print("?>\n");
+ }
+}
+
+/*
+ * Print summary of coefficient of variation for each scenario of the given pattern
+ * both for baseline and current builds.
+ */
+private void printSummary(/*PerformanceResults performanceResults*/) {
+ long start = System.currentTimeMillis();
+ if (this.printStream != null) this.printStream.print("Print scenarios variations summary...");
+ File outputFile = new File(this.outputDir, "cvsummary.html");
+ PrintStream stream = null;
+ try {
+ stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
+ printSummaryPresentation(stream);
+// List scenarioNames = DB_Results.getScenarios();
+// int size = scenarioNames.size();
+ String[] components = this.performanceResults.getComponents();
+ int componentsLength = components.length;
+ printSummaryColumnsTitle(stream/*, performanceResults*/);
+ String[] configs = this.performanceResults.getConfigNames(true/*sorted*/);
+ int configsLength = configs.length;
+ for (int i=0; i<componentsLength; i++) {
+ String componentName = components[i];
+ List scenarioNames = this.performanceResults.getComponentScenarios(componentName);
+ int size = scenarioNames.size();
+ for (int s=0; s<size; s++) {
+ String scenarioName = ((ScenarioResults) scenarioNames.get(s)).getName();
+ if (scenarioName == null) continue;
+ ScenarioResults scenarioResults = this.performanceResults.getScenarioResults(scenarioName);
+ if (scenarioResults != null) {
+ stream.print("<tr>\n");
+ for (int j=0; j<2; j++) {
+ for (int c=0; c<configsLength; c++) {
+ printSummaryScenarioLine(j, configs[c], scenarioResults, stream);
+ }
+ }
+ stream.print("<td>");
+ stream.print(scenarioName);
+ stream.print("</td></tr>\n");
+ }
+ }
+ }
+ } catch (Exception e) {
+ e.printStackTrace();
+ } finally {
+ stream.print("</table></body></html>\n");
+ stream.flush();
+ stream.close();
+ }
+ if (this.printStream != null) this.printStream.println("done in "+(System.currentTimeMillis()-start)+"ms");
+}
+
+/*
+ * Print summary presentation (eg. file start and text presenting the purpose of this file contents)..
+ */
+private void printSummaryPresentation(PrintStream stream) {
+ stream.print(Utils.HTML_OPEN);
+ stream.print(Utils.HTML_DEFAULT_CSS);
+ 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.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.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>&lt;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");
+}
+
+/*
+ * Print columns titles of the summary table.
+ */
+private void printSummaryColumnsTitle(PrintStream stream/*, PerformanceResults performanceResults*/) {
+ String[] configBoxes = this.performanceResults.getConfigBoxes(true/*sorted*/);
+ int length = configBoxes.length;
+ stream.print("<table border=\"1\"><tr><td colspan=\"");
+ stream.print(length);
+ stream.print("\"><b>Baseline CVs</b></td><td colspan=\"");
+ stream.print(length);
+ 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++) {
+ stream.print("<td>");
+ stream.print(configBoxes[c]);
+ stream.print("</td>");
+ }
+ }
+ stream.print("</tr>\n");
+}
+
+/*
+ * Print a scenario line in the summary table.
+ */
+private void printSummaryScenarioLine(int i, String config, ScenarioResults scenarioResults, PrintStream stream) {
+ ConfigResults configResults = scenarioResults.getConfigResults(config);
+ if (configResults == null || !configResults.isValid()) {
+ stream.print("<td>n/a</td>");
+ return;
+ }
+ String url = config + "/" + scenarioResults.getFileName()+".html";
+ double[] stats = null;
+ if (i==0) { // baseline results
+ List baselinePrefixes;
+ if (this.baselinePrefix == null) {
+ baselinePrefixes = Util.BASELINE_BUILD_PREFIXES;
+ } else {
+ baselinePrefixes = new ArrayList();
+ baselinePrefixes.add(this.baselinePrefix);
+ }
+ stats = configResults.getStatistics(baselinePrefixes);
+ } else {
+ stats = configResults.getStatistics(this.currentBuildPrefixes);
+ }
+ double variation = stats[3];
+ if (variation > 0.1 && variation < 0.2) {
+ stream.print("<td bgcolor=\"yellow\">");
+ } else if (variation >= 0.2) {
+ stream.print("<td bgcolor=\"FF9900\">");
+ } else {
+ stream.print("<td>");
+ }
+ stream.print("<a href=\"");
+ stream.print(url);
+ stream.print("\"/>");
+ stream.print(Util.PERCENTAGE_FORMAT.format(variation));
+ stream.print("</a></td>");
+}
+
+/*
+ * Print usage in case one of the argument of the line was incorrect.
+ * Note that calling this method ends the program run due to final System.exit()
+ */
+private void printUsage() {
+ System.out.println(
+ "Usage:\n\n" +
+ "-baseline\n" +
+ " Build id against which to compare results.\n" +
+ " Same as value specified for the \"build\" key in the eclipse.perf.config system property.\n\n" +
+
+ "[-baseline.prefix]\n" +
+ " Optional. Build id prefix used in baseline test builds and reruns. Used to plot baseline historical data.\n" +
+ " A common prefix used for the value of the \"build\" key in the eclipse.perf.config system property when rerunning baseline tests.\n\n" +
+
+ "-current\n" +
+ " build id for which to generate results. Compared to build id specified in -baseline parameter above.\n" +
+ " Same as value specified for the \"build\" key in the eclipse.perf.config system property. \n\n" +
+
+ "[-current.prefix]\n" +
+ " Optional. Comma separated list of build id prefixes used in current build stream.\n" +
+ " Used to plot current build stream historical data. Defaults to \"N,I\".\n" +
+ " Prefixes for values specified for the \"build\" key in the eclipse.perf.config system property. \n\n" +
+
+ "-jvm\n" +
+ " Value specified in \"jvm\" key in eclipse.perf.config system property for current build.\n\n" +
+
+ "-config\n" +
+ " Comma separated list of config names for which to generate results.\n" +
+ " Same as values specified in \"config\" key in eclipse.perf.config system property.\n\n" +
+
+ "-output\n" +
+ " Path to default output directory.\n\n" +
+
+ "[-config.properties]\n" +
+ " Optional. Used by scenario status table to provide the following:\n" +
+ " alternate descriptions of config values to use in columns.\n" +
+ " The value should be specified in the following format:\n" +
+ " name1,description1;name2,description2;etc..\n\n" +
+
+ "[-highlight]\n" +
+ " Optional. Comma-separated list of build Id prefixes used to find most recent matching for each entry.\n" +
+ " Result used to highlight points in line graphs.\n\n" +
+
+ "[-scenario.pattern]\n" +
+ " Optional. Scenario prefix pattern to query database. If not specified,\n" +
+ " default of % used in query.\n\n" +
+
+ "[-fingerprints]\n" +
+ " Optional. Use to generate fingerprints only.\n\n" +
+
+ "[-data]\n" +
+ " 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" +
+
+ "[-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);
+}
+
+/**
+ * Run the generation from a list of arguments.
+ * Typically used to generate results from an application.
+ */
+public IStatus run(String[] args) {
+ parse(args);
+ return run((IProgressMonitor) null);
+}
+
+/**
+ * Run the generation using a progress monitor.
+ * Note that all necessary information to generate properly must be set before
+ * calling this method
+ *
+ * @see #run(String[])
+ */
+public IStatus run(final IProgressMonitor monitor) {
+ long begin = System.currentTimeMillis();
+ int work = 1100;
+ int dataWork = 1000 * this.performanceResults.getConfigBoxes(false).length;
+ if (this.genAll || this.genData) {
+ work += dataWork;
+ }
+ SubMonitor subMonitor = SubMonitor.convert(monitor, work);
+ try {
+
+ // Print whole scenarios summary
+ if (this.printStream != null) this.printStream.println();
+ printSummary(/*performanceResults*/);
+
+ // Copy images and scripts to output dir
+ Bundle bundle = UiPlugin.getDefault().getBundle();
+// URL images = bundle.getEntry("images");
+// if (images != null) {
+// images = FileLocator.resolve(images);
+// Utils.copyImages(new File(images.getPath()), this.outputDir);
+// }
+ /* New way to get images
+ File content = FileLocator.getBundleFile(bundle);
+ BundleFile bundleFile;
+ if (content.isDirectory()) {
+ bundleFile = new DirBundleFile(content);
+ Utils.copyImages(bundleFile.getFile("images", true), this.outputDir);
+ } else {
+ bundleFile = new ZipBundleFile(content, null);
+ Enumeration imageFiles = bundle.findEntries("images", "*.gif", false);
+ while (imageFiles.hasMoreElements()) {
+ URL url = (URL) imageFiles.nextElement();
+ Utils.copyFile(bundleFile.getFile("images"+File.separator+, true), this.outputDir);
+ }
+ }
+ */
+ // Copy bundle files
+ Utils.copyBundleFiles(bundle, "images", "*.gif", this.outputDir); // images
+ Utils.copyBundleFiles(bundle, "scripts", "*.js", this.outputDir); // java scripts
+ Utils.copyBundleFiles(bundle, "scripts", "*.css", this.outputDir); // styles
+ Utils.copyBundleFiles(bundle, "doc", "*.html", this.outputDir); // doc
+ Utils.copyBundleFiles(bundle, "doc/images", "*.png", this.outputDir); // images for doc
+ /*
+ 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 {
+ Util.copyFile(subdirFiles[j], new File(subdir, subdirFiles[j].getName()));
+ }
+ }
+ } else {
+ Util.copyFile(file, new File(this.outputDir, file.getName()));
+ }
+ }
+ }
+ */
+
+ // Print HTML pages and all linked files
+ if (this.printStream != null) {
+ this.printStream.println("Print performance results HTML pages:");
+ this.printStream.print(" - components main page");
+ }
+ long start = System.currentTimeMillis();
+ subMonitor.setTaskName("Write fingerprints: 0%");
+ subMonitor.subTask("Global...");
+ printComponent(/*performanceResults, */"global_fp");
+ subMonitor.worked(100);
+ if (subMonitor.isCanceled()) throw new OperationCanceledException();
+ String[] components = this.performanceResults.getComponents();
+ int length = components.length;
+ int step = 1000 / length;
+ int progress = 0;
+ for (int i=0; i<length; i++) {
+ int percentage = (int) ((progress / ((double) length)) * 100);
+ subMonitor.setTaskName("Write fingerprints: "+percentage+"%");
+ subMonitor.subTask(components[i]+"...");
+ printComponent(/*performanceResults, */components[i]);
+ subMonitor.worked(step);
+ if (subMonitor.isCanceled()) throw new OperationCanceledException();
+ progress++;
+ }
+ if (this.printStream != null) {
+ String duration = Util.timeString(System.currentTimeMillis()-start);
+ this.printStream.println(" done in "+duration);
+ }
+
+ // Print the scenarios data
+ if (this.genData || this.genAll) {
+ start = System.currentTimeMillis();
+ if (this.printStream != null) this.printStream.println(" - all scenarios data:");
+ ScenarioData data = new ScenarioData(this.baselinePrefix, this.pointsOfInterest, this.currentBuildPrefixes, this.outputDir);
+ try {
+ data.print(this.performanceResults, this.printStream, subMonitor.newChild(dataWork));
+ } catch (Exception ex) {
+ ex.printStackTrace();
+ }
+ if (this.printStream != null) {
+ String duration = Util.timeString(System.currentTimeMillis()-start);
+ this.printStream.println(" => done in "+duration);
+ }
+ }
+ if (this.printStream != null) {
+ long time = System.currentTimeMillis();
+ this.printStream.println("End of generation: "+new SimpleDateFormat("H:mm:ss").format(new Date(time)));
+ String duration = Util.timeString(System.currentTimeMillis()-begin);
+ this.printStream.println("=> done in "+duration);
+ }
+ return new Status(IStatus.OK, UiPlugin.getDefault().toString(), "Everything is OK");
+ }
+ catch (OperationCanceledException oce) {
+ return new Status(IStatus.OK, UiPlugin.getDefault().toString(), "Generation was cancelled!");
+ }
+ catch (Exception ex) {
+ return new Status(IStatus.ERROR, UiPlugin.getDefault().toString(), "An unexpected exception occurred!", ex);
+ }
+ finally {
+ if (this.printStream != null) {
+ this.printStream.flush();
+ if (this.printStream != System.out) {
+ this.printStream.close();
+ }
+ }
+ }
+}
+
+private void setDefaults(String buildName, String baseline) {
+ if (buildName == null) {
+ buildName = this.performanceResults.getName();
+ }
+
+ // Set default output dir if not set
+ if (this.outputDir.getPath().indexOf(buildName) == -1) {
+ File dir = new File(this.outputDir, buildName);
+ if (dir.exists() || dir.mkdir()) {
+ this.outputDir = dir;
+ if (this.printStream != null) {
+ this.printStream.println(" + changed output dir to: "+dir.getPath());
+ }
+ }
+ }
+
+ // Verify that build is known
+ String[] builds = this.performanceResults.getAllBuildNames();
+ if (builds == null || builds.length == 0) {
+ System.err.println("Cannot connect to database to generate results build '"+buildName+"'");
+ System.exit(1);
+ }
+ if (Arrays.binarySearch(builds, buildName, Util.BUILD_DATE_COMPARATOR) < 0) {
+ throw new RuntimeException("No results in database for build '"+buildName+"'");
+ }
+ if (this.printStream != null) {
+ this.printStream.println();
+ this.printStream.flush();
+ }
+
+ // Init baseline prefix if not set
+ if (this.baselinePrefix == null) {
+ int index = baseline.lastIndexOf('_');
+ if (index > 0) {
+ this.baselinePrefix = baseline.substring(0, index);
+ } else {
+ this.baselinePrefix = DB_Results.getDbBaselinePrefix();
+ }
+ }
+
+ // Init current build prefixes if not set
+ if (this.currentBuildPrefixes == null) {
+ this.currentBuildPrefixes = new ArrayList();
+ if (buildName.charAt(0) == 'M') {
+ this.currentBuildPrefixes.add("M");
+ } else {
+ this.currentBuildPrefixes.add("N");
+ }
+ this.currentBuildPrefixes.add("I");
+ }
+}
+
+private void setPerformanceResults(String buildName, String baselineName) {
+
+ // Set performance results
+ this.performanceResults = new PerformanceResults(buildName, baselineName, this.baselinePrefix, this.printStream);
+
+ // Set defaults
+ setDefaults(buildName, this.performanceResults.getBaselineName());
+
+ // Read performance results data
+ this.performanceResults.readAll(buildName, this.configDescriptors, this.scenarioPattern, this.dataDir, this.failure_threshold, null);
+}
+
+/* (non-Javadoc)
+ * @see org.eclipse.equinox.app.IApplication#stop()
+ */
+public void stop() {
+ // Do nothing
+}
+
+} \ No newline at end of file