View | Details | Raw Unified | Return to bug 201469 | Differences between
and this patch

Collapse All | Expand All

(-)src/org/eclipse/test/performance/ui/Main.java (-398 / +690 lines)
Lines 10-441 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.test.performance.ui;
11
package org.eclipse.test.performance.ui;
12
12
13
import java.io.File;
13
import java.io.*;
14
import java.io.FileOutputStream;
15
import java.io.PrintStream;
16
import java.net.URL;
14
import java.net.URL;
17
import java.util.ArrayList;
15
import java.util.*;
18
import java.util.Arrays;
19
import java.util.Enumeration;
20
import java.util.Hashtable;
21
16
17
import org.eclipse.core.runtime.FileLocator;
18
import org.eclipse.equinox.app.IApplication;
19
import org.eclipse.equinox.app.IApplicationContext;
20
import org.eclipse.test.internal.performance.PerformanceTestPlugin;
21
import org.eclipse.test.internal.performance.results.AbstractResults;
22
import org.eclipse.test.internal.performance.results.ConfigResults;
23
import org.eclipse.test.internal.performance.results.DB_Results;
24
import org.eclipse.test.internal.performance.results.PerformanceResults;
25
import org.eclipse.test.internal.performance.results.ScenarioResults;
22
import org.osgi.framework.Bundle;
26
import org.osgi.framework.Bundle;
23
27
24
import org.eclipse.core.runtime.IPlatformRunnable;
28
/**
25
import org.eclipse.core.runtime.Platform;
29
 * Main class to generate performance results of all scenarii matching a given pattern
26
30
 * in one HTML page per component.
27
import org.eclipse.test.internal.performance.db.Scenario;
31
 * 
28
import org.eclipse.test.internal.performance.db.SummaryEntry;
32
 * @see #printUsage() method to see a detailed parameters usage
29
import org.eclipse.test.internal.performance.db.Variations;
33
 */
30
import org.eclipse.test.performance.ui.Utils.ConfigDescriptor;
34
public class Main implements IApplication {
31
35
32
public class Main implements IPlatformRunnable{
36
/**
33
37
 * Prefix of baseline builds displayed in data graphs.
34
	private String baseline;
38
 * This field is set using <b>-baselinePrefix</b> argument.
35
	private String baselinePrefix=null;
39
 * <p>
36
	private String output;
40
 * Example:
37
	private String[] configNames;
41
 *		<pre>-baseline.prefix 3.2_200606291905</pre>
38
	private Hashtable configDescriptors;
42
 *
39
	private String currentBuildId;
43
 * @see #currentBuildPrefixes
40
	private ArrayList currentBuildStreamIdPrefixes;
44
 */
41
	private ArrayList pointsOfInterest;
45
private String baselinePrefix = null;
42
	private Variations variations;
46
43
	private Scenario[] scenarios;
47
/**
44
	private String jvm;
48
 * Root directory where all files are generated.
45
	private String scenarioFilter;
49
 * This field is set using <b>-output</b> argument.
46
	private boolean genFingerPrints = false;
50
 * <p>
47
	private boolean genScenarioSummaries =false;
51
 * Example:
48
	private boolean genAll = true;
52
 * 	<pre>-output /releng/results/I20070615-1200/performance</pre>
49
	private Hashtable fingerPrints = new Hashtable();
53
 */
50
	private Hashtable scenarioComments=new Hashtable();
54
private File outputDir;
51
	private Hashtable rawDataTables=new Hashtable();
55
52
	private boolean local = false;
56
/**
53
	
57
 * Arrays of 2 strings which contains config information: name and description.
54
	public Object run(Object args) throws Exception {
58
 * This field is set using <b>-config</b> and/or <b>-config.properties</b> arguments.
55
		parse(args);
59
 * <p>
56
		
60
 * Example:
57
		try {
61
 * <pre>
58
			if (this.local) {
62
 * 	-config eclipseperflnx3_R3.3,eclipseperfwin2_R3.3,eclipseperflnx2_R3.3,eclipseperfwin1_R3.3,eclipseperflnx1_R3.3
59
				int length = configNames.length;
63
 * 	-config.properties
60
				for (int i=0; i<length; i++) {
64
 * 		"eclipseperfwin1_R3.3,Win XP Sun 1.4.2_08 (2 GHz 512 MB);
61
					generate((ConfigDescriptor)configDescriptors.get(configNames[i]));
65
 * 		eclipseperflnx1_R3.3,RHEL 3.0 Sun 1.4.2_08 (2 GHz 512 MB);
62
				}
66
 * 		eclipseperfwin2_R3.3,Win XP Sun 1.4.2_08 (3 GHz 2 GB);
63
			} else {
67
 * 		eclipseperflnx2_R3.3,RHEL 3.0 Sun 1.4.2_08 (3 GHz 2 GB);
64
				Enumeration configIds=configDescriptors.keys();
68
 * 		eclipseperflnx3_R3.3,RHEL 4.0 Sun 1.4.2_08 (3 GHz 2.5 GB)"
65
				while (configIds.hasMoreElements()){
69
 * </pre>
66
					generate((ConfigDescriptor)configDescriptors.get(configIds.nextElement()));
70
 * Note that:
67
				}
71
 * <ul>
68
			}
72
 * <li>if only <b>-config</b> is set, then configuration name is used for description </li>
69
73
 * <li>if only <b>-config.properties</b> is set, then all configurations defined with this argument are generated
70
			Utils.printVariabilityTable(rawDataTables,output+"/cvsummary.html",configDescriptors);
74
 * <li>if both arguments are defined, then only configurations defined by <b>-config</b> argument are generated,
71
		
75
 * 		<b>-config.properties</b> argument is only used to set the configuration description.</li>
72
			Enumeration components = fingerPrints.keys();
76
 * </ul>
73
			Bundle bundle= UiPlugin.getDefault().getBundle();
77
 */
74
			URL images=bundle.getEntry("images");
78
private String[][] configDescriptors;
75
			URL scripts=bundle.getEntry("scripts");
79
76
80
/**
77
			if (images!=null) {
81
 * Scenario pattern used to generate performance results.
78
				images= Platform.resolve(images);
82
 * This field is set using <b>-scenarioPattern</b> argument.
79
				Utils.copyImages(new File(images.getPath()), new File(output));
83
 * <p>
80
			}
84
 * Note that this pattern uses SQL conventions, not RegEx ones,
81
			if (scripts!=null){
85
 * which means that '%' is used to match several consecutive characters
82
				scripts= Platform.resolve(scripts);
86
 * and '_' to match a single character.
83
				Utils.copyScripts(new File(scripts.getPath()), new File(output));
87
 * <p>
84
			}
88
 * Example:
85
		
89
 * 	<pre>-scenario.pattern org.eclipse.%.test</pre>
86
			// print fingerprint/scenario status pages
90
 */
87
			while (components.hasMoreElements()) {
91
private String scenarioPattern;
88
			String component = components.nextElement().toString();
92
89
				File outputFile = new File(output, component + ".php");
93
/**
90
				outputFile.getParentFile().mkdirs();
94
 * A list of prefixes for builds displayed in data graphs.
91
				PrintStream os = new PrintStream(new FileOutputStream(outputFile));
95
 * This field is set using <b>-currentPrefix</b> argument.
92
				os.println(Utils.HTML_OPEN);
96
 * <p>
93
				os.println("<link href=\"ToolTip.css\" rel=\"stylesheet\" type=\"text/css\">"+
97
 * Example:
94
				"<script src=\"ToolTip.js\"></script>");
98
 * 	<pre>-current.prefix N, I</pre>
95
				os.println(Utils.HTML_DEFAULT_CSS);
99
 * 
96
				os.println("<body>");
100
 * @see #baselinePrefix
97
				Hashtable fps = (Hashtable) fingerPrints.get(component);
101
 */
98
				
102
private List currentBuildPrefixes;
99
				int baselineUnderScoreIndex=baseline.indexOf("_");
103
100
				int currentUnderScoreIndex=currentBuildId.indexOf("_");
104
/**
101
105
 * A list of prefixes of builds to highlight in displayed data graphs.
102
				String baselineName=(baselineUnderScoreIndex!=-1)?baseline.substring(0, baseline.indexOf("_")):baseline;
106
 * This field is set using <b>-highlight</b> and/or <b>-highlight.latest</b> arguments.
103
				String currentName=(currentUnderScoreIndex!=-1)?currentBuildId.substring(0, currentBuildId.indexOf("_")):currentBuildId;
107
 * <p>
104
				boolean isGlobal = component.equals("global");
108
 * Example:
105
				StringBuffer title = new StringBuffer("<h3>Performance of ");
109
 * 	<pre>-higlight 3_2</pre>
106
				if (!isGlobal) {
110
 */
107
					title.append(component);
111
private List pointsOfInterest;
108
					title.append(": ");
112
109
				}
113
/**
110
				title.append(currentName);
114
 * Tells whether only fingerprints has to be generated.
111
				title.append(" relative to ");
115
 * This field is set to <code>true</code> if <b>-fingerprints</b> argument is specified.
112
				title.append(baselineName);
116
 * <p>
113
				title.append( "</h3>");
117
 * Default is <code>false</code> which means that scenario data
114
				os.println(title.toString());
118
 * will also be generated.
115
				
119
 * 
116
				//print the html representation of fingerprint for each config 
120
 * @see #genData
117
				Enumeration configs = fps.keys();
121
 * @see #genAll
118
				SummaryEntry[] fpSummaries = null;
122
 */
119
				while (configs.hasMoreElements()) {
123
private boolean genFingerPrints = false;
120
					String config = configs.nextElement().toString();
124
121
					FingerPrint fingerPrint = (FingerPrint) fps.get(config);
125
/**
122
					os.println(fingerPrint.getImageMap());
126
 * Tells whether only fingerprints has to be generated.
123
					if (fpSummaries == null) {
127
 * This field is set to <code>true</code> if <b>-data</b> argument is specified.
124
						fpSummaries = fingerPrint.entries;
128
 * <p>
125
					}
129
 * Default is <code>false</code> which means that fingerprints
126
				}
130
 * will also be generated.
127
				if (isGlobal) {
131
 * 
128
					if (this.local) {
132
 * @see #genFingerPrints
129
						os.println("<table border=0 cellpadding=2 cellspacing=5 width=\"100%\">");
133
 * @see #genAll
130
						os.println("<tbody><tr> <td colspan=3 align=\"left\" bgcolor=\"#0080c0\" valign=\"top\"><b><font color=\"#ffffff\" face=\"Arial,Helvetica\">");
134
 */
131
						os.println("Detailed performance data grouped by scenario prefix</font></b></td></tr></tbody></table>");
135
private boolean genData = false;
132
						os.println("<a href=\"org.eclipse.ant.php?\">org.eclipse.ant*</a><br>");
136
133
						os.println("<a href=\"org.eclipse.compare.php?\">org.eclipse.compare*</a><br>");
137
/**
134
						os.println("<a href=\"org.eclipse.core.php?\">org.eclipse.core*</a><br>");
138
 * Tells whether only fingerprints has to be generated.
135
						os.println("<a href=\"org.eclipse.help.php?\">org.eclipse.help*</a><br>");
139
 * This field is set to <code>false</code>
136
						os.println("<a href=\"org.eclipse.jdt.core.php?\">org.eclipse.jdt.core*</a><br>");
140
 * if <b>-fingerprints</b> or <b>-data</b> argument is specified.
137
						os.println("<a href=\"org.eclipse.jdt.debug.php?\">org.eclipse.jdt.debug*</a><br>");
141
 * <p>
138
						os.println("<a href=\"org.eclipse.jdt.text.php?\">org.eclipse.jdt.text*</a><br>");
142
 * Default is <code>true</code> which means that scenario data
139
						os.println("<a href=\"org.eclipse.jdt.ui.php?\">org.eclipse.jdt.ui*</a><br>");
143
 * will also be generated.
140
						os.println("<a href=\"org.eclipse.jface.php?\">org.eclipse.jface*</a><br>");
144
 * 
141
						os.println("<a href=\"org.eclipse.osgi.php?\">org.eclipse.osgi*</a><br>");
145
 * @see #genData
142
						os.println("<a href=\"org.eclipse.pde.ui.php?\">org.eclipse.pde.ui*</a><br>");
146
 * @see #genFingerPrints
143
						os.println("<a href=\"org.eclipse.swt.php?\">org.eclipse.swt*</a><br>");
147
 */
144
						os.println("<a href=\"org.eclipse.team.php?\">org.eclipse.team*</a><br>");
148
private boolean genAll = true;
145
						os.println("<a href=\"org.eclipse.ua.php?\">org.eclipse.ua*</a><br>");
149
146
						os.println("<a href=\"org.eclipse.ui.php?\">org.eclipse.ui*</a><br><p><br><br>");
150
/**
147
					}
151
 * Tells whether information should be displayed in the console while generating.
148
				} else if (component.length() > 0) {
152
 * This field is set to <code>true</code> if <b>-print</b> argument is specified.
149
					// print the component scenario status table beneath the fingerprint
153
 * <p>
150
					variations.put("config", "%");
154
 * Default is <code>false</code> which means that nothing is print during the generation.
151
					boolean filter = this.local && this.scenarioFilter != null; // use scenario filter to minimize DB requests while testing...
155
 */
152
					ScenarioStatusTable sst = filter
156
private boolean print = false;
153
						? new ScenarioStatusTable(variations, this.scenarioFilter, configDescriptors,scenarioComments, fpSummaries, baseline)
157
154
						: new ScenarioStatusTable(variations, component + "%", configDescriptors,scenarioComments, fpSummaries, baseline);
158
/*
155
					sst.print(os, filter);
159
 * Parse the command arguments and create corresponding performance
156
				}
160
 * results object.
161
 */
162
private PerformanceResults parse(Object argsObject) {
163
	StringBuffer buffer = new StringBuffer("Parameters used to generate performance results:\n");
164
	String[] args = (String[]) argsObject;
165
	int i = 0;
166
	if (args.length == 0) {
167
		printUsage();
168
	}
157
169
158
				os.println(Utils.HTML_CLOSE);
170
	String currentBuildId = null;
159
				os.close();
171
	String baseline = null;
172
	String jvm = null;
173
	this.configDescriptors = null;
174
175
	while (i < args.length) {
176
		String arg = args[i];
177
		if (!arg.startsWith("-")) {
178
			i++;
179
			continue;
180
		}
181
		if (args.length == i + 1 && i != args.length - 1) {
182
			System.out.println("Missing value for last parameter");
183
			printUsage();
184
		}
185
		if (arg.equals("-baseline")) {
186
			baseline = args[i + 1];
187
			if (baseline.startsWith("-")) {
188
				System.out.println("Missing value for -baseline parameter");
189
				printUsage();
160
			}
190
			}
161
		} catch (Exception e) {
191
			buffer.append("	-baseline = "+baseline+'\n');
162
			// Need to print any unexpected exception otherwise the failure will be completely silent...
192
			i++;
163
			e.printStackTrace();
193
			continue;
164
		}
194
		}
165
195
		if (arg.equals("-baseline.prefix")) {
166
		return null;
196
			this.baselinePrefix = args[i + 1];
167
	}
197
			if (this.baselinePrefix.startsWith("-")) {
168
	
198
				System.out.println("Missing value for -baseline.prefix parameter");
169
199
				printUsage();
170
	private void generate(Utils.ConfigDescriptor cd) {
171
			//String config=cd.getName();
172
			String dbloc_property= System.getProperty("eclipse.perf.dbloc");
173
			if (dbloc_property == null || dbloc_property.equals(""))
174
				System.out.println("WARNING:  eclipse.perf.dbloc value set to null");
175
			scenarios = Utils.getScenarios("%", scenarioFilter, cd.name, jvm);
176
			variations = Utils.getVariations("%", cd.name, jvm);
177
178
			//creates and stores fingerprint objects
179
			if (genFingerPrints || genAll) {
180
				System.out.print(cd.name + ": generating fingerprints and scenario status tables...");
181
				
182
				//global
183
				FingerPrint global = new FingerPrint(null, cd, baseline, currentBuildId, variations, output);
184
				
185
				//store mappings of fingerprints per config for each component
186
				Hashtable t;
187
				if (fingerPrints.get("global") != null)
188
					t = (Hashtable) fingerPrints.get("global");
189
				else
190
					t = new Hashtable();
191
192
				t.put(cd.name, global);
193
				fingerPrints.put("global", t);
194
195
				//get unique component names from scenario names
196
				ArrayList components = Utils.getComponentNames(scenarios);
197
		
198
				//store fingerprints for config for each component
199
				for (int i = 0; i < components.size(); i++) {
200
					String component = components.get(i).toString();
201
					variations.put("config", cd.name);
202
					FingerPrint componentFp = new FingerPrint(component, cd, baseline, currentBuildId, variations, output);
203
					if (fingerPrints.get(component) != null)
204
						t = (Hashtable) fingerPrints.get(component);
205
					else
206
						t = new Hashtable();
207
					t.put(cd.name, componentFp);
208
					fingerPrints.put(component, t);
209
					if (componentFp.scenarioComments!=null)
210
						scenarioComments.putAll(componentFp.scenarioComments);
211
				}
212
				System.out.println("done.");
213
			}
200
			}
214
			
201
			buffer.append("	-baselinePrefix = "+this.baselinePrefix+'\n');
215
			//generates scenario result pages and line graphs
202
			i++;
216
			if (genScenarioSummaries || genAll) {
203
			continue;
217
				System.out.print(cd.name
218
						+ ": generating scenario results...");
219
				new ScenarioResults(cd,scenarios, baseline,baselinePrefix,currentBuildId,pointsOfInterest,scenarioComments,currentBuildStreamIdPrefixes,rawDataTables,output,variations);
220
				System.out.println("done.");
221
			}
222
		}
223
	
224
225
	private void parse(Object argsObject) {
226
		String []args=(String[])argsObject;
227
		int i = 0;
228
		if (args.length == 0) {
229
			printUsage();
230
		}
204
		}
231
205
		if (arg.equals("-current.prefix")) {
232
		while (i < args.length) {
206
			String idPrefixList = args[i + 1];
233
			String arg = args[i];
207
			if (idPrefixList.startsWith("-")) {
234
			if (!arg.startsWith("-")){
208
				System.out.println("Missing value for -current.prefix parameter");
235
				i++;
236
				continue;
237
			}
238
			if (args.length==i+1&&i!=args.length-1){
239
				System.out.println("Missing value for last parameter");
240
				printUsage();
209
				printUsage();
241
			}
210
			}
242
			if (arg.equals("-baseline")) {
211
			buffer.append("	-current.prefix = ");
243
				baseline = args[i + 1];
212
			String[] ids = idPrefixList.split(",");
244
				if (baseline.startsWith("-")) {
213
			this.currentBuildPrefixes = new ArrayList();
245
					System.out.println("Missing value for -baseline parameter");
214
			for (int j = 0; j < ids.length; j++) {
246
					printUsage();
215
				this.currentBuildPrefixes.add(ids[j]);
247
				}
216
				buffer.append(ids[j]);
248
				i++;
249
				continue;
250
			}
217
			}
251
			if (arg.equals("-baseline.prefix")) {
218
			buffer.append('\n');
252
				baselinePrefix = args[i + 1];
219
			i++;
253
				if (baselinePrefix.startsWith("-")) {
220
			continue;
254
					System.out.println("Missing value for -baseline.prefix parameter");
221
		}
255
					printUsage();
222
		if (arg.equals("-highlight") || arg.equals("-highlight.latest")) {
256
				}
223
			if (args[i + 1].startsWith("-")) {
257
				i++;
224
				System.out.println("Missing value for -highlight parameter");
258
				continue;
225
				printUsage();
259
			}
226
			}
260
			if (arg.equals("-current.prefix")) {
227
			buffer.append("	"+arg+" = ");
261
				String idPrefixList=args[i + 1];
228
			String[] ids = args[i + 1].split(",");
262
				if (idPrefixList.startsWith("-")) {
229
			this.pointsOfInterest = new ArrayList();
263
					System.out.println("Missing value for -current.prefix parameter");
230
			for (int j = 0; j < ids.length; j++) {
264
					printUsage();
231
				this.pointsOfInterest.add(ids[j]);
265
				}
232
				buffer.append(ids[j]);
266
				String []ids=idPrefixList.split(",");
267
				currentBuildStreamIdPrefixes=new ArrayList();
268
				for (int j=0;j<ids.length;j++){
269
					currentBuildStreamIdPrefixes.add(ids[j]);
270
				}
271
				i++;
272
				continue;
273
			}
233
			}
274
			if (arg.equals("-highlight")||arg.equals("-highlight.latest")) {
234
			buffer.append('\n');
275
				if (args[i + 1].startsWith("-")) {
235
			i++;
276
					System.out.println("Missing value for -highlight parameter");
236
			continue;
277
					printUsage();
237
		}
278
				}
238
		if (arg.equals("-current")) {
279
				String []ids=args[i + 1].split(",");
239
			currentBuildId  = args[i + 1];
280
				pointsOfInterest=new ArrayList();
240
			if (currentBuildId.startsWith("-")) {
281
				for (int j=0;j<ids.length;j++){
241
				System.out.println("Missing value for -current parameter");
282
					pointsOfInterest.add(ids[j]);
242
				printUsage();
283
				}
284
				i++;
285
				continue;
286
			}
243
			}
287
			if (arg.equals("-current")) {
244
			buffer.append("	-current = "+currentBuildId+'\n');
288
				currentBuildId = args[i + 1];
245
			i++;
289
				if (currentBuildId.startsWith("-")) {
246
			continue;
290
					System.out.println("Missing value for -current parameter");
247
		}
291
					printUsage();
248
		if (arg.equals("-jvm")) {
292
				}
249
			jvm = args[i + 1];
293
				i++;
250
			if (jvm.startsWith("-")) {
294
				continue;
251
				System.out.println("Missing value for -jvm parameter");
252
				printUsage();
295
			}
253
			}
296
			if (arg.equals("-jvm")) {
254
			buffer.append("	-jvm = "+jvm+'\n');
297
				jvm = args[i + 1];
255
			i++;
298
				if (jvm.startsWith("-")) {
256
			continue;
299
					System.out.println("Missing value for -jvm parameter");
257
		}
300
					printUsage();
258
		if (arg.equals("-output")) {
301
				}
259
			String dir = args[++i];
302
				i++;
260
			if (dir.startsWith("-")) {
303
				continue;
261
				System.out.println("Missing value for -output parameter");
262
				printUsage();
304
			}
263
			}
305
			if (arg.equals("-output")) {
264
			this.outputDir = new File(dir);
306
				output = args[i + 1];
265
			if (!this.outputDir.exists() && !this.outputDir.mkdirs()) {
307
				if (output.startsWith("-")) {
266
				System.err.println("Cannot create directory "+dir+" to write results in!");
308
					System.out.println("Missing value for -output parameter");
267
				System.exit(2);
309
					printUsage();
310
				}
311
				i++;
312
				continue;
313
			}
268
			}
314
			if (arg.equals("-config")) {
269
			buffer.append("	-output = "+dir+'\n');
315
				String configs = args[i + 1];
270
			continue;
316
				if (configs.startsWith("-")) {
271
		}
317
					System.out.println("Missing value for -config parameter");
272
		if (arg.equals("-config")) {
318
					printUsage();
273
			String configs = args[i + 1];
319
				}
274
			if (configs.startsWith("-")) {
320
				configNames = configs.split(",");
275
				System.out.println("Missing value for -config parameter");
321
				Arrays.sort(configNames);
276
				printUsage();
322
				i++;
277
			}
323
				continue;
278
			String[] names = configs.split(",");
324
			}
279
			int length = names.length;
325
			if (arg.equals("-config.properties")) {
280
			buffer.append("	-config = ");
326
				String configProperties = args[i + 1];
281
			for (int j=0; j<length; j++) {
327
				if (configProperties.startsWith("-")) {
282
				if (j>0) buffer.append(',');
328
					System.out.println("Missing value for -config.properties parameter");
283
				buffer.append(names[j]);
329
					printUsage();
284
			}
285
			if (this.configDescriptors == null) {
286
				this.configDescriptors = new String[length][2];
287
				for (int j=0; j<length; j++) {
288
					this.configDescriptors[j][0] = names[j];
289
					this.configDescriptors[j][1] = names[j];
330
				}
290
				}
331
				configDescriptors = Utils.getConfigDescriptors(configProperties);
291
			} else {
332
				i++;
292
				int confLength = this.configDescriptors[0].length;
333
				continue;
293
				int newLength = confLength;
334
			}
294
				mainLoop: for (int j=0; j<confLength; j++) {
335
			if (arg.equals("-scenario.filter")||arg.equals("-scenario.pattern")) {
295
					for (int k=0; k<length; k++) {
336
				scenarioFilter = args[i + 1];
296
						if (this.configDescriptors[j][0].equals(names[k])) {
337
				if (scenarioFilter.startsWith("-")) {
297
							continue mainLoop;
338
					System.out.println("Missing value for -baseline parameter");
298
						}
339
					printUsage();
299
					}
300
					this.configDescriptors[j][0] = null;
301
					this.configDescriptors[j][1] = null;
302
					newLength--;
303
				}
304
				if (newLength < confLength) {
305
					String[][] newDescriptors = new String[newLength][2];
306
					for (int j=0, c=0; j<newLength; j++) {
307
						if (this.configDescriptors[c] != null) {
308
							newDescriptors[j][0] = this.configDescriptors[c][0];
309
							newDescriptors[j][1] = this.configDescriptors[c][1];
310
						} else {
311
							c++;
312
						}
313
					}
314
					this.configDescriptors = newDescriptors;
340
				}
315
				}
341
				i++;
342
				continue;
343
			}
316
			}
344
			if (arg.equals("-fingerprints")) {
317
			buffer.append('\n');
345
				genFingerPrints = true;
318
			i++;
346
				genAll = false;
319
			continue;
347
				i++;
320
		}
348
				continue;
321
		if (arg.equals("-config.properties")) {
322
			String configProperties = args[i + 1];
323
			if (configProperties.startsWith("-")) {
324
				System.out.println("Missing value for -config.properties parameter");
325
				printUsage();
349
			}
326
			}
350
			if (arg.equals("-scenarioresults")) {
327
			if (this.configDescriptors == null) {
351
				genScenarioSummaries = true;
328
				System.out.println("Missing -config parameter");
352
				genAll = false;
329
				printUsage();
353
				i++;
354
				continue;
355
			}
330
			}
356
			if (arg.equals("-local")) {
331
			int length = this.configDescriptors.length;
357
				this.local  = true;
332
			StringTokenizer tokenizer = new StringTokenizer(configProperties, ";");
358
				i++;
333
			buffer.append("	-config.properties = ");
359
				continue;
334
			while (tokenizer.hasMoreTokens()) {
335
				String labelDescriptor = tokenizer.nextToken();
336
				String[] elements = labelDescriptor.trim().split(",");
337
				for (int j=0; j<length; j++) {
338
					if (elements[0].equals(this.configDescriptors[j][0])) {
339
						this.configDescriptors[j][1] = elements[1];
340
						buffer.append("\n\t\t+ ");
341
						buffer.append(elements[0]);
342
						buffer.append(" -> ");
343
						buffer.append(elements[1]);
344
					}
345
				}
360
			}
346
			}
361
347
			buffer.append('\n');
362
			i++;
348
			i++;
349
			continue;
363
		}
350
		}
364
		if (baseline == null || output == null || configNames == null
351
		if (arg.equals("-scenario.filter") || arg.equals("-scenario.pattern")) {
365
				|| jvm == null
352
			this.scenarioPattern= args[i + 1];
366
				|| currentBuildId == null)
353
			if (this.scenarioPattern.startsWith("-")) {
367
			printUsage();
354
				System.out.println("Missing value for -baseline parameter");
368
		
355
				printUsage();
369
		if (currentBuildStreamIdPrefixes==null){
356
			}
370
			currentBuildStreamIdPrefixes=new ArrayList();
357
			buffer.append("	"+arg+" = "+this.scenarioPattern+'\n');
371
			currentBuildStreamIdPrefixes.add("N");
358
			i++;
372
			currentBuildStreamIdPrefixes.add("I");
359
			continue;
373
		}
360
		}
374
		if (configDescriptors==null){
361
		if (arg.equals("-fingerprints")) {
375
			configDescriptors=new Hashtable();
362
			this.genFingerPrints = true;
376
			for (int j=0;j<configNames.length;j++){
363
			this.genAll = false;
377
				String configName=configNames[j];
364
			buffer.append("	-fingerprints\n");
378
				configDescriptors.put(configName,new Utils.ConfigDescriptor(configName,configName));
365
			i++;
379
		
366
			continue;
380
			}
367
		}
381
		}
368
		if (arg.equals("-data")) {
382
	}
369
			this.genData = true;
383
	
370
			this.genAll = false;
384
	private void printUsage() {
371
			buffer.append("	-data\n");
385
		System.out
372
			i++;
386
				.println("Usage:\n"
373
			continue;
387
						
374
		}
388
						+ "-baseline"
375
		if (arg.equals("-print")) {
389
								+"\n\tBuild id against which to compare results."
376
			this.print = true;
390
								+"\n\tSame as value specified for the \"build\" key in the eclipse.perf.config system property.\n\n"
377
			buffer.append("	-print\n");
391
378
			i++;
392
						+ "[-baseline.prefix]"
379
			continue;
393
								+"\n\tBuild id prefix used in baseline test builds and reruns.  Used to plot baseline historical data."
380
		}
394
								+"\n\tA common prefix used for the value of the \"build\" key in the eclipse.perf.config system property when rerunning baseline tests.\n\n"
381
		i++;
395
								
382
	}
396
						+ "-current" 
383
	if (this.print) System.out.println(buffer.toString());
397
								+"\n\tbuild id for which to generate results.  Compared to build id specified in -baseline parameter above."
384
	if (baseline == null || this.outputDir == null || this.configDescriptors == null || jvm == null || currentBuildId == null) {
398
								+"\n\tSame as value specified for the \"build\" key in the eclipse.perf.config system property. \n\n"
385
		printUsage();
399
386
	}
400
						+ "[-current.prefix]" 
387
	if (this.baselinePrefix == null) {
401
							+"\n\tComma separated list of build id prefixes used in current build stream." 
388
		// Assume that baseline name format is *always* x.y_yyyyMMddhhmm_yyyyMMddhhmm
402
							+"\n\tUsed to plot current build stream historical data.  Defaults to \"N,I\"."
389
		this.baselinePrefix = baseline.substring(0, baseline.lastIndexOf('_'));
403
							+"\n\tPrefixes for values specified for the \"build\" key in the eclipse.perf.config system property. \n\n"
390
	}
404
			
391
405
						+ "-jvm"
392
	if (this.currentBuildPrefixes == null) {
406
								+"\n\tValue specified in \"jvm\" key in eclipse.perf.config system property for current build.\n\n"
393
		this.currentBuildPrefixes = new ArrayList();
407
						
394
		this.currentBuildPrefixes.add("N");
408
						+ "-config" 
395
		this.currentBuildPrefixes.add("I");
409
								+"\n\tComma separated list of config names for which to generate results."
396
	}
410
								+"\n\tSame as values specified in \"config\" key in eclipse.perf.config system property.\n\n"
397
	return new PerformanceResults(currentBuildId, baseline, this.print);
411
398
}
412
						+ "-output"
399
413
								+" \n\tPath to default output directory.\n\n"
400
/*
414
401
 * Print component PHP file
415
						+ "[-config.properties]"
402
 */
416
								+"\n\tOptional.  Used by scenario status table to provide the following:"
403
private void printComponent(PerformanceResults performanceResults, String component) throws FileNotFoundException {
417
								+"\n\t\talternate descriptions of config values to use in columns."
404
	if (this.print) System.out.print(".");
418
								+"\n\tThe value should be specified in the following format:"
405
	File outputFile = new File(this.outputDir, component + ".php");
419
								+"\n\tname1,description1;name2,description2;etc..\n\n"
406
	PrintStream stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
420
407
	stream.println(Utils.HTML_OPEN);
421
						+ "[-highlight]"
408
	stream.println("<link href=\"ToolTip.css\" rel=\"stylesheet\" type=\"text/css\"><script src=\"ToolTip.js\"></script>");
422
								+"\n\tOptional.  Comma-separated list of build Id prefixes used to find most recent matching for each entry." +
409
	stream.println(Utils.HTML_DEFAULT_CSS);
423
										"\n\tResult used to highlight points in line graphs.\n\n"
410
	stream.println("<body>");
424
411
425
						+ "[-scenario.pattern]"
412
	String baselineName = performanceResults.getBaselineName();
426
								+"\n\tOptional.  Scenario prefix pattern to query database.  If not specified,"
413
	String currentName = performanceResults.getName();
427
								+"\n\tdefault of % used in query.\n\n"
414
	boolean isGlobal = component.equals("global");
428
							
415
	StringBuffer title = new StringBuffer("<h3>Performance of ");
429
						+ "[-fingerprints]" 
416
	if (!isGlobal) {
430
								+"\n\tOptional.  Use to generate fingerprints only.\n\n"
417
		title.append(component);
431
									
418
		title.append(": ");
432
						+ "[-scenarioresults]"
419
	}
433
								+"\n\tGenerates table of scenario reference and current data with line graphs.\n\n");
420
	title.append(currentName);
434
										
421
	title.append(" relative to ");
435
		System.exit(1);
422
	int index = baselineName.indexOf('_');
423
	title.append(baselineName.substring(0, index));
424
	title.append(" (");
425
	index = baselineName.lastIndexOf('_');
426
	title.append(baselineName.substring(index+1, baselineName.length()));
427
	title.append(")</h3>");
428
	stream.println(title.toString());
429
430
	// print the html representation of fingerprint for each config
431
	if (genFingerPrints || genAll) {
432
		FingerPrint fingerprint = new FingerPrint(component, stream, this.outputDir);
433
		try {
434
			fingerprint.print(performanceResults);
435
		} catch (Exception ex) {
436
			ex.printStackTrace();
437
		}
438
	}
439
440
	// print scenario status table
441
	if (isGlobal) {
442
		if (!PerformanceTestPlugin.getDBLocation().startsWith("net://")) {
443
			stream.println("<table border=0 cellpadding=2 cellspacing=5 width=\"100%\">");
444
			stream.println("<tbody><tr> <td colspan=3 align=\"left\" bgcolor=\"#0080c0\" valign=\"top\"><b><font color=\"#ffffff\" face=\"Arial,Helvetica\">");
445
			stream.println("Detailed performance data grouped by scenario prefix</font></b></td></tr></tbody></table>");
446
			stream.println("<a href=\"org.eclipse.ant.php?\">org.eclipse.ant*</a><br>");
447
			stream.println("<a href=\"org.eclipse.compare.php?\">org.eclipse.compare*</a><br>");
448
			stream.println("<a href=\"org.eclipse.core.php?\">org.eclipse.core*</a><br>");
449
			stream.println("<a href=\"org.eclipse.jdt.core.php?\">org.eclipse.jdt.core*</a><br>");
450
			stream.println("<a href=\"org.eclipse.jdt.debug.php?\">org.eclipse.jdt.debug*</a><br>");
451
			stream.println("<a href=\"org.eclipse.jdt.text.php?\">org.eclipse.jdt.text*</a><br>");
452
			stream.println("<a href=\"org.eclipse.jdt.ui.php?\">org.eclipse.jdt.ui*</a><br>");
453
			stream.println("<a href=\"org.eclipse.jface.php?\">org.eclipse.jface*</a><br>");
454
			stream.println("<a href=\"org.eclipse.osgi.php?\">org.eclipse.osgi*</a><br>");
455
			stream.println("<a href=\"org.eclipse.pde.ui.php?\">org.eclipse.pde.ui*</a><br>");
456
			stream.println("<a href=\"org.eclipse.swt.php?\">org.eclipse.swt*</a><br>");
457
			stream.println("<a href=\"org.eclipse.team.php?\">org.eclipse.team*</a><br>");
458
			stream.println("<a href=\"org.eclipse.ua.php?\">org.eclipse.ua*</a><br>");
459
			stream.println("<a href=\"org.eclipse.ui.php?\">org.eclipse.ui*</a><br><p><br><br>");
460
		}
461
	} else if (component.length() > 0) {
462
		// print the component scenario status table beneath the fingerprint
463
		ScenarioStatusTable sst = new ScenarioStatusTable(component, stream);
464
		try {
465
			sst.print(performanceResults);
466
		} catch (Exception ex) {
467
			ex.printStackTrace();
468
		}
469
	}
470
471
	stream.println(Utils.HTML_CLOSE);
472
	stream.close();
473
}
474
475
/*
476
 * Print summary of coefficient of variation for each scenario of the given pattern
477
 * both for baseline and current builds.
478
 */
479
private void printSummary(PerformanceResults performanceResults) {
480
	long start = System.currentTimeMillis();
481
	if (this.print) System.out.print("Print scenarii variations summary...");
482
	File outputFile = new File(this.outputDir, "cvsummary.html");
483
	PrintStream stream = null;
484
	try {
485
		stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outputFile)));
486
		printSummaryPresentation(stream);
487
		List scenarioNames = DB_Results.getScenariiNames();
488
		int size = scenarioNames.size();
489
		printSummaryColumnsTitle(stream, performanceResults);
490
		String[] configs = performanceResults.getConfigNames(true/*sorted*/);
491
		int configsLength = configs.length;
492
		for (int i=0; i<size; i++) {
493
			String scenarioName = (String) scenarioNames.get(i);
494
			if (scenarioName == null) continue;
495
			ScenarioResults scenarioResults = performanceResults.getScenarioResults(scenarioName);
496
			if (scenarioResults != null) {
497
				stream.println("<tr>");
498
				for (int j=0; j<2; j++) {
499
					for (int c=0; c<configsLength; c++) {
500
						printSummaryScenarioLine(j, configs[c], scenarioResults, stream);
501
					}
502
				}
503
				stream.print("<td>");
504
				stream.print(scenarioName);
505
				stream.println("</td></tr>");
506
			}
507
		}
508
	} catch (Exception e) {
509
		e.printStackTrace();
510
	} finally {
511
		stream.println("</table></body></html>");
512
		stream.flush();
513
		stream.close();
514
	}
515
	if (this.print) System.out.println("done in "+(System.currentTimeMillis()-start)+"ms");
516
}
436
517
518
/*
519
 * Print summary presentation (eg. file start and text presenting the purpose of this file contents)..
520
 */
521
private void printSummaryPresentation(PrintStream stream) {
522
	stream.println(Utils.HTML_OPEN);
523
	stream.print(Utils.HTML_DEFAULT_CSS);
524
	stream.println("<title>Summary of Elapsed Process Variation Coefficients</title></head>");
525
	stream.println("<body><h3>Summary of Elapsed Process Variation Coefficients</h3>\n");
526
	stream.println("<p> This table provides a bird's eye view of variability in elapsed process times\n");
527
	stream.print("for baseline and current build stream performance scenarios.");
528
	stream.print(" This summary is provided to facilitate the identification of scenarios that should be examined due to high variability.");
529
	stream.println("The variability for each scenario is expressed as a <a href=\"http://en.wikipedia.org/wiki/Coefficient_of_variation\">coefficient\n");
530
	stream.println("of variation</a> (CV). The CV is calculated by dividing the <b>standard deviation\n");
531
	stream.println("of the elapse process time over builds</b> by the <b>average elapsed process\n");
532
	stream.println("time over builds</b> and multiplying by 100.\n");
533
	stream.println("</p><p>High CV values may be indicative of any of the following:<br></p>\n");
534
	stream.println("<ol><li> an unstable performance test. </li>\n");
535
	stream.println("<ul><li>may be evidenced by an erratic elapsed process line graph.<br><br></li></ul>\n");
536
	stream.println("<li>performance regressions or improvements at some time in the course of builds.</li>\n");
537
	stream.println("<ul><li>may be evidenced by plateaus in elapsed process line graphs.<br><br></li></ul>\n");
538
	stream.println("<li>unstable testing hardware.\n");
539
	stream.print("<ul><li>consistent higher CV values for one test configuration as compared to others across");
540
	stream.println(" scenarios may be related to hardward problems.</li></ul></li></ol>\n");
541
	stream.println("<p> Scenarios are listed in alphabetical order in the far right column. A scenario's\n");
542
	stream.println("variation coefficients (CVs) are in columns to the left for baseline and current\n");
543
	stream.println("build streams for each test configuration. Scenarios with CVs > 10% are highlighted\n");
544
	stream.println("in yellow (10%<CV>&lt;CV<20%) and orange(CV>20%). </p>\n");
545
	stream.println("<p> Each CV value links to the scenario's detailed results to allow viewers to\n");
546
	stream.println("investigate the variability.</p>\n");
547
}
548
549
/*
550
 * Print columns titles of the summary table.
551
 */
552
private void printSummaryColumnsTitle(PrintStream stream, PerformanceResults performanceResults) {
553
	String[] configBoxes = performanceResults.getConfigBoxes(true/*sorted*/);
554
	int length = configBoxes.length;
555
	stream.print("<table border=\"1\"><tr><td colspan=\"");
556
	stream.print(length);
557
	stream.print("\"><b>Baseline CVs</b></td><td colspan=\"");
558
	stream.print(length);
559
	stream.println("\"><b>Current Build Stream CVs</b></td><td rowspan=\"2\"><b>Scenario Name</b></td></tr>");
560
	stream.print("<tr>");
561
	for (int n=0; n<2; n++) {
562
		for (int c=0; c<length; c++) {
563
			stream.print("<td>");
564
			stream.print(configBoxes[c]);
565
			stream.print("</td>");
566
		}
437
	}
567
	}
568
	stream.println("</tr>\n");
569
}
438
570
571
/*
572
 * Print a scenario line in the summary table.
573
 */
574
private void printSummaryScenarioLine(int i, String config, ScenarioResults scenarioResults, PrintStream stream) {
575
	ConfigResults configResults = scenarioResults.getConfigResults(config);
576
	if (configResults == null || !configResults.isValid()) {
577
		stream.print("<td>n/a</td>");
578
		return;
579
	}
580
	String url = config + "/" + scenarioResults.getFileName()+".html";
581
	double[] stats = null;
582
	int dim_id = AbstractResults.SUPPORTED_DIMS[0].getId();
583
	if (i==0) { // baseline results
584
		List baselinePrefixes = new ArrayList();
585
		baselinePrefixes.add(this.baselinePrefix);
586
		stats = configResults.getStatistics(baselinePrefixes, dim_id);
587
	} else {
588
		stats = configResults.getStatistics(this.currentBuildPrefixes, dim_id);
589
	}
590
	double variation = stats[3];
591
	if (variation > 10 && variation < 20) {
592
		stream.print("<td bgcolor=\"yellow\">");
593
	} else if (variation >= 20) {
594
		stream.print("<td bgcolor=\"FF9900\">");
595
	} else {
596
		stream.print("<td>");
597
	}
598
	stream.print("<a href=\"");
599
	stream.print(url);
600
	stream.print("\"/>");
601
	stream.print(variation);
602
	stream.print("%</a></td>");
603
}
604
605
/*
606
 * Print usage in case one of the argument of the line was incorrect.
607
 * Note that calling this method ends the program run due to final System.exit()
608
 */
609
private void printUsage() {
610
	System.out.println(
611
		"Usage:\n\n" +
612
		"-baseline\n" +
613
		"	Build id against which to compare results.\n" +
614
		"	Same as value specified for the \"build\" key in the eclipse.perf.config system property.\n\n" +
615
616
		"[-baseline.prefix]\n" +
617
		"	Optional.  Build id prefix used in baseline test builds and reruns.  Used to plot baseline historical data.\n" +
618
		"	A common prefix used for the value of the \"build\" key in the eclipse.perf.config system property when rerunning baseline tests.\n\n" +
619
620
		"-current\n" +
621
		"	build id for which to generate results.  Compared to build id specified in -baseline parameter above.\n" +
622
		"	Same as value specified for the \"build\" key in the eclipse.perf.config system property. \n\n" +
623
624
		"[-current.prefix]\n" +
625
		"	Optional.  Comma separated list of build id prefixes used in current build stream.\n" +
626
		"	Used to plot current build stream historical data.  Defaults to \"N,I\".\n" +
627
		"	Prefixes for values specified for the \"build\" key in the eclipse.perf.config system property. \n\n" +
628
629
		"-jvm\n" +
630
		"	Value specified in \"jvm\" key in eclipse.perf.config system property for current build.\n\n" +
631
632
		"-config\n" +
633
		"	Comma separated list of config names for which to generate results.\n" +
634
		"	Same as values specified in \"config\" key in eclipse.perf.config system property.\n\n" +
635
636
		"-output\n" +
637
		"	Path to default output directory.\n\n" +
638
639
		"[-config.properties]\n" +
640
		"	Optional.  Used by scenario status table to provide the following:\n" +
641
		"		alternate descriptions of config values to use in columns.\n" +
642
		"	The value should be specified in the following format:\n" +
643
		"	name1,description1;name2,description2;etc..\n\n" +
644
645
		"[-highlight]\n" +
646
		"	Optional.  Comma-separated list of build Id prefixes used to find most recent matching for each entry.\n" +
647
		"	Result used to highlight points in line graphs.\n\n" +
648
649
		"[-scenario.pattern]\n" +
650
		"	Optional.  Scenario prefix pattern to query database.  If not specified,\n" +
651
		"	default of % used in query.\n\n" +
652
653
		"[-fingerprints]\n" +
654
		"	Optional.  Use to generate fingerprints only.\n\n" +
655
656
		"[-data]\n" +
657
		"	Optional.  Generates table of scenario reference and current data with line graphs.\n\n" +
658
659
		"[-print]\n" +
660
		"	Optional.  Display output in the console while generating.\n"
661
	);
662
663
	System.exit(1);
664
}
665
666
/**
667
 * Generate the performance results for a specified build regarding to a specific reference.
668
 * This action generates following HTML files:
669
 * <ul>
670
 * <li>A summary table to see the variations for all the concerned scenarii</li>
671
 * <li>A global php file including global scenario fingerprints and links for all concerned components results php files</li>
672
 * <li>A php file for each component including scenario fingerprints and status table with links to a scenario data file</li>
673
 * <li>A data HTML file for each co nfig of each scenario included in status table</li>
674
 * </ul>
675
 * @see org.eclipse.equinox.app.IApplication#start(org.eclipse.equinox.app.IApplicationContext)
676
 */
677
public Object start(IApplicationContext context) throws Exception {
678
679
	// Parse arguments and read DB info
680
	PerformanceResults performanceResults = parse(context.getArguments().get("application.args"));
681
	performanceResults.read(this.configDescriptors, this.scenarioPattern);
682
683
	// Print whole scenarii summary
684
	printSummary(performanceResults);
685
686
	// Copy images and scripts to output dir
687
	Bundle bundle = UiPlugin.getDefault().getBundle();
688
	URL images = bundle.getEntry("images");
689
	URL scripts = bundle.getEntry("scripts");
690
	if (images != null) {
691
		images = FileLocator.resolve(images);
692
		Utils.copyImages(new File(images.getPath()), this.outputDir);
693
	}
694
	if (scripts != null) {
695
		scripts = FileLocator.resolve(scripts);
696
		Utils.copyScripts(new File(scripts.getPath()), this.outputDir);
697
	}
439
698
699
	// Print HTML pages and all linked files
700
	if (this.print) {
701
		System.out.println("Print performance results HTML pages:");
702
		System.out.print("	- all components");
703
	}
704
	long start = System.currentTimeMillis();
705
	printComponent(performanceResults, "global");
706
	Iterator components = performanceResults.getComponents().iterator();
707
	while (components.hasNext()) {
708
		printComponent(performanceResults, (String) components.next());
709
	}
710
	if (this.print) System.out.println("done in "+(System.currentTimeMillis()-start)+"ms");
711
712
	// Print the scenarii data
713
	if (genData || genAll) {
714
		start = System.currentTimeMillis();
715
		if (this.print) System.out.print("	- all scenarii data...");
716
		ScenarioData data = new ScenarioData(this.baselinePrefix, this.pointsOfInterest, this.currentBuildPrefixes, this.outputDir);
717
		try {
718
			data.print(performanceResults);
719
		} catch (Exception ex) {
720
			ex.printStackTrace();
721
		}
722
		if (this.print) System.out.println("done in "+(System.currentTimeMillis()-start)+"ms");
723
	}
724
	return null;
725
}
440
726
727
/* (non-Javadoc)
728
 * @see org.eclipse.equinox.app.IApplication#stop()
729
 */
730
public void stop() {
731
	// Do nothing
732
}
441
}
733
}
(-)src/org/eclipse/test/performance/ui/BarGraph.java (-22 / +19 lines)
Lines 40-53 Link Here
40
	private static class BarItem {
40
	private static class BarItem {
41
41
42
		String title;
42
		String title;
43
		double value;
43
		double value, error;
44
		String url;
44
		String url;
45
		String slowdownExpected;
45
		String slowdownExpected;
46
		boolean significant;
46
		boolean significant;
47
47
48
		BarItem(String t, double v, String u, String slow, boolean sig) {
48
		BarItem(String t, double[] stats, String u, String slow, boolean sig) {
49
			title= t;
49
			title= t;
50
			value= v;
50
			value= -stats[0] * 100;
51
			error = stats[1] * 100;
51
			url= u;
52
			url= u;
52
			slowdownExpected= slow;
53
			slowdownExpected= slow;
53
			significant= sig;
54
			significant= sig;
Lines 62-77 Link Here
62
		fItems= new ArrayList();
63
		fItems= new ArrayList();
63
	}
64
	}
64
65
65
	public void addItem(String name, double value) {
66
	public void addItem(String name, double[] stats, String url, String slow, boolean significant) {
66
		fItems.add(new BarItem(name, value, null, null, true));
67
		fItems.add(new BarItem(name, stats, url, slow, significant));
67
	}
68
69
	public void addItem(String name, double value, String url) {
70
		fItems.add(new BarItem(name, value, url, null, true));
71
	}
72
73
	public void addItem(String name, double value, String url, String slow, boolean significant) {
74
		fItems.add(new BarItem(name, value, url, slow, significant));
75
	}
68
	}
76
69
77
	public int getHeight() {
70
	public int getHeight() {
Lines 195-203 Link Here
195
		for (int i= 0; i < bars.length; i++) {
188
		for (int i= 0; i < bars.length; i++) {
196
189
197
			BarItem bar= bars[i];
190
			BarItem bar= bars[i];
198
			double delta= bar.value;
191
			double delta = bar.value;
192
			double error = bar.error;
199
			double orgDelta= delta;
193
			double orgDelta= delta;
200
194
			
201
			boolean clamped= false;
195
			boolean clamped= false;
202
			if (NO_SCALE) {
196
			if (NO_SCALE) {
203
				if (delta > max) {
197
				if (delta > max) {
Lines 211-225 Link Here
211
205
212
			int barLength= (int) (delta / max * w2);
206
			int barLength= (int) (delta / max * w2);
213
207
214
			if (bar.significant) {
208
			if (delta < 0) {
215
				if (delta > 0.0)
209
				if (bar.slowdownExpected != null) {
216
					gc.setBackground(green);
217
				else if (bar.slowdownExpected == null)
218
					gc.setBackground(red);
219
				else
220
					gc.setBackground(gray);
210
					gc.setBackground(gray);
221
			} else {
211
				} else if (!bar.significant) {
212
					gc.setBackground(yellow);
213
				} else  {
214
					gc.setBackground(red);
215
				}
216
			} else if (!bar.significant) {
222
				gc.setBackground(yellow);
217
				gc.setBackground(yellow);
218
			} else {
219
				gc.setBackground(green);
223
			}
220
			}
224
221
225
			gc.fillRectangle(center, y + (GAP / 2), barLength, BARHEIGHT);
222
			gc.fillRectangle(center, y + (GAP / 2), barLength, BARHEIGHT);
(-)src/org/eclipse/test/performance/ui/TimeLineGraph.java (-26 / +21 lines)
Lines 1-5 Link Here
1
/*******************************************************************************
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2007 IBM Corporation and others.
2
 * Copyright (c) 2004, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
5
 * which accompanies this distribution, and is available at
Lines 10-28 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.test.performance.ui;
11
package org.eclipse.test.performance.ui;
12
12
13
import java.util.ArrayList;
13
import java.util.*;
14
import java.util.Arrays;
15
import java.util.Comparator;
16
import java.util.Enumeration;
17
import java.util.Hashtable;
18
import java.util.List;
19
14
20
import org.eclipse.swt.graphics.Color;
15
import org.eclipse.swt.graphics.Color;
21
import org.eclipse.swt.graphics.GC;
16
import org.eclipse.swt.graphics.GC;
22
import org.eclipse.swt.graphics.Image;
17
import org.eclipse.swt.graphics.Image;
23
import org.eclipse.swt.graphics.Point;
18
import org.eclipse.swt.graphics.Point;
24
import org.eclipse.swt.graphics.Rectangle;
19
import org.eclipse.swt.graphics.Rectangle;
25
26
import org.eclipse.test.internal.performance.data.Dim;
20
import org.eclipse.test.internal.performance.data.Dim;
27
21
28
public class TimeLineGraph extends LineGraph{
22
public class TimeLineGraph extends LineGraph{
Lines 85-92 Link Here
85
        Comparator comparator=new TimeLineGraphItem.GraphItemComparator();
79
        Comparator comparator=new TimeLineGraphItem.GraphItemComparator();
86
 
80
 
87
        while (_enum.hasMoreElements()) {
81
        while (_enum.hasMoreElements()) {
88
 			List fItems = (List) _enum.nextElement();
82
 			List items = (List) _enum.nextElement();
89
			Object[] fItemsArray=fItems.toArray();
83
			Object[] fItemsArray=items.toArray();
90
			Arrays.sort(fItemsArray,comparator);
84
			Arrays.sort(fItemsArray,comparator);
91
			int lastx = 0;
85
			int lastx = 0;
92
			int lasty = 0;
86
			int lasty = 0;
Lines 161-172 Link Here
161
	}
155
	}
162
156
163
    public void addItem(String groupName,String name, String description, double value, Color col, boolean display, long timestamp,boolean isSpecial,boolean drawBaseline) {
157
    public void addItem(String groupName,String name, String description, double value, Color col, boolean display, long timestamp,boolean isSpecial,boolean drawBaseline) {
164
      	List fItems = (List) fItemGroups.get(groupName);
158
      	List items = (List) fItemGroups.get(groupName);
165
  		if (fItemGroups.get(groupName) == null) {
159
  		if (fItemGroups.get(groupName) == null) {
166
  			fItems=new ArrayList();
160
  			items=new ArrayList();
167
  			fItemGroups.put(groupName, fItems);
161
  			fItemGroups.put(groupName, items);
168
  		}
162
  		}
169
  		fItems.add(new TimeLineGraphItem(name, description, value, col, display,
163
  		items.add(new TimeLineGraphItem(name, description, value, col, display,
170
  				timestamp,isSpecial,drawBaseline));
164
  				timestamp,isSpecial,drawBaseline));
171
    }
165
    }
172
     
166
     
Lines 174-182 Link Here
174
    	Enumeration _enum=fItemGroups.elements();
168
    	Enumeration _enum=fItemGroups.elements();
175
        double maxItem= 0;
169
        double maxItem= 0;
176
    	while (_enum.hasMoreElements()) {
170
    	while (_enum.hasMoreElements()) {
177
			List fItems = (List) _enum.nextElement();
171
			List items = (List) _enum.nextElement();
178
			for (int i = 0; i < fItems.size(); i++) {
172
			for (int i = 0; i < items.size(); i++) {
179
				TimeLineGraphItem graphItem = (TimeLineGraphItem) fItems.get(i);
173
				TimeLineGraphItem graphItem = (TimeLineGraphItem) items.get(i);
180
				if (graphItem.value > maxItem)
174
				if (graphItem.value > maxItem)
181
					maxItem = graphItem.value;
175
					maxItem = graphItem.value;
182
			}
176
			}
Lines 191-199 Link Here
191
		double minItem = getMaxItem();
185
		double minItem = getMaxItem();
192
186
193
		while (_enum.hasMoreElements()) {
187
		while (_enum.hasMoreElements()) {
194
			List fItems = (List) _enum.nextElement();
188
			List items = (List) _enum.nextElement();
195
			for (int i = 0; i < fItems.size(); i++) {
189
			for (int i = 0; i < items.size(); i++) {
196
				TimeLineGraphItem graphItem = (TimeLineGraphItem) fItems.get(i);
190
				TimeLineGraphItem graphItem = (TimeLineGraphItem) items.get(i);
197
				if (graphItem.value < minItem)
191
				if (graphItem.value < minItem)
198
					minItem = graphItem.value;
192
					minItem = graphItem.value;
199
			}
193
			}
Lines 209-223 Link Here
209
		TimeLineGraphItem mostRecentItem = null;
203
		TimeLineGraphItem mostRecentItem = null;
210
204
211
		while (_enum.hasMoreElements()) {
205
		while (_enum.hasMoreElements()) {
212
			List fItems = (List) _enum.nextElement();
206
			List items = (List) _enum.nextElement();
213
			for (int i = 0; i < fItems.size(); i++) {
207
			for (int i = 0; i < items.size(); i++) {
214
				if (fItems.size() == 1)
208
				if (items.size() == 1)
215
					return (TimeLineGraphItem) fItems.get(i);
209
					return (TimeLineGraphItem) items.get(i);
216
				else {
210
				else {
217
					TimeLineGraphItem graphItem = (TimeLineGraphItem) fItems.get(i);
211
					TimeLineGraphItem graphItem = (TimeLineGraphItem) items.get(i);
218
					if (graphItem.timestamp > mostRecentTimestamp) {
212
					if (graphItem.timestamp > mostRecentTimestamp) {
219
						mostRecentTimestamp = graphItem.timestamp;
213
						mostRecentTimestamp = graphItem.timestamp;
220
						mostRecentItem = (TimeLineGraphItem) fItems.get(i);
214
						mostRecentItem = (TimeLineGraphItem) items.get(i);
221
					}
215
					}
222
				}
216
				}
223
			}
217
			}
Lines 238-243 Link Here
238
		int n = mainGroup.size();
232
		int n = mainGroup.size();
239
		int xIncrement=width/n;
233
		int xIncrement=width/n;
240
		double max=getMaxItem()*1.2;
234
		double max=getMaxItem()*1.2;
235
//		double min=getMinItem()*0.8;
241
236
242
		for (int i = 0; i < n; i++) {
237
		for (int i = 0; i < n; i++) {
243
			TimeLineGraphItem thisItem = (TimeLineGraphItem) fItemsArray[i];
238
			TimeLineGraphItem thisItem = (TimeLineGraphItem) fItemsArray[i];
(-)src/org/eclipse/test/performance/ui/Utils.java (-597 / +29 lines)
Lines 10-52 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.test.performance.ui;
11
package org.eclipse.test.performance.ui;
12
12
13
import java.io.BufferedOutputStream;
14
import java.io.File;
13
import java.io.File;
15
import java.io.FileInputStream;
14
import java.io.FileInputStream;
16
import java.io.FileNotFoundException;
15
import java.io.FileNotFoundException;
17
import java.io.FileOutputStream;
16
import java.io.FileOutputStream;
18
import java.io.FileWriter;
19
import java.io.IOException;
17
import java.io.IOException;
20
import java.io.InputStream;
18
import java.io.InputStream;
21
import java.io.OutputStream;
19
import java.io.OutputStream;
22
import java.io.PrintWriter;
23
import java.text.DecimalFormat;
20
import java.text.DecimalFormat;
24
import java.text.NumberFormat;
21
import java.text.NumberFormat;
25
import java.util.ArrayList;
26
import java.util.Arrays;
22
import java.util.Arrays;
27
import java.util.Calendar;
23
import java.util.Calendar;
28
import java.util.HashMap;
24
import java.util.HashMap;
29
import java.util.Hashtable;
30
import java.util.StringTokenizer;
31
25
32
import junit.framework.AssertionFailedError;
33
34
import org.eclipse.swt.SWT;
35
import org.eclipse.swt.graphics.Color;
36
import org.eclipse.swt.graphics.Image;
26
import org.eclipse.swt.graphics.Image;
37
import org.eclipse.swt.graphics.ImageData;
27
import org.eclipse.swt.graphics.ImageData;
38
import org.eclipse.swt.graphics.ImageLoader;
39
import org.eclipse.swt.graphics.PaletteData;
28
import org.eclipse.swt.graphics.PaletteData;
40
import org.eclipse.swt.graphics.RGB;
29
import org.eclipse.swt.graphics.RGB;
41
import org.eclipse.swt.widgets.Display;
42
import org.eclipse.test.internal.performance.PerformanceTestPlugin;
30
import org.eclipse.test.internal.performance.PerformanceTestPlugin;
43
import org.eclipse.test.internal.performance.data.Dim;
44
import org.eclipse.test.internal.performance.db.DB;
45
import org.eclipse.test.internal.performance.db.Scenario;
46
import org.eclipse.test.internal.performance.db.SummaryEntry;
47
import org.eclipse.test.internal.performance.db.TimeSeries;
48
import org.eclipse.test.internal.performance.db.Variations;
31
import org.eclipse.test.internal.performance.db.Variations;
49
import org.eclipse.test.performance.Dimension;
50
32
51
33
52
public class Utils {
34
public class Utils {
Lines 79-147 Link Here
79
	public final static int OK = 0;
61
	public final static int OK = 0;
80
	public final static int NAN = 0x1;
62
	public final static int NAN = 0x1;
81
	public final static int ERR = 0x2;
63
	public final static int ERR = 0x2;
82
	public final static int DEV = 0x4;
83
84
	/**
85
	 * @param dimension
86
	 * @return A description of the dimension.
87
	 */
88
	public static String getDimensionDescription(String dimension) {
89
		/* Descriptions of dimensions */
90
		// Windows and Linux
91
		Hashtable descriptions = new Hashtable();
92
		descriptions.put("cpu time", "Amount of time the process ran on the CPU.");
93
94
		descriptions.put("kernel time", "Amount of time the process ran on the CPU, while the CPU was in kernel mode.");
95
		descriptions.put("used java heap", "Change in the amount of memory allocated for Java objects.");
96
		descriptions.put("working set", "Change in the amount of physical memory used by the process (other data resides in swap space).");
97
98
		// Linux
99
		descriptions.put("data size", "Change in the process' data and stack memory size.");
100
		descriptions.put("hard page faults", "Number of memory pages that were loaded from swap space on disk.");
101
		descriptions.put("library size", "Change in the process' library memory size.");
102
		descriptions.put("soft page faults",
103
				"Number of memory pages that were loaded from memory (i.e., they were not mapped in the process' page table, but already present in memory for some reason).");
104
		descriptions.put("text size", "Change in the process' code memory size, useful with start-up tests.");
105
106
		// Windows
107
		descriptions.put("committed", "Change in the amount of allocated memory (both, in physical memory and swap space, can be preallocated for future use).");
108
		descriptions.put("elapsed process", "Amount of wall-clock time.");
109
		descriptions.put("gdi objects", "Change in the number of GDI (Graphics Device Interface) objects, can be useful for UI tests (particularly start-up tests).");
110
		descriptions
111
				.put(
112
						"page faults",
113
						"Number of memory pages that were loaded from swap space on disk or from memory (i.e., in the latter case, they were not mapped in the process' page table, but already present in memory for some reason).");
114
		descriptions.put("system time", "* no longer measured, same as elapsed time, see PerformanceMonitor *");
115
		descriptions.put("working set peak", "Increase of the maximum working set size, useful with start-up tests.");
116
117
		if (descriptions.get(dimension.toLowerCase()) != null)
118
			return descriptions.get(dimension.toLowerCase()).toString();
119
		return "";
120
	}
121
122
	/**
123
	 * @param timeSeriesLabels -
124
	 *            an array of build ID's with results for a scenario.
125
	 * @param current -
126
	 *            the current build ID
127
	 * @return Build Id's of Nightly builds preceding current.
128
	 */
129
	public static ArrayList lastSevenNightlyBuildNames(String[] timeSeriesLabels, String current) {
130
		int currentIndex = getBuildNameIndex(timeSeriesLabels, current);
131
		ArrayList labels = new ArrayList();
132
		int j = 6;
133
134
		for (int i = timeSeriesLabels.length - 1; i > -1; i--) {
135
			if (j == -1)
136
				break;
137
			String timeSeriesLabel = timeSeriesLabels[i];
138
			if (timeSeriesLabel.startsWith("N") && i < currentIndex) {
139
				labels.add(timeSeriesLabel);
140
				j--;
141
			}
142
		}
143
		return labels;
144
	}
145
64
146
	/**
65
	/**
147
	 * Return &lt;html&gt;&lt;head&gt;&lt;meta http-equiv="Content-Type"
66
	 * Return &lt;html&gt;&lt;head&gt;&lt;meta http-equiv="Content-Type"
Lines 167-241 Link Here
167
			+ ".indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}\n" + "</style>";
86
			+ ".indexsub { font-size: xx-small;; font-family: Arial, Helvetica, sans-serif; color: #8080FF}\n" + "</style>";
168
87
169
	/**
88
	/**
170
	 * An utility object which stores a name, description, url and optional
171
	 * output directory.
172
	 */
173
	public static class ConfigDescriptor {
174
		String name;
175
		String description;
176
177
		/**
178
		 *
179
		 * @param name
180
		 *            the value specifed for the key config in the
181
		 *            eclipse.perf.config system.property key value listings.
182
		 *            ie. relengbuildwin2 (machine name)
183
		 * @param description
184
		 *            a meaningful description to further describe the config.
185
		 *            ie. win32-win32-x86 Sun 1.4.2_06
186
		 */
187
		public ConfigDescriptor(String name, String description) {
188
			this.name = name;
189
			this.description = description;
190
		}
191
192
		public String getName() {
193
			return name;
194
		}
195
196
		public boolean descriptionMatches(String descr) {
197
			return descr.equals(this.description);
198
		}
199
	}
200
201
	/**
202
	 * @param configDescriptors
203
	 *            A semi-colon separated listing of config descriptions.<br>
204
	 *            Uses the following format: name,description,
205
	 *            url,outputdir;name2, description2,url2,output2;etc..
206
	 * @return a mapping of config names to their ConfigDescriptors.
207
	 */
208
	public static Hashtable getConfigDescriptors(String configDescriptors) {
209
		// labelMappings in pairs separated by semi-colon ie.
210
		// relengbuildwin2,win32-win32-x86;trelenggtk,linux-gtk-x86
211
		StringTokenizer tokenizer = new StringTokenizer(configDescriptors, ";");
212
		Hashtable configMap = new Hashtable();
213
214
		while (tokenizer.hasMoreTokens()) {
215
			String labelDescriptor = tokenizer.nextToken();
216
			String[] elements = labelDescriptor.trim().split(",");
217
			ConfigDescriptor descriptor = new ConfigDescriptor(elements[0], elements[1]);
218
			configMap.put(elements[0], descriptor);
219
		}
220
		return configMap;
221
	}
222
223
	/**
224
	 * Queries database with variation composed of buildIdPattern, config and
225
	 * jvm.
226
	 *
227
	 * @return Array of scenarios.
228
	 */
229
	public static Scenario[] getScenarios(String buildIdPattern, String scenarioPattern, String config, String jvm) {
230
		Dim[] qd = null;
231
		if (scenarioPattern == null)
232
			scenarioPattern = "";
233
234
		Variations variations = getVariations(buildIdPattern, config, jvm);
235
		return DB.queryScenarios(variations, scenarioPattern + "%", PerformanceTestPlugin.BUILD, qd);
236
	}
237
238
	/**
239
	 * Creates a Variations object using build id pattern, config and jvm.
89
	 * Creates a Variations object using build id pattern, config and jvm.
240
	 *
90
	 *
241
	 * @param buildIdPattern
91
	 * @param buildIdPattern
Lines 252-301 Link Here
252
	}
102
	}
253
103
254
	/**
104
	/**
255
	 * @param scenarios
256
	 * @return list of unique component names derived from prefixes to scenario
257
	 *         names.
258
	 */
259
	public static ArrayList getComponentNames(Scenario[] scenarios) {
260
		ArrayList componentNames = new ArrayList();
261
262
		for (int i = 0; i < scenarios.length; i++) {
263
			String prefix = null;
264
			Scenario scenario = scenarios[i];
265
			String scenarioName = scenario.getScenarioName();
266
267
			// use part of scenario name prior to .test to identify component
268
			if (scenarioName.indexOf(".test") != -1) {
269
				prefix = scenarioName.substring(0, scenarioName.indexOf(".test"));
270
				if (!componentNames.contains(prefix))
271
					componentNames.add(prefix);
272
			}
273
		}
274
		return componentNames;
275
	}
276
277
	/*
278
	 * @param fp -
279
	 *            a FingerPrint object
280
	 * @return - an html representation of the fingerprint.
281
	 *
282
	public static String getImageMap(FingerPrint fp) {
283
		String componentDescription = fp.configDescriptor.description;
284
		String areas = fp.bar.getAreas();
285
		if (areas == null)
286
			areas = "";
287
		String output = "";
288
		if (new File(fp.outputDirectory, fp.getOutName() + ".gif").exists()) {
289
			output = "<h4>" + componentDescription + "</h4>";
290
			output = output.concat("<img src=\"" + fp.getOutName() + ".gif\" usemap=\"#" + fp.outName + "\">" + "<map name=\"" + fp.getOutName() + "\">" + areas + "</map>\n");
291
		} else {
292
			output = output.concat("<br><br>There is no fingerprint for " + componentDescription + "<br><br>\n");
293
		}
294
		return output;
295
	}
296
	*/
297
298
	/**
299
	 * Utility method to copy a file.
105
	 * Utility method to copy a file.
300
	 *
106
	 *
301
	 * @param src the source file.
107
	 * @param src the source file.
Lines 334-508 Link Here
334
	}
140
	}
335
141
336
	/**
142
	/**
337
	 * Returns a LineGraph object representing measurements for a scenario over
338
	 * builds.
339
	 *
340
	 * @param t -
341
	 *            the scenario object.
342
	 * @param dimensionName -
343
	 *            the name of the measurement for which to generate graph.
344
	 * @param baseline -
345
	 *            the reference build to label.
346
	 * @param current -
347
	 *            the current build to label.
348
	 * @param pointsOfInterest -
349
	 *            an array of buildIds. Points for these are highlighted on
350
	 *            graph.
351
	 * @return a LineGraph object.
352
	 */
353
	public static TimeLineGraph getLineGraph(Scenario t, String dimensionName, String baseline, String baselinePrefix, String current, ArrayList pointsOfInterest,ArrayList currentBuildIdPrefixes) {
354
		Display display = Display.getDefault();
355
356
		Color black = display.getSystemColor(SWT.COLOR_BLACK);
357
		Color yellow = display.getSystemColor(SWT.COLOR_DARK_YELLOW);
358
		Color magenta = display.getSystemColor(SWT.COLOR_MAGENTA);
359
360
		String scenarioName = t.getScenarioName();
361
		Dim[] dimensions = t.getDimensions();
362
		Dim dim = null;
363
		for (int i = 0; i < dimensions.length; i++) {
364
			if (dimensions[i].getName().equals(dimensionName))
365
				dim = dimensions[i];
366
		}
367
368
		TimeLineGraph graph = new TimeLineGraph(scenarioName + ": " + dimensionName, dim);
369
		TimeSeries ts = null;
370
		try {
371
			ts = t.getTimeSeries(dim);
372
			int n = ts.getLength();
373
374
			if (n > 0) {
375
				boolean currentFound=false;
376
				for (int j = 0; j < n; j++) {
377
					String buildID = ts.getLabel(j);
378
					int underscoreIndex = buildID.indexOf('_');
379
					String label = (underscoreIndex != -1 && (buildID.equals(baseline) || buildID.equals(current))) ? buildID.substring(0, underscoreIndex) : buildID;
380
381
					double value = ts.getValue(j);
382
383
					if (buildID.equals(current)) {
384
						Color color = black;
385
						if (buildID.startsWith("N"))
386
							color = yellow;
387
388
						graph.addItem("main", label, dim.getDisplayValue(value), value, color, true, getDateFromBuildID(buildID), true);
389
						continue;
390
					}
391
					if (pointsOfInterest.contains(buildID)&&!currentFound) {
392
						graph.addItem("main", label, dim.getDisplayValue(value), value, black, false, getDateFromBuildID(buildID, false), true);
393
						continue;
394
					}
395
					if (buildID.equals(baseline)) {
396
						boolean drawBaseline = (baselinePrefix != null) ? false : true;
397
						graph.addItem("reference", label, dim.getDisplayValue(value), value, magenta, true, getDateFromBuildID(buildID, true), true, drawBaseline);
398
						continue;
399
					}
400
					if (baselinePrefix != null) {
401
						if (buildID.startsWith(baselinePrefix) && !buildID.equals(baseline) && getDateFromBuildID(buildID, true) <= getDateFromBuildID(baseline, true)) {
402
							graph.addItem("reference", label, dim.getDisplayValue(value), value, magenta, false, getDateFromBuildID(buildID, true), false);
403
							continue;
404
						}
405
					}
406
					if (lastSevenNightlyBuildNames(t.getTimeSeriesLabels(), current).contains(buildID)) {
407
						graph.addItem("main", buildID, dim.getDisplayValue(value), value, yellow, false, getDateFromBuildID(buildID), false);
408
						continue;
409
					} else if (buildID.startsWith("N"))
410
							continue;
411
412
					for (int i=0;i<currentBuildIdPrefixes.size();i++){
413
						if (buildID.startsWith(currentBuildIdPrefixes.get(i).toString())&&!currentFound) {
414
							graph.addItem("main", buildID, dim.getDisplayValue(value), value, black, false, getDateFromBuildID(buildID), false);
415
							continue;
416
						}
417
					}
418
				}
419
			}
420
		} catch (AssertionFailedError e) {
421
			// System.err.println("Unable to get result for:
422
			// "+t.getScenarioName()+" "+ts.toString());
423
		}
424
		return graph;
425
	}
426
427
	/**
428
	 * Prints a LineGraph object as a gif
429
	 *
430
	 * @param p -
431
	 *            the LineGraph object.
432
	 * @param output -
433
	 *            the output file path.
434
	 */
435
	public static void printLineGraphGif(LineGraph p, String output) {
436
		File outputFile = new File(output);
437
		outputFile.getParentFile().mkdir();
438
		int GRAPH_WIDTH = 600;
439
		int GRAPH_HEIGHT = 200;
440
		Image image = new Image(Display.getDefault(), GRAPH_WIDTH, GRAPH_HEIGHT);
441
		p.paint(image);
442
443
		/* Downscale to 8 bit depth palette to save to gif */
444
		ImageData data = downSample(image);
445
		ImageLoader il = new ImageLoader();
446
		il.data = new ImageData[] { data };
447
		OutputStream out = null;
448
		try {
449
			out = new BufferedOutputStream(new FileOutputStream(output));
450
			il.save(out, SWT.IMAGE_GIF);
451
452
		} catch (FileNotFoundException e) {
453
			e.printStackTrace();
454
		} finally {
455
			image.dispose();
456
			if (out != null) {
457
				try {
458
					out.close();
459
				} catch (IOException e1) {
460
					// silently ignored
461
				}
462
			}
463
		}
464
	}
465
466
	/**
467
	 * Utility method which returns HTML code representing an image map for a
468
	 * LineGraph object.
469
	 *
470
	 * @param p -
471
	 *            the LineGraph object.
472
	 * @param imageSource -
473
	 *            the path to insert for the src attribute to <img>.
474
	 */
475
	public static String getImageMap(LineGraph p, String imageSource, String rawDataFileLink) {
476
		String result = "";
477
		String areas = p.getAreas();
478
479
		result = result.concat("<img" + " src=\"" + imageSource + "\" usemap=\"#" + p.fTitle + "\">");
480
		result = result.concat("<map name=\"" + p.fTitle + "\">");
481
		result = result.concat(areas);
482
		result = result.concat("</map>\n");
483
484
		return result;
485
	}
486
487
	/**
488
	 * A utility which returns the index of a given buildId in an array.
489
	 *
490
	 * @param timeSeriesLabels -
491
	 *            array of buildIds
492
	 * @param buildId -
493
	 *            the buildId for which to find return value.
494
	 * @return The index of the buildID in the array.
495
	 */
496
	public static int getBuildNameIndex(String[] timeSeriesLabels, String buildId) {
497
		for (int i = timeSeriesLabels.length - 1; i > -1; i--) {
498
			String timeSeriesLabel = timeSeriesLabels[i];
499
			if (timeSeriesLabel.startsWith(buildId))
500
				return i;
501
		}
502
		return -1;
503
	}
504
505
	/**
506
	 * Downsample Image to 8 bit depth format so that the resulting image data
143
	 * Downsample Image to 8 bit depth format so that the resulting image data
507
	 * can be saved to GIF. Note. If the source image contains photo quality
144
	 * can be saved to GIF. Note. If the source image contains photo quality
508
	 * content with more than 256 colours, resulting data will look very poor.
145
	 * content with more than 256 colours, resulting data will look very poor.
Lines 646-786 Link Here
646
283
647
		return -1;
284
		return -1;
648
	}
285
	}
649
	public static void printVariabilityTable(Hashtable rawDataTables, String outputFile, String[] configList) {
286
	
650
		Hashtable configs=new Hashtable();
287
	/**
651
		for (int i=0;i<configList.length;i++){
288
	 * Returns a message corresponding to given statistics.
652
			String configName=configList[i];
289
	 * 
653
			ConfigDescriptor cd=new ConfigDescriptor(configName,configName);
290
	 * @param resultStats The value with its standard error
654
			configs.put(configName,cd);
291
	 * @param full
655
		}
292
	 * @return The failure message. May be empty if stats are good...
656
		printVariabilityTable(rawDataTables,outputFile,configs);
293
	 */
657
	}
658
659
	public static void printVariabilityTable(Hashtable rawDataTables, String outputFile, Hashtable configDescriptors) {
660
		String[] scenarios = (String[]) rawDataTables.keySet().toArray(new String[rawDataTables.size()]);
661
		if (scenarios.length==0)
662
			return;
663
		Arrays.sort(scenarios);
664
		PrintWriter out=null;
665
		try {
666
			out = new PrintWriter(new FileWriter(new File(outputFile)));
667
			out.println(HTML_OPEN + "</head><body>\n");
668
			out.println("<h3>Summary of Elapsed Process Variation Coefficients</h3>\n"+
669
		"<p> This table provides a bird's eye view of variability in elapsed process times\n"+
670
		  "for baseline and current build stream performance scenarios." +
671
		  " This summary is provided to facilitate the identification of scenarios that should be examined due to high variability." +
672
		  "The variability for each scenario is expressed as a <a href=\"http://en.wikipedia.org/wiki/Coefficient_of_variation\">coefficient\n"+
673
		  "of variation</a> (CV). The CV is calculated by dividing the <b>standard deviation\n"+
674
		  "of the elapse process time over builds</b> by the <b>average elapsed process\n"+
675
		  "time over builds</b> and multiplying by 100.\n"+
676
		"</p><p>High CV values may be indicative of any of the following:<br></p>\n"+
677
		"<ol><li> an unstable performance test. </li>\n"+
678
		  "<ul><li>may be evidenced by an erratic elapsed process line graph.<br><br></li></ul>\n"+
679
		  "<li>performance regressions or improvements at some time in the course of builds.</li>\n"+
680
		  "<ul><li>may be evidenced by plateaus in elapsed process line graphs.<br><br></li></ul>\n"+
681
		  "<li>unstable testing hardware.\n" +
682
		  "<ul><li>consistent higher CV values for one test configuration as compared to others across" +
683
		  " scenarios may be related to hardward problems.</li></ul></li></ol>\n"+
684
		"<p> Scenarios are listed in alphabetical order in the far right column. A scenario's\n"+
685
		  "variation coefficients (CVs) are in columns to the left for baseline and current\n"+
686
		  "build streams for each test configuration. Scenarios with CVs > 10% are highlighted\n"+
687
		  "in yellow (10%<CV>&lt;CV<20%) and orange(CV>20%). </p>\n"+
688
		"<p> Each CV value links to the scenario's detailed results to allow viewers to\n"+
689
		  "investigate the variability.</p>\n");
690
691
			Hashtable cvTable = (Hashtable) rawDataTables.get(scenarios[0]);
692
			String[] configNames = (String[]) cvTable.keySet().toArray(new String[cvTable.size()]);
693
			Arrays.sort(configNames);
694
695
696
		  	int configColumns=configNames.length/2;
697
			out.println("<table border=\"1\"><tr>" +
698
					    "<td colspan=\""+configColumns+"\"><b>Baseline CVs</b></td>"+
699
					    "<td colspan=\""+configColumns+"\"><b>Current Build Stream CVs</b></td>"+
700
					    "<td rowspan=\"2\"><b>Scenario Name</b></td>"+
701
					    "</tr><tr>");
702
703
704
			for (int i = 0; i < configNames.length; i++) {
705
				//configNames here have prefix cConfig- or bConfig- depending on whether the data comes from
706
				//current build stream data or baseline data.
707
				out.print("<td>" + ((ConfigDescriptor)configDescriptors.get(configNames[i].substring(8))).description + "</td>");
708
			}
709
			out.println("</tr><tr>\n");
710
711
			for (int i = 0; i < scenarios.length; i++) {
712
				Hashtable aCvTable = (Hashtable) rawDataTables.get(scenarios[i]);
713
				String scenario = scenarios[i];
714
				String scenarioFile=scenario.replace('#', '.').replace(':', '_').replace('\\', '_')+".html";
715
716
				for (int j = 0; j < configNames.length; j++) {
717
					String url=configNames[j].substring(8)+"/"+scenarioFile;
718
					if (aCvTable.get(configNames[j]) == null) {
719
						out.print("<td>n/a</td>");
720
						continue;
721
					}
722
					String displayValue = aCvTable.get(configNames[j]).toString();
723
					if (displayValue==null){
724
						out.print("<td>n/a</td>");
725
						continue;
726
					}
727
					try {
728
						double value = Double.parseDouble(displayValue.substring(0, displayValue.length() - 1));
729
						if (value > 10 && value < 20)
730
							out.print("<td bgcolor=\"yellow\"><a href=\""+url+"\"/>" + displayValue + "</a></td>");
731
						else if (value >= 20)
732
							out.print("<td bgcolor=\"FF9900\"><a href=\""+url+"\">" + displayValue + "</a></td>");
733
						else
734
							out.print("<td><a href=\""+url+"\">" + displayValue + "</a></td>");
735
					} catch (NumberFormatException e) {
736
						e.printStackTrace();
737
						out.print("<td>n/a</td>");
738
					}
739
				}
740
				out.println("<td>" + scenario + "</td>");
741
				out.println("</tr>\n");
742
			}
743
		} catch (Exception e) {
744
			e.printStackTrace();
745
		}finally{
746
			out.println("</table></body></html>");
747
			out.flush();
748
			out.close();
749
		}
750
	}
751
752
    public static double[] resultsStatistics(TimeSeries timeSeries) {
753
    	try {
754
	    	double valueRef = timeSeries.getValue(0), value = timeSeries.getValue(1);
755
	    	long countRef = timeSeries.getCount(0), count = timeSeries.getCount(1);
756
	    	double stddevRef = timeSeries.getStddev(0), stddev = timeSeries.getStddev(1);
757
	    	double stderr = (countRef == 1 || count == 1)
758
    			? Double.NaN
759
				: (Double.isNaN(stddevRef)
760
					? Math.sqrt((stddev * stddev / count)) / valueRef
761
					: Math.sqrt((stddevRef * stddevRef / countRef) + (stddev * stddev / count)) / valueRef);
762
			return new double[] {
763
				(value - valueRef) / valueRef,
764
				stderr,
765
			};
766
    	}
767
    	catch (ArrayIndexOutOfBoundsException aioobe) {
768
    		return null;
769
    	}
770
	}
771
772
	public static boolean hasConfidentResult(TimeSeries timeSeries) {
773
	    double[] resultStats = resultsStatistics(timeSeries);
774
	    return (confidenceLevel(resultStats) & ERR) == 0;
775
    }
776
	public static String failureMessage(Variations variations, String scenarioName, String baseline, String config) {
777
		String current = (String) variations.get(PerformanceTestPlugin.BUILD);
778
		Dim significanceDimension = (Dim) Dimension.ELAPSED_PROCESS;
779
		Scenario newScenario= DB.getScenarioSeries(scenarioName, variations, PerformanceTestPlugin.BUILD, baseline, current, new Dim[] { significanceDimension });
780
        TimeSeries timeSeries = newScenario.getTimeSeries(significanceDimension);
781
        double[] results = resultsStatistics(timeSeries);
782
		return failureMessage(results, true);
783
	}
784
	public static String failureMessage(double[] resultStats, boolean full) {
294
	public static String failureMessage(double[] resultStats, boolean full) {
785
		StringBuffer buffer = new StringBuffer();
295
		StringBuffer buffer = new StringBuffer();
786
		int level = confidenceLevel(resultStats);
296
		int level = confidenceLevel(resultStats);
Lines 816-821 Link Here
816
		}
326
		}
817
		return buffer.toString();
327
		return buffer.toString();
818
	}
328
	}
329
	
330
	/**
331
	 * Returns the confidence level for given statistics:
332
	 * <ul>
333
	 * <li>{@link #NAN}: if the value is infinite or not a number</li>
334
	 * <li>{@link #ERR}: if the standard error is over the expected threshold ({@link #STANDARD_ERROR_THRESHOLD})</li>
335
	 * <li>{@link #OK}: in all other cases</li>
336
	 * </ul>
337
	 * 
338
	 * @param resultStats array of 2 doubles, the former is the average value and
339
	 * 	the latter is the standard error made while computing the average.
340
	 * @return a value telling caller the level of confidence of the provided value
341
	 */
819
	public static int confidenceLevel(double[] resultStats) {
342
	public static int confidenceLevel(double[] resultStats) {
820
		int level = OK;
343
		int level = OK;
821
 		if (resultStats != null){
344
 		if (resultStats != null){
Lines 832-869 Link Here
832
 		}
355
 		}
833
		return level;
356
		return level;
834
	}
357
	}
835
	public static boolean matchPattern(String name, String pattern) {
836
		if (pattern.equals("%")) return true;
837
		if (pattern.indexOf('%') >= 0 || pattern.indexOf('_') >= 0) {
838
			StringTokenizer tokenizer = new StringTokenizer(pattern, "%_", true);
839
			int start = 0;
840
			String previous = "";
841
			while (tokenizer.hasMoreTokens()) {
842
				String token = tokenizer.nextToken();
843
				if (!token.equals("%") && !token.equals("_")) {
844
					if (previous.equals("%")) {
845
						int idx = name.substring(start).indexOf(token);
846
						if (idx < 0) return false;
847
						start += idx;
848
					} else if (previous.equals("_")) {
849
						if (!name.substring(++start).startsWith(token)) return false;
850
					}
851
					start += token.length();
852
				}
853
				previous = token;
854
			}
855
			if (previous.equals("%")) {
856
				return true;
857
			} else if (previous.equals("_")) {
858
				return name.length() == start;
859
			}
860
			return name.endsWith(previous);
861
		}
862
		return name.equals(pattern);
863
	}
864
358
865
	public static String getImage(int confidence, boolean hasExplanation) {
359
	/**
866
	    boolean scenarioFailed = (confidence & DEV) != 0;
360
	 * Get an icon image corresponding to a given level of confidence and explanation.
361
	 * 
362
	 * @param confidence the confiden level
363
	 * @param hasExplanation flags indicates whether the confidence may be tempered by an explanation
364
	 * @return Corresponding image
365
	 */
366
	public static String getImage(int confidence, boolean scenarioFailed, boolean hasExplanation) {
867
	    String image = null;
367
	    String image = null;
868
368
869
	    if (scenarioFailed) {
369
	    if (scenarioFailed) {
Lines 884-955 Link Here
884
	    return image;
384
	    return image;
885
    }
385
    }
886
386
887
	public static boolean hasSummary(SummaryEntry[] summaries, String scenarioName) {
888
		int length = summaries == null ? 0 : summaries.length;
889
		for (int i=0; i<length; i++) {
890
			SummaryEntry summary = summaries[i];
891
			if (summary.scenarioName.equals(scenarioName)) {
892
				return true;
893
			}
894
		}
895
		return false;
896
	}
897
898
	public static String getScenarioShortName(String scenarioName, int max) {
899
900
		// Remove class name qualification
901
		int testSeparator = scenarioName.indexOf('#');
902
		boolean hasClassName = testSeparator >= 0;
903
		if (!hasClassName) {
904
			testSeparator = scenarioName.lastIndexOf('.');
905
			if (testSeparator <= 0) {
906
				if (max > 0 && scenarioName.length() > max) {
907
					return "*"+scenarioName.substring(0, max);
908
				}
909
				return scenarioName;
910
			}
911
		}
912
		int classSeparator = scenarioName.substring(0, testSeparator).lastIndexOf('.');
913
		if (classSeparator < 0) {
914
			if (max > 0 && scenarioName.length() > max) {
915
				return "*"+scenarioName.substring(0, max);
916
			}
917
			return scenarioName;
918
		}
919
		int length = scenarioName.length();
920
		String shortName = scenarioName.substring(classSeparator+1, length);
921
		if (!hasClassName && shortName.startsWith("test.")) { // specific case for swt...
922
			shortName = shortName.substring(5);
923
		}
924
925
		// Remove qualification from test name
926
		StringTokenizer tokenizer = new StringTokenizer(shortName, " :,", true);
927
		StringBuffer buffer = new StringBuffer(tokenizer.nextToken());
928
		while (tokenizer.hasMoreTokens()) {
929
			String token = tokenizer.nextToken();
930
			char fc = token.charAt(0);
931
			while (fc == ' ' || fc == ',' || fc == ':') {
932
				buffer.append(token); // add the separator
933
				token = tokenizer.nextToken();
934
				fc = token.charAt(0);
935
			}
936
			int last = token .lastIndexOf('.');
937
			if (last >= 3) {
938
				int first = token .indexOf('.');
939
				if (first == last) {
940
					buffer.append(token);
941
				} else {
942
//					buffer.append(token.substring(0, first));
943
//					buffer.append("...");
944
					buffer.append(token.substring(last+1));
945
				}
946
			} else {
947
				buffer.append(token);
948
			}
949
		}
950
		if (max > 0 && buffer.length() > max) {
951
			return "*"+buffer.substring(0, max);
952
		}
953
		return buffer.toString();
954
	}
955
}
387
}
(-)src/org/eclipse/test/performance/ui/ScenarioResults.java (-376 lines)
Removed Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.performance.ui;
12
13
import java.io.BufferedOutputStream;
14
import java.io.File;
15
import java.io.FileNotFoundException;
16
import java.io.FileOutputStream;
17
import java.io.PrintStream;
18
import java.util.ArrayList;
19
import java.util.HashMap;
20
import java.util.Hashtable;
21
import java.util.Iterator;
22
23
import junit.framework.AssertionFailedError;
24
25
import org.eclipse.test.internal.performance.data.Dim;
26
import org.eclipse.test.internal.performance.db.Scenario;
27
import org.eclipse.test.internal.performance.db.TimeSeries;
28
import org.eclipse.test.internal.performance.db.Variations;
29
import org.eclipse.test.performance.ui.Utils.ConfigDescriptor;
30
31
public class ScenarioResults {
32
	private Scenario[] scenarios;
33
	private String baseline;
34
	private String baselinePrefix = null;
35
	private String current;
36
	private ArrayList pointsOfInterest;
37
	private ArrayList buildIDStreamPatterns;
38
	private Hashtable scenarioComments;
39
	private Hashtable variabilityData;
40
	private ConfigDescriptor configDescriptor;
41
	private String outputDir;
42
	private HashMap scenarioMap;
43
	private Variations variations;
44
	/**
45
	 * Summary of results for a scenario for a given build compared to a
46
	 * reference.
47
	 * 
48
	 * @param scenarios -
49
	 *            the array of Scenario objects for which to generate results.
50
	 * @param baseline -
51
	 *            the reference build ID
52
	 * @param current -
53
	 *            the current buildID
54
	 * @param configDescriptor -
55
	 *            a ConfigDescriptor object.
56
	 * @param pointsOfInterest -
57
	 *            an ArrayList of buildId's to highlight on line graphs.
58
	 */
59
	public ScenarioResults(Utils.ConfigDescriptor configDescriptor, Scenario[] scenarios, String baseline, String baselinePrefix, String current, 
60
			ArrayList pointsOfInterest, Hashtable scenarioComments, ArrayList buildIDPatterns, Hashtable variabilityTable, String outputDir,Variations variations) {
61
		
62
		this.scenarios = scenarios;
63
		this.variations=variations;
64
		scenarioMap=new HashMap();
65
		for (int i=0;i<scenarios.length;i++){
66
			scenarioMap.put(scenarios[i].getScenarioName(),scenarios[i]);
67
		}
68
		this.baseline = baseline;
69
		this.baselinePrefix = baselinePrefix;
70
		this.pointsOfInterest = pointsOfInterest;
71
		this.scenarioComments = scenarioComments;
72
		this.configDescriptor=configDescriptor;
73
		buildIDStreamPatterns=buildIDPatterns;
74
		this.current = current;
75
		this.outputDir=outputDir+"/"+configDescriptor.name;
76
		variabilityData=variabilityTable;
77
78
		try {
79
			printSummary();
80
			printDetails();
81
		}
82
		catch (Exception e) {
83
			e.printStackTrace();
84
		}
85
	}
86
87
	private void printSummary() {
88
		String outFile = null;
89
		PrintStream ps = null;
90
91
		for (int s = 0; s < scenarios.length; s++) {
92
			ArrayList pointsOfInterest = new ArrayList();
93
			Scenario t = scenarios[s];
94
95
			// get latest points of interest matching
96
			if (this.pointsOfInterest != null) {
97
				Iterator iterator = this.pointsOfInterest.iterator();
98
				while (iterator.hasNext()) {
99
					String buildIdPattern = iterator.next().toString();
100
101
					if (buildIdPattern.endsWith("*")) {
102
						pointsOfInterest.addAll(getAllMatchingBuildIds(t, buildIdPattern.substring(0, buildIdPattern.length() - 1)));
103
					} else {
104
						String match = getMostRecentMatchingBuildID(t, buildIdPattern);
105
						if (match != null)
106
							pointsOfInterest.add(match);
107
					}
108
				}
109
			}
110
111
			int[] buildNameIndeces = { -1, -1 };
112
			buildNameIndeces[0] = Utils.getBuildNameIndex(t.getTimeSeriesLabels(), current);
113
			buildNameIndeces[1] = Utils.getBuildNameIndex(t.getTimeSeriesLabels(), baseline);
114
			// don't produce result if none exists for current build
115
			if (Utils.getBuildNameIndex(t.getTimeSeriesLabels(), current) == -1) {
116
				continue;
117
			}
118
119
			String scenarioFileName = t.getScenarioName().replace('#', '.').replace(':', '_').replace('\\', '_');
120
			outFile=outputDir+"/"+ scenarioFileName + ".html";
121
			String rawDataFile=scenarioFileName+"_raw.html";
122
			if (outFile != null) {
123
				try {
124
					new File(outFile).getParentFile().mkdirs();
125
					ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(outFile)));
126
				} catch (FileNotFoundException e) {
127
					System.err.println("can't create output file" + outFile); //$NON-NLS-1$
128
				}
129
			}
130
			if (ps == null)
131
				ps = System.out;
132
			ps.println(Utils.HTML_OPEN);
133
			ps.println(Utils.HTML_DEFAULT_CSS);
134
			ps.println("<title>" + t.getScenarioName() + "(" + configDescriptor.description + ")" + "</title></head>"); //$NON-NLS-1$
135
			ps.println("<h4>Scenario: " + t.getScenarioName() + " (" + configDescriptor.description + ")</h4><br>"); //$NON-NLS-1$ //$NON-NLS-2$
136
			
137
			String failureMessage = Utils.failureMessage(variations, t.getScenarioName(),baseline,configDescriptor.name);
138
     		if (failureMessage != null){
139
	   			ps.println("<table><tr><td><b>"+failureMessage+"</td></tr></table>\n");
140
     		}
141
142
     		String comment= (String)scenarioComments.get(t.getScenarioName());
143
			if (comment != null) {
144
				ps.println("<p><b>Note:</b><br>\n");
145
				ps.println(comment + "</p>");
146
			}
147
148
			//print link to raw data.
149
			ps.println("<br><br><b><a href=\""+rawDataFile+"\">Raw data and Stats</a></b><br><br>\n");
150
			ps.println("<b>Click measurement name to view line graph of measured values over builds.</b><br><br>\n");
151
			ps.println("<table border=\"1\">"); //$NON-NLS-1$ //$NON-NLS-2$
152
153
			Dim[] dimensions = filteredDimensions(t.getDimensions());
154
			try {
155
				ps.println("<tr><td>Build Id</td>"); //$NON-NLS-1$
156
				for (int i = 0; i < dimensions.length; i++) {
157
					Dim dim = dimensions[i];
158
					String dimName = dim.getName();
159
					ps.println("<td><a href=\"#" + configDescriptor.name + "_" + scenarioFileName + "_" + dimName + "\">" + dimName + "</a></td>");
160
				}
161
				ps.print("</tr>\n");
162
163
				// store current and reference values for diff later
164
				double[][] diffValues = new double[2][dimensions.length];
165
				// to determine if diff is possible
166
				boolean[] refValueExistance = new boolean[dimensions.length];
167
168
				for (int j = 0; j < 2; j++) {
169
					String referenceIndicator = (j == 1) ? "(reference)" : "";
170
171
					String buildName = ((buildNameIndeces[j] == -1) ? "n/a" : t.getTimeSeriesLabels()[buildNameIndeces[j]]) + referenceIndicator;
172
					ps.print("<tr><td>" + buildName + "</td>");
173
174
					for (int i = 0; i < dimensions.length; i++) {
175
						Dim dim = dimensions[i];
176
177
						TimeSeries ts = t.getTimeSeries(dim);
178
						if (j == 1 && buildNameIndeces[j] != -1)
179
							refValueExistance[i] = true;
180
181
						if (buildNameIndeces[j] != -1)
182
							diffValues[j][i] = ts.getValue(buildNameIndeces[j]);
183
184
						String displayValue = (buildNameIndeces[j] == -1) ? "n/a" : dim.getDisplayValue(ts.getValue(buildNameIndeces[j]));
185
						String stddev = (buildNameIndeces[j] == -1) ? "0" : dim.getDisplayValue(ts.getStddev(buildNameIndeces[j]));
186
187
						if (stddev.startsWith("0 ") || stddev.equals("0"))
188
							ps.println("<td>" + displayValue + "</td>");
189
						else
190
							ps.println("<td>" + displayValue + " [" + stddev + "]" + "</td>");
191
					}
192
					ps.print("</tr>");
193
				}
194
				// get diffs and print results
195
				ps.println(getDiffs(diffValues, dimensions, refValueExistance));
196
				ps.println();
197
				ps.println("</font></table>");
198
				ps.println("*Delta values in red and green indicate degradation > 10% and improvement > 10%,respectively.<br><br>");
199
				ps.println("<br><hr>\n\n");
200
201
				// print text legend.
202
				ps.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"
203
						+ "Boxed points represent previous releases, milestone builds, current reference and current build.<br><br>\n" 
204
						+ "Hover over any point for build id and value.\n");
205
					
206
				// print image maps of historical
207
				for (int i = 0; i < dimensions.length; i++) {
208
					Dim dim = dimensions[i];
209
					String dimName = dim.getName();
210
211
					TimeLineGraph lg = Utils.getLineGraph(t, dim.getName(), baseline, baselinePrefix, current, pointsOfInterest,buildIDStreamPatterns);
212
213
					String lgImg = outputDir + "/graphs/" + scenarioFileName + "_" + dimName + ".gif";
214
					Utils.printLineGraphGif(lg, lgImg);
215
					ps.println("<br><a name=\"" + configDescriptor.name + "_" + scenarioFileName + "_" + dimName + "\"></a>");
216
					ps.println("<br><b>" + dimName + "</b><br>");
217
					ps.println(Utils.getDimensionDescription(dimName) + "<br><br>\n");
218
					ps.println(Utils.getImageMap(lg, "graphs/" + scenarioFileName + "_" + dimName + ".gif",scenarioFileName+"_raw.html"));
219
					}
220
				ps.println("<br><br></body>");
221
				ps.println(Utils.HTML_CLOSE); //$NON-NLS-1$
222
				if (ps != System.out)
223
					ps.close();
224
225
			} catch (AssertionFailedError e) {
226
				e.printStackTrace();
227
				continue;
228
			}
229
		}
230
	}
231
232
	private void printDetails() {
233
234
		String outFile = null;
235
		PrintStream ps = null;
236
237
		for (int s = 0; s < scenarios.length; s++) {
238
			Scenario t = scenarios[s];
239
			// don't produce result if none exists for current build
240
			if (Utils.getBuildNameIndex(t.getTimeSeriesLabels(), current) == -1) {
241
				continue;
242
			}
243
			Dim[] dimensions = filteredDimensions(t.getDimensions());
244
			//store cv for aggregate data
245
			Hashtable data=(Hashtable)variabilityData.get(t.getScenarioName());
246
			if (data==null){
247
				data=new Hashtable();
248
				variabilityData.put(t.getScenarioName(),data);
249
			}
250
			
251
			RawDataTable currentResultsTable=new RawDataTable(t,dimensions,buildIDStreamPatterns,current);
252
			data.put("cConfig-"+configDescriptor.name,currentResultsTable.getCV());
253
			
254
			//create table for baseline data
255
			RawDataTable baselineResultsTable;
256
			if (baselinePrefix!=null)
257
				baselineResultsTable=new RawDataTable(t,dimensions,baselinePrefix,baseline);
258
			else
259
				baselineResultsTable=new RawDataTable(t,dimensions,baseline,baseline);
260
			
261
			data.put("bConfig-"+configDescriptor.name,baselineResultsTable.getCV());
262
		
263
264
			String scenarioFileName = t.getScenarioName().replace('#', '.').replace(':', '_').replace('\\', '_');
265
			outFile = outputDir + "/" + scenarioFileName + "_raw.html";
266
			if (outFile != null) {
267
				try {
268
					new File(outFile).getParentFile().mkdirs();
269
					ps = new PrintStream(new BufferedOutputStream(new FileOutputStream(outFile)));
270
				} catch (FileNotFoundException e) {
271
					System.err.println("can't create output file" + outFile); //$NON-NLS-1$
272
				}
273
			}
274
			if (ps == null)
275
				ps = System.out;
276
			ps.println(Utils.HTML_OPEN);
277
			ps.println(Utils.HTML_DEFAULT_CSS);
278
			ps.println("<title>" + t.getScenarioName() + "(" + configDescriptor.description + ")" + " - Details</title></head>"); //$NON-NLS-1$
279
			ps.println("<h4>Scenario: " + t.getScenarioName() + " (" + configDescriptor.description + ")</h4>"); //$NON-NLS-1$
280
			ps.println("<a href=\""+scenarioFileName+".html\">VIEW GRAPH</a><br><br>"); //$NON-NLS-1$
281
			ps.println("<table><td><b>Current Stream Test Runs</b></td><td><b>Baseline Test Runs</b></td></tr>\n");
282
			ps.println("<tr valign=\"top\">" +
283
					"<td>"+currentResultsTable.toHtmlString()+"</td>"
284
					+"<td>"+baselineResultsTable.toHtmlString()+"</td></tr>");
285
			ps.println("</table>");
286
			ps.close();
287
		}
288
	}
289
290
	private String getMostRecentMatchingBuildID(Scenario scenario, String buildIdPrefix) {
291
		String[] buildIds = scenario.getTimeSeriesLabels();
292
		for (int i = buildIds.length - 1; i > -1; i--) {
293
			if (buildIds[i].startsWith(buildIdPrefix))
294
				return buildIds[i];
295
		}
296
		return null;
297
	}
298
299
	private ArrayList getAllMatchingBuildIds(Scenario scenario, String buildIdPrefix) {
300
		ArrayList result = new ArrayList();
301
		String[] buildIds = scenario.getTimeSeriesLabels();
302
		for (int i = buildIds.length - 1; i > -1; i--) {
303
			if (buildIds[i].startsWith(buildIdPrefix) && !buildIds[i].equals(baseline))
304
				result.add(buildIds[i]);
305
		}
306
		return result;
307
	}
308
309
	private String getDiffs(double[][] values, Dim[] dimensions, boolean[] refValueExistance) {
310
		String diffRow = "<tr><td>*Delta</td>";
311
		for (int j = 0; j < dimensions.length; j++) {
312
			Dim dim = dimensions[j];
313
314
			double diffValue = values[0][j] - values[1][j];
315
			double diffPercentage = 0;
316
			if (values[1][j] != 0)
317
				diffPercentage = ((int) (((diffValue / Math.abs(values[1][j])) * 1000))) / 10.0;
318
			String diffDisplayValue = dim.getDisplayValue(diffValue);
319
			// green
320
			String fontColor = "";
321
			if ((diffPercentage < -10 && !dim.largerIsBetter()) || (diffPercentage > 10 && dim.largerIsBetter()))
322
				fontColor = "#006600";
323
			if ((diffPercentage < -10 && dim.largerIsBetter()) || (diffPercentage > 10 && !dim.largerIsBetter()))
324
				fontColor = "#FF0000";
325
326
			diffPercentage = Math.abs(diffPercentage);
327
			String percentage = (diffPercentage == 0) ? "" : "<br>" + diffPercentage + " %";
328
329
			if (diffPercentage > 10 || diffPercentage < -10) {
330
				diffRow = diffRow.concat("<td><FONT COLOR=\"" + fontColor + "\"><b>" + diffDisplayValue + percentage + "</b></FONT></td>");
331
			} else if (refValueExistance[j]) {
332
				diffRow = diffRow.concat("<td>" + diffDisplayValue + percentage + "</td>");
333
			} else {
334
				diffRow = diffRow.concat("<td>n/a</td>");
335
			}
336
		}
337
		diffRow = diffRow.concat("</tr>");
338
		return diffRow;
339
	}
340
341
	private Dim[] filteredDimensions(Dim[] dimensions) {
342
		ArrayList list = new ArrayList();
343
		ArrayList filtered = new ArrayList();
344
		list.add(0, "Elapsed Process");
345
		list.add(1, "CPU Time");
346
		list.add(2, "Invocation Count");
347
		list.add(3, "GDI Objects");
348
		//list.add(4, "Kernel time");
349
		//list.add(5, "Data Size");
350
		//list.add(6, "Library Size");
351
		//list.add(7, "Text Size");
352
		// list.add(8,"Used Java Heap");
353
		// list.add(9,"Committed");
354
		// list.add(10,"Page Faults");
355
		// list.add(11,"Hard Page Faults");
356
		// list.add(12,"Soft Page Faults");
357
358
		for (int i = 0; i < dimensions.length; i++) {
359
			String dimName = dimensions[i].getName();
360
			if (list.contains(dimName))
361
				list.set(list.indexOf(dimName), dimensions[i]);
362
		}
363
		Iterator iterator = list.iterator();
364
		while (iterator.hasNext()) {
365
			Object tmp = iterator.next();
366
			try {
367
				if ((Dim) tmp instanceof Dim)
368
					filtered.add(tmp);
369
			} catch (ClassCastException e) {
370
				//silently ignore
371
			}
372
		}
373
		return (Dim[]) filtered.toArray(new Dim[filtered.size()]);
374
	}
375
376
}
(-)src/org/eclipse/test/performance/ui/ScenarioStatusTable.java (-279 / +193 lines)
Lines 11-302 Link Here
11
package org.eclipse.test.performance.ui;
11
package org.eclipse.test.performance.ui;
12
12
13
import java.io.PrintStream;
13
import java.io.PrintStream;
14
import java.util.ArrayList;
14
import java.util.List;
15
import java.util.Hashtable;
16
import java.util.StringTokenizer;
15
import java.util.StringTokenizer;
17
16
18
import org.eclipse.test.internal.performance.PerformanceTestPlugin;
17
import org.eclipse.test.internal.performance.results.BuildResults;
19
import org.eclipse.test.internal.performance.data.Dim;
18
import org.eclipse.test.internal.performance.results.ConfigResults;
20
import org.eclipse.test.internal.performance.db.DB;
19
import org.eclipse.test.internal.performance.results.PerformanceResults;
21
import org.eclipse.test.internal.performance.db.Scenario;
20
import org.eclipse.test.internal.performance.results.ScenarioResults;
22
import org.eclipse.test.internal.performance.db.SummaryEntry;
21
23
import org.eclipse.test.internal.performance.db.TimeSeries;
22
/**
24
import org.eclipse.test.internal.performance.db.Variations;
23
 * Class used to print a scenario status table.
25
import org.eclipse.test.performance.Dimension;
24
 */
26
27
public class ScenarioStatusTable {
25
public class ScenarioStatusTable {
28
	
29
	private Hashtable configMaps=null;
30
	private Variations variations;
31
	private String scenarioPattern;
32
	private ArrayList configNames=new ArrayList();
33
	private Hashtable scenarioComments;
34
	private SummaryEntry[] fingerprintEntries;
35
	private final String baseline;
36
	
37
	private class ScenarioStatus{
38
		Hashtable statusMap;
39
		String name, shortName;
40
		Hashtable configStatus;
41
		Hashtable resultsMap;
42
		boolean hasSlowDownExplanation=false;
43
		boolean fingerprint = false;
44
		boolean hasBaseline = true;
45
						
46
		public ScenarioStatus(String scenarioName){
47
			name = scenarioName;
48
			statusMap = new Hashtable();
49
			configStatus = new Hashtable();
50
			resultsMap = new Hashtable();
51
		}
52
53
	}
54
	
55
	/**
56
	 * Creates an HTML table of red x/green check for a scenario for each
57
	 * configuration.
58
	 * 
59
	 * @param variations
60
	 * @param scenarioPattern
61
	 * @param configDescriptors
62
	 */
63
	public ScenarioStatusTable(Variations variations,String scenarioPattern,Hashtable configDescriptors,Hashtable scenarioComments, SummaryEntry[] fpSummaries, String baseline){
64
		configMaps=configDescriptors;
65
		this.variations=variations;
66
		this.scenarioPattern=scenarioPattern;
67
		this.scenarioComments=scenarioComments;
68
		this.baseline= baseline;
69
		this.fingerprintEntries = fpSummaries;
70
	}
71
72
	/**
73
	 * Prints the HTML representation of scenario status table into the given stream.
74
	 */
75
	public void print(PrintStream stream, boolean filter) {
76
		String OS="config";
77
        Scenario[] scenarios= DB.queryScenarios(variations, scenarioPattern, OS, null);
78
	
79
		if (scenarios != null && scenarios.length > 0) {
80
			ArrayList scenarioStatusList=new ArrayList();
81
82
			for (int i= 0; i < scenarios.length; i++) {
83
				Scenario scenario= scenarios[i];
84
				String scenarioName=scenario.getScenarioName();
85
				if (filter && !Utils.matchPattern(scenarioName, scenarioPattern)) continue;
86
				// returns the config names. Making assumption that indices in
87
				// the configs array map to the indices of the failure messages.
88
				String[] configs=scenario.getTimeSeriesLabels();
89
				String[] failureMessages= scenario.getFailureMessages();
90
				ScenarioStatus scenarioStatus=new ScenarioStatus(scenarioName);
91
				scenarioStatus.fingerprint = Utils.hasSummary(this.fingerprintEntries, scenarioName);
92
26
93
				String scenarioComment= (String)scenarioComments.get(scenarioName);
27
	private String component;
94
				if (scenarioComment != null)
28
	private PrintStream stream;
95
					scenarioStatus.hasSlowDownExplanation= true;
29
	private int jsIdCount;
96
30
97
				int confsLength = configs.length;
31
/**
98
				for (int j=0; j<confsLength; j++){
32
 * Creates an HTML table of red x/green check for a scenario for each
99
					if (!configNames.contains(configs[j]))
33
 * configuration.
100
						configNames.add(configs[j]);
34
 */
101
35
public ScenarioStatusTable(String  name, PrintStream stream) {
102
					// Compute confidence level and store it in scenario status
36
    this.component = name;
103
					Variations v = (Variations) variations.clone();
37
    this.stream = stream;
104
					v.put(PerformanceTestPlugin.CONFIG, configs[j]);
38
}
105
//    				double[] resultStats = Utils.resultStats(v, scenarioName, baseline, configs[j]);
106
					String current = (String) v.get(PerformanceTestPlugin.BUILD);
107
					Dim significanceDimension = (Dim) Dimension.ELAPSED_PROCESS;
108
					Scenario newScenario= DB.getScenarioSeries(scenarioName, v, PerformanceTestPlugin.BUILD, baseline, current, new Dim[] { significanceDimension });
109
			        String[] timeSeriesLabels= newScenario.getTimeSeriesLabels();
110
			        TimeSeries timeSeries = newScenario.getTimeSeries(significanceDimension);
111
			        boolean hasBaseline = timeSeriesLabels.length == 2 && timeSeriesLabels[0].equals(baseline);
112
			        double[] resultStats = Utils.resultsStatistics(timeSeries);
113
					if (resultStats == null) continue;
114
					if (resultStats != null && resultStats[1] < 0 && scenarioStatus.hasBaseline) scenarioStatus.hasBaseline = false;
115
					
116
					// Store failure message in scenario status
117
					int confidenceLevel = Utils.confidenceLevel(resultStats);
118
					boolean hasScenarioFailure = failureMessages[j] != null && failureMessages[j].indexOf(configs[j]) != -1; // ensure correct failure message relates to config
119
					StringBuffer buffer = new StringBuffer();
120
					if (hasScenarioFailure) {
121
						buffer.append(failureMessages[j]);
122
						if (scenarioStatus.hasSlowDownExplanation) {
123
							buffer.append(" - Explanation comment: ");
124
							buffer.append(scenarioComment);
125
						}
126
						confidenceLevel |= Utils.DEV;
127
					}
128
					scenarioStatus.configStatus.put(configs[j], new Integer(confidenceLevel));
129
					scenarioStatus.statusMap.put(configs[j], buffer.toString());
130
131
					// Store text for numbers in scenario status
132
					String text = Utils.failureMessage(resultStats, false);
133
					scenarioStatus.resultsMap.put(configs[j], text);
134
					
135
					// Store scenario short name in scenario status (for table column)
136
					if (scenarioStatus.shortName == null) {
137
						if (hasBaseline) { // baseline is OK
138
							scenarioStatus.shortName = Utils.getScenarioShortName(scenarioName, -1);
139
						} else {
140
							StringBuffer shortName = new StringBuffer("*");
141
							shortName.append(Utils.getScenarioShortName(scenarioName, -1));
142
							shortName.append(" <small>(vs.&nbsp;");
143
							shortName.append(timeSeriesLabels[0]);
144
							shortName.append(")</small>");
145
							scenarioStatus.shortName = shortName.toString();
146
						}
147
					}
148
39
149
					// Store scenario status
40
/**
150
					if (!scenarioStatusList.contains(scenarioStatus)) {
41
 * Prints the HTML representation of scenario status table into the given stream.
151
						scenarioStatusList.add(scenarioStatus);
42
 */
152
					}
43
public void print(PerformanceResults performanceResults) {
153
				}
44
	printTitle();
154
			}
45
	List scenarii = performanceResults.getComponentScenarii(this.component);
155
			
46
	String baselineName = performanceResults.getBaselineName();
156
			String label=null;
47
	int size = scenarii.size();
157
			stream.println("<br><h4>Scenario Status</h4>");
48
	printColumnsTitle(size, performanceResults);
158
			stream.println("The following table gives a complete but compact view of performance results for the component.<br>");
49
	this.jsIdCount = 0;
159
			stream.println("Each line of the table shows the results for one scenario on all machines.<br><br>");
50
	for (int i=0; i<size; i++) {
160
			stream.println("The name of the scenario is in <b>bold</b> when its results are also displayed in the fingerprints<br>");
51
		ScenarioResults scenarioResults = (ScenarioResults) scenarii.get(i);
161
			stream.println("and starts with an '*' when the scenario has no results in the last baseline run.<br><br>");
52
		this.stream.println("<tr>");
162
			stream.println("Here are information displayed for each test (ie. in each cell):");
53
		this.stream.print("<td>");
163
			stream.println("<ul>");
54
		boolean hasSummary = scenarioResults.hasSummary();
164
			stream.println("<li>an icon showing whether the test fails or passes and whether it's reliable or not.<br>");
55
		if (hasSummary) this.stream.print("<b>");
165
			stream.println("The legend for this icon is:");
56
		String scenarioBaseline = scenarioResults.getBaselineBuildName();
166
			stream.println("<ul>");
57
		boolean hasBaseline = baselineName.equals(scenarioBaseline);
167
			stream.print("<li>Green (<img src=\"");
58
		if (!hasBaseline) {
168
			stream.print(Utils.OK_IMAGE);
59
			this.stream.print("*");
169
			stream.print("\">): mark a <b>successful result</b>, which means this test has neither significant performance regression nor significant standard error</li>");
60
			this.stream.print(scenarioResults.getShortName());
170
			stream.print("<li>Red (<img src=\"");
61
			this.stream.print(" <small>(vs.&nbsp;");
171
			stream.print(Utils.FAIL_IMAGE);
62
			this.stream.print(scenarioBaseline);
172
			stream.println("\">): mark a <b>failing result</b>, which means this test shows a significant performance regression (more than 10%)</li>");
63
			this.stream.print(")</small>");
173
			stream.print("<li>Gray (<img src=\"");
64
		} else {
174
			stream.print(Utils.FAIL_IMAGE_EXPLAINED);
65
			this.stream.print(scenarioResults.getShortName());
175
			stream.println("\">): mark a <b>failing result</b> (see above) with a comment explaining this degradation.</li>");
66
		}
176
			stream.print("<li>Yellow (<img src=\"");
67
		if (hasSummary) this.stream.print("</b>");
177
			stream.print(Utils.FAIL_IMAGE_WARN);
68
		this.stream.println();
178
			stream.print("\"> or <img src=\"");
69
		String[] configs = performanceResults.getConfigNames(true/*sort*/);
179
			stream.print(Utils.OK_IMAGE_WARN);
70
		int length = configs.length;
180
			stream.print("\">): mark a <b>failing or successful result</b> with a significant standard error (more than ");
71
		for (int j=0; j<length; j++) {
181
			stream.print(Utils.STANDARD_ERROR_THRESHOLD_STRING);
72
			printConfigStats(scenarioResults, configs[j]);
182
			stream.println(")</li>");
73
		}
183
			stream.print("<li>Black (<img src=\"");
74
	}
184
			stream.print(Utils.UNKNOWN_IMAGE);
75
	this.stream.println("</table>");
185
			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>");
76
}
186
			stream.println("<li>\"n/a\": mark a test for with <b>no</b> performance results</li>");
187
			stream.println("</ul></li>");
188
			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>");
189
			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>");
190
			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>");
191
			stream.println("</ul>");
192
			stream.println("<u>Hints</u>:<ul>");
193
			stream.println("<li>fly over image of failing tests to see the complete error message</li>");
194
			stream.println("<li>to look at the complete and detailed test results, click on its image</li>");
195
			stream.println("</ul>");
196
			stream.println();
197
			stream.println("<table border=\"1\">");
198
			stream.println("<tr>");
199
			stream.print("<td><h4>All ");
200
			stream.print(scenarios.length);
201
			stream.println(" scenarios</h4></td>");
202
77
203
			for (int i= 0; i < configNames.size(); i++){
78
/*
204
				label = configNames.get(i).toString();
79
 * Print the table columns title.
205
				String columnTitle = label;
80
 */
206
				if (configMaps!=null) {
81
private void printColumnsTitle(int size, PerformanceResults performanceResults) {
207
					Utils.ConfigDescriptor configDescriptor= (Utils.ConfigDescriptor)configMaps.get(label);
82
	this.stream.println("<table border=\"1\">");
208
					if (configDescriptor != null) {
83
	this.stream.println("<tr>");
209
						int idx = configDescriptor.description.indexOf('(');
84
	this.stream.print("<td><h4>All ");
210
						if (idx < 0) {
85
	this.stream.print(size);
211
							columnTitle = configDescriptor.description;
86
	this.stream.println(" scenarios</h4></td>");
212
						} else {
87
	String[] configNames = performanceResults.getConfigNames(true/*sort*/);
213
							// first line
88
	String[] configBoxes = performanceResults.getConfigBoxes(true/*sort*/);
214
    						StringTokenizer tokenizer = new StringTokenizer(configDescriptor.description.substring(0, idx).trim(), " ");
89
	int length = configNames.length;
215
    						StringBuffer buffer = new StringBuffer(tokenizer.nextToken());
90
	for (int i=0; i<length; i++) {
216
    						while (tokenizer.hasMoreTokens()) {
91
		String columnTitle = configNames[i];
217
    							buffer.append("&nbsp;");
92
		String boxName = configBoxes[i];
218
    							buffer.append(tokenizer.nextToken());
93
		int idx = boxName.indexOf('(');
219
    						}
94
		if (idx < 0) {
220
    						buffer.append(' ');
95
			columnTitle = boxName;
221
    						// second line
96
		} else {
222
    						tokenizer = new StringTokenizer(configDescriptor.description.substring(idx).trim(), " ");
97
			// first line
223
    						buffer.append(tokenizer.nextToken());
98
			StringTokenizer tokenizer = new StringTokenizer(boxName.substring(0, idx).trim(), " ");
224
    						while (tokenizer.hasMoreTokens()) {
99
			StringBuffer buffer = new StringBuffer(tokenizer.nextToken());
225
    							buffer.append("&nbsp;");
100
			while (tokenizer.hasMoreTokens()) {
226
    							buffer.append(tokenizer.nextToken());
101
				buffer.append("&nbsp;");
227
    						}
102
				buffer.append(tokenizer.nextToken());
228
    						columnTitle = buffer.toString();
229
						}
230
					}
231
				}
232
				stream.print("<td><h5>");
233
				stream.print(columnTitle);
234
				stream.println("</h5>");
235
			}
103
			}
236
			
104
			buffer.append(' ');
237
			// counter for js class Id's
105
			// second line
238
			int jsIdCount=0;
106
			tokenizer = new StringTokenizer(boxName.substring(idx).trim(), " ");
239
			for (int j= 0; j < scenarioStatusList.size(); j++) {
107
			buffer.append(tokenizer.nextToken());
240
				
108
			while (tokenizer.hasMoreTokens()) {
241
				ScenarioStatus status=(ScenarioStatus)scenarioStatusList.get(j);
109
				buffer.append("&nbsp;");
242
110
				buffer.append(tokenizer.nextToken());
243
				stream.println("<tr>");
244
				stream.print("<td>");
245
				if (status.fingerprint) stream.print("<b>");
246
				if (!status.hasBaseline) stream.print("*");
247
//				stream.print(status.name.substring(status.name.indexOf(".",status.name.indexOf(".test")+1)+1));
248
				stream.print(status.shortName);
249
				if (!status.hasBaseline) stream.print("</i>");
250
				if (status.fingerprint) stream.print("</b>");
251
				stream.println();
252
				for (int i=0;i<configNames.size();i++){
253
					String configName=configNames.get(i).toString();
254
					String aUrl=configName;
255
					if (status.statusMap.containsKey(configName)){
256
						String message = (String) status.statusMap.get(configName);
257
						int confidence = ((Integer) status.configStatus.get(configName)).intValue();
258
						String image = Utils.getImage(confidence, status.hasSlowDownExplanation);
259
						stream.print("<td><a ");
260
						if ((confidence & Utils.DEV) == 0 || (confidence & Utils.NAN) != 0 || message.length() == 0){
261
							// write deviation with error in table when test pass
262
							stream.print("href=\"");
263
							stream.print(aUrl);
264
							stream.print('/');
265
							stream.print(status.name.replace('#', '.').replace(':', '_').replace('\\', '_'));
266
							stream.println(".html\">");
267
							stream.print("<img hspace=\"10\" border=\"0\" src=\"");
268
							stream.print(image);
269
							stream.println("\"/></a>");
270
						} else {
271
							// create message with tooltip text including deviation with error plus failure message
272
							jsIdCount+=1;
273
							stream.print("class=\"tooltipSource\" onMouseover=\"show_element('toolTip");
274
							stream.print(jsIdCount);
275
							stream.print("')\" onMouseout=\"hide_element('toolTip");
276
							stream.print(jsIdCount);
277
							stream.print("')\" \nhref=\"");
278
							stream.print(aUrl);
279
							stream.print('/');
280
							stream.print(status.name.replace('#', '.').replace(':', '_').replace('\\', '_'));
281
							stream.println(".html\">");
282
							stream.print("<img hspace=\"10\" border=\"0\" src=\"");
283
							stream.print(image);
284
							stream.println("\"/>");
285
							stream.print("<span class=\"hidden_tooltip\" id=\"toolTip");
286
							stream.print(jsIdCount);
287
							stream.print("\">");
288
							stream.print(message);
289
							stream.println("</span></a>");
290
						}
291
						String result = (String) status.resultsMap.get(configName);
292
						stream.println(result);
293
					}else{
294
						stream.println("<td> n/a");
295
					}
296
				}
297
				stream.flush();
298
			}
111
			}
299
			stream.println("</table>");
112
			columnTitle = buffer.toString();
300
		}
113
		}
301
    }
114
		this.stream.print("<td><h5>");
115
		this.stream.print(columnTitle);
116
		this.stream.println("</h5>");
117
	}
118
}
119
120
/*
121
 * Print the scenario statistics value for the given configuration.
122
 */
123
private void printConfigStats(ScenarioResults scenarioResults, String config) {
124
	ConfigResults configResults = scenarioResults.getConfigResults(config);
125
	if (configResults == null || !configResults.isValid()) {
126
		this.stream.print("<td>n/a</td>");
127
		return;
128
	}
129
	BuildResults currentBuildResults = configResults.getCurrentBuildResults();
130
	String failure = currentBuildResults.getFailure();
131
	double[] deviation = configResults.getCurrentBuildDeviation();
132
	int confidence = Utils.confidenceLevel(deviation);
133
	boolean hasFailure = failure != null;
134
	String comment = currentBuildResults.getComment();
135
	String image = Utils.getImage(confidence, hasFailure, comment != null);
136
	this.stream.print("<td><a ");
137
	if (!hasFailure|| (confidence & Utils.NAN) != 0 || failure.length() == 0){
138
		// write deviation with error in table when test pass
139
		this.stream.print("href=\"");
140
		this.stream.print(configResults.getName());
141
		this.stream.print('/');
142
		this.stream.print(scenarioResults.getFileName());
143
		this.stream.println(".html\">");
144
		this.stream.print("<img hspace=\"10\" border=\"0\" src=\"");
145
		this.stream.print(image);
146
		this.stream.println("\"/></a>");
147
	} else {
148
		// create message with tooltip text including deviation with error plus failure message
149
		this.jsIdCount+=1;
150
		this.stream.print("class=\"tooltipSource\" onMouseover=\"show_element('toolTip");
151
		this.stream.print(jsIdCount);
152
		this.stream.print("')\" onMouseout=\"hide_element('toolTip");
153
		this.stream.print(jsIdCount);
154
		this.stream.print("')\" \nhref=\"");
155
		this.stream.print(configResults.getName());
156
		this.stream.print('/');
157
		this.stream.print(scenarioResults.getFileName());
158
		this.stream.println(".html\">");
159
		this.stream.print("<img hspace=\"10\" border=\"0\" src=\"");
160
		this.stream.print(image);
161
		this.stream.println("\"/>");
162
		this.stream.print("<span class=\"hidden_tooltip\" id=\"toolTip");
163
		this.stream.print(jsIdCount);
164
		this.stream.print("\">");
165
		this.stream.print(failure);
166
		this.stream.println("</span></a>");
167
	}
168
	String result = Utils.failureMessage(deviation, false);
169
	this.stream.println(result);
170
}
171
172
/*
173
 * Print the status table explanationtitle.
174
 */
175
private void printTitle() {
176
	this.stream.println("<br><h4>Scenario Status</h4>");
177
	this.stream.println("The following table gives a complete but compact view of performance results for the component.<br>");
178
	this.stream.println("Each line of the table shows the results for one scenario on all machines.<br><br>");
179
	this.stream.println("The name of the scenario is in <b>bold</b> when its results are also displayed in the fingerprints<br>");
180
	this.stream.println("and starts with an '*' when the scenario has no results in the last baseline run.<br><br>");
181
	this.stream.println("Here are information displayed for each test (ie. in each cell):");
182
	this.stream.println("<ul>");
183
	this.stream.println("<li>an icon showing whether the test fails or passes and whether it's reliable or not.<br>");
184
	this.stream.println("The legend for this icon is:");
185
	this.stream.println("<ul>");
186
	this.stream.print("<li>Green (<img src=\"");
187
	this.stream.print(Utils.OK_IMAGE);
188
	this.stream.print("\">): mark a <b>successful result</b>, which means this test has neither significant performance regression nor significant standard error</li>");
189
	this.stream.print("<li>Red (<img src=\"");
190
	this.stream.print(Utils.FAIL_IMAGE);
191
	this.stream.println("\">): mark a <b>failing result</b>, which means this test shows a significant performance regression (more than 10%)</li>");
192
	this.stream.print("<li>Gray (<img src=\"");
193
	this.stream.print(Utils.FAIL_IMAGE_EXPLAINED);
194
	this.stream.println("\">): mark a <b>failing result</b> (see above) with a comment explaining this degradation.</li>");
195
	this.stream.print("<li>Yellow (<img src=\"");
196
	this.stream.print(Utils.FAIL_IMAGE_WARN);
197
	this.stream.print("\"> or <img src=\"");
198
	this.stream.print(Utils.OK_IMAGE_WARN);
199
	this.stream.print("\">): mark a <b>failing or successful result</b> with a significant standard error (more than ");
200
	this.stream.print(Utils.STANDARD_ERROR_THRESHOLD_STRING);
201
	this.stream.println(")</li>");
202
	this.stream.print("<li>Black (<img src=\"");
203
	this.stream.print(Utils.UNKNOWN_IMAGE);
204
	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>");
205
	this.stream.println("<li>\"n/a\": mark a test for with <b>no</b> performance results</li>");
206
	this.stream.println("</ul></li>");
207
	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>");
208
	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>");
209
	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>");
210
	this.stream.println("</ul>");
211
	this.stream.println("<u>Hints</u>:<ul>");
212
	this.stream.println("<li>fly over image of failing tests to see the complete error message</li>");
213
	this.stream.println("<li>to look at the complete and detailed test results, click on its image</li>");
214
	this.stream.println("</ul>");
215
}
302
}
216
}
(-)src/org/eclipse/test/performance/ui/FingerPrint.java (-224 / +149 lines)
Lines 16-22 Link Here
16
import java.io.FileOutputStream;
16
import java.io.FileOutputStream;
17
import java.io.IOException;
17
import java.io.IOException;
18
import java.io.OutputStream;
18
import java.io.OutputStream;
19
import java.util.Hashtable;
19
import java.io.PrintStream;
20
import java.util.List;
20
21
21
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.SWT;
22
import org.eclipse.swt.graphics.GC;
23
import org.eclipse.swt.graphics.GC;
Lines 24-259 Link Here
24
import org.eclipse.swt.graphics.ImageData;
25
import org.eclipse.swt.graphics.ImageData;
25
import org.eclipse.swt.graphics.ImageLoader;
26
import org.eclipse.swt.graphics.ImageLoader;
26
import org.eclipse.swt.widgets.Display;
27
import org.eclipse.swt.widgets.Display;
27
import org.eclipse.test.internal.performance.PerformanceTestPlugin;
28
import org.eclipse.test.internal.performance.results.AbstractResults;
28
import org.eclipse.test.internal.performance.data.Dim;
29
import org.eclipse.test.internal.performance.results.ConfigResults;
29
import org.eclipse.test.internal.performance.db.DB;
30
import org.eclipse.test.internal.performance.results.PerformanceResults;
30
import org.eclipse.test.internal.performance.db.Scenario;
31
import org.eclipse.test.internal.performance.results.ScenarioResults;
31
import org.eclipse.test.internal.performance.db.SummaryEntry;
32
32
import org.eclipse.test.internal.performance.db.TimeSeries;
33
/**
33
import org.eclipse.test.internal.performance.db.Variations;
34
 * Class used to create scenario fingerprint.
34
import org.eclipse.test.performance.ui.Utils.ConfigDescriptor;
35
 */
36
public class FingerPrint {
35
37
38
private static final int GRAPH_WIDTH = 1000;
36
39
37
public class FingerPrint {
40
	String component;
38
    
41
	PrintStream stream;
39
    private static final int GRAPH_WIDTH= 1000;
42
	File outputDir;
43
44
public FingerPrint(String name, PrintStream ps, File outputDir) {
45
	if (!name.equals("global")) this.component = name;
46
	this.stream = ps;
47
	this.outputDir = outputDir;
48
}
40
49
41
    String outputDirectory;
50
/**
42
    String referenceBuildId;
51
 * Create and save fingerprints as image and print their reference in the current stream.
43
    String currentBuildId;
52
 * 
44
    String component;
53
 * @param performanceResults The performance results used to print the fingerprints
45
    ConfigDescriptor configDescriptor;
54
 */
46
    SummaryEntry [] entries;
55
public void print(PerformanceResults performanceResults) {
47
    Variations variations;
56
	String baselineBuildName = performanceResults.getBaselineName();
48
    BarGraph bar;
57
	String buildName = performanceResults.getName();
49
    String outName;
58
	
50
    String title;
59
	// Compute fingerprint output file name prefix
51
    Hashtable scenarioComments;
60
	int referenceUnderscoreIndex = baselineBuildName.indexOf('_');
52
    
61
	String baselinePrefix = baselineBuildName;
53
    public FingerPrint() {
62
	if (referenceUnderscoreIndex != -1) {
54
    }
63
		baselinePrefix = baselineBuildName.substring(0, referenceUnderscoreIndex);
55
56
57
    public FingerPrint(String component,ConfigDescriptor config, String reference, String current,Variations variations, String outputDir) {
58
        this.variations=variations;
59
        this.component=component;
60
        referenceBuildId= reference;
61
        currentBuildId= current;
62
        outputDirectory= outputDir;
63
        configDescriptor=config;
64
        variations.put(PerformanceTestPlugin.BUILD, currentBuildId);
65
        if (component==null){
66
        	entries= DB.querySummaries(variations,null);
67
        	this.component="";
68
        } else {
69
        	entries=DB.querySummaries(variations,component+'%');
70
        }
71
       	run();
72
    }    
73
    
74
    /**
75
     * Creates the fingerprint gif, image map and scenario status table for the component.
76
     */
77
    public void run() {
78
        new File(outputDirectory).mkdirs();
79
        String referenceName=referenceBuildId;
80
        String currentName=currentBuildId;
81
        int referenceUnderscoreIndex=referenceBuildId.indexOf('_');
82
        int currentUnderscoreIndex=currentBuildId.indexOf('_');
83
        
84
        if (referenceUnderscoreIndex!=-1)
85
        	referenceName=referenceBuildId.substring(0,referenceUnderscoreIndex);
86
        if (currentUnderscoreIndex!=-1)
87
        	currentName=currentBuildId.substring(0,currentUnderscoreIndex);
88
89
        title="Performance of " + component +" "+currentName + " relative to " + referenceName;
90
        bar= new BarGraph(null);
91
                
92
        if (entries != null) {
93
            for (int i= 0; i < entries.length; i++) {
94
                SummaryEntry summary = entries[i];
95
                if (summary.comment==null)
96
                	add(summary.shortName, new Dim[] { summary.dimension }, summary.scenarioName);
97
                else{
98
                	setComment(summary.scenarioName, summary.comment);
99
                	add(summary.shortName, new Dim[] { summary.dimension }, summary.scenarioName, summary.comment);
100
                }
101
            }
102
        }
103
        
104
        outName= "FP_" + component+ '_'+referenceName + '_' + currentBuildId+"."+configDescriptor.name;
105
               
106
        if (component=="")
107
        	outName= "FP_"+referenceName + '_' + currentBuildId+"."+configDescriptor.name;
108
        save(outputDirectory + '/' + outName);
109
        
110
        //show(bar);
111
     
112
       }
113
114
    private void setComment(String scenario, String comment) {
115
    	if (scenarioComments==null)
116
    		scenarioComments=new Hashtable();
117
    	scenarioComments.put(scenario,comment);
118
    }
119
120
    private void add(String name, Dim[] dims, String scenarioName) {
121
    	add (name,dims,scenarioName,null);
122
    }
123
124
    private void add(String name, Dim[] dims, String scenarioName, String comment) {
125
         String refData= "";
126
        Scenario scenario= DB.getScenarioSeries(scenarioName, variations, PerformanceTestPlugin.BUILD, referenceBuildId, currentBuildId, dims);
127
        String[] timeSeriesLabels= scenario.getTimeSeriesLabels();
128
        if (timeSeriesLabels.length == 2) {
129
            // we mark the label with a '*' or '†' to indicate that no data was available for the specified builds
130
            if (!timeSeriesLabels[0].equals(referenceBuildId)) {
131
                name= '*' + name;
132
                refData= " (" + timeSeriesLabels[0] + ")";
133
            } else if (!timeSeriesLabels[1].equals(currentBuildId)) {
134
                name= '†' + name;
135
                refData= " (" + timeSeriesLabels[1] + ")";
136
            }
137
        }
138
        
139
        for (int i= 0; i < dims.length; i++) {
140
            TimeSeries timeSeries= scenario.getTimeSeries(dims[i]);
141
            int l= timeSeries.getLength();
142
            if (l >= 1) {
143
            	double percent= 0.0;
144
            	boolean hasConfidentResult= true;
145
            	if (l > 1) {
146
//            		hasConfidentResult= Utils.hasConfidentResult(variations, scenario.getScenarioName(),referenceBuildId,configDescriptor.name);
147
            		hasConfidentResult= Utils.hasConfidentResult(timeSeries);
148
            		/*if (!rejectNullHypothesis) {
149
            			NumberFormat percentFormatter= NumberFormat.getPercentInstance();
150
            			String statisticsComment= "There is not enough evidence to reject the null hypothesis at the " + percentFormatter.format(percentile.inside()) + "level";
151
            			if (comment == null)
152
            				comment= statisticsComment;
153
            			else
154
            				comment+= statisticsComment;
155
            			setComment(scenarioName, comment);
156
            		}
157
            		 */
158
            		double ref= timeSeries.getValue(0);
159
            		double val= timeSeries.getValue(1);
160
            		percent= 100.0 - ((val / ref) * 100.0);
161
            	}
162
            	if (Math.abs(percent) < 200) {
163
            		String n= name + " (" + dims[i].getName() + ")" + refData;
164
            		bar.addItem(n, percent,configDescriptor.name+"/"+(scenarioName.replace('#','.').replace(':','_').replace('\\','_'))+".html#"+dims[i].getName(),comment, hasConfidentResult); //$NON-NLS-1$ //$NON-NLS-2$
165
               	}
166
            }
167
        }
168
        //scenario.dump(System.out);
169
	         
170
    }
171
172
    private void save(String output) {
173
174
    	//if (bar.getFItems().size()==0)
175
    		//return;
176
    	
177
        Display display= Display.getDefault();
178
        
179
        int height= bar.getHeight();
180
        Image image= new Image(display, GRAPH_WIDTH, height);
181
        
182
        GC gc= new GC(image);
183
        bar.paint(display, GRAPH_WIDTH, height, gc);
184
        gc.dispose();
185
186
        ImageData data = Utils.downSample(image);
187
        ImageLoader il= new ImageLoader();
188
        il.data= new ImageData[] { data };
189
190
        OutputStream out= null;
191
        try {
192
            out= new BufferedOutputStream(new FileOutputStream(output + ".gif")); //$NON-NLS-1$
193
            //System.out.println("writing: " + output);
194
            il.save(out, SWT.IMAGE_GIF);
195
        } catch (FileNotFoundException e) {
196
            e.printStackTrace();
197
        } finally {
198
            image.dispose();
199
            if (out != null) {
200
                try {
201
                    out.close();
202
                } catch (IOException e1) {
203
                    // silently ignored
204
                }
205
            }
206
        }
207
    }
208
    
209
    /*
210
     * Displays bar graph in window
211
     *
212
    private void show(final BarGraph bar) {
213
        Display display= new Display();
214
        
215
        Shell shell= new Shell(display);
216
        shell.setLayout(new FillLayout());
217
        
218
        final Canvas canvas= new Canvas(shell, SWT.NO_BACKGROUND);
219
        canvas.addPaintListener(new PaintListener() {
220
            public void paintControl(PaintEvent e) {
221
                Point s= canvas.getSize();
222
                bar.paint(canvas.getDisplay(), s.x, s.y, e.gc);
223
            }
224
        });
225
        
226
        shell.open();
227
228
        while (!shell.isDisposed())
229
            if (!display.readAndDispatch())
230
                display.sleep();
231
            
232
        display.dispose();
233
    }
234
	public BarGraph getBar() {
235
		return bar;
236
	}
64
	}
237
	public String getOutName() {
65
	int currentUnderscoreIndex = buildName.indexOf('_');
238
		return outName;
66
	if  (currentUnderscoreIndex != -1){
67
		buildName = buildName.substring(0, currentUnderscoreIndex);
239
	}
68
	}
240
    */
69
	StringBuffer buffer = new StringBuffer("FP_");
70
	if (this.component != null) {
71
		buffer.append(this.component);
72
		buffer.append('_');
73
	}
74
	buffer.append(baselinePrefix);
75
	buffer.append('_');
76
	buffer.append(buildName);
77
	buffer.append('.');
78
	String filePrefix = buffer.toString();
79
80
	// Create each fingerprint and save it
81
	String[] configNames = performanceResults.getConfigNames(false/* not sorted*/);
82
	String[] configBoxes = performanceResults.getConfigBoxes(false/* not sorted*/);
83
	int length = configNames.length;
84
	for (int c=0; c<length; c++) {
85
		String configName  = configNames[c];
86
		List scenarii = performanceResults.getComponentSummaryScenarii(this.component, configName);
87
		if (scenarii == null) continue;
88
89
		// Create BarGraph
90
//		BarGraph barGraph = new BarGraph(null);
91
		BarGraph barGraph = null;
92
		for (int i=0, size=scenarii.size(); i<size; i++) {
93
			ScenarioResults scenarioResults = (ScenarioResults) scenarii.get(i);
94
			ConfigResults configResults = scenarioResults.getConfigResults(configName);
95
			if (configResults == null || !configResults.isValid()) continue;
96
			double[] results = configResults.getCurrentBuildDeviation();
97
			double percent = -results[0] * 100.0;
98
			if (results != null && Math.abs(percent) < 200) {
99
				String defaultDimensionName = AbstractResults.SUPPORTED_DIMS[0].getName();
100
				String name = scenarioResults.getLabel() + " (" + defaultDimensionName + ")";
101
				if (!configResults.getCurrentBuildName().equals(buildName)) {
102
					continue; // the test didn't run on last build, skip it
103
				}
104
				if (!configResults.isBaselined()) {
105
					name = "*" + name + " (" + configResults.getBaselineBuildName() + ")";
106
				}
107
				if (barGraph == null) {
108
					barGraph = new BarGraph(null);
109
				}
110
				barGraph.addItem(name,
111
				    results,
112
				    configName + "/" + scenarioResults.getFileName() + ".html#" + defaultDimensionName,
113
				    configResults.getCurrentBuildResults().getComment(),
114
				    (Utils.confidenceLevel(results) & Utils.ERR) == 0);
115
			}
116
		}
117
		 if (barGraph == null) continue;
241
118
242
	/**
119
		// Save image file
243
	 * @return - an html representation of the fingerprint.
120
		String fileName = filePrefix + configName ;
244
	 */
121
		File outputFile = new File(this.outputDir, fileName+".gif");
245
	public String getImageMap() {
122
		save(barGraph, outputFile);
246
		String componentDescription = this.configDescriptor.description;
123
247
		String areas = this.bar.getAreas();
124
		// Print image file reference in stream
248
		if (areas == null)
125
		String boxName = configBoxes[c];
249
			areas = "";
126
		if (outputFile.exists()) {
250
		String output = "";
127
			String areas = barGraph.getAreas();
251
		if (new File(this.outputDirectory, this.outName + ".gif").exists()) {
128
			if (areas == null) areas = "";
252
			output = "<h4>" + componentDescription + "</h4>";
129
			this.stream.print("<h4>");
253
			output = output.concat("<img src=\"" + this.outName + ".gif\" usemap=\"#" + this.outName + "\">" + "<map name=\"" + this.outName + "\">" + areas + "</map>\n");
130
			this.stream.print(boxName);
131
			this.stream.print("</h4>");
132
			this.stream.print("<img src=\"");
133
			this.stream.print(fileName);
134
			this.stream.print(".gif\" usemap=\"#");
135
			this.stream.print(fileName);
136
			this.stream.print("\"><map name=\"");
137
			this.stream.print(fileName);
138
			this.stream.print("\">");
139
			this.stream.print(areas);
140
			this.stream.print("</map>\n");
254
		} else {
141
		} else {
255
			output = output.concat("<br><br>There is no fingerprint for " + componentDescription + "<br><br>\n");
142
			this.stream.print("<br><br>There is no fingerprint for ");
143
			this.stream.print(boxName);
144
			this.stream.print("<br><br>\n");
256
		}
145
		}
257
		return output;
258
	}
146
	}
259
}
147
}
148
149
/*
150
 * Save the computed bar graph.
151
 */
152
private void save(BarGraph barGraph, File outputFile) {
153
154
	// Create and paint image
155
	Display display = Display.getDefault();
156
	int height = barGraph.getHeight();
157
	Image image = new Image(display, GRAPH_WIDTH, height);
158
	GC gc = new GC(image);
159
	barGraph.paint(display, GRAPH_WIDTH, height, gc);
160
	gc.dispose();
161
162
	// Save image
163
	ImageData data = Utils.downSample(image);
164
	ImageLoader imageLoader = new ImageLoader();
165
	imageLoader.data = new ImageData[] { data };
166
167
	OutputStream out = null;
168
	try {
169
		out = new BufferedOutputStream(new FileOutputStream(outputFile));
170
		imageLoader.save(out, SWT.IMAGE_GIF);
171
	} catch (FileNotFoundException e) {
172
		e.printStackTrace();
173
	} finally {
174
		image.dispose();
175
		if (out != null) {
176
			try {
177
				out.close();
178
			} catch (IOException e1) {
179
				// silently ignored
180
			}
181
		}
182
	}
183
}
184
}
(-)src/org/eclipse/test/performance/ui/RawDataTable.java (-228 / +152 lines)
Lines 10-259 Link Here
10
 *******************************************************************************/
10
 *******************************************************************************/
11
package org.eclipse.test.performance.ui;
11
package org.eclipse.test.performance.ui;
12
12
13
import java.io.PrintStream;
13
import java.util.ArrayList;
14
import java.util.ArrayList;
14
import java.util.Arrays;
15
import java.util.Collections;
15
import java.util.Hashtable;
16
import java.util.List;
16
import java.util.Iterator;
17
import java.util.Set;
18
17
19
import org.eclipse.test.internal.performance.data.Dim;
18
import org.eclipse.test.internal.performance.data.Dim;
20
import org.eclipse.test.internal.performance.db.Scenario;
19
import org.eclipse.test.internal.performance.results.AbstractResults;
21
import org.eclipse.test.internal.performance.db.TimeSeries;
20
import org.eclipse.test.internal.performance.results.BuildResults;
22
21
import org.eclipse.test.internal.performance.results.ConfigResults;
22
23
/**
24
 * Class used to fill details file of scenario builds data.
25
 * @see ScenarioData
26
 */
23
public class RawDataTable {
27
public class RawDataTable {
24
28
25
	private Scenario scenario;
29
	private ConfigResults configResults;
26
	private String currentBuild;
30
	private List buildPrefixes;
27
	private Dim[] dimensions;
31
	private PrintStream stream;
28
	private Hashtable buildIDTable;
32
	private Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
29
	private Hashtable derivedValues;
33
	private boolean debug = false;
30
	private String TOTAL="total";
34
31
	private String SAMPLECOUNT="n";
35
private RawDataTable(ConfigResults results, PrintStream ps) {
32
	private String MEAN="mean";
36
	this.configResults = results;
33
	private String STDDEV="stddev";
37
	this.stream = ps;
34
	private String CV="cv";
38
}
35
	private ArrayList buildIDPatterns;
36
		
37
	
38
	public RawDataTable(Scenario scenario, Dim[] dimensions, ArrayList buildIDPatterns, String currentBuild) {
39
		this.scenario = scenario;
40
		this.dimensions = dimensions;
41
		this.buildIDPatterns=buildIDPatterns;
42
		this.currentBuild=currentBuild;
43
		buildIDTable = new Hashtable();
44
		derivedValues=new Hashtable();
45
		fill();
46
	}
47
	
48
	public RawDataTable(Scenario scenario, Dim[] dimensions, String buildIDPrefix,String currentBuild) {
49
		buildIDPatterns=new ArrayList();
50
		buildIDPatterns.add(buildIDPrefix);
51
		this.currentBuild=currentBuild;
52
		this.scenario = scenario;
53
		this.dimensions = dimensions;
54
		buildIDTable = new Hashtable();
55
		derivedValues=new Hashtable();
56
		fill();
57
	}
58
59
	private void fill() {
60
61
		for (int i = 0; i < dimensions.length; i++) {
62
			TimeSeries ts = scenario.getTimeSeries(dimensions[i]);
63
			double total = 0.0;
64
			int samplesCount=0;
65
			for (int j = 0; j < ts.getLength(); j++) {
66
				String buildID = ts.getLabel(j);
67
				double value = 0.0;
68
				boolean buildIDmatches=false;
69
				Iterator iterator=buildIDPatterns.iterator();
70
				while (iterator.hasNext()){
71
					Object tmp=iterator.next();
72
					if (tmp==null)
73
						continue;
74
					if (buildID.startsWith(tmp.toString())){
75
							buildIDmatches=true;
76
							break;
77
					}
78
				}
79
				if (!buildIDmatches)
80
					continue;
81
				
82
				Hashtable samples=(Hashtable)buildIDTable.get(buildID);
83
				if (samples==null)
84
					samples=new Hashtable();
85
				value = ts.getValue(j);
86
				
87
				// store result for build
88
				samples.put(dimensions[i].getName(),new Double(value));
89
				buildIDTable.put(buildID,samples);
90
91
				//keep count of samples added and total value
92
				total+=value;
93
				samplesCount++;
94
				
95
				//quit after current build
96
				if (buildID.equals(currentBuild))
97
					break;
98
			}
99
					
100
			double mean = total / samplesCount;
101
			double squaredValues = 0.0;
102
		
103
			String[] buildIDs=(String[])buildIDTable.keySet().toArray(new String[buildIDTable.size()]);
104
			for (int j = 0; j < buildIDs.length; j++) {
105
				String buildID = buildIDs[j];
106
				Hashtable storedValues=(Hashtable)buildIDTable.get(buildID);
107
				double value = ((Double) (storedValues.get(dimensions[i].getName()))).doubleValue();
108
				double squaredValue = Math.pow(value - mean, 2);
109
				squaredValues += squaredValue;
110
			}
111
39
112
			double standardDeviation = Math.sqrt((squaredValues / (samplesCount - 1)));
40
public RawDataTable(ConfigResults results, List prefixes, PrintStream ps) {
113
			double coefficientOfVariation = Math.round(((standardDeviation) / mean) * 100 * 100) / 100;
41
	this(results, ps);
114
			
42
	this.buildPrefixes = prefixes;
115
			if (coefficientOfVariation>10&&dimensions[i].getName().startsWith("Elapsed"))
43
}
116
				System.out.println(scenario.getScenarioName()+": "+" "+coefficientOfVariation);
44
public RawDataTable(ConfigResults results, String baselinePrefix, PrintStream ps) {
117
			
45
	this(results, ps);
118
			//store derived values
46
	this.buildPrefixes = new ArrayList();
119
			Hashtable calculatedValuesForDimension=new Hashtable();		
47
	this.buildPrefixes.add(baselinePrefix);
120
			calculatedValuesForDimension.put(TOTAL,dimensions[i].getDisplayValue(total));
48
}
121
			calculatedValuesForDimension.put(SAMPLECOUNT,new Integer(samplesCount));
122
			calculatedValuesForDimension.put(MEAN, dimensions[i].getDisplayValue(mean));
123
			calculatedValuesForDimension.put(STDDEV, dimensions[i].getDisplayValue(standardDeviation));
124
			calculatedValuesForDimension.put(CV, coefficientOfVariation+"%");
125
			derivedValues.put(dimensions[i].getName(),calculatedValuesForDimension);
126
			
127
		}
128
	}
129
49
130
	public String toHtmlString(){
50
/**
131
		return "<table border=\"1\">"+htmlSummary()+htmlDetails()+"</table>\n";
51
 * Print all build data to the current stream.
132
	}
52
 */
133
	
53
public void print(){
134
	private String[] sortBuildIDsByDate(String[] buildIDs) {
54
	stream.print("<table border=\"1\">");
135
		Hashtable tmp = new Hashtable();
55
	printSummary();
136
		String[] result = new String[buildIDs.length];
56
	printDetails();
137
57
	stream.println("</table>");
138
		for (int i = 0; i < buildIDs.length; i++) {
58
}
139
			String date=Utils.getDateFromBuildID(buildIDs[i], true)+"";
140
			if (date.equals("-1"))
141
				date=buildIDs[i];
142
			tmp.put(date, buildIDs[i]);
143
		}
144
		String[] dates = (String[]) tmp.keySet().toArray(new String[tmp.size()]);
145
		Arrays.sort(dates);
146
		for (int i = 0; i < dates.length; i++) {
147
			result[i] = tmp.get(dates[i]).toString();
148
		}
149
59
150
		return result;
60
/*
61
 * Print table columns headers.
62
 */
63
private void printColumnHeaders() {
64
	StringBuffer buffer = new StringBuffer();
65
	int length = this.dimensions.length;
66
	for (int i=0; i<length; i++) {
67
		buffer.append("<td><b>");
68
		buffer.append(this.dimensions[i].getName());
69
		buffer.append("</b></td>");
151
	}
70
	}
71
	stream.print(buffer.toString());
72
}
152
73
153
	private String htmlDimensionColumnHeaders() {
74
/*
154
		String result="";
75
 * Print all build results in the table.
155
		for (int i=0;i<dimensions.length;i++){
76
 */
156
			result = result.concat("<td><b>"+dimensions[i].getName()+"</b></td>");
77
private void printDetails() {
78
	stream.print("<tr><td><b>Build ID</b></td>");
79
	printColumnHeaders();
80
	stream.println("</tr>");
81
82
	List builds = this.configResults.getBuildsMatchingPrefixes(this.buildPrefixes);
83
	Collections.reverse(builds);
84
	int size = builds.size();
85
	for (int i=0; i<size; i++) {
86
		BuildResults buildResults = (BuildResults) builds.get(i);
87
		stream.print("<tr><td>");
88
		stream.print(buildResults.getName());
89
		stream.print("</td>");
90
		int dimLength = this.dimensions.length;
91
		for (int d=0; d<dimLength; d++) {
92
			int dim_id = this.dimensions[d].getId();
93
			double value = buildResults.getValue(dim_id);
94
			printDimTitle(this.dimensions[d].getName());
95
			String displayValue = this.dimensions[d].getDisplayValue(value);
96
			stream.print(displayValue);
97
			if (debug) System.out.print("\t"+displayValue);
98
			stream.print("</td>");
157
		}
99
		}
158
		return result;
100
		if (debug) System.out.println();
101
		stream.println("</tr>");
159
	}
102
	}
103
	if (debug) System.out.println("\n");
104
}
160
105
161
	private String htmlDetails() {	
106
/*
162
		String result="<tr><td><b>Build ID</b></td>";
107
 * Print summary on top of the table.
163
		result = result.concat(htmlDimensionColumnHeaders());
108
 */
164
		result = result.concat("</tr>\n");
109
private void printSummary() {
165
	
110
	stream.print("<tr><td><b>Stats</b></td>");
166
		Set sampleKeys = buildIDTable.keySet();
111
	printColumnHeaders();
167
		String[] buildIDs = sortBuildIDsByDate((String[]) sampleKeys.toArray(new String[buildIDTable.size()]));
112
	stream.println("</tr>");
168
113
169
		for (int i = buildIDs.length; i > 0; i--) {
114
	int length = this.dimensions.length;
170
			String buildID = buildIDs[i-1];
115
	double[][] dimStats = new double[2][];
171
			if (buildID == null)
116
	for (int i=0; i<this.dimensions.length; i++) {
172
				continue;
117
		dimStats[i] = this.configResults.getStatistics(this.buildPrefixes, this.dimensions[i].getId());
173
			
118
	}
174
			Hashtable values=(Hashtable)buildIDTable.get(buildID);
119
175
			if (values==null)
120
	stream.print("<tr><td>#BUILDS SAMPLED</td>");
176
				continue;
121
	for (int i=0; i<length; i++) {
177
			
122
		String dimName = this.dimensions[i].getName();
178
			result = result.concat("<tr><td>" + buildID + "</td>\n");
123
		printDimTitle(dimName);
179
124
		stream.print((int)dimStats[i][0]);
180
			for (int j=0;j<dimensions.length;j++){
125
		stream.print("</td>");
181
				double value = 0.0;
126
	}
182
				String dimensionName=dimensions[j].getName();
127
	stream.println("</tr>");
183
				value = ((Double) (values.get(dimensionName))).doubleValue();
128
	stream.print("<tr><td>MEAN</td>");
184
				result = result.concat("<td title=\""+dimensionName+"\">" + dimensions[j].getDisplayValue(value) + "</td>");
129
	printRowDoubles(dimStats, 1);
185
			}	
130
	stream.println("</tr>");
186
		}
131
	stream.print("<tr><td>STD DEV</td>");
187
		result=result.concat("</tr>\n");
132
	printRowDoubles(dimStats, 2);
188
		return result;
133
	stream.println("</tr>");
134
	stream.print("<tr><td>COEF. VAR</td>");
135
	printRowDoubles(dimStats, 3);
136
	stream.println("</tr>");
137
138
	// Blank line
139
	stream.print("<tr>");
140
	for (int i=0; i<length+1;	i++){
141
		stream.print("<td>&nbsp;</td>");
189
	}
142
	}
143
	stream.println("</tr>");
144
}
190
145
191
	private String htmlSummary() {
146
/*
192
		if (derivedValues==null)
147
 * Print values in table row.
193
			return "";
148
 */
194
		//print summary values
149
private void printRowDoubles(double[][] stats, int idx) {
195
		//print totals
150
	int length = this.dimensions.length;
196
		String result="<tr><td><b>Stats</b></td>";
151
	for (int i=0; i<length; i++) {
197
		result = result.concat(htmlDimensionColumnHeaders());
152
		double value = stats[i][idx];
198
		result = result.concat("</tr><tr>\n");
153
		String dimName = this.dimensions[i].getName();
199
		
154
		if (idx == 3) {
200
		//print sample counts
155
			if (value>10 && value<20) {
201
		
156
				stream.print("<td bgcolor=\"yellow\" title=\"");
202
		result = result.concat("<td>#BUILDS SAMPLED</td>\n");
157
			} else if (value>=20) {
203
		result = result.concat(htmSummaryRow(SAMPLECOUNT));
158
				stream.print("<td bgcolor=\"FF9900\" title=\"");
204
159
			} else {
205
		//print averages
160
				stream.print("<td title=\"");
206
		result = result.concat("</tr><tr><td>MEAN</td>\n");
161
			}
207
		result = result.concat(htmSummaryRow(MEAN));
162
			stream.print(dimName);
208
		
163
			stream.print("\">");
209
		//print standard deviation
164
			stream.print(value);
210
		result = result.concat("</tr><tr><td>STD DEV</td>\n");
165
			stream.print("%</td>");
211
		result = result.concat(htmSummaryRow(STDDEV));
166
		} else {
212
		
167
			printDimTitle(dimName);
213
		//print coefficient of variation
168
			stream.print(this.dimensions[i].getDisplayValue(value));
214
		result = result.concat("</tr><tr><td>CV</td>\n");
169
			stream.print("</td>");
215
		result = result.concat(htmSummaryRow(CV));
216
217
		result = result.concat("</tr><tr>\n");
218
		for (int i=0;i<dimensions.length+1;i++){
219
			result=result.concat("<td>&nbsp;</td>");
220
		}
221
		result=result.concat("</tr>\n");
222
		
223
		return result;
224
	}
225
226
	private String htmSummaryRow(String summaryType) {
227
		String result="";
228
		Hashtable tmp;
229
		for (int j=0;j<dimensions.length;j++){
230
			String dimensionName=dimensions[j].getName();
231
			tmp=(Hashtable)(derivedValues.get(dimensionName));
232
			String displayValue=tmp.get(summaryType).toString();
233
			if (summaryType.equals(CV)){
234
				displayValue=displayValue.substring(0,displayValue.length()-1);
235
				double value=Double.valueOf(displayValue).doubleValue();
236
				if (value>10&&value<20)
237
					result = result.concat("<td bgcolor=\"yellow\" title=\""+dimensionName+"\">"+displayValue+"%</td>");
238
				else if (value>=20)
239
					result = result.concat("<td bgcolor=\"FF9900\" title=\""+dimensionName+"\">"+displayValue+"%</td>");
240
				else
241
					result = result.concat("<td title=\""+dimensionName+"\">"+displayValue+"%</td>");
242
			} else
243
				result= result.concat("<td title=\""+dimensionName+"\">"+displayValue+"</td>");
244
		}
170
		}
245
		return result;
246
	}
171
	}
172
}
247
173
248
	public String getCV() {
174
/*
249
		Hashtable tmp;
175
 * Print dim title inside value reference.
250
		String dimensionName="Elapsed Process";
176
 * TODO (frederic) See if this title is really necessary
251
		tmp=(Hashtable)(derivedValues.get(dimensionName));
177
 */
252
		if (tmp==null)
178
private void printDimTitle(String dimName) {
253
			return "n/a";
179
    stream.print("<td title=\"");
254
		if (tmp.get(CV)!=null)
180
    stream.print(dimName);
255
		return tmp.get(CV).toString();
181
    stream.print("\">");
256
		return "n/a";
182
}
257
		
258
	}
259
}
183
}
(-)META-INF/MANIFEST.MF (-1 lines)
Lines 11-17 Link Here
11
 org.eclipse.test.performance,
11
 org.eclipse.test.performance,
12
 org.eclipse.swt,
12
 org.eclipse.swt,
13
 org.apache.derby;resolution:=optional,
13
 org.apache.derby;resolution:=optional,
14
 org.apache.derby.core;resolution:=optional,
15
 Cloudscape;resolution:=optional,
14
 Cloudscape;resolution:=optional,
16
 org.junit
15
 org.junit
17
Eclipse-LazyStart: true
16
Eclipse-LazyStart: true
(-)src/org/eclipse/test/performance/ui/ScenarioData.java (+409 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2004, 2007 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.performance.ui;
12
13
import java.io.BufferedOutputStream;
14
import java.io.File;
15
import java.io.FileNotFoundException;
16
import java.io.FileOutputStream;
17
import java.io.IOException;
18
import java.io.OutputStream;
19
import java.io.PrintStream;
20
import java.util.ArrayList;
21
import java.util.Iterator;
22
import java.util.List;
23
24
import junit.framework.AssertionFailedError;
25
26
import org.eclipse.swt.SWT;
27
import org.eclipse.swt.graphics.Color;
28
import org.eclipse.swt.graphics.Image;
29
import org.eclipse.swt.graphics.ImageData;
30
import org.eclipse.swt.graphics.ImageLoader;
31
import org.eclipse.swt.widgets.Display;
32
import org.eclipse.test.internal.performance.data.Dim;
33
import org.eclipse.test.internal.performance.data.DimensionMessages;
34
import org.eclipse.test.internal.performance.results.AbstractResults;
35
import org.eclipse.test.internal.performance.results.BuildResults;
36
import org.eclipse.test.internal.performance.results.ComponentResults;
37
import org.eclipse.test.internal.performance.results.ConfigResults;
38
import org.eclipse.test.internal.performance.results.PerformanceResults;
39
import org.eclipse.test.internal.performance.results.ScenarioResults;
40
41
/**
42
 * Class used to print scenario all builds data.
43
 */
44
public class ScenarioData {
45
	private String baselinePrefix = null;
46
	private List pointsOfInterest;
47
	private List buildIDStreamPatterns;
48
	private File rootDir;
49
50
/**
51
 * Summary of results for a scenario for a given build compared to a
52
 * reference.
53
 *
54
 * @param baselinePrefix The prefix of the baseline build names
55
 * @param pointsOfInterest A list of buildId's to highlight on line graphs
56
 * @param buildIDPatterns
57
 * @param outputDir The directory root where the files are generated
58
 *
59
*/
60
public ScenarioData(String baselinePrefix, List pointsOfInterest, List buildIDPatterns, File outputDir) {
61
	this.baselinePrefix = baselinePrefix;
62
	this.pointsOfInterest = pointsOfInterest;
63
	this.buildIDStreamPatterns = buildIDPatterns;
64
	this.rootDir = outputDir;
65
}
66
67
/**
68
 * Print the scenario all builds data from the given performance results.
69
 * 
70
 * @param performanceResults The needed information to generate scenario data
71
 */
72
public void print(PerformanceResults performanceResults) {
73
	String[] configNames = performanceResults.getConfigNames(false/*not sorted*/);
74
	String[] configBoxes = performanceResults.getConfigBoxes(false/*not sorted*/);
75
	int length = configNames.length;
76
	for (int i=0; i<length; i++) {
77
		File outputDir = new File(this.rootDir, configNames[i]);
78
		outputDir.mkdir();
79
		Iterator components = performanceResults.getResults();
80
		while (components.hasNext()) {
81
			ComponentResults componentResults = (ComponentResults) components.next();
82
			printSummary(configNames[i], configBoxes[i], componentResults, outputDir);
83
			printDetails(configNames[i], configBoxes[i], componentResults, outputDir);
84
		}
85
	}
86
}
87
88
/*
89
 * Print the summary file of the builds data.
90
 */
91
private void printSummary(String configName, String configBox, ComponentResults componentResults, File outputDir) {
92
	Iterator scenarii = componentResults.getResults();
93
	while (scenarii.hasNext()) {
94
		List highlightedPoints = new ArrayList();
95
		ScenarioResults scenarioResults = (ScenarioResults) scenarii.next();
96
		ConfigResults configResults = scenarioResults.getConfigResults(configName);
97
		if (configResults == null || !configResults.isValid()) continue;
98
99
		// get latest points of interest matching
100
		if (this.pointsOfInterest != null) {
101
			Iterator buildPrefixes = this.pointsOfInterest.iterator();
102
			while (buildPrefixes.hasNext()) {
103
				String buildPrefix = (String) buildPrefixes.next();
104
				List builds = configResults.getBuilds(buildPrefix);
105
				if (buildPrefix.indexOf('*') <0 && buildPrefix.indexOf('?') < 0) {
106
					if (builds.size() > 0) {
107
						highlightedPoints.add(builds.get(builds.size()-1));
108
					}
109
				} else {
110
					highlightedPoints.addAll(builds);
111
				}
112
			}
113
		}
114
115
		String scenarioFileName = scenarioResults.getFileName();
116
		File outFile = new File(outputDir, scenarioFileName + ".html");
117
		PrintStream stream = null;
118
		try {
119
			stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outFile)));
120
		} catch (FileNotFoundException e) {
121
			System.err.println("can't create output file" + outFile); //$NON-NLS-1$
122
		}
123
		if (stream == null) {
124
			stream = System.out;
125
		}
126
		stream.println(Utils.HTML_OPEN);
127
		stream.println(Utils.HTML_DEFAULT_CSS);
128
129
		stream.println("<title>" + scenarioResults.getName() + "(" + configBox + ")" + "</title></head>"); //$NON-NLS-1$
130
		stream.println("<h4>Scenario: " + scenarioResults.getName() + " (" + configBox + ")</h4><br>"); //$NON-NLS-1$ //$NON-NLS-2$
131
132
		String failureMessage = Utils.failureMessage(configResults.getCurrentBuildDeviation(), true);
133
 		if (failureMessage != null){
134
   			stream.println("<table><tr><td><b>"+failureMessage+"</td></tr></table>\n");
135
 		}
136
137
 		BuildResults currentBuildResults = configResults.getCurrentBuildResults();
138
 		String comment = currentBuildResults.getComment();
139
		if (comment != null) {
140
			stream.println("<p><b>Note:</b><br>\n");
141
			stream.println(comment + "</p>");
142
		}
143
144
		// Print link to raw data.
145
		String rawDataFile = scenarioFileName+"_raw.html";
146
		stream.println("<br><br><b><a href=\""+rawDataFile+"\">Raw data and Stats</a></b><br><br>\n");
147
		stream.println("<b>Click measurement name to view line graph of measured values over builds.</b><br><br>\n");
148
149
		try {
150
			// Print build result table
151
			stream.println("<table border=\"1\">"); //$NON-NLS-1$
152
			stream.print("<tr><td><b>Build Id</b></td>"); //$NON-NLS-1$
153
			Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
154
			int dimLength = dimensions.length;
155
			for (int d=0; d<dimLength; d++) {
156
				String dimName = dimensions[d].getName();
157
				stream.print("<td><a href=\"#" + configName + "_" + scenarioFileName + "_" + dimName + "\"><b>" + dimName + "</b></a></td>");
158
			}
159
			stream.println("</tr>\n");
160
161
			// Write build lines
162
			printTableLine(stream, currentBuildResults);
163
			printTableLine(stream, configResults.getBaselineBuildResults());
164
165
			// Write difference line
166
			printDifferenceLine(stream, configResults);
167
168
			// End of table
169
			stream.println("</table>");
170
			stream.println("*Delta values in red and green indicate degradation > 10% and improvement > 10%,respectively.<br><br>");
171
			stream.println("<br><hr>\n\n");
172
173
			// print text legend.
174
			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"
175
					+ "Boxed points represent previous releases, milestone builds, current reference and current build.<br><br>\n"
176
					+ "Hover over any point for build id and value.\n");
177
178
			// print image maps of historical
179
			for (int d=0; d<dimLength; d++) {
180
				String dimName = dimensions[d].getName();
181
				int dim_id = dimensions[d].getId();
182
				TimeLineGraph lineGraph = getLineGraph(scenarioResults, configResults, dimensions[d], highlightedPoints, this.buildIDStreamPatterns);
183
184
				File graphsDir = new File(outputDir, "graphs");
185
				graphsDir.mkdir();
186
				File imgFile = new File(graphsDir, scenarioFileName + "_" + dimName + ".gif");
187
				saveGraph(lineGraph, imgFile);
188
				stream.println("<br><a name=\"" + configName + "_" + scenarioFileName + "_" + dimName + "\"></a>");
189
				stream.println("<br><b>" + dimName + "</b><br>");
190
				stream.println(DimensionMessages.getDescription(dim_id) + "<br><br>\n");
191
				stream.print("<img src=\"graphs/");
192
				stream.print(imgFile.getName());
193
				stream.print("\" usemap=\"#" + lineGraph.fTitle + "\">");
194
				stream.print("<map name=\"" + lineGraph.fTitle + "\">");
195
				stream.print(lineGraph.getAreas());
196
				stream.println("</map>");
197
			}
198
			stream.println("<br><br></body>");
199
			stream.println(Utils.HTML_CLOSE);
200
			if (stream != System.out)
201
				stream.close();
202
203
		} catch (AssertionFailedError e) {
204
			e.printStackTrace();
205
			continue;
206
		}
207
	}
208
}
209
210
/*
211
 * Print the data for a build results.
212
 */
213
private void printTableLine(PrintStream stream, BuildResults buildResults) {
214
	stream.print("<tr><td>");
215
	stream.print(buildResults.getName());
216
	if (buildResults.isBaseline()) stream.print(" (reference)");
217
	stream.print("</td>");
218
	Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
219
	int dimLength = dimensions.length;
220
	for (int d=0; d<dimLength; d++) {
221
		int dim_id = dimensions[d].getId();
222
		double stddev = buildResults.getDeviation(dim_id);
223
		String displayValue = dimensions[d].getDisplayValue(buildResults.getValue(dim_id));
224
		stream.print("<td>");
225
		stream.print(displayValue);
226
		if (stddev < 0) {
227
			stream.println(" [n/a]");
228
		} else if (stddev > 0) {
229
			stream.print(" [");
230
			stream.print(dimensions[d].getDisplayValue(stddev));
231
			stream.print("]");
232
		}
233
		stream.print( "</td>");
234
	}
235
	stream.println("</tr>");
236
}
237
238
/*
239
 * Print the line showing the difference between current and baseline builds.
240
 */
241
private void printDifferenceLine(PrintStream stream, ConfigResults configResults) {
242
	stream.print("<tr><td>*Delta</td>");
243
	Dim[] dimensions = AbstractResults.SUPPORTED_DIMS;
244
	int dimLength = dimensions.length;
245
	for (int d=0; d<dimLength; d++) {
246
		Dim currentDim = dimensions[d];
247
		int dim_id = currentDim.getId();
248
		BuildResults currentBuild = configResults.getCurrentBuildResults();
249
		BuildResults baselineBuild = configResults.getBaselineBuildResults();
250
251
		double baselineValue = baselineBuild.getValue(dim_id);
252
		double diffValue = currentBuild.getValue(dim_id) - baselineValue;
253
		double diffPercentage =  baselineValue == 0 ? 0 : Math.round(diffValue / baselineValue * 1000) / 10.0;
254
		String diffDisplayValue = currentDim.getDisplayValue(diffValue);
255
		// green
256
		String fontColor = "";
257
		if ((diffPercentage < -10 && !currentDim.largerIsBetter()) || (diffPercentage > 10 && currentDim.largerIsBetter()))
258
			fontColor = "#006600";
259
		if ((diffPercentage < -10 && currentDim.largerIsBetter()) || (diffPercentage > 10 && !currentDim.largerIsBetter()))
260
			fontColor = "#FF0000";
261
262
		diffPercentage = Math.abs(diffPercentage);
263
		String percentage = (diffPercentage == 0) ? "" : "<br>" + diffPercentage + " %";
264
265
		if (diffPercentage > 10 || diffPercentage < -10) {
266
			stream.print("<td><FONT COLOR=\"" + fontColor + "\"><b>" + diffDisplayValue + percentage + "</b></FONT></td>");
267
		} else {
268
			stream.print("<td>" + diffDisplayValue + percentage + "</td>");
269
		}
270
	}
271
	stream.print("</tr></font>");
272
}
273
274
/*
275
 * Returns a LineGraph object representing measurements for a scenario over builds.
276
 */
277
private TimeLineGraph getLineGraph(ScenarioResults scenarioResults, ConfigResults configResults, Dim dim, List highlightedPoints, List currentBuildIdPrefixes) {
278
	Display display = Display.getDefault();
279
280
	Color black = display.getSystemColor(SWT.COLOR_BLACK);
281
	Color yellow = display.getSystemColor(SWT.COLOR_DARK_YELLOW);
282
	Color magenta = display.getSystemColor(SWT.COLOR_MAGENTA);
283
284
	String scenarioName = scenarioResults.getName();
285
	TimeLineGraph graph = new TimeLineGraph(scenarioName + ": " + dim.getName(), dim);
286
	String baseline = configResults.getBaselineBuildName();
287
	String current = configResults.getCurrentBuildName();
288
289
	Iterator builds = configResults.getResults();
290
	List lastSevenNightlyBuilds = configResults.lastNightlyBuildNames(7);
291
	buildLoop: while (builds.hasNext()) {
292
		BuildResults buildResults = (BuildResults) builds.next();
293
		String buildID = buildResults.getName();
294
		int underscoreIndex = buildID.indexOf('_');
295
		String label = (underscoreIndex != -1 && (buildID.equals(baseline) || buildID.equals(current))) ? buildID.substring(0, underscoreIndex) : buildID;
296
297
		double value = buildResults.getValue(dim.getId());
298
299
		if (buildID.equals(current)) {
300
			Color color = black;
301
			if (buildID.startsWith("N"))
302
				color = yellow;
303
304
			graph.addItem("main", label, dim.getDisplayValue(value), value, color, true, Utils.getDateFromBuildID(buildID), true);
305
			continue;
306
		}
307
		if (highlightedPoints.contains(buildID)) {
308
			graph.addItem("main", label, dim.getDisplayValue(value), value, black, false, Utils.getDateFromBuildID(buildID, false), true);
309
			continue;
310
		}
311
		if (buildID.charAt(0) == 'N') {
312
			if (lastSevenNightlyBuilds.contains(buildID)) {
313
				graph.addItem("main", buildID, dim.getDisplayValue(value), value, yellow, false, Utils.getDateFromBuildID(buildID), false);
314
			}
315
			continue;
316
		}
317
		for (int i=0;i<currentBuildIdPrefixes.size();i++){
318
			if (buildID.startsWith(currentBuildIdPrefixes.get(i).toString())) {
319
				graph.addItem("main", buildID, dim.getDisplayValue(value), value, black, false, Utils.getDateFromBuildID(buildID), false);
320
				continue buildLoop;
321
			}
322
		}
323
		if (buildID.equals(baseline)) {
324
			boolean drawBaseline = (baselinePrefix != null) ? false : true;
325
			graph.addItem("reference", label, dim.getDisplayValue(value), value, magenta, true, Utils.getDateFromBuildID(buildID, true), true, drawBaseline);
326
			continue;
327
		}
328
		if (baselinePrefix != null) {
329
			if (buildID.startsWith(baselinePrefix) && !buildID.equals(baseline) && Utils.getDateFromBuildID(buildID, true) <= Utils.getDateFromBuildID(baseline, true)) {
330
				graph.addItem("reference", label, dim.getDisplayValue(value), value, magenta, false, Utils.getDateFromBuildID(buildID, true), false);
331
				continue;
332
			}
333
		}
334
	}
335
	return graph;
336
}
337
338
/*
339
 * Print details file of the scenario builds data.
340
 */
341
private void printDetails(String configName, String configBox, ComponentResults componentResults, File outputDir) {
342
	Iterator scenarii = componentResults.getResults();
343
	while (scenarii.hasNext()) {
344
		ScenarioResults scenarioResults = (ScenarioResults) scenarii.next();
345
		ConfigResults configResults = scenarioResults.getConfigResults(configName);
346
		if (configResults == null || !configResults.isValid()) continue;
347
		String scenarioName= scenarioResults.getName();
348
		String scenarioFileName = scenarioResults.getFileName();
349
		File outFile = new File(outputDir, scenarioFileName + "_raw.html");
350
		PrintStream stream = null;
351
		try {
352
			stream = new PrintStream(new BufferedOutputStream(new FileOutputStream(outFile)));
353
		} catch (FileNotFoundException e) {
354
			System.err.println("can't create output file" + outFile); //$NON-NLS-1$
355
		}
356
		if (stream == null) stream = System.out;
357
		RawDataTable currentResultsTable = new RawDataTable(configResults, this.buildIDStreamPatterns, stream);
358
		RawDataTable baselineResultsTable = new RawDataTable(configResults, this.baselinePrefix, stream);
359
		stream.println(Utils.HTML_OPEN);
360
		stream.println(Utils.HTML_DEFAULT_CSS);
361
		stream.println("<title>" + scenarioName + "(" + configBox + ")" + " - Details</title></head>"); //$NON-NLS-1$
362
		stream.println("<h4>Scenario: " + scenarioName + " (" + configBox + ")</h4>"); //$NON-NLS-1$
363
		stream.println("<a href=\""+scenarioFileName+".html\">VIEW GRAPH</a><br><br>"); //$NON-NLS-1$
364
		stream.println("<table><td><b>Current Stream Test Runs</b></td><td><b>Baseline Test Runs</b></td></tr>\n");
365
		stream.println("<tr valign=\"top\">");
366
		stream.print("<td>");
367
		currentResultsTable.print();
368
		stream.println("</td>");
369
		stream.print("<td>");
370
		baselineResultsTable.print();
371
		stream.println("</td>");
372
		stream.println("</tr>");
373
		stream.println("</table>");
374
		stream.close();
375
	}
376
}
377
378
/*
379
 * Prints a LineGraph object as a gif file.
380
 */
381
private void saveGraph(LineGraph p, File outputFile) {
382
	int GRAPH_WIDTH = 600;
383
	int GRAPH_HEIGHT = 200;
384
	Image image = new Image(Display.getDefault(), GRAPH_WIDTH, GRAPH_HEIGHT);
385
	p.paint(image);
386
387
	/* Downscale to 8 bit depth palette to save to gif */
388
	ImageData data = Utils.downSample(image);
389
	ImageLoader il = new ImageLoader();
390
	il.data = new ImageData[] { data };
391
	OutputStream out = null;
392
	try {
393
		out = new BufferedOutputStream(new FileOutputStream(outputFile));
394
		il.save(out, SWT.IMAGE_GIF);
395
396
	} catch (FileNotFoundException e) {
397
		e.printStackTrace();
398
	} finally {
399
		image.dispose();
400
		if (out != null) {
401
			try {
402
				out.close();
403
			} catch (IOException e1) {
404
				// silently ignored
405
			}
406
		}
407
	}
408
}
409
}
(-)src/org/eclipse/test/internal/performance/data/DimensionMessages.java (-2 / +6 lines)
Lines 26-34 Link Here
26
	private DimensionMessages() {
26
	private DimensionMessages() {
27
		// emtpy
27
		// emtpy
28
	}
28
	}
29
	
29
30
	public static String getString(int id) {
30
	public static String getString(int id) {
31
	    return getString("Dimension." + id); //$NON-NLS-1$
31
	    return getString("dimension." + id); //$NON-NLS-1$
32
	}
33
34
	public static String getDescription(int id) {
35
	    return getString("dimension.description." + id); //$NON-NLS-1$
32
	}
36
	}
33
37
34
	public static String getString(String key) {
38
	public static String getString(String key) {
(-)src/org/eclipse/test/internal/performance/data/DimensionMessages.properties (-40 / +84 lines)
Lines 8-50 Link Here
8
# Contributors:
8
# Contributors:
9
#     IBM Corporation - initial API and implementation
9
#     IBM Corporation - initial API and implementation
10
###############################################################################
10
###############################################################################
11
Dimension.2=System Time
11
12
Dimension.3=Used Java Heap
12
# Dimension Name
13
Dimension.4=Working Set
13
dimension.2=System Time
14
Dimension.7=Committed
14
dimension.3=Used Java Heap
15
Dimension.8=Working Set Peak
15
dimension.4=Working Set
16
Dimension.9=Elapsed Process
16
dimension.7=Committed
17
Dimension.10=User time
17
dimension.8=Working Set Peak
18
Dimension.11=Kernel time
18
dimension.9=Elapsed Process
19
Dimension.19=Page Faults
19
dimension.10=User time
20
Dimension.20=CPU Time
20
dimension.11=Kernel time
21
Dimension.22=Commit Limit
21
dimension.19=Page Faults
22
Dimension.23=Commit Peak
22
dimension.20=CPU Time
23
Dimension.24=Physical Memory
23
dimension.22=Commit Limit
24
Dimension.25=Physical Available
24
dimension.23=Commit Peak
25
Dimension.26=System Cache
25
dimension.24=Physical Memory
26
Dimension.27=Kernel Total
26
dimension.25=Physical Available
27
Dimension.28=Kernel Paged
27
dimension.26=System Cache
28
Dimension.29=Kernel Nonpaged
28
dimension.27=Kernel Total
29
Dimension.30=Page Size
29
dimension.28=Kernel Paged
30
Dimension.31=Handle Count
30
dimension.29=Kernel Nonpaged
31
Dimension.32=Process Count
31
dimension.30=Page Size
32
Dimension.33=Thread Count
32
dimension.31=Handle Count
33
Dimension.34=GDI Objects
33
dimension.32=Process Count
34
Dimension.35=USER Objects
34
dimension.33=Thread Count
35
Dimension.36=Open Handles
35
dimension.34=GDI Objects
36
Dimension.37=Commit Total
36
dimension.35=USER Objects
37
Dimension.38=Read Count
37
dimension.36=Open Handles
38
Dimension.39=Write Count
38
dimension.37=Commit Total
39
Dimension.40=Bytes Read
39
dimension.38=Read Count
40
Dimension.41=Bytes Written
40
dimension.39=Write Count
41
Dimension.42=Hard Page Faults
41
dimension.40=Bytes Read
42
Dimension.43=Soft Page Faults
42
dimension.41=Bytes Written
43
Dimension.44=Text Size
43
dimension.42=Hard Page Faults
44
Dimension.45=Data Size
44
dimension.43=Soft Page Faults
45
Dimension.46=Library Size
45
dimension.44=Text Size
46
Dimension.48=Used Memory
46
dimension.45=Data Size
47
Dimension.49=Free Memory
47
dimension.46=Library Size
48
Dimension.50=Buffers Memory
48
dimension.48=Used Memory
49
Dimension.51=Free Java Memory
49
dimension.49=Free Memory
50
Dimension.52=Invocation Count
50
dimension.50=Buffers Memory
51
dimension.51=Free Java Memory
52
dimension.52=Invocation Count
53
54
# Dimension Description
55
dimension.description.2=* no longer measured, same as elapsed time, see PerformanceMonitor *
56
dimension.description.3=Change in the amount of memory allocated for Java objects.
57
dimension.description.4=Change in the amount of physical memory used by the process (other data resides in swap space).
58
dimension.description.7=Change in the amount of allocated memory (both, in physical memory and swap space, can be preallocated for future use).
59
dimension.description.8=Increase of the maximum working set size, useful with start-up tests.
60
dimension.description.9=Amount of wall-clock time.
61
dimension.description.10=User time
62
dimension.description.11=Amount of time the process ran on the CPU, while the CPU was in kernel mode.
63
dimension.description.19=Number of memory pages that were loaded from swap space on disk or from memory (i.e., in the latter case, they were not mapped in the process' page table, but already present in memory for some reason).
64
dimension.description.20=Amount of time the process ran on the CPU.
65
dimension.description.22=Commit Limit
66
dimension.description.23=Commit Peak
67
dimension.description.24=Physical Memory
68
dimension.description.25=Physical Available
69
dimension.description.26=System Cache
70
dimension.description.27=Kernel Total
71
dimension.description.28=Kernel Paged
72
dimension.description.29=Kernel Nonpaged
73
dimension.description.30=Page Size
74
dimension.description.31=Handle Count
75
dimension.description.32=Process Count
76
dimension.description.33=Thread Count
77
dimension.description.34=Change in the number of GDI (Graphics Device Interface) objects, can be useful for UI tests (particularly start-up tests).
78
dimension.description.35=USER Objects
79
dimension.description.36=Open Handles
80
dimension.description.37=Commit Total
81
dimension.description.38=Read Count
82
dimension.description.39=Write Count
83
dimension.description.40=Bytes Read
84
dimension.description.41=Bytes Written
85
dimension.description.42=Number of memory pages that were loaded from swap space on disk.
86
dimension.description.43=Number of memory pages that were loaded from memory (i.e., they were not mapped in the process' page table, but already present in memory for some reason).
87
dimension.description.44=Change in the process' code memory size, useful with start-up tests.
88
dimension.description.45=Change in the process' data and stack memory size.
89
dimension.description.46=Change in the process' library memory size.
90
dimension.description.48=Used Memory
91
dimension.description.49=Free Memory
92
dimension.description.50=Buffers Memory
93
dimension.description.51=Free Java Memory
94
dimension.description.52=Invocation Count
(-)src/org/eclipse/test/internal/performance/data/Dim.java (-1 / +5 lines)
Lines 69-78 Link Here
69
	public boolean largerIsBetter() {
69
	public boolean largerIsBetter() {
70
	    return fLargerIsBetter;
70
	    return fLargerIsBetter;
71
	}
71
	}
72
	
72
73
	public String getName() {
73
	public String getName() {
74
		return DimensionMessages.getString(fId);
74
		return DimensionMessages.getString(fId);
75
	}
75
	}
76
77
	public String getDescription() {
78
		return DimensionMessages.getString(fId);
79
	}
76
	
80
	
77
	public String toString() {
81
	public String toString() {
78
		return "Dimension [name=" + getName() + ", " + fUnit + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
82
		return "Dimension [name=" + getName() + ", " + fUnit + "]"; //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
(-).settings/org.eclipse.jdt.core.prefs (-64 / +67 lines)
Lines 1-64 Link Here
1
#Wed Apr 19 13:00:25 CEST 2006
1
#Fri Aug 10 17:30:18 CEST 2007
2
eclipse.preferences.version=1
2
eclipse.preferences.version=1
3
org.eclipse.jdt.core.builder.cleanOutputFolder=clean
3
org.eclipse.jdt.core.builder.cleanOutputFolder=clean
4
org.eclipse.jdt.core.builder.duplicateResourceTask=warning
4
org.eclipse.jdt.core.builder.duplicateResourceTask=warning
5
org.eclipse.jdt.core.builder.invalidClasspath=abort
5
org.eclipse.jdt.core.builder.invalidClasspath=abort
6
org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
6
org.eclipse.jdt.core.builder.resourceCopyExclusionFilter=*.launch
7
org.eclipse.jdt.core.circularClasspath=error
7
org.eclipse.jdt.core.circularClasspath=error
8
org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
8
org.eclipse.jdt.core.classpath.exclusionPatterns=enabled
9
org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
9
org.eclipse.jdt.core.classpath.multipleOutputLocations=enabled
10
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
10
org.eclipse.jdt.core.compiler.codegen.inlineJsrBytecode=disabled
11
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
11
org.eclipse.jdt.core.compiler.codegen.targetPlatform=1.2
12
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
12
org.eclipse.jdt.core.compiler.codegen.unusedLocal=preserve
13
org.eclipse.jdt.core.compiler.compliance=1.4
13
org.eclipse.jdt.core.compiler.compliance=1.4
14
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
14
org.eclipse.jdt.core.compiler.debug.lineNumber=generate
15
org.eclipse.jdt.core.compiler.debug.localVariable=generate
15
org.eclipse.jdt.core.compiler.debug.localVariable=generate
16
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
16
org.eclipse.jdt.core.compiler.debug.sourceFile=generate
17
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
17
org.eclipse.jdt.core.compiler.doc.comment.support=enabled
18
org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
18
org.eclipse.jdt.core.compiler.maxProblemPerUnit=100
19
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
19
org.eclipse.jdt.core.compiler.problem.assertIdentifier=warning
20
org.eclipse.jdt.core.compiler.problem.deprecation=warning
20
org.eclipse.jdt.core.compiler.problem.deprecation=warning
21
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
21
org.eclipse.jdt.core.compiler.problem.deprecationInDeprecatedCode=disabled
22
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
22
org.eclipse.jdt.core.compiler.problem.deprecationWhenOverridingDeprecatedMethod=disabled
23
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
23
org.eclipse.jdt.core.compiler.problem.emptyStatement=warning
24
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
24
org.eclipse.jdt.core.compiler.problem.enumIdentifier=warning
25
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
25
org.eclipse.jdt.core.compiler.problem.fieldHiding=warning
26
org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
26
org.eclipse.jdt.core.compiler.problem.finalParameterBound=ignore
27
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
27
org.eclipse.jdt.core.compiler.problem.finallyBlockNotCompletingNormally=warning
28
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
28
org.eclipse.jdt.core.compiler.problem.hiddenCatchBlock=error
29
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
29
org.eclipse.jdt.core.compiler.problem.incompatibleNonInheritedInterfaceMethod=error
30
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
30
org.eclipse.jdt.core.compiler.problem.indirectStaticAccess=warning
31
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
31
org.eclipse.jdt.core.compiler.problem.invalidJavadoc=warning
32
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
32
org.eclipse.jdt.core.compiler.problem.invalidJavadocTags=enabled
33
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
33
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsDeprecatedRef=enabled
34
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
34
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsNotVisibleRef=disabled
35
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
35
org.eclipse.jdt.core.compiler.problem.invalidJavadocTagsVisibility=private
36
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
36
org.eclipse.jdt.core.compiler.problem.localVariableHiding=warning
37
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
37
org.eclipse.jdt.core.compiler.problem.methodWithConstructorName=error
38
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
38
org.eclipse.jdt.core.compiler.problem.missingJavadocComments=ignore
39
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
39
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsOverriding=enabled
40
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
40
org.eclipse.jdt.core.compiler.problem.missingJavadocCommentsVisibility=public
41
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
41
org.eclipse.jdt.core.compiler.problem.missingJavadocTags=warning
42
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
42
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsOverriding=enabled
43
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
43
org.eclipse.jdt.core.compiler.problem.missingJavadocTagsVisibility=private
44
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
44
org.eclipse.jdt.core.compiler.problem.missingSerialVersion=warning
45
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
45
org.eclipse.jdt.core.compiler.problem.noEffectAssignment=error
46
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
46
org.eclipse.jdt.core.compiler.problem.noImplicitStringConversion=error
47
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
47
org.eclipse.jdt.core.compiler.problem.nonExternalizedStringLiteral=warning
48
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
48
org.eclipse.jdt.core.compiler.problem.overridingPackageDefaultMethod=error
49
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
49
org.eclipse.jdt.core.compiler.problem.possibleAccidentalBooleanAssignment=error
50
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
50
org.eclipse.jdt.core.compiler.problem.specialParameterHidingField=disabled
51
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
51
org.eclipse.jdt.core.compiler.problem.staticAccessReceiver=error
52
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
52
org.eclipse.jdt.core.compiler.problem.syntheticAccessEmulation=ignore
53
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
53
org.eclipse.jdt.core.compiler.problem.undocumentedEmptyBlock=warning
54
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
54
org.eclipse.jdt.core.compiler.problem.unnecessaryElse=warning
55
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
55
org.eclipse.jdt.core.compiler.problem.unnecessaryTypeCheck=error
56
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
56
org.eclipse.jdt.core.compiler.problem.unqualifiedFieldAccess=ignore
57
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
57
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownException=ignore
58
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
58
org.eclipse.jdt.core.compiler.problem.unusedDeclaredThrownExceptionWhenOverriding=enabled
59
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
59
org.eclipse.jdt.core.compiler.problem.unusedImport=warning
60
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
60
org.eclipse.jdt.core.compiler.problem.unusedLocal=warning
61
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
61
org.eclipse.jdt.core.compiler.problem.unusedParameter=ignore
62
org.eclipse.jdt.core.compiler.source=1.3
62
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenImplementingAbstract=disabled
63
org.eclipse.jdt.core.incompatibleJDKLevel=ignore
63
org.eclipse.jdt.core.compiler.problem.unusedParameterWhenOverridingConcrete=disabled
64
org.eclipse.jdt.core.incompleteClasspath=error
64
org.eclipse.jdt.core.compiler.problem.unusedPrivateMember=warning
65
org.eclipse.jdt.core.compiler.source=1.3
66
org.eclipse.jdt.core.incompatibleJDKLevel=ignore
67
org.eclipse.jdt.core.incompleteClasspath=error
(-)src/org/eclipse/test/internal/performance/db/SQL.java (-3 / +3 lines)
Lines 25-31 Link Here
25
25
26
	private boolean fCompatibility= false;
26
	private boolean fCompatibility= false;
27
27
28
	private Connection fConnection;
28
	protected Connection fConnection;
29
29
30
	private PreparedStatement fInsertVariation, fInsertScenario, fInsertSample, fInsertDataPoint, fInsertScalar;
30
	private PreparedStatement fInsertVariation, fInsertScenario, fInsertSample, fInsertDataPoint, fInsertScalar;
31
	private PreparedStatement fQueryComment, fInsertComment, fQueryComment2;
31
	private PreparedStatement fQueryComment, fInsertComment, fQueryComment2;
Lines 35-41 Link Here
35
			fQuerySummaryEntries;
35
			fQuerySummaryEntries;
36
	private PreparedStatement fInsertFailure, fQueryFailure;
36
	private PreparedStatement fInsertFailure, fQueryFailure;
37
37
38
	SQL(Connection con) throws SQLException {
38
	protected SQL(Connection con) throws SQLException {
39
		fConnection= con;
39
		fConnection= con;
40
40
41
		boolean needsUpgrade= true;
41
		boolean needsUpgrade= true;
Lines 78-84 Link Here
78
		}
78
		}
79
	}
79
	}
80
80
81
	public void dispose() throws SQLException {
81
	protected void dispose() throws SQLException {
82
		if (fInsertVariation != null)
82
		if (fInsertVariation != null)
83
			fInsertVariation.close();
83
			fInsertVariation.close();
84
		if (fInsertScenario != null)
84
		if (fInsertScenario != null)
(-)META-INF/MANIFEST.MF (-1 / +1 lines)
Lines 11-22 Link Here
11
 org.eclipse.test.internal.performance.data,
11
 org.eclipse.test.internal.performance.data,
12
 org.eclipse.test.internal.performance.db,
12
 org.eclipse.test.internal.performance.db,
13
 org.eclipse.test.internal.performance.eval,
13
 org.eclipse.test.internal.performance.eval,
14
 org.eclipse.test.internal.performance.results,
14
 org.eclipse.test.internal.performance.tests,
15
 org.eclipse.test.internal.performance.tests,
15
 org.eclipse.test.performance
16
 org.eclipse.test.performance
16
Require-Bundle: org.eclipse.core.runtime,
17
Require-Bundle: org.eclipse.core.runtime,
17
 org.junit,
18
 org.junit,
18
 org.apache.derby;resolution:=optional,
19
 org.apache.derby;resolution:=optional,
19
 org.apache.derby.core;resolution:=optional,
20
 Cloudscape;resolution:=optional
20
 Cloudscape;resolution:=optional
21
Eclipse-LazyStart: true
21
Eclipse-LazyStart: true
22
Bundle-ClassPath: .
22
Bundle-ClassPath: .
(-)src/org/eclipse/test/internal/performance/results/PerformanceResults.java (+244 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.internal.performance.results;
12
13
import java.util.*;
14
15
16
/**
17
 * Root class to handle performance results.
18
 * 
19
 * Usually performance results are built for a current build vs. a baseline build.
20
 * 
21
 * This class allow to read all data from releng performance database for given
22
 * configurations and scenario pattern.
23
 * 
24
 * Then it provides easy and speedy access to all stored results.
25
 */
26
public class PerformanceResults extends AbstractResults {
27
28
	final String baselineName; // Name of the baseline build used for comparison
29
	final String baselinePrefix;
30
	private String scenarioPattern;
31
	private List components;
32
	private String[] configNames, sortedConfigNames;
33
	private String[] configBoxes, sortedConfigBoxes;
34
35
public PerformanceResults(String name, String baseline, boolean print) {
36
	super(null, name);
37
	this.baselineName = baseline;
38
	this.baselinePrefix = baseline.substring(0, baseline.lastIndexOf('_'));
39
	this.print = print;
40
}
41
42
/**
43
 * Returns the name of the baseline used for extracted results
44
 * 
45
 * @return The build name of the baseline of <code>null</code>
46
 * 	if no specific baseline is used for the extracted results.
47
 */
48
public String getBaselineName() {
49
	return this.baselineName;
50
}
51
52
String getBaselinePrefix() {
53
	return this.baselinePrefix;
54
}
55
56
/**
57
 * Return the list of components concerned by performance results.
58
 * 
59
 * @return The list of the components
60
 */
61
public List getComponents() {
62
	return components;
63
}
64
65
/**
66
 * Get the scenarii of a given component.
67
 *
68
 * @param componentName The component name. Should not be <code>null</code>
69
 * @return A list of {@link ScenarioResults scenario results}
70
 */
71
public List getComponentScenarii(String componentName) {
72
	ComponentResults componentResults = (ComponentResults) getResults(componentName);
73
	if (componentResults == null) return null;
74
	return Collections.unmodifiableList(componentResults.children);
75
}
76
77
/**
78
 * Get the scenarii which have a summary for a given component.
79
 *
80
 * @param componentName The component name
81
 * @param config Configuration name
82
 * @return A list of {@link ScenarioResults scenario results} which have a summary
83
 */
84
public List getComponentSummaryScenarii(String componentName, String config) {
85
	if (componentName == null) {
86
		int size = size();
87
		List scenarii = new ArrayList();
88
		for (int i=0; i< size; i++) {
89
			ComponentResults componentResults = (ComponentResults) this.children.get(i);
90
			scenarii.addAll(componentResults.getSummaryScenarii(true, config));
91
		}
92
		return scenarii;
93
	}
94
	ComponentResults componentResults = (ComponentResults) getResults(componentName);
95
	return componentResults.getSummaryScenarii(false, config);
96
}
97
98
/**
99
 * Return the configuration boxes considered for this performance results
100
 * sorted or not depending on the given flag.
101
 * 
102
 * @param sort Indicates whether the list must be sorted or not.
103
 * 	The order is defined by the configuration names, not by the box names
104
 * @return The list of configuration boxes sorted by configuration names
105
 */
106
public String[] getConfigBoxes(boolean sort) {
107
	return sort ? this.sortedConfigBoxes : this.configBoxes;
108
}
109
110
/**
111
 * Return the configuration names considered for this performance results
112
 * sorted or not depending on the given flag.
113
 * 
114
 * @param sort Indicates whether the list must be sorted or not
115
 * @return The list of configuration names
116
 */
117
public String[] getConfigNames(boolean sort) {
118
	return sort ?this.sortedConfigNames : this.configNames;
119
}
120
121
String getConfigurationsPattern() {
122
	int length = this.sortedConfigNames == null ? 0 : this.sortedConfigNames.length;
123
	if (length == 0) return null;
124
	String configurations = this.sortedConfigNames[0];
125
	int refLength = configurations.length();
126
	for (int i=1; i<length; i++) {
127
		String config = this.sortedConfigNames[i];
128
		StringBuffer newConfig = null;
129
		if (refLength != config.length()) return null; // strings have not the same length => cannot find a pattern
130
		for (int j=0; j<refLength; j++) {
131
			char c = configurations.charAt(j);
132
			if (config.charAt(j) != c) {
133
				if (newConfig == null) {
134
					newConfig = new StringBuffer(refLength);
135
					if (j == 0) return null; // first char is already different => cannot find a pattern
136
					newConfig.append(configurations.substring(0, j));
137
				}
138
				newConfig.append('_');
139
			} else if (newConfig != null) {
140
				newConfig.append(c);
141
			}
142
		}
143
		if (newConfig != null) {
144
			configurations = newConfig.toString();
145
		}
146
	}
147
	return configurations;
148
}
149
150
PerformanceResults getPerformance() {
151
	return this;
152
}
153
154
/**
155
 * Get the results of a given scenario.
156
 *
157
 * @param scenarioName The scenario name
158
 * @return The {@link ScenarioResults scenario results}
159
 */
160
public ScenarioResults getScenarioResults(String scenarioName) {
161
	ComponentResults componentResults = (ComponentResults) getResults(DB_Results.getComponentNameFromScenario(scenarioName));
162
	return componentResults == null ? null : (ScenarioResults) componentResults.getResults(scenarioName);
163
}
164
165
/**
166
 * Read all data from performance database for the given configurations
167
 * and scenario pattern.
168
 * 
169
 * @param configs All configs to extract results. If <code>null</code>,
170
 * 	then all known configurations ({@link #CONFIGS})  are read.
171
 * @param pattern The pattern of the concerned scenarii
172
 */
173
public void read(String[][] configs, String pattern) {
174
175
	this.scenarioPattern = pattern;
176
177
	// Print title
178
	StringBuffer buffer = new StringBuffer("Read performance results until build '"); //$NON-NLS-1$
179
	buffer.append(this.name);
180
	if (scenarioPattern == null) {
181
		buffer.append("':"); //$NON-NLS-1$
182
	} else {
183
		buffer.append("' using scenario pattern '"); //$NON-NLS-1$
184
		buffer.append(scenarioPattern);
185
		buffer.append("':"); //$NON-NLS-1$
186
	}
187
	println(buffer);
188
189
	// Store given configs
190
	if (configs == null) {
191
		int length=CONFIGS.length;
192
		this.configNames = new String[length];
193
		this.sortedConfigNames = new String[length];
194
		this.configBoxes = new String[length];
195
		for (int i=0; i<length; i++) {
196
			this.configNames[i] = this.sortedConfigNames[i] = CONFIGS[i];
197
			this.configBoxes[i] = BOXES[i];
198
		}
199
	} else {
200
		int length = configs.length;
201
		this.configNames = new String[length];
202
		this.sortedConfigNames = new String[length];
203
		this.configBoxes = new String[length];
204
		for (int i=0; i<length; i++) {
205
			this.configNames[i] = this.sortedConfigNames[i] = configs[i][0];
206
			this.configBoxes[i] = configs[i][1];
207
		}
208
	}
209
	Arrays.sort(this.sortedConfigNames);
210
	int length = this.sortedConfigNames.length;
211
	this.sortedConfigBoxes = new String[length];
212
	for (int i=0; i<length; i++) {
213
		for (int j=0; j<length; j++) {
214
			if (this.sortedConfigNames[i] == this.configNames[j]) { // == is intentional!
215
				this.sortedConfigBoxes[i] = this.configBoxes[j];
216
				break;
217
			}
218
		}
219
	}
220
221
	// Get scenarii from the given pattern
222
	print("	+ get all scenarii for build: "+this.name); //$NON-NLS-1$
223
	long start = System.currentTimeMillis();
224
	Map allScenarii = DB_Results.queryAllScenarii(this.scenarioPattern, this.name);
225
	println(" -> "+(System.currentTimeMillis()-start)+"ms"); //$NON-NLS-1$ //$NON-NLS-2$
226
227
	// Create corresponding children
228
	List allComponents = DB_Results.getAllComponents();
229
	int size = allComponents.size();
230
	this.components = new ArrayList(size);
231
	for (int i=0; i<size; i++) {
232
		String componentName = (String) allComponents.get(i);
233
		List scenarii = (List) allScenarii.get(componentName);
234
		if (scenarii == null) continue;
235
		this.components.add(componentName);
236
		ComponentResults componentResults = new ComponentResults(this, componentName);
237
		addChild(componentResults, true);
238
		componentResults.read(scenarii);
239
	}
240
241
	// Print time
242
	printGlobalTime(start);
243
}
244
}
(-)src/org/eclipse/test/internal/performance/results/ConfigResults.java (+291 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.internal.performance.results;
12
13
import java.util.ArrayList;
14
import java.util.List;
15
16
import org.eclipse.test.internal.performance.InternalDimensions;
17
18
/**
19
 * Class to handle results for an Eclipse performance test box
20
 * (called a <i>configuration</i>).
21
 * 
22
 * It gives access to results for each build on which this configuration has been run.
23
 * 
24
 * @see BuildResults
25
 */
26
public class ConfigResults extends AbstractResults {
27
	BuildResults baseline, current;
28
	boolean baselined = false, valid = false;
29
30
public ConfigResults(AbstractResults parent, int id) {
31
	super(parent, id);
32
	this.name = DB_Results.getConfig(id);
33
	this.print = parent.print;
34
}
35
36
/**
37
 * Returns the baseline build name used to compare results with.
38
 *
39
 * @return The name of the baseline build
40
 * @see #getBaselineBuildResults()
41
 */
42
public String getBaselineBuildName() {
43
	return this.baseline.getName();
44
}
45
46
/**
47
 * Returns the baseline build results.
48
 * <p>
49
 * This build is currently the last reference build which has performance
50
 * 
51
 * @return The baseline build results.
52
 * @see BuildResults
53
 */
54
public BuildResults getBaselineBuildResults() {
55
	return this.baseline;
56
}
57
58
/**
59
 * Returns the build results matching a given pattern.
60
 *
61
 * @param buildPattern The pattern of searched builds
62
 * @return The list of the builds which names match the given pattern.
63
 * 	The list is ordered by build results date.
64
 */
65
public List getBuilds(String buildPattern) {
66
	List builds = new ArrayList();
67
	int size = size();
68
	for (int i=0; i<size; i++) {
69
		BuildResults buildResults = (BuildResults) this.children.get(i);
70
		if (buildResults.match(buildPattern)) {
71
			builds.add(buildResults);
72
		}
73
	}
74
	return builds;
75
}
76
77
/**
78
 * Returns a list of build results which names starts with one of the given prefixes.
79
 *
80
 * @param prefixes List of expected prefixes
81
 * @return A list of builds which names start with one of the given patterns.
82
 */
83
public List getBuildsMatchingPrefixes(List prefixes) {
84
	List builds = new ArrayList();
85
	int size = size();
86
	int length = prefixes.size();
87
	for (int i=0; i<size; i++) {
88
		BuildResults buildResults = (BuildResults) this.children.get(i);
89
		String buildName = buildResults.getName();
90
		for (int j=0; j<length; j++) {
91
			if (buildName.startsWith((String)prefixes.get(j))) {
92
				builds.add(buildResults);
93
			}
94
		}
95
	}
96
	return builds;
97
}
98
99
/**
100
 * Return the deviation value and its associated standard error for the default dimension
101
 * (currently {@link InternalDimensions#ELAPSED_PROCESS}).
102
 *
103
 * @return an array of double. First number is the deviation itself and
104
 * 	the second is the standard error.
105
 */
106
public double[] getCurrentBuildDeviation() {
107
	int dim_id = SUPPORTED_DIMS[0].getId();
108
	double baselineValue = this.baseline.getValue(dim_id);
109
	double currentValue = this.current.getValue(dim_id);
110
	double deviation = (currentValue - baselineValue) / baselineValue;
111
	if (Double.isNaN(deviation)) {
112
		return new double[] { Double.NaN, Double.NaN };
113
	}
114
	long baselineCount = this.baseline.getCount(dim_id);
115
	long currentCount = this.current.getCount(dim_id);
116
	if (baselineCount == 1 || currentCount == 1) {
117
		return new double[] { deviation, Double.NaN };
118
	}
119
	double baselineError = this.baseline.getError(dim_id);
120
	double currentError = this.current.getError(dim_id);
121
	double stderr = Double.isNaN(baselineError)
122
			? currentError / baselineValue
123
			: Math.sqrt(baselineError*baselineError + currentError*currentError) / baselineValue;
124
	return new double[] { deviation, stderr };
125
}
126
127
/**
128
 * Returns the current build name.
129
 *
130
 * @return The name of the current build
131
 * @see #getCurrentBuildResults()
132
 */
133
public String getCurrentBuildName() {
134
	return this.current.getName();
135
}
136
137
/**
138
 * Returns the current build results.
139
 * <p>
140
 * This build is currently the last integration or nightly
141
 * build which has performance results in the database.
142
 * It may differ from the {@link PerformanceResults#getName()}.
143
 * 
144
 * @return The current build results.
145
 * @see BuildResults
146
 */
147
public BuildResults getCurrentBuildResults() {
148
	return this.current;
149
}
150
151
/**
152
 * Get all dimension builds statistics for a given list of build prefixes
153
 * and a given dimension.
154
 *
155
 * @param prefixes List of prefixes to filter builds. If <code>null</code>
156
 * 	then all the builds are taken to compute statistics.
157
 * @param dim_id The id of the dimension on which the statistics must be computed
158
 * @return An array of double built as follows:
159
 * 	- 0:	numbers of values
160
 * 	- 1:	mean of values
161
 * 	- 2:	standard deviation of these values
162
 * 	- 3:	coefficient of variation of these values
163
 */
164
public double[] getStatistics(List prefixes, int dim_id) {
165
	int size = size();
166
	int length = prefixes == null ? 0 : prefixes.size();
167
	int count = 0;
168
	double mean=0, stddev=0, variation=0;
169
	double[] values = new double[size];
170
	count = 0;
171
	mean = 0.0;
172
	for (int i=0; i<size; i++) {
173
		BuildResults buildResults = (BuildResults) children.get(i);
174
		String buildName = buildResults.getName();
175
		if (prefixes == null) {
176
			double value = buildResults.getValue(dim_id);
177
			values[count] = value;
178
			mean += value;
179
			count++;
180
		} else {
181
			for (int j=0; j<length; j++) {
182
				if (buildName.startsWith((String)prefixes.get(j))) {
183
					double value = buildResults.getValue(dim_id);
184
					values[count] = value;
185
					mean += value;
186
					count++;
187
				}
188
			}
189
		}
190
	}
191
	mean /= count;
192
	for (int i=0; i<count; i++) {
193
		stddev += Math.pow(values[i] - mean, 2);
194
	}
195
	stddev = Math.sqrt((stddev / (count - 1)));
196
	variation = Math.round(((stddev) / mean) * 100 * 100) / 100;
197
	return new double[] { count, mean, stddev, variation };
198
}
199
200
/**
201
 * Returns whether the configuration has results for the performance
202
 * baseline build or not.
203
 * 
204
 * @return <code>true</code> if the configuration has results
205
 * 	for the performance baseline build, <code>false</code> otherwise.
206
 */
207
public boolean isBaselined() {
208
	return this.baselined;
209
}
210
211
/**
212
 * Returns whether the configuration has results for the performance
213
 * current build or not.
214
 * 
215
 * @return <code>true</code> if the configuration has results
216
 * 	for the performance current build, <code>false</code> otherwise.
217
 */
218
public boolean isValid() {
219
	return this.valid;
220
}
221
222
/**
223
 * Returns the 'n' last nightly build names.
224
 *
225
 * @param n Number of last nightly builds to return
226
 * @return Last n nightly build names preceding current.
227
 */
228
public List lastNightlyBuildNames(int n) {
229
	List labels = new ArrayList();
230
	for (int i=size()-2; i>=0; i--) {
231
		BuildResults buildResults = (BuildResults) this.children.get(i);
232
		String buildName = buildResults.getName();
233
		if (buildName.startsWith("N")) { //$NON-NLS-1$
234
			labels.add(buildName);
235
			if (labels.size() >= n) break;
236
		}
237
	}
238
	return labels;
239
}
240
241
/*
242
 * Read scenario results information available in three maps.
243
 */
244
void read() {
245
246
	// Get performance results builds name
247
	PerformanceResults perfResults = getPerformance();
248
	String baselineBuildName = perfResults.getBaselineName();
249
	String currentBuildName = perfResults.getName();
250
251
	// Set baseline and current builds
252
	int size = size();
253
	for (int i=0; i<size; i++) {
254
		BuildResults buildResults = (BuildResults) this.children.get(i);
255
		if (buildResults.values != null) {
256
			buildResults.cleanValues();
257
		}
258
		if (buildResults.getName().equals(baselineBuildName)) {
259
			this.baseline = buildResults;
260
			this.baselined = true;
261
		} else if (buildResults.getName().equals(currentBuildName)) {
262
			this.current = buildResults;
263
			this.valid = true;
264
		}
265
	}
266
	if (this.baseline == null) {
267
		this.baseline = (BuildResults) this.children.get(0);
268
	}
269
	if (this.current == null) {
270
		this.current = (BuildResults) this.children.get(size()-1);
271
	}
272
273
	// Get current and baseline builds failures and summaries
274
	ScenarioResults scenarioResults = (ScenarioResults) this.parent;
275
	DB_Results.queryScenarioFailures(scenarioResults, this.name, this.current, this.baseline);
276
	DB_Results.queryScenarioSummaries(scenarioResults, this.name, this.current, this.baseline);
277
}
278
279
/*
280
 * Set the configuration value from database information
281
 */
282
void setValue(int build_id, int dim_id, int step, long value) {
283
	BuildResults buildResults = (BuildResults) getResults(build_id);
284
	if (buildResults == null) {
285
		buildResults = new BuildResults(this, build_id);
286
		addChild(buildResults, true);
287
	}
288
	buildResults.setValue(dim_id, step, value);
289
}
290
291
}
(-)src/org/eclipse/test/internal/performance/results/ScenarioResults.java (+216 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.internal.performance.results;
12
13
import java.util.StringTokenizer;
14
15
16
/**
17
 * Class to handle performance results of a component's scenario
18
 * (for example 'org.eclipse.jdt.core.FullSourceWorkspaceSearchTest#searchAllTypeNames()').
19
 * 
20
 * It gives access to results for each configuration run on this scenario.
21
 * 
22
 * @see ConfigResults
23
 */
24
public class ScenarioResults extends AbstractResults {
25
	String fileName;
26
	String label;
27
	String shortName;
28
29
public ScenarioResults(int id, String name, String shortName) {
30
	super(null, id);
31
	this.name = name;
32
	this.label = shortName;
33
}
34
35
/**
36
 * Returns the first configuration baseline build name.
37
 *
38
 * @return The name of the baseline build
39
 * @see ConfigResults#getBaselineBuildName()
40
 */
41
public String getBaselineBuildName() {
42
	int size = size();
43
	StringBuffer buffer = new StringBuffer();
44
	for (int i=0; i<size; i++) {
45
		ConfigResults configResults = (ConfigResults) this.children.get(i);
46
		if (configResults.isValid()) {
47
			return configResults.getBaselineBuildName();
48
			/* TODO (frederic) decide what return when baseline is not the same on all configs...
49
			String baselineName = configResults.getBaselineBuildName();
50
			if (buffer.indexOf(baselineName) < 0) {
51
				if (buffer.length() > 0) buffer.append('|');
52
				buffer.append(baselineName);
53
			}
54
			*/
55
		}
56
	}
57
	return buffer.toString();
58
}
59
60
/**
61
 * Return the results of the given configuration.
62
 * 
63
 * @param config The configuration name
64
 * @return The {@link ConfigResults results} for the given configuration
65
 * 	or <code>null</code> if none was found.
66
 */
67
public ConfigResults getConfigResults(String config) {
68
	return (ConfigResults) getResults(config);
69
}
70
71
/**
72
 * Return a name which can be used as a file name to store information
73
 * related to this scenario. This name does not contain the extension.
74
 * 
75
 * @return The file name
76
 */
77
public String getFileName() {
78
	if (this.fileName == null) {
79
		this.fileName = this.name.replace('#', '.').replace(':', '_').replace('\\', '_');
80
	}
81
	return this.fileName;
82
}
83
84
/**
85
 * Returns the scenario label. If no label exist as there's no associated summary,
86
 * then the short name is returned
87
 *
88
 * @return The label of the scenario or it's short name if no summary exists
89
 */
90
public String getLabel() {
91
	return this.label;
92
}
93
94
/**
95
 * Returns the short name of the scenario. Short name is the name scenario
96
 * from which package declaration has been removed.
97
 * 
98
 * @return The scenario short name
99
 */
100
public String getShortName() {
101
	if (this.shortName == null) {
102
		// Remove class name qualification
103
		int testSeparator = this.name.indexOf('#');
104
		boolean hasClassName = testSeparator >= 0;
105
		if (!hasClassName) {
106
			testSeparator = this.name.lastIndexOf('.');
107
			if (testSeparator <= 0) {
108
				return this.shortName = this.name;
109
			}
110
		}
111
		int classSeparator = this.name.substring(0, testSeparator).lastIndexOf('.');
112
		if (classSeparator < 0) {
113
			return this.shortName = this.name;
114
		}
115
		int length = this.name.length();
116
		String testName = this.name.substring(classSeparator+1, length);
117
		if (!hasClassName && testName.startsWith("test.")) { // specific case for swt... //$NON-NLS-1$
118
			testName = testName.substring(5);
119
		}
120
	
121
		// Remove qualification from test name
122
		StringTokenizer tokenizer = new StringTokenizer(testName, " :,", true); //$NON-NLS-1$
123
		StringBuffer buffer = new StringBuffer(tokenizer.nextToken());
124
		while (tokenizer.hasMoreTokens()) {
125
			String token = tokenizer.nextToken();
126
			char fc = token.charAt(0);
127
			while (fc == ' ' || fc == ',' || fc == ':') {
128
				buffer.append(token); // add the separator
129
				token = tokenizer.nextToken();
130
				fc = token.charAt(0);
131
			}
132
			int last = token.lastIndexOf('.');
133
			if (last >= 3) {
134
				int first = token .indexOf('.');
135
				if (first == last) {
136
					buffer.append(token);
137
				} else {
138
					buffer.append(token.substring(last+1));
139
				}
140
			} else {
141
				buffer.append(token);
142
			}
143
		}
144
		this.shortName = buffer.toString();
145
	}
146
	return this.shortName;
147
}
148
149
/**
150
 * Returns whether one of the scenario's config has a summary or not.
151
 * 
152
 * @return <code>true</code> if one of the scenario's config has a summary
153
 * 	<code>false</code> otherwise.
154
 */
155
public boolean hasSummary() {
156
	int size = size();
157
	for (int i=0; i<size; i++) {
158
		ConfigResults configResults = (ConfigResults) this.children.get(i);
159
		if (configResults.getCurrentBuildResults().hasSummary()) return true;
160
	}
161
	return false;
162
}
163
164
/* (non-Javadoc)
165
 * @see org.eclipse.test.internal.performance.results.AbstractResults#hashCode()
166
 */
167
public int hashCode() {
168
	return this.id;
169
}
170
171
/**
172
 * Returns whether the current build of the given config has valid results or not.
173
 * 
174
 * @param config The name of the configuration
175
 * @return <code>true</code> if the build has valid results
176
 * 	<code>false</code> otherwise.
177
 */
178
public boolean isValid(String config) {
179
	return getResults(config) != null;
180
}
181
182
/*
183
 * Read scenario results information from database.
184
 */
185
void read() {
186
	
187
	// Get values
188
	print("+ scenario '"+getShortName()+"': "); //$NON-NLS-1$ //$NON-NLS-2$
189
	long start = System.currentTimeMillis();
190
	String configPattern = getPerformance().getConfigurationsPattern();
191
	DB_Results.queryScenarioValues(this, configPattern);
192
	print(" values for "+size()+" configs ("+(System.currentTimeMillis()-start)+"ms), "); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
193
194
	// Set baseline and current builds
195
	start = System.currentTimeMillis();
196
	int size = size();
197
	for (int i=0; i<size; i++) {
198
		ConfigResults configResults = (ConfigResults) this.children.get(i);
199
		configResults.read();
200
	}
201
	println("failures and summaries ("+(System.currentTimeMillis()-start)+"ms)."); //$NON-NLS-1$ //$NON-NLS-2$
202
}
203
204
/*
205
 * Set value from database information.
206
 */
207
void setValue(int build_id, int dim_id, int config_id, int step, long value) {
208
	ConfigResults configResults = (ConfigResults) getResults(config_id);
209
	if (configResults == null) {
210
		configResults = new ConfigResults(this, config_id);
211
		addChild(configResults, true);
212
	}
213
	configResults.setValue(build_id, dim_id, step, value);
214
}
215
216
}
(-)src/org/eclipse/test/internal/performance/results/DB_Results.java (+1147 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.internal.performance.results;
12
13
import java.io.File;
14
import java.io.PrintWriter;
15
import java.io.StringWriter;
16
import java.sql.Connection;
17
import java.sql.DriverManager;
18
import java.sql.ResultSet;
19
import java.sql.SQLException;
20
import java.util.ArrayList;
21
import java.util.Arrays;
22
import java.util.HashMap;
23
import java.util.List;
24
import java.util.Map;
25
import java.util.StringTokenizer;
26
27
import org.eclipse.test.internal.performance.PerformanceTestPlugin;
28
29
/**
30
 * Specific and private implementation of {@link org.eclipse.test.internal.performance.db.DB} class
31
 * to get massive results from performance results database.
32
 */
33
public class DB_Results {
34
    
35
    static final boolean DEBUG = true;
36
    
37
    // the two supported DB types
38
    private static final String DERBY= "derby"; //$NON-NLS-1$
39
    private static final String CLOUDSCAPE= "cloudscape"; //$NON-NLS-1$
40
        
41
    private static DB_Results fgDefault;
42
    
43
    private Connection fConnection;
44
    private SQL_Results fSQL;
45
    private boolean fIsEmbedded;
46
    private String fDBType;	// either "derby" or "cloudscape"
47
48
    // Store results of global request
49
    final static StringWriter STRING_WRITER = DEBUG ? new StringWriter() : null;
50
    final static PrintWriter LOG_WRITER = DEBUG ? new PrintWriter(STRING_WRITER) : null;
51
    
52
	// Data storage from queries
53
	private static String[] CONFIGS, COMPONENTS, BUILDS;
54
	private static int BUILDS_LENGTH;
55
	private static String[] SCENARII;
56
	private static String[] COMMENTS;
57
58
	// Static data
59
	private final static int MAX_CONFIGS = 5;
60
	private final static String[] SUPPORTED_VMS =  { // Consider only supported VMs a static data
61
		"sun" //$NON-NLS-1$
62
	};
63
	private final static String[] SUPPORTED_COMPONENTS = {
64
		"org.eclipse.ant", //$NON-NLS-1$
65
		"org.eclipse.compare", //$NON-NLS-1$
66
		"org.eclipse.core", //$NON-NLS-1$
67
		"org.eclipse.help", //$NON-NLS-1$
68
		"org.eclipse.jdt.core", //$NON-NLS-1$
69
		"org.eclipse.jdt.debug", //$NON-NLS-1$
70
		"org.eclipse.jdt.text", //$NON-NLS-1$
71
		"org.eclipse.jdt.ui", //$NON-NLS-1$
72
		"org.eclipse.jface", //$NON-NLS-1$
73
		"org.eclipse.osgi", //$NON-NLS-1$
74
		"org.eclipse.pde.ui", //$NON-NLS-1$
75
		"org.eclipse.swt", //$NON-NLS-1$
76
		"org.eclipse.team", //$NON-NLS-1$
77
		"org.eclipse.ua", //$NON-NLS-1$
78
		"org.eclipse.ui" //$NON-NLS-1$
79
	};
80
    
81
    //---- private implementation
82
    
83
	/**
84
     * Private constructor to block instance creation.
85
     */
86
    private DB_Results() {
87
    	// empty implementation
88
    }
89
90
    synchronized static DB_Results getDefault() {
91
        if (fgDefault == null) {
92
            fgDefault= new DB_Results();
93
            fgDefault.connect();
94
            if (PerformanceTestPlugin.getDefault() == null) {
95
            	// not started as plugin
96
	            Runtime.getRuntime().addShutdownHook(
97
	                new Thread() {
98
	                    public void run() {
99
	                    	shutdown();
100
	                    }
101
	                }
102
	            );
103
            }
104
        }
105
        return fgDefault;
106
    }
107
    
108
    public static void shutdown() {
109
        if (fgDefault != null) {
110
            fgDefault.disconnect();
111
            fgDefault= null;
112
        }
113
        if (DEBUG) {
114
        	LOG_WRITER.println("DB.shutdown"); //$NON-NLS-1$
115
        	System.out.println(STRING_WRITER.toString());
116
        }
117
    }
118
119
/**
120
 * Get all components read from database.
121
 *
122
 * @return A list of component names matching the given pattern
123
 */
124
static List getAllComponents() {
125
	return Arrays.asList(COMPONENTS);
126
}
127
128
/**
129
 * Return the build name from a given id.
130
 * 
131
 * @param id The build id
132
 * @return The name of the build (eg. I20070615-1200)
133
 */
134
static String getBuildName(int id) {
135
	return BUILDS[id];
136
}
137
138
/**
139
 * Get component name from a scenario.
140
 * 
141
 * @param scenarioName The name of the scenario
142
 * @return The component name
143
 */
144
static String getComponentNameFromScenario(String scenarioName) {
145
	int length = SUPPORTED_COMPONENTS.length;
146
	for (int i=0; i<length; i++) {
147
		if (scenarioName.startsWith(SUPPORTED_COMPONENTS[i])) {
148
			return SUPPORTED_COMPONENTS[i];
149
		}
150
	}
151
	return null;
152
}
153
154
/**
155
 * Return the name of the configuration from the given id.
156
 * 
157
 * @param id The index of the configuration in the stored list.
158
 * @return The name of the configuration (eg. eclipseperflnx1_R3.3)
159
 */
160
static String getConfig(int id) {
161
	return CONFIGS[id];
162
}
163
164
/**
165
 * Returns all the scenarii names stored in the dynamic list.
166
 * 
167
 * @return The list of all scenarii matching the pattern for a given build.
168
 * @see #internalQueryBuildScenarii(String, String)
169
 */
170
public static List getScenariiNames() {
171
	return Arrays.asList(SCENARII);
172
}
173
174
/**
175
 * Get all scenarii read from database matching a given pattern.
176
 * Note that all scenarii are returned if the pattern is <code>null</code>.
177
 *
178
 * @param scenarioPattern The pattern of the requested scenarii
179
 * @param buildName TODO
180
 * @return A list of scenario names matching the given pattern
181
 */
182
static Map queryAllScenarii(String scenarioPattern, String buildName) {
183
	return getDefault().internalQueryBuildScenarii(scenarioPattern, buildName);
184
}
185
186
/**
187
 * Get all the failures from DB for a given scenario, configuration
188
 * pattern and builds.
189
 * 
190
 * @param scenarioResults The scenario results where to store data
191
 * @param configPattern The configuration pattern concerned by the query
192
 * @param currentBuild The current build to narrow the query
193
 * @param baselineBuild The baseline build to narrow the query 
194
 */
195
static void queryScenarioFailures(ScenarioResults scenarioResults, String configPattern, BuildResults currentBuild, BuildResults baselineBuild) {
196
	getDefault().internalQueryScenarioFailures(scenarioResults, configPattern, currentBuild, baselineBuild);
197
}
198
199
/**
200
 * Get all summaries from DB for a given scenario, configuration
201
 * pattern and builds.
202
 *
203
 * @param scenarioResults The scenario results where to store data
204
 * @param configPattern The configuration pattern concerned by the query
205
 * @param currentBuild The current build to narrow the query
206
 * @param baselineBuild The baseline build to narrow the query 
207
 */
208
static void queryScenarioSummaries(ScenarioResults scenarioResults, String configPattern, BuildResults currentBuild, BuildResults baselineBuild) {
209
	getDefault().internalQueryScenarioSummaries(scenarioResults, configPattern, currentBuild, baselineBuild);
210
}
211
212
/**
213
 * Query and store all values for given scenario results
214
 *
215
 * @param scenarioResults The scenario results where the values has to be put
216
 * @param configPattern The pattern of the configuration concerned by the query 
217
 *
218
public static void queryScenarioValues(int id, ScenarioResults scenarioResults, String[] configNames) {
219
	getDefault().internalQueryScenarioValues(id, scenarioResults, configNames);
220
}
221
*/
222
static void queryScenarioValues(ScenarioResults scenarioResults, String configPattern) {
223
	getDefault().internalQueryScenarioValues(scenarioResults, configPattern);
224
}
225
226
/**
227
 * dbloc=						embed in home directory
228
 * dbloc=/tmp/performance			embed given location
229
 * dbloc=net://localhost			connect to local server
230
 * dbloc=net://www.eclipse.org	connect to remove server
231
 */
232
private void connect() {
233
234
	if (fConnection != null)
235
		return;
236
237
	String dbloc = PerformanceTestPlugin.getDBLocation();
238
	if (dbloc == null)
239
		return;
240
241
	String dbname = PerformanceTestPlugin.getDBName();
242
	String url = null;
243
	java.util.Properties info = new java.util.Properties();
244
245
	if (DEBUG) {
246
		LOG_WRITER.println();
247
		LOG_WRITER.println("==========================================================="); //$NON-NLS-1$
248
		LOG_WRITER.println("Database information logged during processing"); //$NON-NLS-1$
249
	}
250
251
	fDBType = DERBY; // assume we are using Derby
252
	try {
253
		if (dbloc.startsWith("net://")) { //$NON-NLS-1$
254
			// remote
255
			fIsEmbedded = false;
256
			// connect over network
257
			if (DEBUG)
258
				LOG_WRITER.println("Trying to connect over network..."); //$NON-NLS-1$
259
			Class.forName("com.ibm.db2.jcc.DB2Driver"); //$NON-NLS-1$
260
			info.put("user", PerformanceTestPlugin.getDBUser()); //$NON-NLS-1$
261
			info.put("password", PerformanceTestPlugin.getDBPassword()); //$NON-NLS-1$
262
			info.put("retrieveMessagesFromServerOnGetMessage", "true"); //$NON-NLS-1$ //$NON-NLS-2$
263
			info.put("create", "true"); //$NON-NLS-1$ //$NON-NLS-2$
264
			url = dbloc + '/' + dbname;
265
		} else if (dbloc.startsWith("//")) { //$NON-NLS-1$
266
			// remote
267
			fIsEmbedded = false;
268
			// connect over network
269
			if (DEBUG)
270
				LOG_WRITER.println("Trying to connect over network..."); //$NON-NLS-1$
271
			Class.forName("org.apache.derby.jdbc.ClientDriver"); //$NON-NLS-1$
272
			info.put("user", PerformanceTestPlugin.getDBUser()); //$NON-NLS-1$
273
			info.put("password", PerformanceTestPlugin.getDBPassword()); //$NON-NLS-1$
274
			info.put("create", "true"); //$NON-NLS-1$ //$NON-NLS-2$
275
			url = dbloc + '/' + dbname;
276
		} else {
277
			// workaround for Derby issue:
278
			// http://nagoya.apache.org/jira/browse/DERBY-1
279
			if ("Mac OS X".equals(System.getProperty("os.name"))) //$NON-NLS-1$//$NON-NLS-2$
280
				System.setProperty("derby.storage.fileSyncTransactionLog", "true"); //$NON-NLS-1$ //$NON-NLS-2$
281
282
			// embedded
283
			fIsEmbedded = true;
284
			try {
285
				Class.forName("org.apache.derby.jdbc.EmbeddedDriver"); //$NON-NLS-1$
286
			} catch (ClassNotFoundException e) {
287
				Class.forName("com.ihost.cs.jdbc.CloudscapeDriver"); //$NON-NLS-1$
288
				fDBType = CLOUDSCAPE;
289
			}
290
			if (DEBUG)
291
				LOG_WRITER.println("Loaded embedded " + fDBType); //$NON-NLS-1$
292
			File f;
293
			if (dbloc.length() == 0) {
294
				String user_home = System.getProperty("user.home"); //$NON-NLS-1$
295
				if (user_home == null)
296
					return;
297
				f = new File(user_home, fDBType);
298
			} else
299
				f = new File(dbloc);
300
			url = new File(f, dbname).getAbsolutePath();
301
			info.put("user", PerformanceTestPlugin.getDBUser()); //$NON-NLS-1$
302
			info.put("password", PerformanceTestPlugin.getDBPassword()); //$NON-NLS-1$
303
			info.put("create", "true"); //$NON-NLS-1$ //$NON-NLS-2$
304
		}
305
		try {
306
			fConnection = DriverManager.getConnection("jdbc:" + fDBType + ":" + url, info); //$NON-NLS-1$ //$NON-NLS-2$
307
		} catch (SQLException e) {
308
			if ("08001".equals(e.getSQLState()) && DERBY.equals(fDBType)) { //$NON-NLS-1$
309
				if (DEBUG)
310
					LOG_WRITER.println("DriverManager.getConnection failed; retrying for cloudscape"); //$NON-NLS-1$
311
				// try Cloudscape
312
				fDBType = CLOUDSCAPE;
313
				fConnection = DriverManager.getConnection("jdbc:" + fDBType + ":" + url, info); //$NON-NLS-1$ //$NON-NLS-2$
314
			} else
315
				throw e;
316
		}
317
		if (DEBUG)
318
			LOG_WRITER.println("connect succeeded!"); //$NON-NLS-1$
319
320
		fConnection.setAutoCommit(false);
321
		fSQL = new SQL_Results(fConnection);
322
		fConnection.commit();
323
324
	} catch (SQLException ex) {
325
		PerformanceTestPlugin.logError(ex.getMessage());
326
327
	} catch (ClassNotFoundException e) {
328
		PerformanceTestPlugin.log(e);
329
	}
330
}
331
332
private void disconnect() {
333
	if (DEBUG)
334
		LOG_WRITER.println("disconnecting from DB"); //$NON-NLS-1$
335
	if (fSQL != null) {
336
		try {
337
			fSQL.dispose();
338
		} catch (SQLException e1) {
339
			PerformanceTestPlugin.log(e1);
340
		}
341
		fSQL = null;
342
	}
343
	if (fConnection != null) {
344
		try {
345
			fConnection.commit();
346
		} catch (SQLException e) {
347
			PerformanceTestPlugin.log(e);
348
		}
349
		try {
350
			fConnection.close();
351
		} catch (SQLException e) {
352
			PerformanceTestPlugin.log(e);
353
		}
354
		fConnection = null;
355
	}
356
357
	if (fIsEmbedded) {
358
		try {
359
			DriverManager.getConnection("jdbc:" + fDBType + ":;shutdown=true"); //$NON-NLS-1$ //$NON-NLS-2$
360
		} catch (SQLException e) {
361
			String message = e.getMessage();
362
			if (message.indexOf("system shutdown.") < 0) //$NON-NLS-1$
363
				e.printStackTrace();
364
		}
365
	}
366
}
367
368
/*
369
 * Return the index of the build in the list.
370
 */
371
private int getBuildId(String build) {
372
	if (BUILDS == null) return -1;
373
	return Arrays.binarySearch(BUILDS, build);
374
}
375
376
/*
377
 * Return the index of the given configuration in the stored list.
378
 */
379
private int getConfigId(String config) {
380
	if (CONFIGS == null) return -1;
381
	return Arrays.binarySearch(CONFIGS, config);
382
}
383
384
SQL_Results getSQL() {
385
    return fSQL;
386
}
387
388
/*
389
 * Query all comments from database
390
 */
391
private void internalQueryAllComments() {
392
	if (fSQL == null) return;
393
	if (COMMENTS != null) return;
394
	long start = System.currentTimeMillis();
395
	if (DEBUG) LOG_WRITER.print("		[DB query all comments..."); //$NON-NLS-1$
396
	ResultSet result = null;
397
	try {
398
		String[] comments = null;
399
		result = fSQL.queryAllComments();
400
		while (result.next()) {
401
			int commentID = result.getInt(1);
402
			// Ignore kind as there's only one
403
			// int commentKind = result.getInt(2); 
404
			String comment = result.getString(3);
405
			if (comments == null) {
406
				comments = new String[commentID+10];
407
			} else if (commentID >= comments.length) {
408
				int length = comments.length;
409
				System.arraycopy(comments, 0, comments = new String[commentID+10], 0, length);
410
			}
411
			comments[commentID] = comment;
412
		}
413
		COMMENTS = comments;
414
	} catch (SQLException e) {
415
		PerformanceTestPlugin.log(e);
416
	} finally {
417
		if (result != null) {
418
			try {
419
				result.close();
420
			} catch (SQLException e1) {
421
				// ignored
422
			}
423
		}
424
		if (DEBUG) LOG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
425
	}
426
}
427
428
/*
429
 * Query all variations. This method stores all config and build names.
430
 */
431
private void internalQueryAllVariations(String configPattern) {
432
	if (fSQL == null) return;
433
	if (BUILDS != null) return;
434
	long start = System.currentTimeMillis();
435
	if (DEBUG) {
436
		LOG_WRITER.print("	- DB query all variations for configuration pattern: "+configPattern); //$NON-NLS-1$
437
		LOG_WRITER.print("..."); //$NON-NLS-1$
438
	}
439
	ResultSet result = null;
440
	try {
441
		CONFIGS = new String[MAX_CONFIGS];
442
		BUILDS = null;
443
		BUILDS_LENGTH = 0;
444
		result = fSQL.queryAllVariations(configPattern);
445
		while (result.next()) {
446
			String variation = result.getString(1); //  something like "||build=I20070615-1200||config=eclipseperfwin2_R3.3||jvm=sun|"
447
			StringTokenizer tokenizer = new StringTokenizer(variation, "=|"); //$NON-NLS-1$
448
			tokenizer.nextToken(); 												// 'build'
449
			String buildName = tokenizer.nextToken();				// 'I20070615-1200'
450
			tokenizer.nextToken();												// 'config'
451
			storeConfig(tokenizer.nextToken()); 	// 'eclipseperfwin2_R3.3'
452
			tokenizer.nextToken();												// 'jvm'
453
			String vmName = tokenizer.nextToken();					// 'sun'
454
			if (!vmName.equals(SUPPORTED_VMS[0])) {
455
				throw new RuntimeException("Unexpected vm name: "+vmName); //$NON-NLS-1$
456
			}
457
			storeBuildName(buildName);
458
		}
459
		System.arraycopy(BUILDS, 0, BUILDS = new String[BUILDS_LENGTH], 0, BUILDS_LENGTH);
460
		for (int i=0; i<MAX_CONFIGS; i++) {
461
			if (CONFIGS[i] == null) {
462
				System.arraycopy(CONFIGS, 0, CONFIGS = new String[i], 0, i);
463
				break;
464
			}
465
		}
466
	} catch (SQLException e) {
467
		PerformanceTestPlugin.log(e);
468
	} finally {
469
		if (result != null) {
470
			try {
471
				result.close();
472
			} catch (SQLException e1) {
473
				// ignored
474
			}
475
		}
476
		if (DEBUG) LOG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
477
	}
478
}
479
/*
480
private void internalQueryAllScenarii(String scenarioPattern) {
481
	if (fSQL == null) return;
482
	long start = System.currentTimeMillis();
483
	if (DEBUG) {
484
		LOG_WRITER.print("	- DB query all scenarii from DB..."); //$NON-NLS-1$
485
	}
486
	ResultSet result = null;
487
	SCENARII = null;
488
	COMPONENTS = null;
489
	try {
490
		result = fSQL.queryAllScenarii();
491
		for (int i = 0; result.next(); i++) {
492
			int id = result.getInt(1);
493
			String name = result.getString(2);
494
			String label = result.getString(3);
495
			if (scenarioPattern == null || matchPattern(name, scenarioPattern)) {
496
				storeComponent(getComponentNameFromScenario(name));
497
			}
498
			if (SCENARII == null) {
499
				// as scenario ar order by id descendent order, the first id gives the size of the array
500
				SCENARII = new String[id];
501
				SCENARII_LABEL = new String[id];
502
			}
503
			SCENARII[id-1] = name;
504
			SCENARII_LABEL[id-1] = label;
505
		}
506
507
	} catch (SQLException e) {
508
		PerformanceTestPlugin.log(e);
509
510
	} finally {
511
		if (result != null) {
512
			try {
513
				result.close();
514
			} catch (SQLException e1) { // ignored
515
			}
516
		}
517
		if (DEBUG) LOG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
518
	}
519
}
520
*/
521
/*
522
public static class Scenario {
523
	int id, component_id;
524
	String name;
525
	String label;
526
	Scenario(int id, int component_id, String name, String label) {
527
	    this.id = id;
528
	    this.name = name;
529
	    this.label = label;
530
	    this.component_id = component_id;
531
    }
532
	
533
}
534
*/
535
private Map internalQueryBuildScenarii(String scenarioPattern, String buildName) {
536
	if (fSQL == null) return null;
537
	long start = System.currentTimeMillis();
538
	if (DEBUG) {
539
		LOG_WRITER.print("	- DB query all scenarii"); //$NON-NLS-1$
540
		if (scenarioPattern != null) LOG_WRITER.print(" with pattern "+scenarioPattern); //$NON-NLS-1$
541
		LOG_WRITER.print(" for build: "+buildName); //$NON-NLS-1$
542
	}
543
	ResultSet result = null;
544
	Map allScenarii = new HashMap();
545
	try {
546
		result = fSQL.queryBuildScenarii(scenarioPattern, buildName);
547
		int previousId = -1;
548
		List scenarii = null;
549
		List scenariiNames = new ArrayList();
550
		for (int i = 0; result.next(); i++) {
551
			int id = result.getInt(1);
552
			String name = result.getString(2);
553
			scenariiNames.add(name);
554
			String shortName = result.getString(3);
555
			int component_id = storeComponent(getComponentNameFromScenario(name));
556
			if (component_id != previousId) {
557
				allScenarii.put(COMPONENTS[component_id], scenarii = new ArrayList());
558
				previousId = component_id;
559
			}
560
			scenarii.add(new ScenarioResults(id, name, shortName));
561
		}
562
		SCENARII = new String[scenariiNames.size()];
563
		scenariiNames.toArray(SCENARII);
564
	} catch (SQLException e) {
565
		PerformanceTestPlugin.log(e);
566
	} finally {
567
		if (result != null) {
568
			try {
569
				result.close();
570
			} catch (SQLException e1) { // ignored
571
			}
572
		}
573
		if (DEBUG) LOG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
574
	}
575
	return allScenarii;
576
}
577
/*
578
private int[] internalQueryScenarioSummaries(int scenarioID, String[] configNames) {
579
	if (fSQL == null) return null;
580
	long start = System.currentTimeMillis();
581
	if (DEBUG) LOG_WRITER.print("	- DB query all summaries from DB for scenario ID: "+scenarioID+"..."); //$NON-NLS-1$ //$NON-NLS-2$
582
	internalQueryAllComments();
583
	ResultSet result = null;
584
	try {
585
		int[] summaries = null;
586
		int confLength = configNames.length;
587
		for (int config_id=0; config_id<confLength; config_id++) {
588
			result = fSQL.queryScenarioSummaries(configNames[config_id], scenarioID);
589
			while (result.next()) {
590
				int variation_id = result.getInt(1);
591
				int global = result.getShort(2);
592
				int comment_id = result.getInt(3);
593
				if (summaries == null) {
594
					summaries = new int[variation_id+10];
595
				} else if (variation_id >= summaries.length) {
596
					int length = summaries.length;
597
					System.arraycopy(summaries, 0, summaries = new int[variation_id+10], 0, length);
598
				}
599
				summaries[variation_id-1] = global == 1 ? comment_id: -comment_id;
600
			}
601
		}
602
		return summaries;
603
	} catch (SQLException e) {
604
		PerformanceTestPlugin.log(e);
605
	} finally {
606
		if (result != null) {
607
			try {
608
				result.close();
609
			} catch (SQLException e1) {
610
				// ignored
611
			}
612
		}
613
//		this.logWriter.print(", db="+(System.currentTimeMillis()-start)+") "); //$NON-NLS-1$ //$NON-NLS-2$
614
		if (DEBUG) LOG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
615
	}
616
	return null;
617
}
618
*/
619
/*
620
private String[] internalQueryScenarioFailures(int scenarioID, String[] configNames) {
621
	if (fSQL == null) return null;
622
	long start = System.currentTimeMillis();
623
	if (DEBUG) LOG_WRITER.print("	[DB query all failures from DB for scenario ID: "+scenarioID+"..."); //$NON-NLS-1$ //$NON-NLS-2$
624
	ResultSet result = null;
625
	try {
626
		String[] failures = null;
627
		int confLength = configNames.length;
628
		for (int config_id=0; config_id<confLength; config_id++) {
629
			result = fSQL.queryScenarioFailures(configNames[config_id], scenarioID);
630
			while (result.next()) {
631
				int variation_id = result.getInt(1);
632
				String message = result.getString(2);
633
				if (failures == null) {
634
					failures = new String[variation_id+10];
635
				} else if (variation_id >= failures.length) {
636
					int length = failures.length;
637
					System.arraycopy(failures, 0, failures = new String[variation_id+10], 0, length);
638
				}
639
				failures[variation_id-1] = message;
640
			}
641
		}
642
		return failures;
643
	} catch (SQLException e) {
644
		PerformanceTestPlugin.log(e);
645
646
	} finally {
647
		if (result != null) {
648
			try {
649
				result.close();
650
			} catch (SQLException e1) {
651
				// ignored
652
			}
653
		}
654
//		this.logWriter.print(", db="+(System.currentTimeMillis()-start)+") "); //$NON-NLS-1$ //$NON-NLS-2$
655
		if (DEBUG) LOG_WRITER.println("	-> done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
656
	}
657
	return null;
658
}
659
*/
660
/*
661
private Map internalQueryScenariiBuilds(String config) {
662
	if (fSQL == null) return null;
663
	Map scenariiBuilds = (Map) this.allScenariiBuilds.get(config);
664
	if (scenariiBuilds != null) return scenariiBuilds;
665
	long start = System.currentTimeMillis();
666
	if (DEBUG) this.logWriter.print("	- query all build names from DB for config '"+config+"'..."); //$NON-NLS-1$ //$NON-NLS-2$
667
	ResultSet result = null;
668
	try {
669
		result = fSQL.queryScenariiBuilds(config);
670
//		this.logWriter.print("(sql="+(System.currentTimeMillis()-start)); //$NON-NLS-1$
671
//		start = System.currentTimeMillis();
672
		scenariiBuilds = new HashMap();
673
		for (int i = 0; result.next(); i++) {
674
			int scenario_id = result.getInt(1);
675
			Integer scenarioID = new Integer(scenario_id);
676
			StringTokenizer variation = new StringTokenizer(result.getString(2), "|="); //$NON-NLS-1$
677
			variation.nextToken(); // skip first token
678
			List buildNames = (List) scenariiBuilds.get(scenarioID);
679
			if (buildNames == null) {
680
				scenariiBuilds.put(scenarioID, buildNames = new ArrayList());
681
			}
682
			buildNames.add(variation.nextToken());
683
		}
684
		this.allScenariiBuilds.put(config, scenariiBuilds);
685
		return scenariiBuilds;
686
	} catch (SQLException e) {
687
		PerformanceTestPlugin.log(e);
688
	} finally {
689
		if (result != null) {
690
			try {
691
				result.close();
692
			} catch (SQLException e1) {
693
				// ignored
694
			}
695
		}
696
//		this.logWriter.print(", db="+(System.currentTimeMillis()-start)+") "); //$NON-NLS-1$ //$NON-NLS-2$
697
		if (DEBUG) this.logWriter.println("done in " + (System.currentTimeMillis() - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
698
	}
699
	return null;
700
}
701
*/
702
703
/*
704
private Map internalQueryScenarioDimValues(String config, int scenarioID, int dimID) {
705
	if (fSQL == null) return null;
706
	long start = System.currentTimeMillis();
707
	if (DEBUG) {
708
		this.logWriter.println("	- query all data points from DB:"); //$NON-NLS-1$
709
		this.logWriter.println("		+ config = " + config); //$NON-NLS-1$
710
		this.logWriter.println("		+ scenario id = " + scenarioID); //$NON-NLS-1$
711
	}
712
	ResultSet result = null;
713
	try {
714
		result = fSQL.queryScenarioDimValues(config, scenarioID, dimID);
715
		this.logWriter.print("(sql="+(System.currentTimeMillis()-start)); //$NON-NLS-1$
716
		start = System.currentTimeMillis();
717
		if (DEBUG) {
718
			long time = System.currentTimeMillis();
719
			this.logWriter.println("done in " + (time - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
720
			start = time;
721
		}
722
		Map dimValues = new HashMap();
723
		long[] values = null;
724
		String currentBuild = null;
725
		String buildName = null;
726
		while (result.next()) {
727
			int dp_id = result.getInt(1);
728
			int step = result.getInt(2);
729
//			long value = result.getBigDecimal(2).longValue();
730
			StringTokenizer variation = new StringTokenizer(result.getString(3), "|="); //$NON-NLS-1$
731
			variation.nextToken(); // skip first token
732
			buildName = variation.nextToken();
733
			ResultSet rs2 = fSQL.queryScalars(dp_id, dimID);
734
			rs2.next();
735
			long value = rs2.getBigDecimal(1).longValue();
736
			rs2.close();
737
			int idx = InternalPerformanceMeter.AVERAGE - step;
738
			if (!buildName.equals(currentBuild)) {
739
				if (currentBuild != null) dimValues.put(buildName, values);
740
				values = new long[3];
741
				currentBuild = buildName;
742
			}
743
			values[idx] = value;
744
		}
745
		dimValues.put(buildName, values);
746
		if (DEBUG) this.logWriter.println("		-> " + dimValues.size() + " datapoints created in " + (System.currentTimeMillis() - start) + "ms");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
747
		return dimValues;
748
	} catch (SQLException e) {
749
		PerformanceTestPlugin.log(e);
750
	} finally {
751
		if (result != null) {
752
			try {
753
				result.close();
754
			} catch (SQLException e1) {
755
				// ignored
756
			}
757
		}
758
		this.logWriter.print(", db="+(System.currentTimeMillis()-start)+") "); //$NON-NLS-1$ //$NON-NLS-2$
759
	}
760
	return null;
761
}
762
*/
763
/*
764
private Map internalQueryScenarioValues(String config, int scenarioID, Dim[] dims) {
765
	if (fSQL == null) return null;
766
	long start = System.currentTimeMillis();
767
	if (DEBUG) {
768
		this.logWriter.println("	- query all data points from DB:"); //$NON-NLS-1$
769
		this.logWriter.println("		+ config = " + config); //$NON-NLS-1$
770
		this.logWriter.println("		+ scenario id = " + scenarioID); //$NON-NLS-1$
771
	}
772
	ResultSet result = null;
773
	try {
774
		result = fSQL.queryScenarioDataPoints(config, scenarioID);
775
//		this.logWriter.print("(sql="+(System.currentTimeMillis()-start)); //$NON-NLS-1$
776
//		start = System.currentTimeMillis();
777
		if (DEBUG) {
778
			long time = System.currentTimeMillis();
779
			this.logWriter.println("done in " + (time - start) + "ms"); //$NON-NLS-1$ //$NON-NLS-2$
780
			start = time;
781
		}
782
		Map buildsValues = new HashMap();
783
		String buildName = null;
784
		int count = 0;
785
		int length = dims.length;
786
		while (result.next()) {
787
			int dp_id = result.getInt(1);
788
			int step = result.getInt(2);
789
//			long value = result.getBigDecimal(3).longValue();
790
			StringTokenizer variation = new StringTokenizer(result.getString(3), "|="); //$NON-NLS-1$
791
			variation.nextToken(); // skip first token
792
			buildName = variation.nextToken();
793
			Map dimsValues = (Map) buildsValues.get(buildName);
794
			if (dimsValues == null) {
795
				buildsValues.put(buildName, dimsValues = new HashMap());
796
			}
797
			int idx = InternalPerformanceMeter.AVERAGE - step;
798
			ResultSet rs2 = fSQL.queryScalars(dp_id);
799
			while (rs2.next()) {
800
				Dim dim = Dim.getDimension(rs2.getInt(1));
801
				for (int i=0; i<length; i++) {
802
					if (dim == dims[i]) {
803
						long value = rs2.getBigDecimal(2).longValue();
804
						long[][] values = (long[][]) dimsValues.get(dim);
805
						int valuesLength = values == null ? 0 : values.length;
806
						if (values == null) {
807
							values = new long[1][3];
808
							values[0][idx] = value;
809
							dimsValues.put(dim, values);
810
						} else if (values[valuesLength-1][idx] == 0) {
811
							values[valuesLength-1][idx] = value;
812
						} else {
813
							System.arraycopy(values, 0, values = new long[valuesLength+1][3], 0, valuesLength);
814
							for (int j=0; j<3; j++) values[valuesLength][j] = 0;
815
							values[valuesLength][idx] = value;
816
							dimsValues.put(dim, values);
817
						}
818
					}
819
				}
820
			}
821
			count++;
822
		}
823
		if (DEBUG) this.logWriter.println("		-> " + count + " values read in " + (System.currentTimeMillis() - start) + "ms");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
824
		return buildsValues;
825
	} catch (SQLException e) {
826
		PerformanceTestPlugin.log(e);
827
	} finally {
828
		if (result != null) {
829
			try {
830
				result.close();
831
			} catch (SQLException e1) {
832
				// ignored
833
			}
834
		}
835
//		this.logWriter.print(", db="+(System.currentTimeMillis()-start)+") "); //$NON-NLS-1$ //$NON-NLS-2$
836
	}
837
	return null;
838
}
839
*/
840
/*
841
private void internalQueryScenarioValues(int scenarioId, ScenarioResults scenarioResults, String[] configNames) {
842
	if (fSQL == null) return;
843
	long start = System.currentTimeMillis();
844
	if (DEBUG) LOG_WRITER.println("	- DB query all data points from DB for scenario: " + scenarioResults.getName()); //$NON-NLS-1$
845
	internalQueryAllVariations(configNames); // need to read all variations to have all build names
846
	ResultSet result = null;
847
	try {
848
		int length = configNames.length;
849
		int count = 0;
850
		for (int config_id=0; config_id<length; config_id++) {
851
			result = fSQL.queryScenarioDataPoints(configNames[config_id], scenarioId);
852
			while (result.next()) {
853
				int dp_id = result.getInt(1);
854
				int step = result.getInt(2);
855
				StringTokenizer variation = new StringTokenizer(result.getString(3), "|="); //$NON-NLS-1$
856
				variation.nextToken(); // skip first token
857
				String buildName = variation.nextToken();
858
				int build_id = getBuildId(config_id, buildName);
859
				ResultSet rs2 = fSQL.queryDimScalars(dp_id);
860
				while (rs2.next()) {
861
					int dim_id = rs2.getInt(1);
862
					long value = rs2.getBigDecimal(2).longValue();
863
					scenarioResults.setValue(build_id, dim_id, config_id, step, value);
864
					count++;
865
				}
866
			}
867
		}
868
		if (DEBUG) LOG_WRITER.println("		-> " + count + " values read in " + (System.currentTimeMillis() - start) + "ms]");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
869
	} catch (SQLException e) {
870
		PerformanceTestPlugin.log(e);
871
	} finally {
872
		if (result != null) {
873
			try {
874
				result.close();
875
			} catch (SQLException e1) {
876
				// ignored
877
			}
878
		}
879
	}
880
}
881
*/
882
/*
883
private String[] internalQueryScenarioFailures(int scenarioID) {
884
	if (fSQL == null) return null;
885
	long start = System.currentTimeMillis();
886
	if (DEBUG) LOG_WRITER.print("	- DB query all failures from DB for scenario ID: "+scenarioID+"..."); //$NON-NLS-1$ //$NON-NLS-2$
887
	ResultSet result = null;
888
	try {
889
		result = fSQL.queryScenarioFailures(scenarioID);
890
//		this.logWriter.print("(sql="+(System.currentTimeMillis()-start)); //$NON-NLS-1$
891
//		start = System.currentTimeMillis();
892
		String[] failures = null;
893
		while (result.next()) {
894
			int variationID = result.getInt(1);
895
			String message = result.getString(2);
896
			if (failures == null) {
897
				failures = new String[variationID+10];
898
			} else if (variationID >= failures.length) {
899
				int length = failures.length;
900
				System.arraycopy(failures, 0, failures = new String[variationID+10], 0, length);
901
			}
902
			failures[variationID] = message;
903
		}
904
		return failures;
905
	} catch (SQLException e) {
906
		PerformanceTestPlugin.log(e);
907
908
	} finally {
909
		if (result != null) {
910
			try {
911
				result.close();
912
			} catch (SQLException e1) {
913
				// ignored
914
			}
915
		}
916
//		this.logWriter.print(", db="+(System.currentTimeMillis()-start)+") "); //$NON-NLS-1$ //$NON-NLS-2$
917
		if (DEBUG) LOG_WRITER.println("	-> done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
918
	}
919
	return null;
920
}
921
*/
922
/*
923
private int[] internalQueryScenarioSummaries(int scenarioID) {
924
	if (fSQL == null) return null;
925
	long start = System.currentTimeMillis();
926
	if (DEBUG) LOG_WRITER.print("	- DB query all summaries from DB for scenario ID: "+scenarioID+"..."); //$NON-NLS-1$ //$NON-NLS-2$
927
	internalQueryAllComments();
928
	ResultSet result = null;
929
	try {
930
		int[] summaries = null;
931
		result = fSQL.queryScenarioSummaries(scenarioID);
932
//		this.logWriter.print("(sql="+(System.currentTimeMillis()-start)); //$NON-NLS-1$
933
//		start = System.currentTimeMillis();
934
		while (result.next()) {
935
			int variationID = result.getInt(1);
936
			int global = result.getShort(2);
937
			int comment_id = result.getInt(3);
938
			if (summaries == null) {
939
				summaries = new int[variationID+10];
940
			} else if (variationID >= summaries.length) {
941
				int length = summaries.length;
942
				System.arraycopy(summaries, 0, summaries = new int[variationID+10], 0, length);
943
			}
944
			summaries[variationID] = global == 1 ? comment_id: -comment_id;
945
		}
946
		return summaries;
947
	} catch (SQLException e) {
948
		PerformanceTestPlugin.log(e);
949
	} finally {
950
		if (result != null) {
951
			try {
952
				result.close();
953
			} catch (SQLException e1) {
954
				// ignored
955
			}
956
		}
957
//		this.logWriter.print(", db="+(System.currentTimeMillis()-start)+") "); //$NON-NLS-1$ //$NON-NLS-2$
958
		if (DEBUG) LOG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
959
	}
960
	return null;
961
}
962
*/
963
private void internalQueryScenarioValues(ScenarioResults scenarioResults, String configPattern) {
964
	if (fSQL == null) return;
965
	long start = System.currentTimeMillis();
966
	if (DEBUG) LOG_WRITER.print("	- DB query all data points for config pattern: "+configPattern+" for scenario: " + scenarioResults.getShortName()); //$NON-NLS-1$ //$NON-NLS-2$
967
	internalQueryAllVariations(configPattern); // need to read all variations to have all build names
968
	ResultSet result = null;
969
	try {
970
		int count = 0;
971
		result = fSQL.queryScenarioDataPoints(configPattern, scenarioResults.getId());
972
		while (result.next()) {
973
			int dp_id = result.getInt(1);
974
			int step = result.getInt(2);
975
			String variation = result.getString(3); //  something like "||build=I20070615-1200||config=eclipseperfwin2_R3.3||jvm=sun|"
976
			StringTokenizer tokenizer = new StringTokenizer(variation, "=|"); //$NON-NLS-1$
977
			tokenizer.nextToken(); 									// 'build'
978
			String buildName = tokenizer.nextToken();	// 'I20070615-1200'
979
			tokenizer.nextToken();									// 'config'
980
			int config_id = getConfigId(tokenizer.nextToken()); 			// 'eclipseperfwin2_R3.3'
981
			int build_id = getBuildId(buildName);
982
			ResultSet rs2 = fSQL.queryDimScalars(dp_id);
983
			while (rs2.next()) {
984
				int dim_id = rs2.getInt(1);
985
				long value = rs2.getBigDecimal(2).longValue();
986
				scenarioResults.setValue(build_id, dim_id, config_id, step, value);
987
				count++;
988
			}
989
		}
990
		if (DEBUG) LOG_WRITER.println("		-> " + count + " values read in " + (System.currentTimeMillis() - start) + "ms]");  //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
991
	} catch (SQLException e) {
992
		PerformanceTestPlugin.log(e);
993
	} finally {
994
		if (result != null) {
995
			try {
996
				result.close();
997
			} catch (SQLException e1) {
998
				// ignored
999
			}
1000
		}
1001
	}
1002
}
1003
private void internalQueryScenarioFailures(ScenarioResults scenarioResults, String config, BuildResults currentBuild, BuildResults baselineBuild) {
1004
	if (fSQL == null) return;
1005
	long start = System.currentTimeMillis();
1006
	if (DEBUG) LOG_WRITER.print("	- DB query all failures for config pattern: "+config+" for scenario : "+scenarioResults.getShortName()+"..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1007
	ResultSet result = null;
1008
	try {
1009
		String currentBuildName = currentBuild.getName();
1010
		String baselineBuildName = baselineBuild.getName();
1011
		result = fSQL.queryScenarioFailures(scenarioResults.getId(), config, currentBuildName, baselineBuildName);
1012
		while (result.next()) {
1013
			String variation = result.getString(1);
1014
			String failure = result.getString(2);
1015
			StringTokenizer tokenizer = new StringTokenizer(variation, "=|"); //$NON-NLS-1$
1016
			tokenizer.nextToken(); 									// 'build'
1017
			String buildName = tokenizer.nextToken();	// 'I20070615-1200'
1018
//			tokenizer.nextToken();									// 'config'
1019
//			String configName = tokenizer.nextToken();	// 'eclipseperfwin2_R3.3'
1020
//			int config_id = getConfigId(configName);
1021
			if (buildName.equals(currentBuildName)) {
1022
				currentBuild.setFailure(failure);
1023
			} else if (buildName.equals(baselineBuildName)) {
1024
				baselineBuild.setFailure(failure);
1025
			}
1026
		}
1027
	} catch (SQLException e) {
1028
		PerformanceTestPlugin.log(e);
1029
1030
	} finally {
1031
		if (result != null) {
1032
			try {
1033
				result.close();
1034
			} catch (SQLException e1) {
1035
				// ignored
1036
			}
1037
		}
1038
//		this.logWriter.print(", db="+(System.currentTimeMillis()-start)+") "); //$NON-NLS-1$ //$NON-NLS-2$
1039
		if (DEBUG) LOG_WRITER.println("	-> done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
1040
	}
1041
}
1042
1043
private void internalQueryScenarioSummaries(ScenarioResults scenarioResults, String config, BuildResults currentBuild, BuildResults baselineBuild) {
1044
	if (fSQL == null) return;
1045
	long start = System.currentTimeMillis();
1046
	if (DEBUG) LOG_WRITER.print("	- DB query all summaries for config: "+config+" for scenario: "+scenarioResults.getShortName()+"..."); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
1047
	internalQueryAllComments();
1048
	ResultSet result = null;
1049
	try {
1050
		String currentBuildName = currentBuild.getName();
1051
		String baselineBuildName = baselineBuild.getName();
1052
		result = fSQL.queryScenarioSummaries(scenarioResults.getId(), config, currentBuild.getName(), baselineBuild.getName());
1053
		while (result.next()) {
1054
			String variation = result.getString(1);
1055
			int summaryKind = result.getShort(2);
1056
			int comment_id = result.getInt(3);
1057
			StringTokenizer tokenizer = new StringTokenizer(variation, "=|"); //$NON-NLS-1$
1058
			tokenizer.nextToken(); 									// 'build'
1059
			String buildName = tokenizer.nextToken();	// 'I20070615-1200'
1060
//			tokenizer.nextToken();									// 'config'
1061
//			String configName = tokenizer.nextToken();	// 'eclipseperfwin2_R3.3'
1062
//			int config_id = getConfigId(configName);
1063
			BuildResults buildResults = null;
1064
			if (buildName.equals(currentBuildName)) {
1065
				buildResults = currentBuild;
1066
			} else if (buildName.equals(baselineBuildName)) {
1067
				buildResults = baselineBuild;
1068
			}
1069
			buildResults.setSummary(summaryKind, COMMENTS[comment_id]);
1070
		}
1071
	} catch (SQLException e) {
1072
		PerformanceTestPlugin.log(e);
1073
	} finally {
1074
		if (result != null) {
1075
			try {
1076
				result.close();
1077
			} catch (SQLException e1) {
1078
				// ignored
1079
			}
1080
		}
1081
		if (DEBUG) LOG_WRITER.println("done in " + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
1082
	}
1083
}
1084
1085
/*
1086
 * Store a component in the dynamic list. The list is sorted alphabetically.
1087
 */
1088
private int storeComponent(String component) {
1089
	if (COMPONENTS == null) {
1090
		COMPONENTS = new String[SUPPORTED_COMPONENTS.length];
1091
	}
1092
	int idx = Arrays.binarySearch(SUPPORTED_COMPONENTS, component);
1093
	if (idx < 0) {
1094
		throw new RuntimeException("Unexpected component name: "+component); //$NON-NLS-1$
1095
	}
1096
	if (COMPONENTS[idx] == null) {
1097
		COMPONENTS[idx] = SUPPORTED_COMPONENTS[idx];
1098
	}
1099
	return idx;
1100
}
1101
1102
/*
1103
 * Store a build name in the dynamic list.
1104
 * The list is sorted alphabetically.
1105
 */
1106
private int storeBuildName(String build) {
1107
	if (BUILDS == null) {
1108
		BUILDS = new String[1];
1109
		BUILDS[BUILDS_LENGTH++] = build;
1110
		return 0;
1111
	}
1112
	int idx = Arrays.binarySearch(BUILDS, build);
1113
	if (idx >= 0) return idx;
1114
	int index = -idx-1;
1115
	int length = BUILDS.length;
1116
	if (BUILDS_LENGTH == length) {
1117
		String[] array = new String[length+1];
1118
		if (index > 0) System.arraycopy(BUILDS, 0, array, 0, index);
1119
		array[index] = build;
1120
		if (index < length) System.arraycopy(BUILDS, index+1, array, 0, length-index);
1121
		BUILDS = array;
1122
	} else if (index < length) {
1123
		System.arraycopy(BUILDS, index, BUILDS, index+1, length-index);
1124
		BUILDS[index] = build;
1125
	}
1126
	BUILDS_LENGTH++;
1127
	return index;
1128
}
1129
1130
/*
1131
 * Store a configuration in the dynamic list.
1132
 * The list is sorted alphabetically.
1133
 */
1134
private int storeConfig(String config) {
1135
	for (int i=0; i<MAX_CONFIGS; i++) {
1136
		if (CONFIGS[i] == null) {
1137
			CONFIGS[i] = config;
1138
			return i;
1139
		}
1140
		if (config.equals(CONFIGS[i])) {
1141
			return i;
1142
		}
1143
	}
1144
	return -1;
1145
}
1146
1147
}
(-)src/org/eclipse/test/internal/performance/results/AbstractResults.java (+255 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.internal.performance.results;
12
13
import java.util.ArrayList;
14
import java.util.Iterator;
15
import java.util.List;
16
17
import org.eclipse.test.internal.performance.InternalDimensions;
18
import org.eclipse.test.internal.performance.data.Dim;
19
20
/**
21
 * Abstract class to store performance results.
22
 * 
23
 * Each results gives access to specific children depending on model.
24
 */
25
public abstract class AbstractResults implements Comparable {
26
27
	/**
28
	 * The lis of supported dimensions.
29
	 * <p>
30
	 * Currently only {@link InternalDimensions#ELAPSED_PROCESS}
31
	 * and {@link InternalDimensions#CPU_TIME}.
32
	 */
33
	public final static Dim[] SUPPORTED_DIMS = {
34
		InternalDimensions.ELAPSED_PROCESS,
35
		InternalDimensions.CPU_TIME
36
	};
37
38
	/**
39
	 * The list of possible configurations.
40
	 * <p>
41
	 * Only used if no specific configurations are specified
42
	 * (see {@link PerformanceResults#read(String[][], String)}.
43
	 */
44
	public final static String[] CONFIGS = {
45
		"eclipseperflnx3_R3.3", //$NON-NLS-1$
46
		"eclipseperfwin2_R3.3", //$NON-NLS-1$
47
		"eclipseperflnx2_R3.3", //$NON-NLS-1$
48
		"eclipseperfwin1_R3.3", //$NON-NLS-1$
49
		"eclipseperflnx1_R3.3", //$NON-NLS-1$
50
	};
51
52
	/**
53
	 * The list of possible test boxes.
54
	 * <p>
55
	 * Only used if no specific configurations are specified
56
	 * (see {@link PerformanceResults#read(String[][], String)}.
57
	 */
58
	public final static String[] BOXES = {
59
		"RHEL 4.0 Sun 1.4.2_10 (3 GHz 2.5 GB)", //$NON-NLS-1$
60
		"Win XP Sun 1.4.2_10 (3 GHz 2 GB)", //$NON-NLS-1$
61
		"RHEL 3.0 Sun 1.4.2_10 (3 GHz 2 GB)", //$NON-NLS-1$
62
		"Win XP Sun 1.4.2_10 (2 GHz 512 MB)", //$NON-NLS-1$
63
		"RHEL 3.0 Sun 1.4.2_10 (2 GHz 512 MB)", //$NON-NLS-1$
64
	};
65
66
67
	AbstractResults parent;
68
	int id = -1;
69
	String name;
70
	List children;
71
	private boolean newLine = true;
72
	boolean print = false;
73
74
static Dim getDimension(int id) {
75
	int length = SUPPORTED_DIMS.length;
76
	for (int i=0; i<length; i++) {
77
		if (SUPPORTED_DIMS[i].getId() == id) {
78
			return SUPPORTED_DIMS[i];
79
		}
80
	}
81
	return null;
82
}
83
84
AbstractResults(AbstractResults parent, String name) {
85
	this.parent = parent;
86
	this.children = new ArrayList();
87
	this.name = name;
88
}
89
90
AbstractResults(AbstractResults parent, int id) {
91
	this.parent = parent;
92
	this.children = new ArrayList();
93
	this.id = id;
94
}
95
96
/*
97
 * Add a child to current results, using specific sort
98
 * order if specified.
99
 */
100
void addChild(Comparable child, boolean sort) {
101
	if (sort) {
102
		int size = this.children.size();
103
		for (int i=0; i<size; i++) {
104
			Object results = this.children.get(i);
105
			if (child.compareTo(results) < 0) {
106
				this.children.add(i, child);
107
				return;
108
			}
109
		}
110
	}
111
	this.children.add(child);
112
}
113
114
/**
115
 * Compare the results to the given one using the name.
116
 * 
117
 * @see java.lang.Comparable#compareTo(java.lang.Object)
118
 */
119
public int compareTo(Object obj) {
120
	if (obj instanceof AbstractResults) {
121
		AbstractResults res = (AbstractResults) obj;
122
		return getName().compareTo(res.getName());
123
	}
124
	return -1;
125
}
126
127
/**
128
 * Returns whether two results are equals using the name
129
 * to compare them.
130
 * 
131
 * @param obj  The results to compare with
132
 * @return <code>true</code> if the name are equals,
133
 * 	<code>false</code> otherwise
134
 * @see java.lang.Comparable#compareTo(java.lang.Object)
135
 */
136
public boolean equals(Object obj) {
137
	if (obj instanceof AbstractResults) {
138
		return this.name.equals(((AbstractResults)obj).getName());
139
	}
140
	return super.equals(obj);
141
}
142
143
int getId() {
144
	return this.id;
145
}
146
147
/**
148
 * Returns the name of the results object.
149
 * 
150
 * @return The name of the results
151
 */
152
public String getName() {
153
	return this.name;
154
}
155
156
PerformanceResults getPerformance() {
157
	if (this.parent != null) {
158
		return this.parent.getPerformance();
159
	}
160
	return null;
161
}
162
163
String getPath() {
164
	String path = this.parent==null || this.parent.parent==null ? "" : this.parent.getPath() + ">"; //$NON-NLS-1$ //$NON-NLS-2$
165
	return path+this.name;
166
}
167
168
/**
169
 * Return the children list of the current results.
170
 * 
171
 * @return An iterator on the children list
172
 */
173
public Iterator getResults() {
174
	return this.children.iterator();
175
}
176
177
AbstractResults getResults(String resultName) {
178
	int size = this.children.size();
179
	for (int i=0; i<size; i++) {
180
		AbstractResults searchedResults = (AbstractResults) this.children.get(i);
181
		if (searchedResults.getName().equals(resultName)) {
182
			return searchedResults;
183
		}
184
	}
185
	return null;
186
}
187
188
AbstractResults getResults(int searchedId) {
189
	int size = this.children.size();
190
	for (int i=0; i<size; i++) {
191
		AbstractResults searchedResults = (AbstractResults) this.children.get(i);
192
		if (searchedResults.id == searchedId) {
193
			return searchedResults;
194
		}
195
	}
196
	return null;
197
}
198
199
public int hashCode() {
200
	return this.name.hashCode();
201
}
202
203
void printTab() {
204
	if (this.parent != null) {
205
		if (this.print) System.out.print("\t"); //$NON-NLS-1$
206
		this.parent.printTab();
207
	}
208
}
209
void print(String text) {
210
	if (this.print) {
211
		if (this.newLine) printTab();
212
		System.out.print(text);
213
		this.newLine = false;
214
	}
215
}
216
217
void printGlobalTime(long start) {
218
	printGlobalTime(start, null);
219
}
220
221
void printGlobalTime(long start, String end) {
222
	StringBuffer buffer = new StringBuffer("=> time spent in '"); //$NON-NLS-1$
223
	buffer.append(this.name);
224
	buffer.append("' was "); //$NON-NLS-1$
225
	buffer.append((System.currentTimeMillis()-start)/1000.0);
226
	if (end == null) {
227
		buffer.append('s');
228
	} else {
229
		buffer.append("s. "); //$NON-NLS-1$
230
		buffer.append(end.trim());
231
	}
232
	println(buffer);
233
}
234
235
void println(String text) {
236
	if (this.print) {
237
		if (this.newLine) printTab();
238
		System.out.println(text);
239
		this.newLine = true;
240
	}
241
}
242
243
void println(StringBuffer buffer) {
244
	println(buffer.toString());
245
}
246
247
public int size() {
248
	return this.children == null ? 0 : this.children.size();
249
}
250
251
public String toString() {
252
	return getPath();
253
}
254
255
}
(-)src/org/eclipse/test/internal/performance/results/ComponentResults.java (+75 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.internal.performance.results;
12
13
import java.util.ArrayList;
14
import java.util.List;
15
16
/**
17
 * Class to handle performance results of an eclipse component
18
 * (for example 'org.eclipse.jdt.core').
19
 * 
20
 * It gives access to results for each scenario run for this component.
21
 * 
22
 * @see ScenarioResults
23
 */
24
public class ComponentResults extends AbstractResults {
25
26
public ComponentResults(AbstractResults parent, String name) {
27
	super(parent, name);
28
	this.print = parent.print;
29
}
30
31
ComponentResults getComponent() {
32
	return this;
33
}
34
35
/**
36
 * Returns a list of scenario results which have a summary
37
 * 
38
 * @param global Indicates whether the summary must be global or not.
39
 * @param config Configuration name
40
 * @return A list of {@link ScenarioResults scenario results} which have a summary
41
 */
42
public List getSummaryScenarii(boolean global, String config) {
43
	int size= size();
44
	List scenarii = new ArrayList(size);
45
	for (int i=0; i<size; i++) {
46
		ScenarioResults scenarioResults = (ScenarioResults) this.children.get(i);
47
		ConfigResults configResults = scenarioResults.getConfigResults(config);
48
		if (configResults != null) {
49
			BuildResults buildResults = configResults.getCurrentBuildResults();
50
			if ((global && buildResults.summaryKind == 1) || (!global && buildResults.summaryKind >= 0)) {
51
				scenarii.add(scenarioResults);
52
			}
53
		}
54
	}
55
	return scenarii;
56
}
57
58
/*
59
 * Read performance results information available in three maps.
60
 */
61
void read(List scenarii) {
62
	println("Component '"+this.name+"':"); //$NON-NLS-1$ //$NON-NLS-2$
63
	long start = System.currentTimeMillis();
64
	int size = scenarii.size();
65
	for (int i=0; i<size; i++) {
66
		ScenarioResults scenarioResults= (ScenarioResults) scenarii.get(i);
67
		scenarioResults.parent = this;
68
		scenarioResults.print = this.print;
69
		scenarioResults.read();
70
		addChild(scenarioResults, true);
71
	}
72
	printGlobalTime(start);
73
}
74
75
}
(-)src/org/eclipse/test/internal/performance/results/SQL_Results.java (+202 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2005 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.internal.performance.results;
12
13
import java.sql.Connection;
14
import java.sql.PreparedStatement;
15
import java.sql.ResultSet;
16
import java.sql.SQLException;
17
18
import org.eclipse.test.internal.performance.InternalDimensions;
19
import org.eclipse.test.internal.performance.db.SQL;
20
21
/**
22
 * Specific implementation for massive database requests.
23
 */
24
public class SQL_Results extends SQL {
25
26
	private PreparedStatement queryBuildScenarii, queryScenarioFailures, queryScenarioSummaries, queryAllComments, queryScenariiBuilds, queryScenarioDataPoints, queryDimScalars, queryAllVariations;
27
28
29
SQL_Results(Connection con) throws SQLException {
30
	    super(con);
31
	    // TODO Auto-generated constructor stub
32
    }
33
34
protected void dispose() throws SQLException {
35
	super.dispose();
36
	if (this.queryBuildScenarii != null)
37
		this.queryBuildScenarii.close();
38
	if (this.queryScenarioFailures != null)
39
		this.queryScenarioFailures.close();
40
	if (this.queryScenarioSummaries != null)
41
		this.queryScenarioSummaries.close();
42
	if (this.queryAllComments != null)
43
		this.queryAllComments.close();
44
	if (this.queryScenariiBuilds != null)
45
		this.queryScenariiBuilds.close();
46
	if (this.queryScenarioDataPoints != null)
47
		this.queryScenarioDataPoints.close();
48
	if (this.queryDimScalars != null)
49
		this.queryDimScalars.close();
50
	if (this.queryAllVariations != null)
51
		this.queryAllVariations.close();
52
}
53
54
/**
55
 * Get all comments from database
56
 *
57
 * @return A set of the query result
58
 * @throws SQLException
59
 */
60
ResultSet queryAllComments() throws SQLException {
61
	if (this.queryAllComments == null)
62
		this.queryAllComments = fConnection.prepareStatement("select ID, KIND, TEXT from COMMENT"); //$NON-NLS-1$
63
	return this.queryAllComments.executeQuery();
64
}
65
66
/**
67
 * Get all variations from database.
68
 *
69
 * @param configPattern The pattern for all the concerned configurations
70
 * @return A set of the query result
71
 * @throws SQLException
72
 */
73
ResultSet queryAllVariations(String configPattern) throws SQLException {
74
	long start = System.currentTimeMillis();
75
	if (DB_Results.DEBUG) DB_Results.LOG_WRITER.print("[SQL query (config pattern="+configPattern); //$NON-NLS-1$
76
	if (this.queryAllVariations == null) {
77
		this.queryAllVariations = fConnection.prepareStatement("select KEYVALPAIRS from VARIATION where KEYVALPAIRS like ? order by KEYVALPAIRS"); //$NON-NLS-1$
78
	}
79
	this.queryAllVariations.setString(1, "%"+configPattern+"%"); //$NON-NLS-1$ //$NON-NLS-2$
80
	ResultSet resultSet =  this.queryAllVariations.executeQuery();
81
	if (DB_Results.DEBUG) DB_Results.LOG_WRITER.print(")=" + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
82
	return resultSet;
83
}
84
85
/**
86
 * Query all scenarii corresponding to a given scenario pattern
87
 * and for a specific build name.
88
 *
89
 * @param scenarioPattern The pattern for all the concerned scenarii
90
 * @param buildName The name of the concerned build
91
 * @return Set of the query result
92
 * @throws SQLException
93
 */
94
ResultSet queryBuildScenarii(String scenarioPattern, String buildName) throws SQLException {
95
	if (this.queryBuildScenarii == null) {
96
		String statement = "select distinct SCENARIO.ID, SCENARIO.NAME , SCENARIO.SHORT_NAME from SCENARIO, SAMPLE, VARIATION where " + //$NON-NLS-1$
97
			"SAMPLE.VARIATION_ID = VARIATION.ID and VARIATION.KEYVALPAIRS LIKE ? and " + //$NON-NLS-1$
98
			"SAMPLE.SCENARIO_ID = SCENARIO.ID and SCENARIO.NAME LIKE ? " + //$NON-NLS-1$
99
			"order by SCENARIO.NAME"; //$NON-NLS-1$
100
		this.queryBuildScenarii = fConnection.prepareStatement(statement);
101
	}
102
	this.queryBuildScenarii.setString(1, "|build=" + buildName + '%'); //$NON-NLS-1$
103
	this.queryBuildScenarii.setString(2, scenarioPattern);
104
	return this.queryBuildScenarii.executeQuery();
105
}
106
107
/**
108
 * Query all scalars for a given data point.
109
 * 
110
 * @param datapointId The id of the data point
111
 * @return Set of the query result
112
 * @throws SQLException
113
 */
114
ResultSet queryDimScalars(int datapointId) throws SQLException {
115
	if (this.queryDimScalars == null) {
116
		this.queryDimScalars = fConnection.prepareStatement("select DIM_ID, VALUE from SCALAR where " + //$NON-NLS-1$
117
			"DATAPOINT_ID = ? and " + //$NON-NLS-1$
118
			"(DIM_ID = "+InternalDimensions.CPU_TIME.getId()+" or DIM_ID = "+InternalDimensions.ELAPSED_PROCESS.getId()+") " +   //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
119
			"order by DIM_ID");  //$NON-NLS-1$
120
	}
121
	this.queryDimScalars.setInt(1, datapointId);
122
	return this.queryDimScalars.executeQuery();
123
}
124
125
/**
126
 * Get all data points for a given scenario and configuration.
127
 *
128
 * @param config The name of the concerned configuration
129
 * @param scenarioID The id of the scenario
130
 * @return A set of the query result
131
 * @throws SQLException
132
 */
133
ResultSet queryScenarioDataPoints(String config, int scenarioID) throws SQLException {
134
	long start = System.currentTimeMillis();
135
	if (DB_Results.DEBUG) DB_Results.LOG_WRITER.print("[SQL query (config="+config+", scenario ID="+scenarioID); //$NON-NLS-1$ //$NON-NLS-2$
136
	if (this.queryScenarioDataPoints== null) {
137
		String statement = "select DATAPOINT.ID, DATAPOINT.STEP, VARIATION.KEYVALPAIRS from VARIATION, SAMPLE, DATAPOINT where " + //$NON-NLS-1$
138
			"VARIATION.KEYVALPAIRS like ? and SAMPLE.VARIATION_ID = VARIATION.ID and " + //$NON-NLS-1$
139
			"SAMPLE.SCENARIO_ID = ? and " + //$NON-NLS-1$
140
			"DATAPOINT.SAMPLE_ID = SAMPLE.ID " + //$NON-NLS-1$
141
			"ORDER BY DATAPOINT.ID, DATAPOINT.STEP"; //$NON-NLS-1$
142
		this.queryScenarioDataPoints = fConnection.prepareStatement(statement);
143
	}
144
	this.queryScenarioDataPoints.setString(1, "%"+config+"%"); //$NON-NLS-1$ //$NON-NLS-2$
145
	this.queryScenarioDataPoints.setInt(2, scenarioID);
146
	ResultSet resultSet =  this.queryScenarioDataPoints.executeQuery();
147
	if (DB_Results.DEBUG) DB_Results.LOG_WRITER.print(")=" + (System.currentTimeMillis() - start) + "ms]"); //$NON-NLS-1$ //$NON-NLS-2$
148
	return resultSet;
149
}
150
151
/**
152
 * Query all failures from database for a given scenario,
153
 * configuration and builds.
154
 *
155
 * @param config The name of the concerned configuration
156
 * @param scenarioID The id of the scenario
157
 * @param currentBuildName The name of the current build
158
 * @param baselineBuildName The name of the baseline build
159
 * @return A set of the query result
160
 * @throws SQLException
161
 */
162
ResultSet queryScenarioFailures(int scenarioID, String config, String currentBuildName, String baselineBuildName) throws SQLException {
163
	if (this.queryScenarioFailures == null) {
164
		this.queryScenarioFailures = fConnection.prepareStatement("select KEYVALPAIRS, MESSAGE from VARIATION, FAILURE where " + //$NON-NLS-1$
165
			"(KEYVALPAIRS like ? or KEYVALPAIRS like ?) and " + //$NON-NLS-1$
166
			"VARIATION_ID = VARIATION.ID and " + //$NON-NLS-1$
167
			"SCENARIO_ID = ? " + //$NON-NLS-1$
168
			"ORDER BY VARIATION_ID"); //$NON-NLS-1$
169
	}
170
	this.queryScenarioFailures.setString(1, "|build=" + currentBuildName+ "||config="+ config + "||jvm=sun|"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
171
	this.queryScenarioFailures.setString(2, "|build=" + baselineBuildName+ "||config="+ config + "||jvm=sun|"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
172
	this.queryScenarioFailures.setInt(3, scenarioID);
173
	return this.queryScenarioFailures.executeQuery();
174
}
175
176
/**
177
 * Query all summaries from database for a given scenario,
178
 * configuration and builds.
179
 *
180
 * @param config The name of the concerned configuration
181
 * @param scenarioID The id of the scenario
182
 * @param currentBuildName The name of the current build
183
 * @param baselineBuildName The name of the baseline build
184
 * @return Set of the query result
185
 * @throws SQLException
186
 */
187
ResultSet queryScenarioSummaries(int scenarioID, String config, String currentBuildName, String baselineBuildName) throws SQLException {
188
	if (this.queryScenarioSummaries == null) {
189
		this.queryScenarioSummaries= fConnection.prepareStatement("select KEYVALPAIRS, IS_GLOBAL, COMMENT_ID from VARIATION, SUMMARYENTRY where " + //$NON-NLS-1$
190
			"(KEYVALPAIRS like ? or KEYVALPAIRS like ?) and " + //$NON-NLS-1$
191
			"VARIATION_ID = VARIATION.ID and " + //$NON-NLS-1$
192
			"SCENARIO_ID = ? and " + //$NON-NLS-1$
193
			"DIM_ID = " + InternalDimensions.ELAPSED_PROCESS.getId() + //$NON-NLS-1$
194
			" order by VARIATION_ID"); //$NON-NLS-1$
195
	}
196
	this.queryScenarioSummaries.setString(1, "|build=" + currentBuildName+ "||config="+ config + "||jvm=sun|"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
197
	this.queryScenarioSummaries.setString(2, "|build=" + baselineBuildName+ "||config="+ config + "||jvm=sun|"); //$NON-NLS-1$ //$NON-NLS-2$ //$NON-NLS-3$
198
	this.queryScenarioSummaries.setInt(3, scenarioID);
199
	return this.queryScenarioSummaries.executeQuery();
200
}
201
202
}
(-)src/org/eclipse/test/internal/performance/results/BuildResults.java (+366 lines)
Added Link Here
1
/*******************************************************************************
2
 * Copyright (c) 2000, 2006 IBM Corporation and others.
3
 * All rights reserved. This program and the accompanying materials
4
 * are made available under the terms of the Eclipse Public License v1.0
5
 * which accompanies this distribution, and is available at
6
 * http://www.eclipse.org/legal/epl-v10.html
7
 *
8
 * Contributors:
9
 *     IBM Corporation - initial API and implementation
10
 *******************************************************************************/
11
package org.eclipse.test.internal.performance.results;
12
13
import java.text.ParseException;
14
import java.text.SimpleDateFormat;
15
import java.util.StringTokenizer;
16
17
import org.eclipse.test.internal.performance.InternalPerformanceMeter;
18
import org.eclipse.test.internal.performance.data.Dim;
19
20
/**
21
 * Class providing numbers of a scenario running on a specific configuration
22
 * at a specific time (for example 'I20070615-1200').
23
 */
24
public class BuildResults extends AbstractResults {
25
26
	// Build information
27
	String date;
28
	boolean baseline;
29
	String failure;
30
	String comment;
31
	int summaryKind = -1;
32
33
	// Dimensions informations
34
	Dim[] dimensions;
35
	double[] average, stddev;
36
	long[] count;
37
	double[][] values;
38
39
BuildResults(AbstractResults parent, int id) {
40
	super(parent, id);
41
	this.name = DB_Results.getBuildName(id);
42
	this.baseline = this.name.startsWith(parent.getPerformance().getBaselinePrefix());
43
}
44
45
/*
46
 * Clean values when several measures has been done for the same build.
47
 */
48
void cleanValues() {
49
	int length = values.length;
50
	for (int dim_id=0; dim_id<length; dim_id++) {
51
		int vLength = values[dim_id].length;
52
		/* Log clean operation
53
		if (dim_id == 0) {
54
			IStatus status = new Status(IStatus.WARNING, PerformanceTestPlugin.PLUGIN_ID, "Clean "+vLength+" values for "+this.parent+">"+this.name+" ("+this.count[dim_id]+" measures)...");    //$NON-NLS-1$//$NON-NLS-2$//$NON-NLS-3$//$NON-NLS-4$ //$NON-NLS-5$
55
			PerformanceTestPlugin.log(status);
56
		}
57
		*/
58
		for (int i=0; i<vLength; i++) {
59
			this.average[dim_id] += values[dim_id][i];
60
		}
61
		this.average[dim_id] /= vLength;
62
		double squaredDeviations= 0;
63
		for (int i=0; i<vLength; i++) {
64
		    double deviation= this.average[dim_id] - values[dim_id][i];
65
		    squaredDeviations += deviation * deviation;
66
		}
67
		this.stddev[dim_id] = Math.sqrt(squaredDeviations / (this.count[dim_id] - 1)); // unbiased sample stdev
68
		this.values[dim_id] = null;
69
	}
70
	for (int i=0; i<length; i++) {
71
		if (this.values[i] != null) {
72
			return;
73
		}
74
	}
75
	this.values = null;
76
}
77
78
/**
79
 * Compare build results using the date of the build.
80
 * 
81
 * @see Comparable#compareTo(Object)
82
 */
83
public int compareTo(Object obj) {
84
	if (obj instanceof BuildResults) {
85
		BuildResults res = (BuildResults) obj;
86
		return getDate().compareTo(res.getDate());
87
	}
88
	return -1;
89
}
90
91
/**
92
 * Returns the comment associated with the scenario for the current build.
93
 *
94
 * @return The comment associated with the scenario for the current build
95
 * 	or <code>null</code> if no comment was stored for it.
96
 */
97
public String getComment() {
98
	if (this.comment == null) {
99
		return null;
100
	}
101
	return this.comment;
102
}
103
104
/*
105
 * Return the number of stored values for the given dimension
106
 *  (see {@link Dim#getId()})
107
 */
108
long getCount(int dim_id) {
109
	return this.count[getDimIndex(dim_id)];
110
}
111
112
/**
113
 * Returns the date of the build which is a part of its name.
114
 *
115
 * @return The date of the build as YYYYMMDD
116
 */
117
public String getDate() {
118
	if (this.date == null) {
119
		if (this.baseline) {
120
			int length = this.name.length();
121
			this.date = this.name.substring(length-12, length);
122
		} else {
123
			char first = this.name.charAt(0);
124
			if (first == 'N' || first == 'I' || first == 'M') { // TODO (frederic) should be buildIdPrefixes...
125
				this.date = this.name.substring(1, 9)+this.name.substring(10, 14);
126
			} else {
127
				SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmm"); //$NON-NLS-1$
128
				int length = this.name.length() - 12 /* length of date */;
129
				for (int i=0; i<=length; i++) {
130
					try {
131
						String substring = i == 0 ? this.name : this.name.substring(i);
132
						format.parse(substring);
133
						this.date = substring; // if no exception is raised then the substring has a correct date format => store it
134
						break;
135
					} catch(ParseException ex) {
136
						// skip
137
					}
138
				}
139
			}
140
		}
141
	}
142
	return this.date;
143
}
144
145
/**
146
 * Returns the standard deviation of the given dimension computed
147
 * while running the scenario for the current build.
148
 * 
149
 * @param dim_id The id of the dimension (see {@link Dim#getId()})
150
 * @return The value of the standard deviation
151
 */
152
public double getDeviation(int dim_id) {
153
	return this.stddev[getDimIndex(dim_id)];
154
}
155
156
/*
157
 * Return the index of the dimension corresponding to the given
158
 * dimension id (see {@link Dim#getId()})
159
 */
160
int getDimIndex(int dim_id) {
161
	if (this.dimensions == null) return -1;
162
	int length = this.dimensions.length;
163
	for (int i=0; i<length; i++) {
164
		if (this.dimensions[i] == null) break;
165
		if (this.dimensions[i].getId() == dim_id) {
166
			return i;
167
		}
168
	}
169
	return -1;
170
}
171
172
/*
173
 * Return the error computed while storing values for the given dimension
174
 *  (see {@link Dim#getId()})
175
 */
176
double getError(int dim_id) {
177
	long n = getCount(dim_id);
178
	if (n == 1) return Double.NaN;
179
	return getDeviation(dim_id) / Math.sqrt(n);
180
}
181
182
/**
183
 * Return the failure message which may happened on this scenario
184
 * while running the current build
185
 *
186
 * @return The failure message or <code>null</null> if the scenario passed.
187
 */
188
public String getFailure() {
189
	if (this.failure == null) {
190
		return null;
191
	}
192
	return this.failure;
193
}
194
195
/**
196
 * Return the value of the performance result stored
197
 * for the given dimension of the current build.
198
 * 
199
 * @param dim_id The id of the dimension (see {@link Dim#getId()})
200
 * @return The value of the performance result
201
 */
202
public double getValue(int dim_id) {
203
	return this.average[getDimIndex(dim_id)];
204
}
205
206
/**
207
 * Returns whether the build is a baseline build or not.
208
 * 
209
 * @return <code>true</code> if the build name starts with the baseline prefix
210
 * 	(see {@link PerformanceResults#getBaselinePrefix()} or <code>false</code>
211
 * 	otherwise.
212
 */
213
public boolean isBaseline() {
214
	return baseline;
215
}
216
217
/**
218
 * Returns whether the build has a summary or not. Note that the summary
219
 * may be global or not.
220
 * 
221
 * @return <code>true</code> if the summary kind is equals to 0 or 1
222
 * 	<code>false</code> otherwise.
223
 */
224
public boolean hasSummary() {
225
	return this.summaryKind >= 0;
226
}
227
/**
228
 * Returns whether the build has a global summary or not.
229
 * 
230
 * @return <code>true</code> if the summary kind is equals to 1
231
 * 	<code>false</code> otherwise.
232
 */
233
public boolean hasGlobalSummary() {
234
	return this.summaryKind == 1;
235
}
236
237
/*
238
 * Returns a given pattern match the build name or not.
239
 */
240
boolean match(String pattern) {
241
	if (pattern.equals("*")) return true; //$NON-NLS-1$
242
	if (pattern.indexOf('*') < 0 && pattern.indexOf('?') < 0) {
243
		pattern += "*"; //$NON-NLS-1$
244
	}
245
	StringTokenizer tokenizer = new StringTokenizer(pattern, "*?", true); //$NON-NLS-1$
246
	int start = 0;
247
	String previous = ""; //$NON-NLS-1$
248
	while (tokenizer.hasMoreTokens()) {
249
		String token = tokenizer.nextToken();
250
		if (!token.equals("*") && !token.equals("?")) { //$NON-NLS-1$ //$NON-NLS-2$
251
			if (previous.equals("*")) { //$NON-NLS-1$
252
				int idx = this.name.substring(start).indexOf(token);
253
				if (idx < 0) return false;
254
				start += idx;
255
			} else {
256
				if (previous.equals("?")) start++; //$NON-NLS-1$
257
				if (!name.substring(start).startsWith(token)) return false;
258
			}
259
			start += token.length();
260
		}
261
		previous = token;
262
	}
263
	if (previous.equals("*")) { //$NON-NLS-1$
264
		return true;
265
	} else if (previous.equals("?")) { //$NON-NLS-1$
266
		return this.name.length() == start;
267
	}
268
	return this.name.endsWith(previous);
269
}
270
271
/*
272
 * Set the build summary and its associated comment.
273
 */
274
void setSummary(int kind, String comment) {
275
	this.comment = comment;
276
	this.summaryKind = kind;
277
}
278
279
/*
280
 * Set the build failure.
281
 */
282
void setFailure(String failure) {
283
	this.failure = failure;
284
}
285
286
/*
287
 * Set the build value from database information.
288
 */
289
void setValue(int dim_id, int step, long value) {
290
	int length = SUPPORTED_DIMS.length;
291
	Dim dimension = getDimension(dim_id);
292
	int idx = 0;
293
	if (this.dimensions == null){
294
		this.dimensions = new Dim[length];
295
		this.average = new double[length];
296
		this.stddev = new double[length];
297
		this.count = new long[length];
298
		this.dimensions[0] = dimension;
299
	} else {
300
		length = this.dimensions.length;
301
		for (int i=0; i<length; i++) {
302
			if (this.dimensions[i] == null) {
303
				this.dimensions[i] = dimension;
304
				idx = i;
305
				break;
306
			}
307
			if (this.dimensions[i].getId() == dim_id) {
308
				idx = i;
309
				break;
310
			}
311
		}
312
	}
313
	switch (step) {
314
		case InternalPerformanceMeter.AVERAGE:
315
			if (this.average[idx] != 0) {
316
				if (values == null) {
317
					values = new double[length][];
318
					values[idx] = new double[2];
319
					values[idx][0] = this.average[idx];
320
					values[idx][1] = value;
321
					this.average[idx] = 0;
322
				} else if (this.values[idx] == null) {
323
					values[idx] = new double[2];
324
					values[idx][0] = this.average[idx];
325
					values[idx][1] = value;
326
					this.average[idx] = 0;
327
				}
328
			} else if (this.values != null && this.values[idx] != null) {
329
				int vLength = values[idx].length;
330
				System.arraycopy(values[idx], 0, values[idx] = new double[vLength+1], 0, vLength);
331
				values[idx][vLength] = value;
332
			} else {
333
				this.average[idx] = value;
334
			}
335
			break;
336
		case InternalPerformanceMeter.STDEV:
337
			this.stddev[idx] += Double.longBitsToDouble(value);
338
			break;
339
		case InternalPerformanceMeter.SIZE:
340
			this.count[idx] += value;
341
			break;
342
	}
343
}
344
345
/* (non-Javadoc)
346
 * @see org.eclipse.test.internal.performance.results.AbstractResults#toString()
347
 */
348
public String toString() {
349
	StringBuffer buffer = new StringBuffer(this.name);
350
	buffer.append(": "); //$NON-NLS-1$
351
	int length = this.dimensions.length;
352
	for (int i=0; i<length; i++) {
353
		if (i>0)	buffer.append(", "); //$NON-NLS-1$
354
		buffer.append('[');
355
		buffer.append(dimensions[i].getId());
356
		buffer.append("]="); //$NON-NLS-1$
357
		buffer.append(average[i]);
358
		buffer.append('/');
359
		buffer.append(count[i]);
360
		buffer.append('/');
361
		buffer.append(Math.round(stddev[i]*1000)/1000.0);
362
	}
363
	return buffer.toString();
364
}
365
366
}

Return to bug 201469